Arduino web server

Moje první pokusy s připojením Arduina k ethernetu proběhly už před více než rokem, protože jsem měl ze školy půjčené Arduino Ethernet. Poměrně dlouho pak leželo ve skříni, až jsem ho nakonec musel vrátit. Proto jsem se rozhodl objednat si z Dealextreme Ethernet Shield a k němu Arduino UNO. Pochopitelně to nejsou originály, ale fungují naprosto stejně za podstatně nižší cenu - celá objednávka mě vyšla na necelých 23 USD. Zájemcům o koupi doporučuji vyzkoušet ještě Ebay, tam lze stejné komponenty sehnat ještě levněji. Protože návodů na jednoduchý server s Arduinem je na internetu dost, nebudu se zabývat úplnými základy, ale spíše se podělím o zkušenosti s tvorbou něčeho trochu složitějšího.

Proč to nefunguje, aneb máš dost volné RAM?

Brzy se během mých pokusů objevily záhadné problémy s funkčností programů - mohl za ně nedostatek paměti RAM. Bohužel s těmi 2 kB, kterými Atmega328 disponuje, se musí hospodařit opatrně. Pokud člověk postupuje například podle tohoto tutoriálu a celou web stránku vypisuje klientovi následujícím způsobem:

client.println("<html>");

Každý odesílaný string takto uzavřený v uvozovkách zabírá místo v RAM, nestudoval jsem nikde detailně, jak to vlastně přesně funguje, pouze jsem to vypozoroval. V případě krátkých stringů to nevadí, ale vytvořit i celkem jednoduchou web stránku, která bude mít třeba 1000 znaků není problém a pak už to vadí dost podstatně. Každý znak obsadí jeden bajt a půlka RAM je hned zabraná. Pro chod zbytku programu už nemusí zbýt dost prostoru. Ke zjištění volného místa v RAM slouží jedna šikovná knihovna.

Řešení - napadly mě 3 varianty:

  1. Použít větší Arduino Mega s 8 kB RAM
  2. Zkusit program s web stránkou nějak optimalizovat
  3. Uložit stránku do souboru na SD kartu

První řešení je asi nejrychlejší, pokud máme Arduino k dispozici, nicméně není úplně ideální, protože časem by mohla dojít i ta větší RAMka... A hlavně je zbytečné skladovat v RAM stringy web stránky, které se nemění. Po chvíli hledání na internetu jsem narazil na možnost ukládat data do programové FLASH paměti mikrokontroléru pomocí modifikátoru PROGMEM. Doporučuji prostudovat část Arrays of strings, kde je i názorný příklad použití, podle kterého jsem sám postupoval. Takto je tedy možné program optimalizovat, aby obsadil co nejméně prostoru v RAM.

Pochopitelně jsem vyzkoušel i třetí způsob, tedy SD kartu. Rovněž lze postupovat podle velmi dobře zpracovaného tutoriálu. Obrovskou výhodou je pohodlné uložení a editace web stránky v souboru na SD kartě. Nepřekáží vám v programu a upravit ji můžete třeba v poznámkovém bloku nebo PSPadu. Nicméně čtení z karty je dost pomalé... Provedl jsem malý srovnávací test se stránkou o velikost přibližně 1200 bajtů. Odeslání celého obsahu klientovi z programové FLASH paměti netrvalo ani 25 ms, zatímco z SD karty téměř čtvrt sekundy - 250 ms. Rozdíl je tedy asi desetinásobný. Ta čtvrtina sekundy už je na straně uživatele s prohlížečem skutečně poznat. Těžko tedy rozhodnout, který způsob je vlastně nejlepší, prozatím jsem zvolil programovou paměť.

Už nestačí ani FLASH...

Mým cílem bylo vytvořit server, který by měřil vnitřní a venkovní teplotu, kterou by prezentoval na web stránce. Obě teploty by měl pravidelně ukládat do souboru na SD kartě s časovým údajem získaným z RTC hodin. Dalším úkolem bylo ovládání LED pomocí tlačítek formuláře a možnost odeslat krátkou zprávu, která by se zobrazila na LCD displeji. Když jsem do programu vložil všechny potřebné knihovny a zkusil ho zkompilovat, skončil jsem s chybovou hláškou sketch is too big. A bylo vymalováno, můj program přesáhl 32 kB, takže se do FLASH paměti kontroléru prostě nevešel. Prakticky to znamenalo návrat k řešení číslo 1 z předchozího odstavce. Vznikl tak webový server se starším Arduino Mega, které jsem vykuchal z předchozího projektu.

Verze s Arduino Mega

Následující obrázky zachycují současnou podobu serveru - jak fyzickou, tak i zobrazené web stránky a informace vypisované do konzole. Zkusil jsem ze zvědavosti nakreslit schéma v softwaru Fritzing, bohužel s exportovanou podobou obrázku nejsem vůbec spokojen, vypadá spíš jako nepovedená omalovánka.(Nejspíš by to chtělo nakreslit znovu v osvědčeném Eaglu.) Ethernet Shield není nikam připojený, protože vše potřebné se realizuje nasazením na Arduino. Jedno teplotní čidlo v odolném provedení jsem připojil pomocí 10 metrového kabelu a vytáhnul na balkon pro měření venkovní teploty, takže na fotografii není vidět.

Aktuální funkce serveru:

  • Měření vnitřní a venkovní teploty pomocí čidel DS18B20
  • Záznam teplot na SD kartu každých 15 minut s časovým údajem z RTC. Naměřené hodnoty si lze nechat vypsat buď do konzole nebo na web stránku.
  • Ovládání LED pomocí tlačítek webového formuláře.
  • Odeslání krátké zprávy z web stránky přímo na LCD displej serveru - maximálně 32 znaků. Tyto zprávy se rovněž archivují do souboru na SD kartě.
  • Soubor se záznamy teplot a zpráv lze příkazem vymazat přes konzoli, aby nebylo nutné vyjímat kartu.

Komponenty:

Program pro Arduino ke stažení - snažil jsem se okomentovat co šlo, rozhodně by se dalo členění a přehlednost ještě vylepšit, ale na to dojde možná časem. Pokud by si chtěl někdo server postavit a dodrží schéma zapojení, měl by po nahrání programu hned naskočit. Pochopitelně je ale třeba nastavit takovou IP a MAC adresu, která nekoliduje s žádnou jinou v síti. K levným Ethernet Shieldům z Číny štítek s MAC adresou není, takže je třeba si nějakou vymyslet. Rovněž použití čidel DS18B20 vyžaduje nastavení - každé čidlo má totiž svoji jedinečnou adresu. Knihovna k čidlům obsahuje i program Tester, který najde všechna dostupná čidla na sběrnici a vypíše jejich adresy.

Další vylepšení

Je jasné, že výše popsaná verze není poslední, záleží pouze, kolik budu mít času. Určitě bych rád použil nějaký větší displej - možná i grafický. Rovněž by se mi zamlouvalo osvobodit server od síťového kabelu a místo Ethernet Shieldu zkusit nějaký wifi modul - třeba od Adafruit.

- Stránka vytvořena 25. září 2014