Pojďme programovat elektroniku | Arduino

Programování elektroniky: Redakční rýmovník dostal věčný displej, který vůbec nic nežere

  • Už déle než měsíc stavíme zavlažovací systém pro redakční rýmovník
  • Pohání ho droboučká lithiová baterie, takže musí být úsporný
  • Existuje v podstatě jen jeden displej, který k němu můžeme připojit

V našem seriálu o programování elektroniky si posledních pár týdnů hrajeme s automatizovaným zavlažovacím systémem na baterii pro náš redakční rýmovník.

Skládá se z kapacitního čidla půdní vlhkosti, maličkého čerpadla, které dle potřeby nažene do květináče vodu z nádržky, a z řídící desky, kterou pohání drobný jednočlánkový lithiový akumulátor a dobíjecí 5V solární panel.

Připomeňte si všechny díly série:

  1. V první části jsme postavili surový prototyp s lithiovou baterií
  2. V druhé části jsme si ukázali, jak kreslit grafy rýmovníku na službě TMEP
  3. V třetí části jsme do nádržky s vodou přimontovali laserový dálkoměr

V dalším pokračování si ukážeme, jak k prototypu připojit extrémně úsporný prototypovací modul displeje s elektronickým inkoustem a jak na něm zobrazit základní údaje o stavu rýmovníku.

Podívejte se na video, jak jsme dnes vylepšili rýmovník:

Buňky plné barevných částic

E-inkové displeje používají ke změně pixelů na obrazovce techniku tzv. elektroforézy, která, jak praví Wikipedie, využívá k dělení látek jejich odlišnou pohyblivost ve stejnosměrném elektrickém poli.

0ac1e706-867e-4704-aaae-7f59bf1833b5
Základní princip přeskupení částeček v buňkách pixelů e-inkového displeje

Jednoduše řečeno, pixelové buňky jsou naplněné drobnými částečkami s různou barvou, které se působením elektrického pole přesunou do popředí, nebo naopak do pozadí. E-inkové displeje proto spalují elektřinu prakticky jen při překreslení.

Jakmile drobné částečky zobrazí to, co potřebujeme, displej klidně můžeme odpojit od napájení, schovat někam do skříně, a když jej po letech vytáhneme, bude ukazovat stále to samé.

E-ink není vhodný pro rychlé animace

Na stranu druhou, jelikož e-ink pracuje na elektromechanickém principu, trpí velmi nízkou rychlostí. Přeskupení částeček po celé ploše chvíli trvá, a proto se drtivá většina laciných modulů nehodí pro zobrazování animací. Však to sami znáte třeba z elektronických čteček knih.

77985a4f-ec73-443c-ab56-7304ef482988f07b367b-ee20-40ef-a0e3-4812fe347065
Povrch dvoubarevného e-inkového displeje pod mikroskopem a jeho zadní strana, na kterou se přeskupily částečky opačné barvy, takže vidíme negativ v zajímavé mřížkové konfiguraci

Na stranu druhou, pokud se má displej obnovovat třeba jen jednou za čas, nic lepšího na trhu nenajdete. A to je i případ našeho zavlažovacího systému, který běží na baterii, a proto jeho řídící čip po většinu času spí v hlubokém spánku s minimálním odběrem elektrického proudu.

0,00027 fps

Vzbudí se jen jednou za hodinu, pomocí kapacitního čidla zapíchnutého v květináči změří půdní vlhkost a pomocí laserového dálkoměru v nádržce na vodu také výšku hladiny. Pokud vlhkost klesne pod 60 % a v nádrži bude dostatek vody, řídící mikrokontroler na pět sekund spustí čerpadlo, které vžene do květináče doušek čerstvé vody.

Na závěr se čip připojí k redakční Wi-Fi, odešle změřené údaje na internet, aktualizuje e-inkový displej a přepne se zpět do hlubokého spánku.

Suma sumárum, náš e-inkový displej pracuje s obnovovací frekvencí zhruba 0,00027 fps.

Monochromatický 2,9" e-ink za pár stovek

Na zahraničních i českých e-shopech seženete celý zástup jak surových displejů, které ovšem budou vyžadovat ještě napájecí obvod, tak i hotových a dražších modulů, které rovnou připojíte k Arduinu, Raspberry Pi nebo k čemukoliv jinému.

dfafa792-c40c-427d-83e6-d2e067d87c80f07be494-9199-4ffc-b5a9-6c171497400a
Monochromatický 2,9" eink a sedmibarevný 4" eink v prototypovacím provedení od asijského výrobce Waveshare

Tyto displeje zpravidla komunikují skrze sběrnici SPI doplněnou hromadou vlastních řídících signálů a k dispozici je hned několik knihoven pro Arduino, které vše usnadní.

K nám do redakce nakonec zamířily dva exempláře od Wavesharu:

Odkazy výše sice vedou na originální asijský e-shop Wavesharu, nicméně oba displeje samozřejmě pořídíte i v tuzemských obchodech pro kutily. Ještě jednou, tím výčet e-inkových prototypovacích modulů rozhodně nekončí a jen Waveshare jich vyrábí desítky ve všech velikostech a cenových hladinách.

