SpaceX je za sodobna vesoljska plovila Starship v razvoju priredil krmilno elektroniko in programje svojega »delovnega konja«, rakete Falcon 9, a šele v peto se mu je posrečil njegov pristanek z višine 10 km. Podobno velja za domačo elektroniko. Kako hitro in enostavno razvijati? Kako testirati in dopolnjevati ugnezdeno programsko opremo? Kaj narediti, da bo zanesljivo delovalo tudi, ko gre kaj narobe? Kdaj začeti vsakodnevno uporabljati?
Avtor: dr. Simon Vavpotič
E-pošta: simon.vavpotic@siol.net
2021-297-44
Svet ni idealen, zato moramo pri razvoju nove elektronike, še posebej njene ugnezdene programske opreme, vselej dobro premisliti in preizkusiti (skoraj) vse možnosti, do katerih lahko pride med delovanjem naprave. V nasprotnem primeru bomo prej kot slej izkusili prastaro reklo, ki je veljalo za prve različice Microsoftovih Windows: »Če ne deluje, zaprite vsa okna in odprite vsa okna… V skrajnem primeru pritisnite tipko reset na ohišju računalnika«. K sreči že dolgo ni več tako, a to grenko izkušnjo je na eni izmed odmevnih televizijskih predstavitev tehnologije Plug nad Play na kanalu CNN v takrat novih Windows 98 izkusil celo Bill Gates.
Ta vsebina je samo za naročnike
Še nekaj se lahko naučimo od ustanovitelja in CEO SpaceXa, Elona Muska, ki je tudi sam odličen programer. Testiranje moramo izvesti hitro in učinkovito in se ob vsaki napaki, še posebej usodni, čim več naučiti. Elon Musk je tudi diplomirani inženir fizike, kar mu pride še kako prav pri razumevanju težkih problemov načrtovanja (elektronike) vesoljskih plovil. Vsekakor je pomembno, da razumemo delovanje in zgradbo naprave, ki jo gradimo, in ne le, da projekt natančno prekopiramo s spleta. Pri delu ne smemo obupati, saj pogosto uspeh ni tako daleč, kot si mislimo, razen če smo izbrali povsem napačen koncept… Za doma so najboljše enostavne in poceni rešitve, pri katerih je s pravilno izdelano vgrajeno programsko opremo malo možnost, da gre kaj narobe, kljub temu pa zadovoljivo rešijo problem.
Kako bomo razvijali in testirali?
V seriji člankov se bomo lotevali številnih praktičnih primerov programiranja mikrokontrolerjev, vendar ne bi bilo prav, če bi pisanju programske kode samo teoretizirali in prav tako ne, če bi bili praktični primeri namenjeni samo eni družini mikrokontrolerjev. Če je programski jezik C/C++ nekoč poenotil programiranje sistemske programske opreme za strežnike in namizne računalnike, je Arduino razvojno okolje danes na dobri poti, da poenoti tehnike programiranja mikrokontrolerjev.
Arduino razvojno okolje je bilo v začetku namenjeno predvsem manj izkušenim programerjem, vendar to ne pomeni, da ga ne moremo uporabit za pripravo kakovostne ugnezdene programske opreme, saj lahko vanj vgradimo vse programske strukture in funkcije, ki zagotavljajo zanesljivo in varno delovanje. V zahtevnejše razvojna okolja, kot je MPLAB X Harmony, lahko vgradimo enako funkcionalnost, le da se moramo bolj potruditi, da pridobimo podatke za njihovo delovanje. Denimo, vrednost sistemskega števca v Arduino razvojnem okolju preberemo s preprostim klicem ugnezdene funkcije millis(), ki vrne 64-bitno nepredznačeno celo število, v MPLAB X Harmony razvojnem okolju pa moramo prej pripraviti ustrezne programske strukture, za kar potrebujemo več programskih vrstic pa tudi vključitev ustrezne programske knjižnice.
Arduino s chipKIT tudi za Microchip PIC32 mikrokontrolerje
Arduino razvojno okolje mogoče uporabiti tudi za programiranje s chipKITom združljivih razvojnih plošč z Microchip PIC mikrokontrolerji, za katere ne potrebujemo dodatnega Flash RAM čipa, kot ga imajo Espressif Systemsovi ESP moduli, ampak se s pomočjo zagonskega nalagalnika programske kode slednja shrani kar v vgrajeni pomnilnik PICov. Podoben dizajn imajo tudi najnovejši Espressifovi ESP32C moduli. Pri tem za PIC mikrokontrolerje ni bojazni, da bi ostali brez Wi-Fi podpore, saj je v Arduino razvojnem okolju odlična podpora za WINC15x0 module, ki jih povežemo prek SPI vodila.
Za začetnike je zanimiva razvojna plošča chipKIT DP32 s PIC32MX250F128B mikrokontrolerjem, ki je sicer ne proizvajajo več, jo pa lahko izdelamo doma tudi na tiskanem vezju za prototipiranje ali prototipni plošči (angl. protoboard), saj je mikrokontrolerju dodanih le nekaj pasivnih električnih komponent. Za shranjevanje programov lahko prek SPI vodila oddamo tudi zunanji Flash RAM.
Po drugi strani, lahko za razvoj v Arduino okolju uporabimo tudi zmogljivejši PIC32MX270F256B ali že izdelano razvojno ploščo chipKIT Lenny ali katerega od PIC32MZ Starter Kitov, če nanj namestimo zagonski nalagalnik Arduino kode iz datoteke HEX, ali pa v okolju MPLAB X IDE kodo priredimo za izbrani mikrokontroler. Nalagalniki zagonski nalagalniki za standardne razvojne plošče so v voljo v HEX datotekah, ki jih najdemo na chipKIT spletni strani chipkit.net.
Če se lotimo izdelave lastne Wi-Fi PIC z Arduino združljive razvojne plošče, je PIC32MX270F256B + WINC1510 modul odlična kombinacija, saj lahko v MPLAB X IDE priredimo zagonski nalagalnik chipKIT Lenny razvojne plošče. Vseeno pa opozorimo, da za prevajanje ugnezdene programske kode v 16-bitnem načinu »s« potrebujemo plačljivo različico Microchip XC32 C/C++ prevajalnika. Lahko pa namesto tega uporabimo PIC32MX250F128B z 8 MHz resonatorjem in že preveden zagonski nalagalnik za chipKIT DP32 razvojno ploščo.
Uporabniški vmesniki
Uporabniški vmesniki naprav z vgnezdeno programsko opremo so navadno enostavni, veliko jih niti nima tekstovnega ali grafičnega prikazovalnika, ampak le LED-ice, vseeno pa v zadnjem času postajajo popularni majhni LCD in OLED prikazovalniki, ki jih z napravo povežemo prek SPI ali I2C vodila. O tem več v prihodnjih nadaljevanjih.
Po drugi strani, je pri večini naprav nepogrešljiva taka ali drugačna tipkovnica, ki jo sestavljajo stikalne ali kapacitivne mikro tipke. Večina mikrokontrolerjev, ki jih lahko programiramo v Arduino razvojnem okolju ima vgrajeno strojno podporo za priklop kapacitivnih tipk, za kar najdemo podporo tudi v nekaterih Arduino programskih knjižnicah. Tokrat nas bo zanimalo, kako pravilno zajemati in obdelati pritiske na (mikro) tipke, da bo v mikrokontroler vgrajena aplikacija delovala uporabniku prijazno pa tudi, da bomo lahko eno tipko uporabili za proženje več kot ene funkcije.
»Podivjana« tipka
Mikro tipke pogosto uporabljamo v domačih projektih, saj so za upravljanje mikrokontrolerjev več kot priročne. Ko je naprava nova, navadno z njimi nimamo veliko težav, ko pa se obrabijo, se obnašajo skoraj kot majhni oscilatorji. Preklop tipke ni več takojšen, ampak lahko mikrokontroler ob enem pritisku zazna več impulzov – t.i. odboje oz. nihljaje signala. Je za to kriv proizvajalec mikro tipk? Smo krivi mi ker smo kupili najcenejše, da bi znižali stroške projekta? Kaj pa če bi vgnezdeno programsko opremo namesto tega raje napisali tako, da bi upoštevali tudi možnost neidealnega delovanja mikro tipke?
V Arduino razvojnem okolju je med splošnimi primeri tudi programček Debounce.ino, ki nazorno prikaže eno od tehnik preverjanja stanj tipk in mikro tipke, pri kateri preberemo stanje digitalnega vhoda šele, ko se to umiri za zahtevani časovni interval t.i. debounce time, oziroma čas ko se umirijo odboji in drugi prehodni pojavi. Navadno zadošča okoli pol sekunde.
Druga možnost je, da v glavni zanki nekajkrat preverimo digitalni nivo vhoda, s katerim je povezana tipka in izračunamo povprečje. Če je to več kot pol, je tipka pritisnjena, sicer pa ne. Boljša rešitev je meritev časa trajanja logične 0 in logične 1 s pomočjo sistemske ure. V praksi to pomeni, da v spremenljivko najprej preberemo vrednost sistemskega števca, ki se poveča za 1 z vsakim procesorskim taktom, nato pa ob vsakem prehodu sistemske zanke preverimo, ali se je vrednost števca že povečala za zahtevano vrednost, kar lahko prevedemo v trajanje v mikrosekundah ali milisekundah, če poznamo hitrost procesorske ure.
Kljub temu enotnega pravila za preverjanje digitalnih vhodov tipk ni, saj se lahko na daljših signalnih linijah od panela s tipkami do mikrokontrolerja pojavljajo tudi kratkotrajni neželeni impulzi tudi ko čas odbojev mine.
Za praktični preizkus lahko uporabimo tipko za zvonec, ki jo običajno uporabljamo pri vhodnih vratih, ki je zelo trpežno, vendar neidealno stikalo s sorazmerno dolgim časom odbojev. Tipko prek upora (npr. 4,7 k ohm) vežemo med napajalno napetost (npr. +3,3 V) in maso, priključek, kjer je povezana z uporom pa dodatno vežemo na vhod mikrokontrolerja (npr. ESP32 modula). Če smo čas odbojev v Debounce.ino pravilno nastavili, bo mikrokontroler zaznaval le po en pritisk na tipko, ko jo enkrat pritisnemo.
Kako s tipko sporočimo več kot stanje enega bita?
Enostavna digitalna naprava, denimo predvajalnik zvočnih posnetkov, se na pritisk določene tipke (npr. START) vselej odzove enako. Lahko pa namesto tega isto tipko uporabimo tako za START kot za STOP, če shranjujemo kontekst. Ko predvajalnik ne predvaja zvoka, pomeni pritisk na tipko START, med predvajanjem pa STOP. Zdi se enostavno, a naiven in neizkušen programer bo hitro ugotovil, da se pogosto predvajanje za hip vklopi in nato takoj izklopi. Vendar bo s preizkušanjem navadno prišel do zaključka, da če je tipko po startu dovolj hitro spusti, predvajanje vseeno steče in se ne ustavi. Podobno velja, ko tipko pritisne med predvajanjem in jo mora nato dovolj hitro spustiti, da se predvajanje ponovno ne začne. Kaj je naredil narobe? Pri preverjanju stanja tipke ni upošteval, da mora tipko najprej spustiti, preden lahko sproži novo akcijo. Torej, pritisk na tipko velja samo, če tipka prej ni bila pritisnjena. Najenostavnejša kontrola v tem primeru, je da program po vsakem pritisku na tipko sproži ustrezno akcijo šele, ko je tipka spuščena. Vendar zna biti to moteče, saj pogosto želimo, da akcija steče že tipko še držimo pritisnjeno. V tem primeru programsko implementacijo raje nekoliko spremenimo, tako da program ob zagonu naprave najprej preveri stanje tipke, ki mora biti spuščena, sicer lahko uporabnika opozori tipkovnica pokvarjena ali da ne deluje pravilno, kot je to pri zagonu osebnega računalnika. Začetno stanje tipke je tako vsakič NEPRITISNJENA. Nato ob vsakem preverjanju stanja s tipko povezanega digitalnega vhoda upoštevamo le spremembo iz 0 v 1, ki pomeni, da je bila tipka spuščena (negativna logika) in iz 1 v 0, ki pomeni, da je bila tipka pritisnjena. Če nas zanima kolikokrat je uporabnik pritisnil tipko, preprosto preštejemo prehode stanja iz 1 v 0. Mogoča je tudi vezava tipke med napajanje in upor. V tem primeru pomeni prehod iz 0 v 1, da je tipka pritisnjena, iz 1 v 0 pa da je spuščena. Pri takem načinu delovanja zmoti le to, da ni ponavljanja akcij oziroma moramo tipko še enkrat pritisniti, če želimo, da se akcija ponovi.
Namesto tega lahko uporabimo nadzor nad ponavljanjem akcij, kakršen je pri računalniški tipkovnici. Zdaj nas zanima čas trajanja pritisnjenosti tipke, torej čas trajanja po prehodu iz stanja nepritisnjenosti tipke v stanje pritisnjenosti. Vsekakor velja stanje pritisnjenosti šele po tem, ko je minil čas odbojev. Če traja pritisk na tipko dovolj dolgo, lahko akcijo ponovimo. Vendar se tako pojavi še vprašanje filtracije morebitnih neželenih kratkih impulzov. Te odstranimo z enostavnim merjenjem časa, ki mora miniti med spremembo stanja digitalnega vhoda in potrditvijo novega stanja tipke.
Večkratni pritiski na tipko in različno dolga trajanja pritiska
Ustanovitelj Apple, Steve Jobs, je bil dolgo časa prepričan, da na računalniški miški zadošča ena sama tipka, pri čemer navadno en klik pomeni zgrabi, dvoklik pa izvedi. Dvoklik že dolgo uporabljamo tudi v Microsoftovih Windows, čeprav ima večina današnjih mišk dve tipki in kolesce, kar je bolj praktično za izbiro posebnih funkcionalnosti, kot če bi morali naše želje kodirati prek ene tipke. Je pa res, da so tehniko sporočanja veliko informacij preko omejene tipkovnice najbolj izpopolnili proizvajalci klasičnih mobilnih telefonov, pri katerih so morali črke pri sestavi SMS sporočila kodirati prek številčnice. Tudi pri pametnih telefonih z zaslonom na dotik ima navadno tipka za vklop in izkop še kopico drugih funkcionalnosti.
Zaenkrat se omejimo samo na najbolj enostaven primer, ko želimo s tipko za vklop in izklop sporočiti zgolj tri akcije: VKLOPI/IZKLOPI prikazovalnik in PRIŽGI/UGASNI napravo. Kratek pritisk na tipko vklopi ali izklopi prikazovalnik (opcijsko samo njegovo osvetlitev), dolg pritisk pa prižge ali ugane napravo. Vgnezdeno programsko opremo moramo prilagoditi človeški zaznavi toka časa in pri tem upoštevati čas odbojev. Dolg pritisk naj navadno ne bi trajal dlje od dveh sekund, kratki pa naj ne bi bil krajši od 250 milisekund. Zdaj moramo le še izmeriti čas pritisnjenosti tipke, pri čemer lahko kratek pritisk upoštevamo le, če uporabnik tipko spusti pred potekom 2000 ms (dveh sekund).
Želeno funkcionalnost tako izdelamo na zelo podoben način, kot ponavljanje akcij v prvem primeru, le da po izteku najdaljšega časa pritisnjenosti tipke prožimo drugo akcijo, v tem primeru izklopimo napravo. Upravljanju vklopa naprave imamo, po drugi strani, dve možnosti: Ker je naprava izklopljena in ne poganja uporabniških programov, bi jo lahko vklopili takoj po pritisku tipke, vendar navadno želimo preprečiti neželen vklop in zato raje počakamo 2 sekundi. Po drugi strani pa si med delovanjem naprave vklop in izklop zaslona sledita takoj, ko uporabnik tipko za vklop spusti.
Če se ponovno navežemo na že omenjeni primer Debounce.ino iz Arduino razvojnega okolja, moramo vanj poleg spremenljivk lastDebounceTime in debounceDelay dodati še spremenljivko delay01, s katero določimo zakasnitev za akcijo VKLOP/IZKLOP, ki jo merimo po prehodu stanja digitalnega vhoda iz 1 v 0, ki je določen s trajanjem debounceDelay, vse dokler je tipka pritisnjena. Torej bomo napravo vklopili/izklopili po preteku časa delay01 + debounceDelay. Pri tem lahko iz programa preberemo, da je debounceDelay nastavljen na 50 ms, kar na skupno trajanje za proženja akcije VKLOP/IZKLOP skoraj ne vpliva (traja 2050 ms namesto 2000 ms).
Kako krmiliti in zaznavati prek istega digitalnega vhoda?
Čeprav pri sodobnih mikrokontrolerjih s 64 in več priključki redko zmanjka priključkov, si lahko v takih primerih pomagamo tako, da en priključek hkrati uporabimo kot vhod in izhod. Če želimo z istim priključkom hkrati krmiliti signalno LED in preverjati stanje tipke, lahko tipko, LED in digitalni vhod-izhod mikrokontrolerja vzporedno vežemo na skupen upor, ki je povezan na napajalno napetost.
Zdaj lahko LED izklopimo na dva načina, programsko s krmiljenjem priključka kot digitalni izhod z nizkim logičnim stanjem, pri čemer tok steče skozi mikrokontroler namesto skozi LED, ali z mikro tipko, s katero premostimo LED in tok steče preko stikala namesto preko LED.
Če digitalni priključek sprogramiramo kot vhod, bo LED svetila, razen če pritisnemo mikro tipko, ko bo hkrati na digitalnem vhodu logična 0.
Kaj pa če želimo, da LED sveti samo, ko je mikro tipka pritisnjena? Nič lažjega! Potem LED preko 1 k ohm upora zvežemo na napajanje (+3,3 V ali +5 V, odvisno od izbranega mikrokontrolerja), katodo LED pa vzporedno povežemo z digitalnim vhodom mikrokontrolerja in enostavnim vezjem, v katerem sta zaporedno vezana mikro tipka in 330 ohmski upor. Slednjega moramo dodati za zaščito priključka mikrokontrolerja, ko ta deluje kot izhod. Če je pritisnemo mikro tipko, ki je izhod v visokem stanju, bo tok stekel čez 330 ohmski upor in s tem ne bomo poškodovali mikrokontrolerja. Ko pa deluje priključek mikrokontrolerja kot vhod, bi v visokem stanju (logična 1), saj preko upora napaja LED, vendar je tok tako majhen, da LED ne zasveti, zasveti pa, če pritisnemo mikro tipko. Takrat je digitalni vhod v nizkem stanju in mikrokontroler bo prebral logično 0.
Kaj moramo paziti v Arduino kodi? Preklop med režimoma delovanja izhodnega priključka kot digitalni vhod in digitalni izhod ni hipen, ampak zahteva nekaj malega časa. Zato moramo po spremembi režima iz izhodnega v vhodnega v programski kodi počakati, preden preverimo stanje digitalnega vhoda. Poglejmo:
if(!LEDactive){ // Check GPIO only when it is programmed as input pinMode(SW_GPIO_NUM, INPUT); button=digitalRead(SW_GPIO_NUM); ... if(button){ // if button is pressed then LED ON LEDsignal=3000;LEDactive=true;LEDactive_tm=mllis(); pinMode(SW_GPIO_NUM, OUTPUT); // OUTPUT digitalWrite(SW_GPIO_NUM, LOW); // LED ON } ... } else { // Switch GPIO back to input mode after if((uint32_t)(millis()-LEDactive_tm)>LEDsignal){ pinMode(SW_GPIO_NUM, INPUT); // little red led on back of chip LEDactive=false; } }
Kako pravilno meriti sistemski čas
Sistemski čas merimo s pomočjo sistemskega števca, katerega vrednost najprej shranimo v spremenljivko, nato pa jo primerjamo s trenutno vrednostjo sistemskega števca. Pri tem je zelo pomembno, da pravilno določimo tip spremenljivke. ESP32 ima vgrajen 64-bitni sistemski števec, ki šteje mikrosekunde, ki se lahko med daljšim delovanjem modula (okoli 50 dni) prevrti in začne ponovno šteti od nič. Medtem, ko Arduino funkcija millis() vrača samo vrednost števca v milisekundah in je nepredznačeno 32-bitno celo število. Vendar te funkcije ne smemo zamešati s funkcijo esp_timer_get_time(), ki jo imajo samo ESP moduli in prebere celotno 64-bitno vrednost sistemskega števca.
In tu so izkušeni programerji AiThinkerja, proizvajalca ESP32-CAM modulov namerno ali nenamerno naredili napako, saj so za hrambo vrednosti sistemskega števca izbrali napačen podatkovni tip, 64-bitno predznačeno celo število (angl. integer), namesto nepredznačenega (angl. unsigned integer). Težave so se zato pojavile, ko je sistemski števec presegel polovico svojega dosega, oziroma se je v bit 63 zapisala enica. Zato je program tako vrednost obravnaval kot negativno, namesto kot pozitivno. Razlika med trenutno vrednostjo sistemskega števca in shranjeno vrednostjo je bila tako zelo velika tudi če sta se vrednosti razlikovali za en sam bit. Tako so potrebne zakasnitve zmanjšale skoraj na nič, kar je imelo za posledico odpoved delovanja.
Napako lahko odpravimo tako, da preprosto zamenjamo podatkovni tip iz 64-bitnega predznačenega števila v 64-bitno nepredznačeno. Če računamo razliko dveh nepredznačenih števil in rezultat shranimo v 64-bitno nepredznačeno vrednost, bo rezultat vselej pravilen.
Podobno velja tudi za funkcijo millis(), le da pri tej računamo čas z 32-bitnimi vrednostmi. Za pravilno izračunavanje razlike je tako potrebno v programskem jeziku uporabiti na primer naslednji stavek:
uint32_t Tstart=millis(); uint32_t Tdelay; Tdelay=(uint32_t)(millis()-Tstart);
pri čemer moramo Tdelay in Tstart deklarirati kot spremenljivki tipa uint32_t. Z dodatno pretvorbo podatkovnega tipa zagotovimo, da to tudi rezultat izračunan kot 32-bitno celo število in bo razlika tudi, če bo funkcija millis() vrnila manjšo vrednost od Tstart, saj bo pri odštevanju prišlo do t.i. prevrtenja. Nasprotno bi morali, če bi hoteli računati s predznačenimi celimi števili, uporabiti vsaj 33-bitni zapis, pri čemer bi bil zadnji bit namenjen za predznak. Vendar bi namesto tega skoraj gotovo raje uporabili 64-bitna cela števila (int64_t) z dvakrat daljšim zapisom, saj bi s tem ohranili pravilo, da je daljši podatkovni tip sestavljen iz dveh krajših tako, kot smo doslej imeli: int8_t (8-bitno predznačeno celo število), int16_t (16-bitno predznačeno celo število), int32_t (32-bitno predznačeno celo število).
PROJEKT: Digitalna preklopna ura z upravljanjem prek Wi-Fi
ESP8266 in ESP32 moduli združujejo kopico funkcionalnosti in znajo sorazmerno dobro meriti čas tudi brez dodatnega 32,768 kHz resonatorja, ki ga mikrokotrolerjih uporabljamo za pogon. Preklopno uro sestavljajo +3,3 V napetostni stabilizator, Wi-Fi modul ESP8266, krmilnik relejev ULN2803 in do 8 relejev, ki lahko delujejo pri napetosti do +30 V. Za programiranje ESP8266 potrebujemo še USB-RS232 vmesnik, kot so: CH340, CH341, MCP2200, .. Dizajn je sorazmerno enostaven, saj moramo ESP8266 zagotoviti stabilizirano 3,3 V napajanje, medtem, ko se ULN2803 napaja z napetostjo za releje. Če uporabimo 5 V napajalnik in 5 V rele, je vezje, kot je prikazano na sliki, zares enostavno.
V vezju potrebujemo le še Arduino ugnezdeno programsko opremo, ki si jo lahko prenesete iz spletne strani PC USB Projects. Ker ESP8266 nima ugnezdene strojne podpore za uro realnega časa, je ta realizirana kar v glavni zanki in se osvežuje ob vsakem prehodu glavne sistemske zanke s klicem funkcije TimeUpdate(), ki vrednost sekund v programski realizaciji realnega časa na vsakih 1000 ms (1 sekunda) poveča za 1, obenem pa po potrebi poveča tudi števce minut, ur, dni, mesecev in let. Pri tem upošteva tudi prestopna leta. Čas 1 sekunde meri kot razliko časov med dvema klicema iz glavne zanke.
Funkcija Schedule_process() je namenjena vzdrževanju urnika preklopov relejev. Dokler je urnik prazen preklopna ura zgolj meri čas, ko pa s funkcijo Schedule_addItem(String s_event), do damo novo postavko, ob določeni uri prižge ali ugasne krmiljeni rele, odvisno od akcije, ki je navedena v spremenljivki s_event. S klicem funkcije Schedule_deleteItem(String s_event) je brišemo postavke iz urnika.
Ostane le še odgovor na vprašanje, kako nastavimo začetno vrednost ure realnega časa, saj naprava nima tipk. ESP8266 obenem deluje kot telnet strežnik, na katerega se po vzpostavitvi Wi-Fi prijavimo z eno od odjemalskih aplikaciji, ki so na voljo za vse peceje, mikro peceje, pametne telefone in tablice. Na običajnem PC lahko uporabimo na primer TeraTerm, ali pa kar iz ukaznega poziva dosegljivo Microsoft Windows funkcijo telnet, vendar le, če smo to funkcionalnost prej namestili. Prek aplikacije dodajamo in brišemo tudi postavke urnika. Vsekakor pa je prikladnejši način komunikacije preko namenske aplikacije, ki sama tvori za ESP8266 berljiv zapis časa in datuma v obliki znakovnega niza. Ker pa tako aplikacijo z »lepotnimi popravki« lahko napiše vsako, omenimo še primera upravljanja preklopne ure prek telneta:
Nastavi čas in datum: 1.7.2021, 14:50:55… T(20210701145055) Nastavi vklop ob 17:00 (akcija 0 pomeni vklop)… E01700
Kako deluje v praksi? Merjenje časa je pri ESP8266-13 modulu dokaj natančno tudi samo z glavnim 26 MHz oscilatorjem, zato si lahko brez skrbi pomagamo s programsko implementacijo ure realnega časa in ne potrebujemo dodatnega 32,768 kHz oscilatorja, kot to velja za nekatere ESP32, ki so pri takem načinu merjenja časa lahko precej nenatančni. Ni izključeno, da sta za to težavo krivi dve procesorski jedri. ESP8266 modul potrebuje +3,3 V napajanje, medtem, ko večina relejev, primernih za krmiljenje naprav prek omrežne napetosti, zahteva +5 V ali višnjo napajalno napetost, najpogosteje +12 V. Kljub temu pa za napajanje vse logike navadno zadošča že +3,3 V regulator napetosti, ki ga napajamo iz +12 V. Pri tem povejmo, da releji z deklarirano napetostjo 12 V dopuščajo tudi manjša napetostna odstopanja, zato je pred izbiro enosmernega napajalnika dobro preveriti specifikacije proizvajalca.
Prihodnjič
V naslednjem nadaljevanju se ponovno lotimo pogostih napak pri pisanju ugnezdene programske opreme, poleg tega pa še: Kaj moramo paziti pri krmiljenju grafičnega prikazovalnika? Kako popraviti zamaknjen izpis? Kako izdelati generator znakov? Kako risati grafične elemente? Kako hitro lahko prenašamo podatke? Kako prilagodimo programsko kodo za I2C prikazovalnik za SPI prikazovalnik in obratno? Ali lahko prikazovalnik z vodilom SPI spremenimo v prikazovalnik z vodilom I2C?
Kako zagotovimo stabilno komunikacijo med dvema Arduino napravama, če za prenos podatkov pri uporabimo diagnostični zaporedni vmesnik RS232? Kako ločimo komunikacijo naprav od diagnostičnih sporočil? Preizkusili bomo neposredno zaporedno povezavo med ESP8266 in ESP32. Že res, da modula lahko komunicirata prek Wi-Fi, ampak če sta v isti napravi, sta navadno blizu skupaj, zato je lahko moten prenos z oddaljenih naprav. No, kakorkoli, če ju povežemo s kablom, bosta sodelovala ne glede na zasedenost Wi-Fi frekvenčnega prostora. Preizkusili bomo tudi, ali se da antenska priključka ESP32 modulov preprosto povezati s koaksialnim kablom in kako hitro lahko v tem primeru prenašamo podatke. Ukvarjali se bomo tudi za napajanjem in nastavljali napetost, pri kateri ESP modul zaradi varnosti preneha delovati t.i. brownout voltage…