Individální projekty MPOA

Mikroprocesory s architekturou ARM

Uživatelské nástroje

Nástroje pro tento web


2018:thermometer

Digitální bateriový multifunkční teploměr

Vypracoval: Ondřej Jeřábek


Zadání

Vytvořte teploměr s funkcí měření teploty, atmosférického tlaku a vlhkosti (čidlo BME280). Z naměřených hodnot lze vykreslit graf za posledních 24 hodin. Zobrazení aktuálně naměřených hodnot a grafů zajistí černobílý e-ink displej. Řídící MCU zvolte od firmy NXP řady Kinetis. Důraz bude kladen na celkovou spotřebu zařízení a související optimalizaci vhodných provozních režimů použitého MCU.

Úvod

Důvodem pro vytvoření tohoto zařízení bylo zejména otestovat vlastnosti a funkci E-ink displeje, který vyniká především svou velice nízkou spotřebou, avšak doprovázenou relativně malou obnovovací rychlostí. Z principu věci se tedy tento typ displeje hodí především pro zobrazování pomalu měnících se hodnot. Jako jedna z ideálních možností je využít jej v domácím teploměru či meteostanici. Venkovní i vnitřní prostředí se mění relativně pomalu, tedy obnovování zobrazených hodnot třeba jednou za 5 minut nebude energeticky náročné a přesto nám dá informaci o aktuálním stavu okolí.

Hardwarová část

Celý hardwarový návrh je relativně jednoduchý. Lze jej vidět na blokovém schématu níže. Srdcem je mikrokontrolér od firmy NXP, ke kterému jsou připojeny okolní periferie pomocí sběrnic SPI a I2C. Napájení v diagramu není zaznačeno, avšak předpokládá se využití knoflíkové baterie formátu CR2450 poskytující napětí o hodnotě 3V.

BME280

Jedná se o integrované multifunkční čidlo od firmy Bosch, umožňující měřit teplotu vlhkost a tlak v jeho okolí. Pro komunikaci využívá sběrnice I2C a díky internímu low power oscilátoru lze u něj nastavit periodická měření v daných časových intervalech.

E-ink Displej

Jak už bylo výše zmíněno, výhodou tohoto displeje je především velice nízká spotřeba dosahující téměř nulových hodnot ve statickém stavu, a také výborná čitelnost na slunci rovnající se obyčejnému papíru. Pro teploměr byl zvolen dvoubarevný typ od firmy Waveshare s úhlopříčkou 2.9 palce a rozlišením 296×128 pixelů. Velmi výhodnou funkcí je možnost částečné aktualizace což umožní dosáhnout rychlejšího překreslení spolu s nižší spotřebou. Existují také varianty s třemi barvami (kromě bílé a černé také žlutá nebo červená). Avšak jejich velkým neduhem je dlouhé překreslování trvající až 15 sekund vždy celého displeje.

Veškeré řízení a odesílání obrazu se provádí skrz 4-wire SPI sběrnici a jednoho signálového vodiče specifikující, zda se odesílá instrukce, či grafická data. Grafická paměť v displeji se skládá z dvou bufferů pro dva snímky. Mezitím co je jeden aktivní a do druhého se provádí zápis nových dat. V momentě aktualizace se automaticky buffery prohodí.

Mikrokontroler (MCU)

Jako srdce celého teploměru byl vybrán mikrokontroler od firmy NXP MKL16Z128. Tento typ obsahuje jádro Cortex M0+ zaměřené především na nízkou spotřebu, ale v případě nutnosti vyššího výkonu lze taktovací frekvenci nastavit až na 48 MHz, což se hodí především ve výpočetně náročných operacích. Tato varianta disponuje 128 kB interní paměti Flash doplněné o 16 kB RAM.

Podmínkou pro výběr mikrokontroléru byla také presence RTC oscilátoru schopného pracovat i ve velice úsporných režimech procesoru, kdy může sloužit pro následné probuzení v konkrétní čas.

Bezdrátový modul

Do budoucna se počítá s rozšířením o další část, měřicí venkovní povětrnostní podmínky. Naměřená data by byla odesílána prostřednictvím bezdrátové komunikace do této vnitřní jednotky, která zajistí jejich záznam a zobrazení. Výběr padl na velice známý čip NRF24L01+. Ten komunikuje v ISM pásmu 2,4 GHz s datovou propustností až 2 Mbit/s. Pro jednodušší implementaci byla zvolena varianta modulu s integrovanou anténou.

Externí paměti

