Zápisník experimentátora
Hierarchy: Sviečkové grafy
V dnešnom dieli prerobíme sviečkové grafy z celých čísiel na reálne. Toto bude iba drobná zmena voči pôvodnému algoritmu, pretože sme ho od začiatku písali cez šablóny. Vďaka tomuto kódu budeme môcť v nasledovnom článku zobrazovať reálnu teplotu zo senzora DS18B20.
Schéma zapojenia sa v ničom neodlišuje od predchádzajúcich zapojení s displejom Nokia 5110, kde sme nepotrebovali pripojiť žiadne ďalšie súčiastky. Iba Arduino, level shifter a displej Nokia 5110.
Pretože chceme používať reálne čísla namiesto celých, musíme v celom kóde nahradiť funkciu map za jej alternatívu, ktorá zvládne aj reálne čísla. Urobíme to tak, že zoberieme pôvodný zdrojový kód funkcie a urobíme z neho šablónovú funkciu, ktorá sa automaticky dokáže prispôsobiť svojim parametrom. Všetky parametre musia mať rovnaký typ a vďaka tomu vystačíme iba s jedným šablónovým parametrom.
template<typename ohlcvalue>
ohlcvalue fmap(ohlcvalue x, ohlcvalue in_min, ohlcvalue in_max, ohlcvalue out_min, ohlcvalue out_max)
{
return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}
Potom už musíme len nahradiť volania pôvodnej funkcie za novú. Pritom je rozumné, ak použijeme pretypovanie parametra na ohlcvalue, čo pomôže kompilátoru s uhádnutím toho, aké presne parametre dávame do funkcie.
template<class ohlcvalue>
class OHLCNokia5110BarRender : public OHLCNokia5110BaseRender<ohlcvalue> {
public:
void drawBar(int pos, OHLCData<ohlcvalue> *bar, ohlcvalue minimum, ohlcvalue maximum) {
if(this->display==NULL)
return;
if(minimum==maximum)
return;
OHLCData<ohlcvalue> _bar=*bar;
int START = 5 + pos * 6;
const int BW = 2;
const int HEIGHT = 47;
int top;
int bottom;
// transformation
_bar.o = fmap(_bar.o,minimum,maximum,(ohlcvalue)0,(ohlcvalue)HEIGHT);
_bar.h = fmap(_bar.h,minimum,maximum,(ohlcvalue)0,(ohlcvalue)HEIGHT);
_bar.l = fmap(_bar.l,minimum,maximum,(ohlcvalue)0,(ohlcvalue)HEIGHT);
_bar.c = fmap(_bar.c,minimum,maximum,(ohlcvalue)0,(ohlcvalue)HEIGHT);
if(_bar.o < _bar.c) {
top = _bar.c;
bottom = _bar.o;
} else {
top = _bar.o;
bottom = _bar.c;
}
// high
this->display->drawLine(START+1*BW,HEIGHT-_bar.h,START+1*BW,HEIGHT-top,BLACK);
// low
this->display->drawLine(START+1*BW,HEIGHT-_bar.l,START+1*BW,HEIGHT-bottom,BLACK);
// bar
if(_bar.o < _bar.c) {
this->display->fillRect(START,HEIGHT-bottom,2*BW+1,bottom-top+1,WHITE);
this->display->drawRect(START,HEIGHT-bottom,2*BW+1,bottom-top+1,BLACK);
}
else
this->display->fillRect(START,HEIGHT-bottom,2*BW+1,bottom-top+1,BLACK);
}
};
A to je všetko. Vidíte, že niekedy sú šablóny úžasná vec, ako sa veľa nenarobiť a ako rovnaký algoritmus aplikovať na rôzne dátové typy.
OHLCChart<double, 12, 10000, OHLCNokia5110BarRender<double> > ohlc;
double value=22.4;
void loop() {
// update random data
int valuemove=random(30)-15;
value+=valuemove/100.;
value=constrain(value,10,40);
//Serial.println(value);
ohlc.addValue(value);
// render chart
display.clearDisplay();
// draw candlesticks
ohlc.draw();
// draw last value
display.fillRect(5,5,5+5*5+3,11,BLACK);
display.fillRect(6,6,5+5*5+1,9,WHITE);
display.setCursor(7,7);
display.print(value);
// draw indicator
int _v=fmap(value,ohlc.minimum,ohlc.maximum,0.,47.);
display.drawLine(82,47-_v,83,47-_v,BLACK);
display.drawLine(83,47-_v+1,83,47-_v-1,BLACK);
display.display();
delay(200); // 5 values/second
}
Zdrojový kód sa nachádza na GitHub.
21.10.2016