E-ink bude kreslit knihovna GxEPD pro Arduino

V naší instalaci jsme nakonec použili cenově dostupnější a menší 2,8“ displej (ten větší si ukážeme příště), který oživíme pomocí knihovny GxEPD pro Arduino od Jeana-Marca Zingga. Umí kreslit všechny základní vektorové tvary, bitmapy a podporuje i práci s rastrovými fonty formátu Adafruit GFX, na které je založená.

ae1d6eca-eb4a-480e-8387-367cc674fa11
O vykreslení základních tvarů, textu a bitmap se nám postará knihovna GxEPD

K dispozici jsou nicméně i ukázkové kódy přímo od Wavesharu, který na GitHub vystavil příklady pro všechny své displeje.

Připojení 2,9" e-inku k desce ESP32-LPKit

Náš systém je založený na české prototypovací desce ESP32-LPKit s Wi-Fi mikrokontrolerem ESP32. Ve srovnání s cetkami z AliExpressu je sice o něco dražší, nabízí ale velmi nízkou spotřebu v hlubokém spánku v řádu jednotek mikroampérů a nabíjecí obvod pro jednočlánkový lithiový akumulátor (4,2 V).

Do konektoru JST připojíme akumulátor a do USB malý solární panel s 5V regulovaným výstupem. O vše ostatní se už postarají obvody na desce.

5d1b27c3-6374-40fd-b550-9fc4269dc2d6
Schéma připojení e-inkového modulu a desky ESP32-LPKit

Jak už jsme si řekli výše, e-inkové moduly od Wavesharu zpravidla komunikují skrze sériovou sběrnici SPI, přičemž vyžadují ještě několik dalších pomocných signálů. Připojení k desce ESP32-LPKit proto bude vypadat jako na obrázku výše.

Grafické rozhraní

Náš displej bude zobrazovat toto grafické prostředí:

1b112bc8-c513-4798-9c92-5055f0edb5a0
Toto se bude zobrazovat na skutečném displeji

Všimněte si hrubé grafiky bez jakéhokoliv vyhlazení, displej samotný má totiž k dispozici pouze dvě barvy: světlou a tmavou. Displej má zároveň nízké rozlišení/DPI, abychom vyhlazení a odstíny šedi simulovali třeba pomocí dittheringu.

Grafické rozhraní můžeme rozdělit na tři části:

  1. Základní tvary dělících linek a černého obdélníku patičky
  2. Texty
  3. Bitmapy

Adafruit GFX

Všechny tyto operace displej provádí pomocí abstraktní knihovny Adafruit GFX, kterou známe i z práce s jinými displeji. Vše se vlastně liší jen v tom, že v případě dvoubarevného 2,9" displeje od Wavesharu máme k dispozici jen dvě barvy GxEPD_BLACK a GxEPD_WHITE.

Takže primitivní černý obdélník, který jako proužek vyplňuje patičku displeje, jsme vytvořili příkazem:

display.fillRect(0, 98, 296, 30, GxEPD_BLACK);

Přičemž objekt display je instance třídy GxEPD_Class, kterou jsme si vytvořili na začátku našeho programu (viz kód v závěru článku).

Bitmapy

Naše grafické rozhraní vykresluje na plátno také tři bitmapy s ikonami květináče, baterie a vodoměru. Knihovna samozřejmě neumí dekódovat obvyklé formáty jako JPEG, PNG nebo BMP, bitmapou totiž máme na mysli opravdu jen pole bajtů, které představují barvy jednotlivých černých a bílých pixelů s 1bit kódováním (1B = 8 po sobě jdoucích pixelů).

Dobrým zdrojem svobodných ikon je katalog flaticon.com

C/C++ pole za nás vygeneruje letitý, ale stále funkční webový generátor Image2cpp na GitHubu. Stačí nahrát černobílý obrázek v některém z obvyklých formátů, ponechat ostatní volby ve výchozím stavu a pouze v závěru v sekci Output vybrat Arduino code, single bitmap.

c49dce9a-e980-4aca-83df-eb84f5b354479f71bab3-9639-4953-828f-04ab317c696b8ac07409-0853-4b05-a8e2-9967350b12fb
Vyhledání ikony na flaticon.com, transformace do C/C++ pole v Image2cpp a výsledek v hlavičkovém souboru ikony.h našeho projektu pro Arduino

Po vygenerování získáme pole, které jen podle svého gusta přejmenujeme a zkopírujeme do nového hlavičkového souboru našeho projektu třeba s názvem ikony.h. Na začátek ještě odkážeme na hlavičkový soubor pgmspace.h:

#include <pgmspace.h>

Který dá překladači vědět, že tato rozměrná data označená klíčovým slovem PROGMEM nemá program nahrávat do maličké RAM, ale načítat je přímo z flashové paměti (program memory).

V hlavním souboru našeho programu po odkázaní na hlavičkový soubor s ikonami pak můžeme bitmapu vykreslit pomocí metody drawBitmap:

display.drawBitmap(ico_kvetinac, 0, 16, 64, 64, GxEPD_BLACK, 1);

