V této části kurzu Arduino porovnáme dva koncepty senzorů. Vyzkoušíme analogové a digitální teploměry v praxi!
K tomuto účelu použijeme velmi oblíbené senzory LM35 a DS18B20. Kombinací těchto obvodů s programovatelnými diodami, o kterých jsme se učili, můžeme sestrojit zajímavý domácí teploměr!
Objednejte si sadu prvků a začněte se učit v praxi! Kliknutím sem přejdete do obchodu >>
V této části kurzu Arduino se budeme zabývat teplotními senzory, které mohou být užitečné pro mnoho projektů. Tentokrát bude elektronická část velmi jednoduchá. Nejdůležitější věcí, kterou si po této lekci zapamatujte, je rozdíl mezi analogovými a digitálními senzory.
Analogový senzor vs. digitální senzor
Na trhu je velké množství senzorů. Barevné senzory, zvukové senzory, senzory vzdálenosti, senzory polohy – výběr je opravdu velký! Lze však jasně rozlišit dvě skupiny senzorů:
- Digitální senzory,
- Analogové senzory.
Analogové senzory převádějí měřenou veličinu (např. teplotu) na elektrickou veličinu, která je úměrná měřené hodnotě. Pokud se například zvýší teplota, zvýší se napětí nebo odpor na výstupu snímače.
Digitální senzory posílají informace ve formě posloupnosti bitů. K jejich čtení jsou zapotřebí digitální obvody, obvykle mikrokontroléry – například naše Arduino.
Digitální snímače jsou v dnešní době stále oblíbenější. Mohou provádět stále složitější měření a čtení a správná interpretace výsledků těchto senzorů je někdy snazší než u podobných analogových systémů.
Mnoho lidí však stále volí analogové snímače, protože jsou levnější. Kromě toho je senzor s analogovým výstupem často jednoduše praktičtější pro jednoduchá měření teploty (stačí jej připojit k analogovému vstupu).
Přejděme tedy k praxi!
Hotové sady pro kurzy Forbot
Komponenty pro cvičení z kurzu Arduino (úroveň 2) jsou k dispozici jako hotové sady! Patří sem programovatelné diody, analogové a digitální teploměry, 7-segmentové displeje a senzor pohybu (PIR).
Analogový teploměr: LM35
Nejprve se podíváme na oblíbený teploměr LM35. Senzor je umístěn v pouzdře TO-92, které si obvykle spojujeme s tranzistory. Jeho vývody zde mají samozřejmě zcela jiný účel. V případě LM35 se napájení provádí z vnějších přípojek a teplota se odečítá na prostřední přípojce (měřením napětí).
Nejdůležitější informace o analogovém teploměru LM35:
- kalibrované pro stupnici Celsia (10 mV/°C),
- měření od 0 do 100 °C
- napájecí napětí od 4 do 30 V,
- podrobnosti naleznete v dokumentu LM35.
Jak vidíte, rozsah přípustného napájecího napětí je obrovský. Senzory budeme samozřejmě napájet standardním napětím 5 V, které je k dispozici na desce Arduino. Senzor LM35 je lineární, tzn. že každé zvýšení výstupního napětí o 10 mV odpovídá zvýšení teploty o 1 °C.
Další informace o LM35 naleznete v související dokumentaci.
Připojení LM35 k Arduino
Začněme připojením senzoru. Napájecí zdroj připojíme tak, jak je vyznačeno na obrázku výše. Následně připojíme prostřední vodič přímo k analogovému pinu Arduina (např. A5).
Toto je zdaleka jedno z nejjednodušších spojení, které se v průběhu kurzu vyžaduje, kéž by to bylo vždy tak snadné! Nyní můžete pokračovat v programu…
Měření teploty: analogový senzor
Úkolem programu bude přečíst napětí na vývodu A5 a odpovídajícím způsobem ho převést. Jak je popsáno v dokumentaci, 1 °C odpovídá 10 mV. Hodnota ADC se proto musí nejprve převést na napětí. Připomínáme, že to provedeme tak, že naměřenou hodnotu vynásobíme 5 a tento výsledek vydělíme 1024 (pracovní rozsah vysílače je 0…1023). Abychom na konci získali stupně Celsia, vynásobíme výslednou hodnotu 100 (protože každých 10 mV je 1 stupeň).
To lze v programu zapsat na jeden řádek:
#define LM35 A5
void setup(){
Serial.begin(9600);
}
void loop(){
//Přepočet hodnoty ADC na teplotu podle popisu v kurzu
float teplota = ((analogRead(LM35) * 5.0) / 1024.0) * 100;
//Odesílání aktuální teploty přes UART
Serial.print("Aktuální teplota: ");
Serial.print(teplota);
Serial.println("*C");
delay(200);
}
Po spuštění výše uvedeného programu obdržíme na sériovém monitoru aktuální naměřené hodnoty teploty. Následující animace ukazuje, jak senzor funguje po zahřátí.
Pokud se pokusíme senzor ochladit (například kostkou ledu), na displeji se zobrazí pouze 0 °C. Bohužel je nutné změnit zapojení LM35, aby mohl měřit záporné teploty. Podrobnější informace o tom najdete v datovém listu!
Bezpečnostní pokyny!
Pokud někoho napadne chladit senzory stlačeným vzduchem a pak je zahřívat zapalovačem, rád bych připomněl, že většina plechovek se stlačeným vzduchem obsahuje hořlavé plyny!
Bezpečnější je otestovat snímač tak, že na něj položíte něco studeného (například kostku ledu v plastovém sáčku, aby voda nepoškodila elektroniku).
Doplňkový úkol 7.1
Rozšíření programu o podporu 2 teplotních senzorů a zobrazení jejich výsledků vedle sebe. Třetí zobrazená hodnota (v novém řádku) by měla být rozdílem mezi dvěma měřeními.
Teploměr s funkcí MAX/MIN
Předpokládejme, že měření teploty v rozsahu 0-100 °C je dostačující. Vytvořme pokojový teploměr s funkcí ukládání minimální a maximální teploty.
Začněme uložením maximální hodnoty. K tomu stačí vytvořit proměnnou, například:
float tempMAX = 0; //Aktuální maximální teplota
Tato proměnná musí být samozřejmě deklarována na samém začátku (před setup()/loop()), protože nechceme, aby ji každá funkce loop() resetovala. Nyní je třeba zkontrolovat, zda bylo právě dosaženo nejvyšší teploty. Jak to uděláme?
V každém průchodu smyčkou musíme pouze zkontrolovat, zda je aktuální teplota vyšší než uložená maximální hodnota, a pak:
- pokud je podmínka splněna,
pak by se aktuální hodnota měla uložit jako maximální hodnota, - pokud podmínka není splněna,
pak neděláme nic!
V praxi bude celý program vypadat takto:
#define LM35 A5
float tempMAX = 0; //Aktuální maximální teplota
void setup(){
Serial.begin(9600);
}
void loop(){
//Přepočet hodnoty ADC na teplotu podle popisu v kurzu
float teplota = ((analogRead(LM35) * 5.0) / 1024.0) * 100;
if (teplota > tempMAX) { //Pokud je aktuální teplota vyšší než maximální teplota
tempMAX = teplota; //pak nastavte aktuální teplotu jako maximální.
}
//Odesílání maximální teploty přes UART
Serial.print("Max: ");
Serial.print(tempMAX);
Serial.println("*C");
delay(200);
}
Tentokrát se na monitoru sériového rozhraní zobrazí pouze informace o nejvyšší hodnotě. Není možné, aby další zobrazená hodnota byla menší než předchozí:
Pokusme se nyní stejným způsobem uložit minimální hodnotu. Vytvoříme novou proměnnou:
float tempMIN = 0; //Aktuální minimální teplota
Následně zkontrolujeme, zda je aktuální hodnota menší než dříve uložená hodnota, tj:
if (teplota < tempMIN) { //Pokud je aktuální teplota nižší než minimální teplota
tempMIN = teplota; //pak nastavte aktuální teplotu jako minimální.
}
Skvělé, jen výše popsané hledání nejnižší teploty nebude fungovat! Když jsme vytvořili novou proměnnou, přiřadili jsme jí hodnotu „0“, takže není možné nikdy naměřit ještě nižší teplotu (náš senzor neumí měřit záporné hodnoty).
Tuto chybu dělá mnoho začátečníků!
Při inicializaci proměnné, která obsahuje informaci o minimální teplotě, bychom jí měli přiřadit přijatelnou maximální teplotu, např. 150. Pak je možné, že naměřená hodnota je nižší.
To je jeden ze způsobů, jak tento problém vyřešit.
Další teploměr zkontrolujeme při testování druhého teploměru.
Po změně bude celý program vypadat následovně:
#define LM35 A5
float tempMAX = 0; //Aktuální maximální teplota
float tempMIN = 150; //Aktuální minimální teplota
void setup(){
Serial.begin(9600);
}
void loop(){
//Přepočet hodnoty ADC na teplotu podle popisu v kurzu
float teplota = ((analogRead(LM35) * 5.0) / 1024.0) * 100;
if (teplota > tempMAX) { //Pokud je aktuální teplota vyšší než maximální teplota
tempMAX = teplota ; //pak nastavte aktuální teplotu jako maximální.
}
if (teplota < tempMIN) { //Pokud je aktuální teplota nižší než minimální teplota
tempMIN = teplota ; //pak nastavte aktuální teplotu jako minimální.
}
// Odesílání maximální teploty přes UART
Serial.print("Max: ");
Serial.print(tempMAX);
Serial.println("*C");
//Odesílání minimální teploty přes UART
Serial.print("Min: ");
Serial.print(tempMIN);
Serial.println("*C");
delay(200);
}
Pro lepší čitelnost však doporučuji přesunout části kódu, které jsou zodpovědné za odesílání textu do počítače. Nemá smysl neustále odesílat maximální a minimální hodnoty. Je lepší to udělat, až když se změní:
#define LM35 A5
float tempMAX = 0; //Aktuální maximální teplota
float tempMIN = 150; //Aktuální minimální teplota
void setup(){
Serial.begin(9600);
}
void loop(){
//Přepočet hodnoty ADC na teplotu podle popisu v kurzu
float teplota = ((analogRead(LM35) * 5.0) / 1024.0) * 100;
if (teplota > tempMAX) { //Pokud je aktuální teplota vyšší než maximální teplota
tempMAX = teplota ; //pak nastavte aktuální teplotu jako maximální.
//Odesílání maximální teploty přes UART
Serial.print("Nová max. hodnota: ");
Serial.print(tempMAX);
Serial.println("*C");
}
if (teplota < tempMIN) { //Pokud je aktuální teplota nižší než minimální teplota
tempMIN = teplota ; //pak nastavte aktuální teplotu jako minimální.
//Odesílání minimální teploty přes UART
Serial.print(" Nová min. hodnota: ");
Serial.print(tempMIN);
Serial.println("*C");
}
delay(200);
}
Pokud je nyní spuštěn monitor sériového rozhraní, dostáváme pouze informace o změnách. Následující animace ukazuje účinky mírného zahřátí a následného rychlého ochlazení senzoru:
Výhody a nevýhody modelu LM35
Na jedné straně máme relativně levný a snadno použitelný senzor. Na druhou stranu má i své nevýhody. Zaprvé, čtení přes ADC může být těžkopádné, zejména při použití dlouhých měřicích kabelů, které mohou zachytit „rušení ze vzduchu“. Pro každý senzor je také zapotřebí další kanál ADC.
Pokud bychom chtěli měřit teplotu v 6 místnostech,
bychom již měli příliš málo volných pinů ADC.
Za druhé, rozsah měření je poměrně omezený a v takovém základním provedení není čidlo LM35 vhodné například pro měření teploty, která může panovat za oknem v České republice. Je tedy na čase zabývat se digitálním senzorem, který řeší výše uvedené problémy!
Doplňkový úkol 7.2
Teploměr by měl každé 2 sekundy odesílat do počítače informace o aktuální teplotě. Stisknutím dvou tlačítek zobrazíte aktuálně uložené extrémní teploty.
Digitální teploměr: DS18B20
Nyní se podíváme na velmi, velmi populární digitální senzor DS18B20, který komunikuje s Arduino prostřednictvím 1-wire rozhraní, o kterém si můžete přečíst více na Wikipedii.
Tento snímač je rovněž vyroben v pouzdře TO-92 a stejně jako dříve budeme data snímat ze středního ramene. Ale pozor na napájení! U tohoto senzoru musí být napájení v opačném směru (ve srovnání s LM35)! Správný popis zapojení je následující:
Nejdůležitější informace o digitálním teploměru DS18B20:
- měření v rozsahu -50 až 125 °C
- napájecí napětí 3 až 5,5 V,
- přesnost: +/- 0,5 °C v rozsahu od -10 °C do 85 °C,
- podrobnosti naleznete v datovém listu.
Připojení digitálního teploměru k Arduino
Připojení tohoto senzoru vypadá podobně. Dva krajní konektory jsou připojeny k napájení (jak je znázorněno výše) a prostřední noha je připojena k Arduino (v mém případě A5). Je však důležité přidat rezistor 4,7 kΩ mezi výstup (střední nohu) a kladnou lištu napájecího zdroje.
Instalace tohoto rezistoru je nezbytná!
Příklad spojení:
Měření teploty: digitální senzor
Se snímačem byste měli komunikovat prostřednictvím 1-wire rozhraní. Je však třeba prostudovat datový list, abyste věděli, jaké informace je třeba do snímače odeslat a jak interpretovat informace, které se vrátí. Takové experimenty se doporučují těm, kteří se nebojí dlouhých programů.
V tomto kurzu se však zaměříme na knihovnu: Arduino Temperature Control Library. Na stránkách OneWire-knihovna je nutná pro správnou funkci. Proces instalace nových balíčků byl v kurzu již několikrát popsán (přinejmenším v části 2), takže jej nebudu opakovat.
Než budete pokračovat, nezapomeňte nainstalovat výše uvedené knihovny!
Stejně jako u analogového senzoru začneme načítáním aktuální hodnoty okolní teploty ve smyčce. Nejprve přidáme dva řádky, které informují překladač o knihovnách:
#include
#include
První je zodpovědný za komunikaci prostřednictvím 1-Wire a druhý je knihovna teplotních čidel, která byla právě nainstalována. Dále je třeba deklarovat připojení senzoru:
OneWire oneWire(A5); // Připojení k A5
DallasTemperature sensors(&oneWire); //Poskytování informací do knihovny
První řádek je zodpovědný za spuštění 1-wire komunikace na pinu č. A5 a druhý řádek přenáší tyto informace do nainstalované knihovny, která spravuje naše senzory.
Ve funkci setup() spustíme přenos přes UART a inicializujeme senzory:
void setup(void) {
Serial.begin(9600);
sensors.begin(); //Inicializace senzorů
}
Ve smyčce loop() se „zeptáme“ čidla na aktuální teplotu a poté ji zobrazíme:
void loop(void) {
sensors.requestTemperatures(); // Stažení teploty senzoru
Serial.print("Aktuální teplota: ");
Serial.println(sensors.getTempCByIndex(0)); //Zobrazení informací
delay(500);
}
Záhadné označení sensors.getTempCByIndex(0) znamená, že teplota prvního senzoru (jsou číslovány od 0) je měřena ve stupních Celsia. Čtení informací z druhého senzoru by tedy vypadalo takto: sensors.getTempCByIndex(1). Připojení více senzorů se však budeme věnovat o něco později.
Volání sensors.getTempFByIndex(0) vrátí hodnotu ve stupnici Fahrenheita.
V současné době vypadá celý program takto:
#include
#include
OneWire oneWire(A5); // Připojení k A5
DallasTemperature sensors(&oneWire); //Přenos informací do knihovny
void setup(void) {
Serial.begin(9600);
sensors.begin(); //Inicializace senzorů
}
void loop(void) {
sensors.requestTemperatures(); //Stažení teploty senzoru
Serial.print("Aktuální teplota: ");
Serial.println(sensors.getTempCByIndex(0)); //Zobrazení informací
delay(500);
}
Vliv na monitor sériového protokolu:
Mimochodem, je možné zkontrolovat to, co při použití analogového snímače nebylo možné, a to měření záporných teplot. K tomuto účelu jsem využil „chladicí možnosti“ obrácené plechovky se stlačeným vzduchem. Jak vidíte, bylo dosaženo teploty -27 °C!
Důrazně vám však nedoporučuji hrát si se stlačeným hořlavým plynem. Bezpečnější je testovat senzor tak, že na něj položíte něco studeného (např. kostku ledu v plastovém sáčku, aby voda nepoškodila elektroniku).
Teploměr s funkcí MAX/MIN - verze 2
Jak jsme slíbili, nyní se vrátíme k tématu měření minimální a maximální teploty. Tentokrát řešíme „problém“ s předřazením hodnot proměnných jinak. Na začátku deklarujeme také dvě nové proměnné.
Tentokrát jejich hodnota není důležitá!
float tempMAX = 0; //Aktuální maximální teplota
float tempMIN = 0; //Aktuální minimální teplota
O jejich hodnotu se nemusíme starat, protože o něco dále ve funkci setup() jim při prvním čtení přiřadíme jedinečnou hodnotu:
void setup(void) {
Serial.begin(9600);
sensors.begin(); //Inicializace senzorů
//nastavit první odečet jako MAX a MIN
sensors.requestTemperatures();
tempMAX = sensors.getTempCByIndex(0);
tempMIN = sensors.getTempCByIndex(0);
}
Tímto způsobem se nemusíme starat o provozní rozsah senzoru. Vždy budeme vycházet z hodnoty zaznamenané čidlem, tj. budeme zaznamenávat jak nižší, tak vyšší teploty.
Celý program nyní vypadá takto:
#include
#include
OneWire oneWire(A5); // Připojení k A5
DallasTemperature sensors(&oneWire); //Přenos informací do knihovny
float tempMAX = 0; //
Aktuální maximální teplota
float tempMIN = 0; //Aktuální minimální teplota
void setup(void) {
Serial.begin(9600); sensors.begin(); //Inicializace senzorů
//nastavit první odečet jako MAX a MIN
sensors.requestTemperatures();
tempMAX = sensors.getTempCByIndex(0);
tempMIN = sensors.getTempCByIndex(0);
}
void loop(void) {
sensors.requestTemperatures(); // Stažení teploty senzoru
float teplota = sensors.getTempCByIndex(0); //zápis teploty do proměnné
if (teplota > tempMAX) { //Pokud je aktuální teplota vyšší než maximální teplota
tempMAX = teplota; //pak nastavte aktuální teplotu jako maximální.
//Odesílání maximální teploty přes UART
Serial.print("Nová max. hodnota: ");
Serial.print(tempMAX);
Serial.println("*C");
}
if (teplota < tempMIN) { //Pokud je aktuální teplota nižší než minimální teplota
tempMIN = teplota; //pak nastavte aktuální teplotu jako minimální.
//Odesílání minimální teploty přes UART
Serial.print("Nová min. hodnota: ");
Serial.print(tempMIN);
Serial.println("*C");
}
delay(500);
}
Efekt je stejný jako v předchozím případě:
Čtení informací z více senzorů
Velkou výhodou digitálních snímačů je, že komunikují prostřednictvím sofistikovanějších mechanismů, které přinášejí mnoho výhod. V tomto případě lze například k jednomu pinu připojit několik senzorů.
V tomto testu se budu zabývat pouze jednou z několika možností
použití DS18B20!
Pro testování proto můžete jednoduše připojit druhý snímač ve stejných řadách na kontaktní desce nebo přesunout spoje pomocí kabelů. Z důvodu lepší čitelnosti jsem se rozhodl pro druhou variantu:
Pokud připojíte další senzor, nemusíte přidávat další odpor!
Stačí jeden pro celou datovou linku!
Jak již bylo řečeno, pro načtení teploty z dalšího čidla je třeba zavolat sensors.getTempCByIndex(1). Celý testovací program je následující:
#include
#include
OneWire oneWire(A5); // Připojení k A5
DallasTemperature sensors(&oneWire); //Přenos informací do knihovny
void setup(void) {
Serial.begin(9600);
sensors.begin(); //Inicializace senzorů
}
void loop(void) {
sensors.requestTemperatures(); //Stažení teploty senzoru
Serial.print("První: ");
Serial.println(sensors.getTempCByIndex(0)); //Zobrazení informací
Serial.print("Druhý: ");
Serial.println(sensors.getTempCByIndex(1)); //Zobrazení informací
delay(500);
}
V praxi kód funguje následovně:
Každý senzor má adresu!
Senzory je možné připojit k jedné datové lince, protože výrobce každému vyrobenému senzoru přiřadil jedinečnou adresu. Tyto adresy se vyplatí používat pro rozsáhlejší projekty. Pak můžeme jasně identifikovat naše senzory.
Adresu samozřejmě nelze zjistit na krytu, ale musí být načtena pomocí softwaru.
Zde můžeme použít ukázkový program Soubor → Příklady → OneWire → DS18x20, ale nesmíme zapomenout změnit informace o připojení senzoru hned na začátku, tj:
OneWire ds(10);
Nahrazuje se:
OneWire ds(A5);
Po provedení programu se na monitoru sériového rozhraní zobrazí následující informace. Barevně jsem zvýraznil jedinečné adresy senzorů, které jsou uloženy v hexadecimálním tvaru:
Použití adres senzorů DS18B20
Nyní bude možné v programu odkazovat na konkrétní senzory. Za tímto účelem vytvoříme před funkcí setup() objekt typu DeviceAddress s názvem ThermometerExternal a zadáme adresu našeho senzoru:
Pozor! Každý zde musí zadat individuální adresu svého senzoru!
DeviceAddress teplomerExterni = { 0x10, 0x7A, 0x31, 0x99, 0x1, 0x8, 0x0, 0x4A };
V dalším průběhu programu se údaje o teplotě zaznamenané tímto čidlem získají vyvoláním příkazu sensors.getTempC(teplomerExterni).
Celý program pak vypadá takto:
#include
#include
OneWire oneWire(A5); // Připojení k A5
DallasTemperature sensors(&oneWire); //Přenos informací do knihovny
DeviceAddress teplomerExterni = { 0x10, 0x7A, 0x31, 0x99, 0x1, 0x8, 0x0, 0x4A };
void setup(void) {
Serial.begin(9600);
sensors.begin(); //Inicializace senzorů
}
void loop(void) {
sensors.requestTemperatures(); //Stažení teploty senzoru
Serial.print("Aktuální teplota: ");
Serial.println(sensors.getTempC(teplomerExterni)); //Zobrazení informací
delay(500);
}
Toto řešení je velmi praktické pro velký počet senzorů. Kdybychom měli tato čidla nastavit například v celém bytě, bylo by mnohem jednodušší použít v programu názvy jako „TeploměrVnější“, „TeploměrKuchyň“ atd.
Program pak není citlivý ani na změny pořadí, v jakém jsou senzory připojeny!
Vizualizace teploty na RGB LED diodách
Nakonec by mělo smysl přidat k našemu teploměru další ukazatel teploty. K tomu jsou ideální pásky s LED diodami RGB, o kterých jsme se učili na začátku kurzu. Předpokládejme, že každá z 8 LED diod symbolizuje 5 °C.
Pokud se zespodu rozsvítí červeně jedna za druhou, znamenají kladné hodnoty:
Pokud naopak svítí shora, tj. modře, jedná se o záporné hodnoty:
Připojil jsem standardně pásek RGB, jak jsem to udělal v druhé části tohoto kurzu. Proto to zde nebudu popisovat. Z bezpečnostních důvodů poskytuji pouze obrázky.
Na začátku programu, který jsme napsali dříve, musíme přidat informace o nové knihovně a deklarovat pás RGB:
Inicializace dříve deklarovaného proužku musí být přidána ve funkci setup():
#include //Připojení knihovny
#include
#include
//Konfigurace pásky
Adafruit_NeoPixel pásky = Adafruit_NeoPixel(8, A0, NEO_GRB + NEO_KHZ800);
OneWire oneWire(A5); // Připojení k A5
DallasTemperature sensors(&oneWire); //Přenos informací do knihovny
DeviceAddress teplomerExterni = { 0x10, 0x7A, 0x31, 0x99, 0x1, 0x8, 0x0, 0x4A };
void setup(void) {
Serial.begin(9600);
sensors.begin(); //Inicializace senzorů
pásky.begin(); //Inicializace
}
Ve smyčce loop() nejen odešleme údaje o teplotě do počítače, ale také vytvoříme novou proměnnou typu int, do které přepisujeme načtenou teplotu. Proměnná je deklarována jako int, tedy jako celé číslo, protože zde stejně nebudeme používat desetinná místa.
Toto číslo se předává funkci teplomerRGB(), která je zodpovědná za kontrolu proužku:
void loop(void) {
sensors.requestTemperatures(); // Stažení teploty senzoru
Serial.print("Aktuální teplota: ");
Serial.println(sensors.getTempC(teplomerExterni)); //Zobrazení informací
int tempPásky = sensors.getTempC(teplomerExterni);
teplomerRGB(tempPásky);
delay(500);
}
Funkce teplomerRGB()
Předpokládáme, že minimální zobrazená teplota je -40 °C a maximální teplota je +40 °C. Proto na začátku funkce zkontrolujeme podmínky, abychom se ujistili, že získaná hodnota nepřekračuje tento rozsah.
V takovém případě předpokládáme, že teplota dosáhla maximální hodnoty:
void teplomerRGB(int teplota) {
//Kontrolujeme, zda je teplota ve správném rozmezí
if (teplota > 40) {
teplota = 40;
} else if (teplota < -40) {
teplota = -40;
}
[...]
}
Nyní se musíme vypořádat se zobrazováním informací na LED diodách. Nejprve vypneme všechny LED pomocí funkce pásky.clear(). Poté zkontrolujeme, zda hodnota, kterou máme zobrazit, je větší nebo rovna nule, nebo ne. Teplotu také převedeme na hodnoty, které může náš teploměr zobrazit (od 1 do 8 LED):
//Vyčistěte pásky
pásky.clear();
if (teplota >= 0) {
//Pro kladné hodnoty
teplota = map(teplota, 0, 40, 1, 8);
} else {
//Pro záporné hodnoty
teplota = map(teplota, -40, 0, 1, 8);
}
Poté pomocí smyčky for rozsvítíme příslušné diody LED. Pro kladné hodnoty chceme LED diody zapínat zespodu, takže smyčka musí běžet od i=0 do hodnoty, která popisuje aktuální teplotu.
V případě záporné hodnoty chceme LED diody zapínat shora dolů, proto je nejvhodnější, když smyčka for běží v opačném směru – od maximální hodnoty i=8 k hodnotě, která udává aktuální teplotu. Nakonec zavoláme funkci pásky.show().
Hotový program vypadá takto:
#include //Připojení knihovny
#include
#include
//Konfigurace pásky
Adafruit_NeoPixel pásky = Adafruit_NeoPixel(8, A0, NEO_GRB + NEO_KHZ800);
OneWire oneWire(A5); //Připojení k A5
DallasTemperature sensors(&oneWire); //Přenos informací do knihovny
DeviceAddress teplomerExterni = { 0x10, 0x7A, 0x31, 0x99, 0x1, 0x8, 0x0, 0x4A };
void setup(void) {
Serial.begin(9600);
sensors.begin(); //Inicializace senzorů
Streifen.begin(); //Inicializace
}
void loop(void) {
sensors.requestTemperatures(); //Stažení teploty senzoru
Serial.print("Aktuální teplota: ");
Serial.println(sensors.getTempC(teplomerExterni)); //Zobrazení informací
int tempPásky = sensors.getTempC(teplomerExterni);
teplomerRGB(tempPásky);
delay(500);
}
void teplomerRGB(int teplota) {
//Kontrolujeme, zda je teplota ve správném rozmezí
if (teplota > 40) {
teplota = 40;
} else if (teplota < -40) {
teplota = -40;
}
//Vyčistěte pásku
pásky.clear();
if (teplota >= 0) {
//Pro kladné hodnoty
teplota = map(teplota , 0, 40, 1, 8);
int i = 0;
for (i = 0; i < teplota; i++) {
pásky.setPixelColor(i, pásky.Color(255, 0, 0)); //LED č. i svítí červeně
}
} else {
//Pro záporné hodnoty
teplota = map(teplota, -40, 0, 1, 8);
int i = 0;
for (i = 8; i > teplota; i--) {
pásky.setPixelColor(i, pásky.Color(0, 0, 255)); //LED č. i svítí modře
}
}
pásky.show();
}
Když je program v provozu, RGB LED pásek zobrazuje aktuální teplotu!
Co jsem o DS18B20 ještě nenapsal?
V tomto článku jsem se zabýval pouze základní konfigurací pro použití těchto senzorů. V praxi umožňují mnoho dalších operací. Například je možné nastavit rozlišení měření teploty.
Možné jsou i jiné varianty připojení snímačů, např. pouze dvěma kabely. Tento článek měl poskytnout pouze základní přehled o analogových a digitálních teploměrech, takže jsem nechtěl zacházet do podrobností.
Pokud máte zájem, podívejte se do dokumentace k senzoru a dalším příkladům obsaženým ve zde použitých knihovnách.
Výhody a nevýhody modelu DS18B20
V porovnání s dříve diskutovaným analogovým čidlem se ukázalo, že manipulace s teploměrem DS18B20 je mnohem „obtížnější“. Musíte tomu věnovat trochu více času. Bohužel je také dražší než jeho předchůdce.
Při měření teploty dochází k minimálnímu zahřívání konstrukce snímače,
Časté dotazování na výsledky proto může vést ke zfalšování měření!
Na druhou stranu je tento snímač mnohem univerzálnější. Digitální přenos přes rozhraní 1-Wire se ukazuje jako nepostradatelný, pokud chcete pokrýt větší plochu senzory.
Pokud se počet senzorů zvýší, nemusíme zvyšovat počet kabelů.
Kromě toho lze teploměry snadno identifikovat díky jejich jedinečným adresám.
Shrnutí
Použití probíraných senzorů se neomezuje pouze na konstrukci jednoduchého domácího teploměru. Měření atmosférických podmínek je užitečné také pro kontrolu činnosti složitějších zařízení. Například u mobilního robota můžete zkontrolovat, zda motory nebo baterie nedosáhly příliš vysoké teploty. Taková diagnóza může zařízení ochránit před poškozením!
V příštím díle kurzu Arduino se budeme podrobněji věnovat atmosférickým senzorům. Tentokrát však mluvíme o oblíbeném DHT11, senzoru teploty a vlhkosti v jednom krytu.
Objednejte si sadu prvků a začněte se učit v praxi! Kliknutím sem přejdete do obchodu >>
Přílohy
LM35 (pdf, 342 KB)
Dokumentace LM35.
DS18B20 (pdf, 256 KB)
DS18B20 Dokumentace.