Mam następujący problem. Odczytuję z urządzenia pomiarowego wartość co 5 sek, korzystając z gotowej biblioteki w C dostarczonej przez producenta. Są tp liczby typu float. Istotne jest policzenie średniej z 50 pomiarów. W tej chwili po prostu dodaję wartości kolejnych 50 pomiarów i potem dzielę przez 50. No tylko że w tym momencie mam tak naprawdę jeden wynik docelowy pomiaru co 250 sek. A mnie zależy żeby wynik docelowy pomiaru był co 5 sek. Tak więc najstarsza dodana wartość powinna być odjęta a dodana najnowsza wartość. Ma ktoś z Kolegów pomysł na parę linijek w C które by załatwiły ten problem? Proszę zauważyć że nie interesuje mnie kolejność zapisanych pomiarów ale suma ostatnich 50, zmieniana co 5 sek po nadejściu nowej wartości.
Potrzebujesz zaimplementować kolejkę / tablicę rotacyjną na 50 elementów.
Ostatni element usuwać.
Z tej tablicy liczyć sobie średnią.
Fajnie, tylko że u mnie z programowaniem kruchawo, bo to ni mój zawód.
Coś w tym stylu co niżej.
Jest to najprostsze rozwiązanie problemu.
Nie jest z pewnością optymalne. Lepiej byłoby mieć wskaźnik na kolejny element do podmiany w tablicy -> unikniemy wtedy przesuwania.
Oczywiście średnią możesz dopiero zacząć liczyć, gdy już będziesz miał pierwsze 50 elementów, czyli po czasie 50 * 5s;
#include <stdio.h>
#define MAX_ARRAY 50
int arr[MAX_ARRAY];
void newElement(int element)
{
/* shift elements */
for (int i = MAX_ARRAY-i;i>0;i--)
{
arr[i] = arr[i-1];
}
/* new element */
arr[0] = element;
}
double avg()
{
double tmp = 0.0f;
for (int i = 0 ;i<MAX_ARRAY;i++)
{
tmp += arr[i];
}
return tmp/MAX_ARRAY;
}
int main()
{
/* wait for data */
for (int i = 0 ;i < MAX_ARRAY;i++)
{
arr[i] = i;
}
printf("avg %f\n",avg());
newElement(69);
printf("avg %f\n",avg());
newElement(11);
printf("avg %f\n",avg());
for (int i = 0;i<MAX_ARRAY;i++)
{
printf("arr[%d] = %d\n",i, arr[i]);
}
}
Jasne. Dzięki Kolego, popróbuję !
Ten kod powyżej to właśnie przykład jak nie należy tego robić.
Hasła do wyszukania:
- "bufor cykliczny"
- "bufor kołowy"
Wyniki:
http://www.embeddeddev.pl/bufor-kolowy-1-zasada-dzialania/
https://darvark.wordpress.com/2014/12/07/ringbuffer-prosty-bufor-cykliczny/
Zrobiłem to bardzo prymitywnie ale skutecznie. Zrzucam wyniki pomiarów do ramdisku, każdy wynik pomiaru jest w osobnej linii. Używam 200MB ramdisk gdzie wykonuję właściwie wszystkie operacje dyskowe bo jest to Malinka a więc inaczej "zarżnął" bym kartę SD, (szczególnie plikami tymczasowymi SQL Lite).. A następnie wywołuję za pomocą instrukcji "system" funkcje bash "tail -50". Teraz pytanie jak po otworzeniu pliku w C, zsumować wszystkie liczby w kolejnych liniach. Plik przecież jest tekstowy. W bash to potrafię ale w C - nie. Jakaś pomoc?
vpiotr napisał(a):
Ten kod powyżej to właśnie przykład jak nie należy tego robić.
Hasła do wyszukania:
- "bufor cykliczny"
- "bufor kołowy"
Wyniki:
http://www.embeddeddev.pl/bufor-kolowy-1-zasada-dzialania/
https://darvark.wordpress.com/2014/12/07/ringbuffer-prosty-bufor-cykliczny/
Bufor cykliczny to pierwszy rok informatyki, względnie 3ci semestr. Tego się nie zapomina jak jazdy na rowerze.
Pewnie tak. Ja ukończyłem studia z automatyki w 1986 roku. Trochę stareńki więc jestem. A na 3 semestrze to miałem "Teorię obwodów i sygnałów" i "Analizę matematyczną". A programowałem wtedy w językach Algol, Pascal, Plan i Fortran. Tak nota bene WSZYSTKIE biblioteki matemetyczne C są napisane w Fortranie. No prawie wszystkie.
Ale to zastosowane przeze mnie rozwiązanie ma jeszcze jedną istotną zaletę z punktu widzenia urządzenia które robię. Otóż przechowywanie danych na ramdisku pozwala na łatwe synchronizowanie/przekazywanie danych do centralnego serwera i tam opracowywanie ich do formy docelowej. Tak więc - w moim konkretnym przypadku - bufor kołowy byłby właściwie przeszkodą.
To rozwiązanie które zrobiłeś jest rodem z mainframe.
OK, jeśli działa to nie ma co drążyć, miej tylko świadomość że są inne, lepsze rozwiązania.
Tak kończąc temat - faktycznie. Rodem z mainframe. Bo uważam że SNA (tak był kiedyś taki protokół sieciowy) był the best. Cała reszta w tym wszystkie dodatki do TCP/IP czy UDP to tylko próba dorównaiania temu ideałowi. Ale cóż. Stareńki już jestem i może się mylę.
Życzę zdrowia Koledze i w sumie bardzo dziękuję. Bo dzięki Tobie wpadłem na pomysł który mi teraz działa idealnie.