Příkaz výše projde C/C++ pole pixelů ico_kvetinac, a vykreslí jej na souřadnice 0;16 (X ;Y). Ještě mu musíme sdělit rozměry bitmapy, tedy 64×64 pixelů, a barvu GxEPD_BLACK, kterou má kreslit.

Písma

Velmi podobným způsobem jako s bitmapami můžeme pracovat i s různými rastrovými písmy ve formátu Adafruit GFX. Písmem není ve své podstatě vlastně není nic jiného než pole podobných bitmap vždy pro každý znak abecedy.

3f7988e7-b165-4643-97ec-2599ed2f465f952d35a0-f014-4dc8-822d-7d8697018457b004c61d-7362-41f4-802a-f47d270fa453
Stažení vhodného TTF písma ze služby Google Fonts, vygenerování rastrového řezu pro konkrétní velikost v nástroji fontconvert a hotový hlavičkový soubor v Arduinu

K dispozici je několik předpřipravených řezů v různých velikostech, Adafruit nicméně nabízí i vlastní textový linuxový konvertor fontconvert z obvyklého formátu TrueType, který jsem použil i já. Návod, jak jej přeložit ze zdrojových kódů a jak se používá, najdete v nápovědě knihovny Adafruit GFX.

Příkaz v vykreslení textu „96“ vlastním rastrovým písmem na displej pak může vypadat analogicky takto:

display.setFont(&bebas37pt7b);
display.setTextColor(GxEPD_BLACK);
display.setCursor(62, 75);
display.print("96");

Inicializace displeje

Už umíme vykreslovat primitivní tvary, bitmapy i text, takže nám chybí jen samotné spojení s displejem, následná změna dění na obrazovce a závěrečné přepnutí do úsporného režimu.

Nejprve v hlavním zdrojovém souboru našeho programu odkážeme na konkrétní hlavičkové soubory pro náš 2,9" displej (GxGDEH029A1) a knihovny GxEPD:

#include <GxEPD.h>
#include <GxGDEH029A1/GxGDEH029A1.h>
#include <GxIO/GxIO_SPI/GxIO_SPI.h>
#include <GxIO/GxIO.h>

Poté si vytvoříme instance dvou tříd. Ta první se stará o spojení s displejem skrze sběrnici SPI a pomocných signálů (viz schéma zapojení displeje výše), ta druhá pak o samotné kreslení:

GxIO_Class io(SPI, 5, 17, 16);
GxEPD_Class display(io, 16, 4);

Čísla představují konkrétní vodiče

  • BUSY: GPIO4
  • SPI CS/SS: GPIO5
  • RST: GPIO16
  • DC: GPIO17

Knihovna dále předpokládá výchozí zapojení zbývajících vodičů sběrnice SPI, tedy:

  • Takt SPI SCK: GPIO18
  • Zápis SPI MOSI: GPIO23

SPI MISO (čtení) nepoužíváme, protože do displeje pouze zapisujeme.

Máme vytvořenou instanci displeje, takže jej zkusíme nastartovat:

display.init(115200);

Parametrem je rychlost sériové linky (115 200 b/s), do které může knihovna vypisovat případné chybové hlášky, pokud by se to nepodařilo.

Výchozí orientace displeje je na výšku, takže si ji upravíme po 90° krocích (0-3) do libovolné polohy, jak se nám to hodí. Třeba:

display.setRotation(3);

A vymažeme plátno tím, že jej celé překreslíme pseudobílou barvou:

display.fillScreen(GxEPD_WHITE);

Proč pseudobílou? Skutečná barva odpovídá odstínu částeček v buňkách pixelů, což nemusí být vždy dokonalá bílá, ale spíše našedlá, nažloutlá atp.

V dalším kroku můžeme pomocí metod, které jsme si ukázali výše, displej pokreslit, čím zrovna potřebujeme. 

Vše završíme skutečnou aktualizací displeje, protože všechny dosavadní úpravy jsme prováděli jen v mezipaměti:

display.update();

Displej, který nic nežere

Až budeme mít hotovo, můžeme displej vypnout pro co nejnižší odběr elektrické energie v době nečinnosti:

display.powerDown();

I když tedy modul zůstane i nadále pod napětím, jeho elektrické obvody by měly odebírat opravdu naprosto zanedbatelné množství šťávy z baterie. Kdybychom celý modul nyní odpojili od řídící desky, vykreslený obraz na něm zůstane klidně i celé roky.

Jak už jsme si totiž řekli výše, e-ink je vlastně elektromechanický typ displeje a instrukcemi jsme nerozsvěcovali nějaké LCD/OLED subpixely jako na běžných displejích, ale opravdu mechanicky přeskupovali mikroskopické částečky elektroinkoustu. Elektroinkoustu, jehož pozice se pochopitelně nezmění ani po úplném odpojení zdroje elektřiny.

Diskuze (12) Další článek: Evropa chce dohnat Čínu a Silicon Valley. Obří iniciativa má za cíl do roku 2025 vychovat milión špičkových odborníků

Témata článku: , , , , , , , , , , , , , , , , , , , , , , , ,