Zápisník experimentátora
Počas prípravy pokračovania článku o hodinách z NeoPixel Ring som napísal tento kód. Je to rýchla implementácia plávajúceho priemeru, ktorý sa hodí na vyhladzovanie meraní, ktoré mierne oscilujú okolo jednej hodnoty. Princíp plávajúceho priemeru je jednoduchý. Zaznamenávate si X hodnôt dozadu a výsledok je suma hodnôt / X. Podrobnosti o plávajúcom priemere si môžete naštudovať na stránke na Wikipédií.
Plávajúci priemer si vysvetlíme na kóde, ktorý využíva fotorezistor a analógový pin na Arduíne na meranie intenzity svetla. O meraní intenzity cez fotorezistor si môžete prečítať podrobnosti v samostatnom článku. Tu sa budeme venovať už len samotnému procesu vyhladzovania.
Ako zapojenie využijeme zapojenie z obrázka vpravo. Vcc je tam pripojené na fotorezistor, čo nám dodáva výsledky v podobe:
Zaujímavý je pre nás kód plávajúceho priemeru. Napísal som ho v podobe šablóny, ktorej nastavíte dátový typ a počet záznamov v bufferi.
///
/// Moving average
///
/// Simple moving average with fast calculation.
/// typ - any type (int, float, ...)
/// sz - size of buffer
///
template<typename typ, int sz> class MovingAverage
{
typ data[sz]; // buffer
int pos; // actual position in buffer
typ sum; // precalculated sum
public:
MovingAverage()
: pos(0), sum(0)
{
memset(data,0,sizeof(data));
}
void Push(typ value)
{
sum-=data[pos];
sum+=value;
data[pos]=value;
pos++;
if(pos==sz)
pos=0;
}
typ MA()
{
return sum/sz;
}
};
MovingAverage<uint16_t,16> ma;
A použitie v kóde je nasledovné. Meriame analógové hodnoty, zasielame ich do buffera a na ďalšie výpočty už používame hodnotu vypočítaného plávajúceho priemeru.
void loop() {
uint16_t sv = analogRead(A0);
ma.Push(sv);
uint16_t sva = ma.MA();
int svc=constrain(sva,100,900);
int m=map(svc,100,900,0,255);
Serial.print(sv);
Serial.print(", ");
Serial.print(sva);
Serial.print(", ");
Serial.print(svc);
Serial.print(", ");
Serial.print(m);
Serial.println("");
delay(1000);
}
Toto je elementárna implementácia plávajúcich priemerov, ktorá ale splní všetky bežné požiadavky. Môžete vyskúšať aj iné implementácie zo stránok Arduina.
07.08.2015