Arduino mini mobil
- February 27 2021
- Atmel mikrokontroléry (AVR, ATMega, ATXMega, ATTiny...)
- 2630x Přečteno
Za zaslání článku děkuji.
Zabývám se Arduinem na amatérské úrovni cca 3 roky a předem bych chtěl zmínit, že se nepokládám vůbec za žádného pokročilého uživatele. Jen mě to úplně chytlo v tom dělat z několika důvodů. Je kolem toho dostupných spousta modulů, knihoven a ukázkových příkladů, funguje to vždy na první dobrou a hlavně je to vše strašně levné, zvlášť, když člověk objednává komponenty z Aliexpressu. Za mě ideání platforma na takové to domácí bastlení, kdy člověk něco měří a chce zobrazit hodnoty na displeji nebo je někam poslat, apod.. Omezení Arduina Una jistě všichni znají a to 2kB RAM a 32kB ROM, ale i přesto lze při troše snahy vytvořit věci, na které byste zvolili o několik tříd lepší procesor. Jde v podstatě o to co nejvíc optimalizovat kód.
Postupem času jsem si začal ošahávat čím dál zajímavější a komplexnější komponenty, až jsem došel na GPS a GSM modul. Tento projekt původně totiž neměl být vůbec mini mobil, ale gps tracker do mopedu Babetta (vyhledávání ukradeného mopedu). Jsem totiž velkým fandou do tohoto mopedu a také členem Babetta klubu Brno. V rámci klubu ladíme jak motory, tak na něj vymýšlíme různé elektronické doplňky (led světla, usb nabíjení, měřič hladiny paliva, Babetta computer, který měří otáčky a teplotu). Otáčkoměr je velmi přesný, do 15000ot/min ukazuje úplně přesně na otáčku (otestováno pomocí přesného arbitrážního generátoru). Kromě toho jsem vyvinul i mluvící hodiny řízené rádiem a hlas namluvil můj syn.
Tak a teď k samotnému řešení mini mobilu. Cílem bylo postavit minimalistický mobil s minimem komponent na minimalistické platformě Arduino. Využití by se jistě našlo pro děti, kde budou mít 2 tlačítka máma a táta a toť vše. Nebo pro důchodce, který špatně vidí a potřebuje opravdu jen zavolat rodině, takže 1-4 tlačítka na kontakty a hotovo. Rovněž mě lákalo sestrojit jednoduchý mobil za cenu do 200Kč. Když to dítě rozbije nebo ztratí, tak jen 200Kč v čudu a to tak nebolí...Iphone by bolel víc :)
Zapojení je přímo geniálně jednoduché. Jsou tam 2 světelné diody a k nim sériově odpory. Pak 2 tlačítka, jedna ATmega328p, mikrofon a reproduktor, modul GSM a displej. A toť vše. Jednodušeji to snad ani nejde. GSM modul SIM 800L stojí cca 40Kč v Číně a s Arduinem komunikuje na 9600 Bd po sériové lince. Přes I2C je připojen dvoubarevný 0,96 '' OLED displej 128x64. Baterii 1200mAh jsem použil z dronu Syma X5C a mám na ní rovněž z Číny napojen dobíjecí modul USB-C 5V/1A. Řešení jsem spájel na prototypové desce a spodek strany plošných spojů pak zalil do průhledné pryskyřice . Formu na odlití jsem si ručně uplácal z plastelíny :)
Plošňák má 3x7cm a na něj je umístěno všechno. Rozmístění součástek jsem provedl v rámci jednoho večera, že jsem si je rozmisťoval tak, aby se to tam všechno vlezlo a pak začal za pochodu pájet. Pájení mi zabralo půl dne a 3 týdny pak samotný program. Displej mám zasunutý do patice a opírá se přímo o mikrokontrolér ATmega, který je rovněž posazen v patici, aby šel vyndávat. Ještě mám z boku možnost připojit napájecí zdroj, kterým by mělo být 1S Li-ion / Li-Pol článek (3,7-4,5V) a z druhého boku mám vyvedený HW seriový port pro případné nahrání aktualizovaného sketche. Mobil má 2 tlačítka, jedním se vybírá v seznamu volajícího, druhým tlačítkem zavolá nebo ukončí hovor.
Telefonní seznam je hardkódovaný (viz kód) a může obsahovat libovolný počet kontaktů. Po spuštění mobilu se nastaví parametry SIM modulu, nastaví vyzváněcí melodie, přečtou se informace o síti, úrovni nabití v %, napětí baterie, datum a čas a síla GSM signálu (1-4čárky).Zjistí se, jestli nedošla nějaká sms a tu poslední vypíše. Modul nepodporuje sms s diaktitikou, neboť tyto SMS chodí zakódované jinak než v ASCII a neměl jsem na to čas to tam dodělat. Takže posílat na mini mobil ideálně krátké SMS bez hacku a carek.
Když někdo volá, tak zobrazí jméno volajícího, pokud je v telefonním seznamu, jinak napíše neznámé číslo. Mobil zobrazuje upozornění na přijatou SMS a rovnou vypíše sms, přičemž 10sekund přehrává melodii. SMS jsou tam čistě jako doplněk, pouze pro čtení. Zobrazí se jen 1x na displej a pak nenávratně zmizí. Po restartu mobilu se smažou všechny sms. Údaje na displeji jsou zobrazovány ve formě logu v konzoli. Poslední příkaz nebo volba je vždy vypsána dole a displej roluje informace nahoru jako když jste na příkazovém řádku ve Windows. Jednoduchou modifikací lze změnit grafické uživatelské rozhraní (vše je v jedné funkci), ale já jsem chtěl udělat geek mobil s inženýrským módem :) Mimochodem log je dobrý i na to, že člověk může koukat, co chodí ze SIM modulu za AT response a objevit třeba i nějaké nové věci, o kterých nevěděl (např. změna sítě operátora při přejezdu do zahraničí a už vídíte v logu nějaký status).Podrobně o notifikačních diodách viz dále.
V rámci tohoto projektu jsem musel řešit několik technických problémů, které mě posunuly dál a věřím, že čtenářům budou hodně užitečné. Mezi ně patří:
a) Arduino Uno jako single chip řešení bez přídavných součástek (krystal, kondenzátor, odpory, apod..). Můj první projekt čistě na švábu Atmega 328p s upraveným bootloaderem
b) postupná optimalizace klidové spotřeby až na 5mA včetně GSM modulu = výdrž mobilu týden na 1x 18650 baterii nebo 3 dny na 1200mAh baterii
c) multitasking, kdy se současně načítají tlačítka, aktualizuje obrazovka, blikají ledky atd.. (šikovná knihovna Tasker)
d) notifikační diody (nepřijatý hovor, slabá baterie)
e) snímání tlačítek s odstraněním šumu během přechodového stavu (mnou mírně modifikovaná knihovna Debounce)
f) komunikace s GSM modemem pomocí ATE příkazů a seznámení se s těmi nejužitečnějšími
g) odrušení od GSM bzučení
h) optimalizace kódu, aby zabíral co nejmíň RAM (přesun co nejvíce konstant do PROGMEM, sdílení paměti stringů, apod. featurky)
ad a) Arduino běží na interním 8MHz krystalu a používá upravený bootloader. Použil jsem řešení z tohoto odkazu https://www.hackster.io/techmirtz/arduino-without-external-clock-crystal-on-atmega328-d4fcc4
ad b) Atmega 328p má spotřebu přibližně kolem 3.5mA. GSM modul SIM800L žere standardně v klidu kolem 15-20mA, ale lze přepnout do úsporného režimu, kde když 5 sekund neprobíhá žádná komunikace po sériové lince, uspí se jen do režimu "listen" a spotřeba klesne na 1mA. Z tohoto režimu ho probudí SMS, hovor nebo komunikace po sériové lince s tím, že se ztratí první byte komunikace. Proto každý AT příkaz začínám mezerou, kterou si naštěstí GSM modul sám odtrimuje v případě, že zrovna nespí. Kromě toho zhasínám i displej po 1 minutě nečinnosti, což ušetří také pár mA. Jinými slovy bez výše uvedených optimalizací by mini mobil odebíral v klidu kolem 30mA, což by mi samo o sobě vytřískalo baterii za den a něco.
ad c) našel jsem šikovnou jednoduchou kniohovnu na realizaci pseudo multitaskingu od pana Stehlíka (Joysfera) https://github.com/joysfera/arduino-tasker . Tato knihovna značně zpřehlední kód, pokud potřebujete provádět nějaké úlohy v určitém čase. Programátor ale musí optimalizovat svůj kód tak, aby daný task netrval příliš dlouho, jinak se nepřepne kontext na další úlohu v čase, kdy má. Úlohy se přepínají automaticky vložením příkazu v sekci void loop()
ad d) každý správný mobil má mít notifikační diodu, která ukazuje slabou baterii a nepřijatý hovor, aniž bych musel zapnout displej. V kódu načítám každých 20 sekund stav baterie, když je zapnutý displej (u vypnutého jednou za hodinu) a pokud nabití klesne pod 40%, tak začne červená dioda blikat. Když klesne napětí pod 30%, tak dioda svítí pořád. SIM800L modul funguje pouze od 3.7V výš. Jakmile klesne napětí baterie níž, tak se nedovoláte.Proto je třeba nabíjet baterii dřív než je člověk zvyklý u komerčních mobilů. A to vlastně není ani na škodu, neboť se tím značně prodlouží životnost baterie. Pokud někdo volal, tak bliká žlutá dioda a uživatel pozná jednoduše, že zmeškal hovor
ad e) opět převzatá šikovná knihovna, kterou používám úplně v každém projektu, kde snímám stisk tlačítek. Trochu jsem ji vylepšil https://github.com/wkoch/Debounce
ad f) AT příkazy lze krásně vyčíst z kódu. Doporučuji projít sekci void setup (), tam je jich většina
ad g) v datasheetu k modulu SIM800L doporučují postavit dolní propust, která odfiltruje parazitní bzučení z GSM vysílání. Sestává z kondenzátorů 10pF a 33pF. Doporučují je dát co nejblíže k mikrofonu. Bohužel jsem nezaznamenal nějaké větší zlepšení, proto během hovoru bude slyšet bzukot víc než jste zvyklý u komerčních mobilů. Toto chce opravdu víc času a vychytat stínění, ale na to jsem neměl čas
ad h) tu největší výzvu jsem si nechal na závěr. Napsat kód, kde se vlezete do 2kB RAM s bufferem pro displej, na textovou konzoli, bufferem pro sériový port a spoustou globálních proměnných je velká výzva. Do této paměti se musí vlézt i halda (heap memory) a jakmile jste se při kompilaci přehoupli přes 1.7kB RAM, tak to začalo být nestabilní a padalo to. Toto mě donutilo přesunout všechny textové hlášky do paměti flash příkazem print F("ahoj"). To F říká kompilátoru, že má jít text do flash paměti a ne do RAM. Všiml jsem si, že hodně lidi toto ve svých programech nevyužívá. Dalším obrovským problémem jsou textové řetězce. Původně jsem chtěl projekt dělat jednoduše a tak jsem použil třídu String, ale velmi rychle jsem si zaplácal pamět a musel jsem přejít na čistě C řečení s 0 ukončeným řetězcem. Takže při podrobnějším studiu zjistíte, že někde mám String a někde už buffer, jak jsem byl postupně nucen kód optimalizovat. Doporučuji tuto bezvadnou stránku pro ty, co chtějí optimalizovat RAM.
https://www.instructables.com/Arduino-String-Manipulation-Using-Minimal-Ram/
Odteď už budu psát kód tak, že mi nebude žrát skoro žádnou RAM paměť. Tohle mě opravdu posunulo hodně daleko v optimalizaci kódu.
Kód pro Arduino, příslušné knihovny i schéma najdete v tomto zip balíku.
Pavel Majerek z Babetta klubu Brno (facebook) mi poslal svůj projekt miniaturního mini mobilu založeného na Arduino Uno. Sice to neměl být mobil, ale tracker, ale někdy se to tak přihodí :-)
Za zaslání článku děkuji.