Tvoří je dvojice čipů AT25SF041-SSHD a 25LC040. Jedná se o paměť FLASH s kapacitou 4 Mbit a paměť EEPROM o velikosti 4kBit. Jejich účel je zde čistě redundantní. EEPROM paměť může do budoucna sloužit například pro ukládání nastavení, kdežto větší paměť flash pro záznam měřených hodnot v průběhu roku, nebo v momentě přehrávání firmwaru v mikrokontroléru, kdy se nejprve nová verze uloží do této paměti a až po kontrole dojde k jejímu překopírování.

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. Zapojení ostatních periferií k mikrokontroléru je standardní dle doporučení v dokumentaci.

Plošný spoj rozměrově vycházel z použitého modulu E-ink displeje. Tedy navrhovaná řídící deska se umístí na distanční sloupky pod tento modul a vzájemně se propojí pomocí konektorů. Vzhledem k relativně protáhlému formátu desek plošných spojů jsou zde vloženy pouze odkazy na jednotlivé obrázky návrhu.

Horní strana (Top): thermometer_top.png

Spodní strana (Bottom): thermometer_bot.png

Osazovací plán: thermometer_place.png

Firmware

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

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:

  • Fast mód: Výkonný režim s mikroprocesorem taktovaným na 24 MHz
  • Slow mód: Úsporný režim s taktovacím kmitočtem 4 MHz
  • 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é konfiguraci časovače už s novou frekvencí, aby byla dodržena správná perioda čítání.

void switch_clk(enum e_clk_mode mode)
{
	systick_disable();
	if (mode == E_CLK_FAST_MODE)
	{
		CLOCK_HAL_SetOutDiv1(SIM, 1);		// Core clock division 1x -> 24MHz
	}
	else if (mode == E_CLK_SLOW_MODE)
	{
		CLOCK_HAL_SetOutDiv1(SIM, 6);		// Core clock division 6x -> 4MHz
	}
	SystemCoreClockUpdate();
	SysTick_Config(SystemCoreClock/1000);
	systick_enable();
}

Poslední sleep mód je více komplexní a skládá se ze 3 procedur. Spoléhá se především na úsporný RTC oscilátor s čítačem, kterému je nastaven čas, kdy má dojít k probuzení, tzv. RTC Alarm, nebo je probouzen periodicky v sekundových intervalech.

Před vstupem do sleep režimu je volána funkce before_sleep(). Tato funkce zajistí vynulování některých stavových proměnných, inicializaci pinů do předem definované úrovně, zastavení nepotřebných periferií a nastavení přerušení od RTC čítače. Poté dojde k volání funkce POWER_SYS_SetMode() zajišťující přepnutí celého mikrokontroléru do režimu VLPS (Very low power sleep), kdy je hlavní oscilátor zastaven. Z tohoto režimu jej lze probudit pouze přerušením např. od tlačítek, či výše zmíněného RTC alarmu. Po probuzení zajistí funkce after_sleep() rekonfiguraci všech potřebných periferií do provozního režimu.

Do sleep módu se vstoupí pouze v případě, pokud není vznesen požadavek na zahájení měření čidlem BME280.

if (!flags.measure)
{
	before_sleep();			// Prepare MCU to sleep
	POWER_SYS_SetMode(1U, kPowerManagerPolicyAgreement);
	after_sleep();			// Prepare MCU to run
}

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.

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;
}

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.

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
}; 

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.

Problémy s napájením

V průběhu programování a následného testování se ukázalo, že aktualizace E-Ink displeje je velice proudově náročná operace. Při kompletní obnově dosahuje špičkově až 100 mA, což způsobuje problémy u více vybitých knoflíkových baterií. Vlivem vnitřního odporu poklesne napětí až pod hraniční mez, kdy E-Ink displej dokáže správně fungovat. Ve většině případů došlo k zaseknutí v nedefinovaném stavu a vysokému proudovému odběru, který vybil celou baterii. Dočasně je tedy celé zařízení napájeno ze dvou tužkových baterií, které jsou celkem nevzhledně umístěné ve slotu přilepeném na spodní straně. S nimi teploměr funguje bez problémů i při použití více vybitých kusů.

Řešení tohoto problému tedy spočívá buď v použití jiného typu baterie, nebo zařazením superkondenzátoru v napájecí větvi, který by dokázal vykrýt tyto odběrové špičky.

Závěr

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 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ě.

Video a fotografie

Firmware a schémata

Zdroje

2018/thermometer.txt · Poslední úprava: 2019/01/14 20:46 autor: Ondřej Jeřábek