Zde můžete vidět rozdíly mezi vybranou verzí a aktuální verzí dané stránky.
Obě strany předchozí revize Předchozí verze Následující verze | Předchozí verze | ||
2018:thermometer [2019/01/14 18:11] Ondřej Jeřábek [Řízení spotřeby] |
2018:thermometer [2019/01/14 20:46] (aktuální) Ondřej Jeřábek [Firmware a eagle] |
||
---|---|---|---|
Řádek 40: | Řádek 40: | ||
===== Schéma zapojení ===== | ===== Schéma zapojení ===== | ||
- | V napájecí části je hned na vstupu zařazen tranzistor pro zamezení přepólování vlivem otočené knoflíkové baterie. Jelikož použitý typ CR2450 má nominální napětí 3V, není třeba dále provádět žádné úpravy a lze jej rovnou použít k napájení celého teploměru. | + | V napájecí části je hned na vstupu zařazen tranzistor pro zamezení přepólování vlivem otočené knoflíkové baterie. Jelikož použitý typ CR2450 má nominální napětí 3V, není třeba dále provádět žádné úpravy a lze jej rovnou použít k napájení celého teploměru. Zapojení ostatních periferií k mikrokontroléru je standardní dle doporučení v dokumentaci. |
- | + | ||
- | Zapojení jednotlivých periferií k mikrokontroléru je standardní. | + | |
{{ :2018:thermometer:thermometer_sch.png?400 |}} | {{ :2018:thermometer:thermometer_sch.png?400 |}} | ||
Řádek 59: | Řádek 58: | ||
Celý firmware je vyvíjen za použití volně dostupného prostředí Kinetis Design Studio určeného především pro mikrokontroléry NXP řady Kinetis. Pro usnadnění práce bylo použito Kinetis-SDK spolu s knihovnami pro ovládání E-Ink displeje a kreslení na něm. | Celý firmware je vyvíjen za použití volně dostupného prostředí Kinetis Design Studio určeného především pro mikrokontroléry NXP řady Kinetis. Pro usnadnění práce bylo použito Kinetis-SDK spolu s knihovnami pro ovládání E-Ink displeje a kreslení na něm. | ||
+ | Celý firmware se zdrojovými soubory je přiložen na konci této práce. Pro úspěšné buildnutí je třeba stáhnout si příslušné SDK (odkaz je na konci) a navést k němu cestu pomocí systémové proměnné KSDK-PATH v nastavení proměnného prostředí operačního systému. | ||
+ | ===== Hlavní program ===== | ||
+ | Samotný hlavní program vypadá relativně jednoduše, avšak velkou část výpočetního času zabere výpočet obrazu zobrazovaného E-ink displejem. Na začátku při startu je prováděna inicializace pinů mikrokontroléru spolu s nastavením taktovacího kmitočtu. Následně dochází ke konfiguraci okolních periferií. Ty zatím aktuálně nevyužité, jako je bezdrátový modul, nebo flash paměť se převedou do low-power režimu. | ||
+ | |||
+ | Taktéž se provádí měření napětí baterie. V případě nedostatečného napětí je mikrokontrolér uspán a rozblikána červená LED. Program v tomto místě končí v nekonečné smyčce, kde čeká na její výměnu. Pokud ovšem napětí baterie dostačuje, pokračuje inicializací měřicího čidla a E-ink displeje. | ||
+ | |||
+ | Hlavní smyčka není úplně periodická, jak se může na první pohled zdát, ale bývá pozastavena v každém cyklu úsporným režimem, kdy mikrokontrolér přechází do spánku (viz kapitola Řízení spotřeby). Taktéž bývá průběžně prováděno měření napájecího napětí, parametrů okolního prostředí (teplota, tlak, vlhkost) a obnova dat na displeji. | ||
===== Řízení spotřeby ===== | ===== Řízení spotřeby ===== | ||
- | Hlavním cílem bude dostat spotřebu celého zařízení na co nejnižší hodnoty, pro dosažení maximální výdrže na baterii. V kontrastu s tímto požadavkem je sestavování obrazu pro následné vykreslení na displej které je bohužel náročné na výpočetní výkon. Proto je nutné vhodně měnit výkon mikrokontroléru a využívat jeho úsporné režimy. | + | Hlavním cílem bude dostat spotřebu celého zařízení na co nejnižší hodnoty, pro dosažení maximální výdrže na baterii. V kontrastu s tímto požadavkem je sestavování obrazu pro následné vykreslení na displej které je bohužel náročné na výpočetní výkon. Proto je nutné vhodně měnit výkon mikrokontroléru a využívat jeho úsporné profily. |
Celkově jsou používány 3 výkonové režimy: | Celkově jsou používány 3 výkonové režimy: | ||
Řádek 69: | Řádek 75: | ||
* Sleep mód: Velice úsporný režim kdy je hlavní oscilátor zastaven a běží pouze periferie RTC | * Sleep mód: Velice úsporný režim kdy je hlavní oscilátor zastaven a běží pouze periferie RTC | ||
- | Přepínání taktovacího kmitočtu je zajištěno funkcí **//switch_clk(enum e_clk_mode mode)//**, které se jako parametr zadá aktuální mód. Funkce provede zakázání systémového milisekundového časovače systick, změnu předděličky taktovacího kmitočtu a poté znovu konfiguraci časovače už s novou frekvencí, aby byla dodržena správná perioda čítání. | + | Přepínání taktovacího kmitočtu je zajištěno funkcí **//switch_clk(enum e_clk_mode mode)//**, které se jako parametr zadá aktuální mód. Funkce provede zakázání systémového milisekundového časovače systick, změnu předděličky taktovacího kmitočtu a poté konfiguraci časovače už s novou frekvencí, aby byla dodržena správná perioda čítání. |
<code cpp> | <code cpp> | ||
Řádek 104: | Řádek 110: | ||
</code> | </code> | ||
+ | ===== Měření parametrů čidlem BME280 ===== | ||
+ | Samotné měření obstarává funkce **//bmp_measure_handle()//** volaná v sekundových intervalech (pokud mikrokontrolér zrovna nespí). Měření probíhá každých 5 minut a je vyvoláno přerušením RTC Alarm v daný časový okamžik. V tento moment je nastaven příznak požadavku na měření, kdy dojde k odstartování měření na čidlu. V následující sekundě poté jsou naměřená data vyčtena a zpracována funkcí **//bmp_read_data()//**. Zpracování dat definuje dokumentace k čidlu BME280, kdy je nutné provést korekci hodnot dle kalibračních křivek uložených v čidlu. | ||
+ | <code cpp> | ||
+ | uint8_t bmp_read_data(int16_t * temp, uint16_t * humid, uint32_t * press) | ||
+ | { | ||
+ | uint8_t press_raw[3]; | ||
+ | uint8_t temp_raw[3]; | ||
+ | uint8_t hum_raw[2]; | ||
+ | |||
+ | static int32_t temp_c; | ||
+ | static uint32_t press_c; | ||
+ | static uint32_t hum_c; | ||
+ | |||
+ | if (bmp_is_busy()) | ||
+ | return 0; | ||
+ | |||
+ | if (bmp_read_block(BMP_press_msb, press_raw, 3)) | ||
+ | return 0; | ||
+ | |||
+ | if (bmp_read_block(BMP_temp_msb, temp_raw, 3)) | ||
+ | return 0; | ||
+ | |||
+ | if (bmp_read_block(BMP_hum_msb, hum_raw, 2)) | ||
+ | return 0; | ||
+ | |||
+ | temp_c = (int32_t)(((uint32_t)temp_raw[2] >> 4) | ((uint32_t)temp_raw[1] << 4) | ((uint32_t)temp_raw[0] << 12)); | ||
+ | press_c = ((uint32_t)press_raw[2] >> 4) | ((uint32_t)press_raw[1] << 4) | ((uint32_t)press_raw[0] << 12); | ||
+ | hum_c = (uint32_t)hum_raw[1] | ((uint32_t)hum_raw[0] << 8); | ||
+ | |||
+ | temp_c = bmp280_compensate_T_int32(temp_c); | ||
+ | press_c = bmp280_compensate_P_int64(press_c); | ||
+ | hum_c = bme280_compensate_H_int32(hum_c); | ||
+ | |||
+ | *temp = (int16_t)temp_c; | ||
+ | *press = press_c >> 8; | ||
+ | *humid = (hum_c * 100) >> 10; | ||
+ | |||
+ | return 1; | ||
+ | } | ||
+ | </code> | ||
+ | |||
+ | ===== Vykreslování a ovládání ===== | ||
+ | Vykreslování veškerých obrazovek a obsluha tlačítek je definována ve zdrojovém souboru **ui.c**. Periodicky volaná funkce v hlavní smyčce **//ui_handle()//** obsluhuje reakce na stisknutá tlačítka následovaná vykreslováním daných typů obrazovek. V momentě vytváření obrazu se mění výkonový režim na Fast mode, k vůli vyšší výpočetní náročnosti. Výsledek je rovnou odesílán do E-ink displeje a po jeho kompletním odeslání se spustí překreslení. V rámci probíhající obnovy displeje se mikrokontrolér z důvodu úspory energie uspí. Probuzení zajistí přerušení od pinu busy. | ||
+ | |||
+ | Funkce pro vykreslování využívají volně dostupnou knihovnu přímo od výrobce displeje Waveshare. Obsahuje několik druhů fontů s různou velikostí a funkce vykreslující geometrické tvary. Nejdůležitější částí, bez které není možno E-ink vůbec řídit je obnovovací sekvence tvořená look-up tabulkou, která musí být do něj nahrána. Její podobu definuje výrobce a zajistí správné obnovení. Pro tento typ displeje existují dva typy tabulek. Jedna provádí částečný update, kdežto druhá aktualizuje celý displej. | ||
+ | |||
+ | <code cpp> | ||
+ | const unsigned char lut_full_update[] = | ||
+ | { | ||
+ | 0x02, 0x02, 0x01, 0x11, 0x12, 0x12, 0x22, 0x22, | ||
+ | 0x66, 0x69, 0x69, 0x59, 0x58, 0x99, 0x99, 0x88, | ||
+ | 0x00, 0x00, 0x00, 0x00, 0xF8, 0xB4, 0x13, 0x51, | ||
+ | 0x35, 0x51, 0x51, 0x19, 0x01, 0x00 | ||
+ | }; | ||
+ | |||
+ | const unsigned char lut_partial_update[] = | ||
+ | { | ||
+ | 0x10, 0x18, 0x18, 0x08, 0x18, 0x18, 0x08, 0x00, | ||
+ | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
+ | 0x00, 0x00, 0x00, 0x00, 0x13, 0x14, 0x44, 0x12, | ||
+ | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 | ||
+ | }; | ||
+ | </code> | ||
+ | |||
+ | Ovládání a navigace probíhá pomocí tří tlačítek na pravé straně. Při jejich stisku dojde k přerušení a probuzení mikrokontroléru ze spánku. Ten poté provede definovanou činnost dle aktuální obrazovky. K tlačítkům jsou v průběhu ovládání na displeji vypisovány aktuální funkce. Strukturu ovládání a možnosti, které displej nabízí lze vidět na blokovém schématu níže. Detailnější popis s demonstrací funkce lze nalézt v přiloženém videu na konci této práce. | ||
+ | |||
+ | {{ :2018:thermometer:program_struct.png?600 |}} | ||
Řádek 115: | Řádek 188: | ||
Navrhované zařízení je plně funkční a lze jej využívat jako plnohodnotný domácí teploměr schopný zobrazovat i detailnější informace jako vlhkost či atmosférický tlak. Z naměřených hodnot jsou průběžně vytvářeny grafy, díky kterým si lze prohlédnout změny za posledních 24 hodin. Taktéž si lze vyvolat minimální a maximální naměřené hodnoty za celou dobu provozu teploměru, případně je lze v menu vynulovat. | Navrhované zařízení je plně funkční a lze jej využívat jako plnohodnotný domácí teploměr schopný zobrazovat i detailnější informace jako vlhkost či atmosférický tlak. Z naměřených hodnot jsou průběžně vytvářeny grafy, díky kterým si lze prohlédnout změny za posledních 24 hodin. Taktéž si lze vyvolat minimální a maximální naměřené hodnoty za celou dobu provozu teploměru, případně je lze v menu vynulovat. | ||
- | Aktuální návrh je také velice úsporný na baterii, kdy v režimu nečinnosti odebírá pouze 7 μA. Měření teploty s překreslením displeje se provádí jednou za 5 minut se skokovým nárůstem spotřeby trvajícím přibližně 0,3 - 1 sekundu. Dle propočtů tedy vychází celková průměrná spotřeba na 50 µA a při použití baterie CR2450 s kapacitou 500 mAh činí výdrž přibližně 1 rok. Bohužel se v průběhu vývoje se vyskytly potíže s nedostatečným napájením na obnovu E-Ink displeje. Chyba byla prozatím vyřešena použitím tužkových baterií a bude opravena v další iteraci revizí hardwarového návrhu. | + | Aktuální návrh je také velice úsporný na baterii, kdy v režimu nečinnosti odebírá pouze 7 μA. Měření teploty s překreslením displeje se provádí jednou za 5 minut se skokovým nárůstem spotřeby trvajícím přibližně 0,3 - 1 sekundu. Dle propočtů tedy vychází celková průměrná spotřeba na 50 µA a při použití baterie CR2450 s kapacitou 500 mAh činí výdrž přibližně 1 rok. Bohužel se v průběhu vývoje vyskytly potíže s nedostatečným napájením na obnovu E-Ink displeje. Chyba byla prozatím vyřešena použitím tužkových baterií a bude opravena v další iteraci revizí hardwarového návrhu. |
Návrh lze dále v budoucnu rozšířit o venkovní teplotní čidlo, nebo přímo meteostanici, která bude svá naměřená data bezdrátově odesílat tomuto teploměru a ten se postará o jejich vyhodnocení a zobrazení. Výhodné by bylo také použít jiný bezdrátový modul, například s technologií LoRa umožňující komunikaci se vzdálenějším senzorem či připojení do LoRaWAN IoT sítě. | Návrh lze dále v budoucnu rozšířit o venkovní teplotní čidlo, nebo přímo meteostanici, která bude svá naměřená data bezdrátově odesílat tomuto teploměru a ten se postará o jejich vyhodnocení a zobrazení. Výhodné by bylo také použít jiný bezdrátový modul, například s technologií LoRa umožňující komunikaci se vzdálenějším senzorem či připojení do LoRaWAN IoT sítě. | ||
Řádek 126: | Řádek 199: | ||
{{ youtube>AyAU04ToL1Y?medium |}} | {{ youtube>AyAU04ToL1Y?medium |}} | ||
+ | |||
+ | |||
+ | ====== Firmware a schémata ====== | ||
+ | {{ :2018:thermometer:thermometer.zip |}} | ||
====== Zdroje ====== | ====== Zdroje ====== |