Avtor: dr. Simon Vavpotič
2020_288_46
ESP8266 Wi-Fi moduli, kot majhna, enostavna in učinkovita 32-bitna osnova za gradnjo naprav in sistemov interneta stvari (IoT), že leta burijo domišljijo programerjev. Čeprav so novi navadno predprogramirani kot brezžični Wi-Fi modemi, jih lahko z lastno programsko opremo spremenimo v samostojne krmilnike enostavnih IoT naprav
V preteklem smo sestavili internetni radio, ki je zahteval veliko časa in testiranj pa tudi veliko dodatne strojne opreme. ESP32 in ESP8266 imata z nekaj dodatne strojne opreme vse, kar potrebujemo za predvajanje spletnega radija, potrebujemo le še ustrezno programsko opremo. Na Internetu, oziroma na GitHubu, najdemo več tovrstnih projektov, vendar je mojo pozornost najbolj pritegnil ESP32-radio, ki je zasnovan dovolj splošno, da ga lahko prilagodimo lastnim željam in potrebam, hkrati pa je zanj na voljo vsa izvorna programska koda. ESP32-radio morda ni najenostavnejši za implementacijo, a ponudi kopico možnosti za različne kombinacije opcijske strojne opreme pa tudi spremembe in dopolnitve programske kode. Tokrat bomo dodali enkoder, IR sprejemnik in zaslon. Osnovna električna shema radija je bila objavljena v pretekli številki, shemo s tokratnimi dodatki, pa si lahko ogledate na spletni strani: https://sites.google.com/site/pcusbprojects.
Našli boste tudi izvorno kodo vgrajene programske opreme. Kot vidimo, je novi spletni radio povsem »zadovoljen« v LEGO ohišju, ki ga z lahkoto prilagajamo novim napravam in lastnim potrebam.
Ta vsebina je samo za naročnike
Kako internetni radio zapakirati v LEGO ohišje?
Za LEGO kocke lahko nabavimo originalne električne pogonske in upravljavske sklope, katerih ohišja so izdelana iz enake plastike kot ostale LEGO kocke. Za gradnjo lastnih LEGO ohišij tako ni posebnih ovir. Paziti moramo le, da vanje ne vgrajujemo komponent, ki se pri svojem delovanju lahko močno segrejejo. Internetni radio ne vsebuje takih komponent, vseeno pa ga moramo pred vgradnjo preizkusiti in preveriti pravilno delovanje vseh vezij. Močno segrevanje bi lahko povzročil kvečjemu kratek stik ali napačna polariteta, vendar v obeh primerih radio ne bo deloval, zato bomo tako napako tudi takoj opazili, a se lahko zgodi, da bomo katero od komponent pri tem uničili in jo bomo morali zamenjati z novo… No, kakorkoli, če radio v LEGO ohišju pravilno deluje, ni razloga za močno segrevanje njegovih komponent, razen če boste napačno realizirali napajalni del, a tu bi vseeno šlo težko kaj narobe. Če nimate drugih idej, kako realizirati +3,3 V in +5 V napajanje, je ena od preprostih možnosti nakup dveh vtičnih napajalnikov za +3,3 V in +5 V. Resda boste tako za napajanje radia uporabili dve električni vtičnici, a napajanji za +3,3 V in +5 V bosta povsem ločeni. Vse kar morate še narediti, uporaba skupnega električnega razdelilnika s stikalom za vklop, s katerim boste oba napajalnika vklopili hkrati. Druga možnost je uporaba le enega enosmernega napajalnika (npr. +12 V=), ki zagotavlja nekoliko višjo enosmerno električno napetost in hkrati poganja napetostna stabilizatorja za +3,3 V in +5 V. Prav taka rešitev je uporabljena tudi pri Microchip Starter Kit I/O Expansion Board 16, ki sem ga uporabil za napajanje, kot smo videli v SE287.
Prednost LEGO ohišja je tudi enostavna prilagodljivosti, saj ga brez težav dopolnjujemo, ko dodajamo opcijske komponente, kot so OLED prikazovalnik, rotacijski enkoder z gumbom in IR sprejemnik.
OLED prikazovalnik
Čeprav se zdi, da za priklop prikazovalnika ni dovolj priključkov, lahko slednjega povežemo preko SPI ali I2C vodila. Pri tem lahko isti priključki uporabijo za SPI in I2C vodilo, saj lahko način delovanja in hitrosti komunikacije sproti prilagajamo zahtevam priključnih perifernih naprav. Je pa res, da ne morejo vse komunicirati hkrati. Pri tem povejmo še to, da programska koda in strojna oprema spletnega radia, ki smo ga predstavili v preteklem nadaljevanju, podpirata množico različnih prikazovalnikov, med njimi tudi 1,3” LANMU OLED s SSD1106 kontrolerjem, ki zmore prikazati miniaturno modro-črno sliko ločljivosti 128 x 64 pik. Zanimivo, je da avtor originalnega projekta, Ed Smallenburg, ni podprl tudi SPI komunikacije za SPI vodilo. Lep prikaz slike pa je prilagojen samo za krmilnik SSD1306, za starejšega SSD1106, moramo narediti nekaj popravkov nastavitev, sicer je prikaz slike zamaknjen.
No, sam sem si želel prav 1,3” LANMU OLED s SSD1106 krmilnikom na SPI vodilu, saj sem tak način komunikacije uporabil že pri projektu Strojni upravljalnik gesel iz SE264 in SE265, obenem pa je SPI komunikacija hitrejša in zahteva manj procesorskega časa. Res, da bi prek I2C vodila lahko iz zaslona tudi bral podatke, vendar to ni potrebno, saj predpriprava zaslonske slika poteka v pomnilniku ESP32, zaslon pa z eno samo funkcijo izriše zgolj spremenjene vrstice. Tako je 1,3” LANMU OLED končal na HSPI vodilu, skupaj z V1053 modulom in mikro SD kartico. Spomnimo le še na to, da je večina zaslonov OLED z SSD1106 kontrolerjem originalno prirejena za povezav I2C. Za uporabo SPI vodila moramo prestaviti SMD upor na sosednje prazno ležišče.
Kaj pa programska oprema? Za začetek sem si pomagal s programsko kodo za PIC32, ki sem jo izdelal za strojni upravljalnik gesel. Vendar pri ESP32 ni potrebno kodirati osnove SPI komunikacije, saj imamo na voljo programsko knjižnico SPI (datoteka glave knjižnice: SPI.h), zato je dovolj predelava datoteke SSD1306.h, v kateri popravimo zgolj inicializacijski in prikazovalni podprogram. Nova programska koda tako vsebuje ukaze za SPI namesto za I2C vodilo, vsebina podatkov pa je skoraj nespremenjena; razlike so zgolj zaradi starejšega krmilnika, SSD1106 , glej program 1.
Program 1: Inicializacija SSD1106 SSD1306::SSD1306 ( uint8_t sda, uint8_t scl) { esp_err_t espRc ; ssdbuf = (page_struct*) malloc ( 8 * sizeof(page_struct) ) ; // Create buffer for screen SPI.beginTransaction(SSD1306_SPI); pinMode(ini_block.tft_cs_pin,OUTPUT); pinMode(ini_block.tft_dc_pin,OUTPUT); digitalWrite(ini_block.tft_cs_pin,LOW); // display select digitalWrite(ini_block.tft_dc_pin,LOW); // command font = SSD1306font ; delay(100); // wait 100 ms for display init SPI.write(OLED_CONTROL_BYTE_CMD_STREAM); SPI.write(OLED_CMD_SET_CHARGE_PUMP); SPI.write(0x14); // Enable charge pump SPI.write(0x4); // lower column address= 4 SPI.write(0x10); // highter clumn address =0 SPI.write(OLED_CMD_SET_CONTRAST); SPI.write(255); SPI.write(OLED_CMD_DISPLAY_ON); digitalWrite(ini_block.tft_cs_pin,HIGH); // display deselect SPI.endTransaction(); clear() ; // Clear the display }
Podobno sem spremenil tudi podprogram SSD1306::display(), ki zdaj uporablja ukaz SPO.write, namesto ukazov za pisanje na vodilo I2C. Pri tem sem seveda ohranil ime razreda SSD1306, ki je uporabljen programski kodi glavnega programa. Zato v slednjem ni potrebno ničesar spreminjati. Podrobnosti si oglejte v celotni programski kodi, ki jo lahko prenesete iz spletne strani sites.google.com/site/pcusbprojects. Omenimo še ukaza SPI.beginTransaction in SPI.endTransaction, ki sta namenjena zagotavljanju celovitosti prenosov podatkov med večopravilnim delovanjem ESP32. Ker se programska koda za prenos podatkov na prikazovalnik izvaja v glavni programski zanki, bi njeno izvajanje pogosto prekinil kak prekinitveni program ostalih SPI naprav (mikro SD kartica ali VS1053). Z uporabo ukazov za začetek in konec transakcije to preprečimo in dovolimo izvajanje samo tistih prekinitvenih programov, ki niso vezani na vodilo HSPI. Ostala komunikacija prek vodila HSPI lahko steče šele, ko je prenos podatkov na prikazovalnik zaključen.
Čeprav OLED prikazovalnik ni obvezen, omogoča samostojno uporabo spletnega radija z daljinskim upravljalnikom in rotacijskim enkoderjem, saj prikazuje podatke o trenutno izbrani spletni radijski postaji, sprotne informacije postaje (navadno predvajano vsebino) ter točen čas, ki ga radio ob zagonu samodejno prebere iz enega od javnih internetnih časovnih strežnikov, ki jih poganjajo atomske ure. Tako je na zaslonu spletnega radija vedno na voljo tudi točen čas.
IR sprejemnik
Originalni spletni radio ima vgrajen VS1838B IR sprejemnik, katerega izhod povežemo s prostim vhodnim priključkom ESP32 (npr. GPIO35), in bi bil morda boljša izbira od Sharpovega GP1UX511QS, ki sem ga naročil zgolj zato, ker bi moral na VS1838B med prvim koronavirusnim obdobjem predolgo čakati. Kakorkoli, za uporabo drugačnega IR sprejemnika sem moral ustrezno prilagoditi tudi prekinitveni podprogram, ki sem mu dodal diagnostični del, v katerem v posebno pomnilniško polje shrani celotno zaporedje dolžin intervalov med ničlami in enicami. To omogoča analizo sprejetega signala za vsako od tipk na izbranem daljinskem upravljalniku. Na podlagi analize je mogoče nato prilagoditi pričakovani dolžini časovnih intervalov, ki določata vrednosti 0 in 1. Izkaže se, da sta pri GP1UX511QS intervala nekoliko krajša kot pri VS1838B, kar moramo upoštevati tudi v prekinitveni programski kodi, s katero izračunavamo zaporedje ničel in enic, ki določajo kodo pritisnjene tipke. Proizvajalec IR sprejemnika določi tudi, katere in koliko vrednosti ničel in enic moramo upoštevati. Praviloma pri izračunu kode upoštevamo zadnje vrednosti. Res pa je, da je število zajetih vrednosti odvisno tudi od tipa daljinskega upravljalnika. Nekateri upravljalniki s pritiskom na eno samo tipko oddajajo tudi različna zaporedja kod, ki vsebujejo kontrolne kode z različnimi pomeni. Zato bomo morda šele iz zaporedja dveh kod lahko ugotovil pomen, oziroma katera tipka je bila pritisnjena. Vseeno pa so take kombinacije redke in se jim zlahka izognemo tako, da uporabimo samo tipke z enostavnimi kodami. Podrobnosti si oglejte programski kodi na spletni strani: sites.google.com/site/pcusbprojects.
Rotacijski enkoder z gumbom
Tudi digitalne naprave lahko krmilimo z vrtljivimi gumbi, vendar za to ne potrebujemo vrtljivih ali drsnih potenciometrov. Enkoder med vrtenjem v levo ali desno smer oddaja značilno zaporedje električnih impulzov, iz katerega lahko programsko razberemo število korakov vrtenja v eno ali drugo smer pa tudi hitrost vrtenja. Stikalo, ki ga sprožimo s pritiskom vrtljive ročice ali gumbe navzdol, omogoča potrditev programsko izmerjene vrednosti in s tem njeno uveljavitev. Denimo, če zavrtimo gumb za tri pozicije navzdol in pri tem nastavljamo glasnost, bo slednja za toliko stopenj nižja, podobno bo glasnost višja ob vrtenju v nasprotno smer. Z rotacijskim enkoderjem se lahko sprehodimo tudi skozi različne menije, prek katerih lahko poleg glasnosti nastavljamo še številne druge vrednosti, recimo zamenjamo radijsko postajo, nastavimo jakost osvetlitve zaslona, način prikazovanja podatkov ipd. Vse našteto smo že vajeni s profesionalnih radijskih sprejemnikov.
Enkoder povežemo ESP32 prek treh vhodnih priključkov (npr. GPIO34 = CLK, GPIO36 = DATA in GPIO39 = SWITCH) in mase, ki ji v tem primeru lahko uporabimo le kot čiste digitalne vhode. Zato moramo enkoderju dodati še tri 10 k ohmske upore proti masi (ali proti napajanju, če uporabimo alternativo vezavo), s katerimi zagotovimo ustrezen nivo napetosti tudi, ko enkoderjevi kontakti ne prevajajo.
Kako deluje ožičeni spletni radio v praksi?
Varen in hiter dostop do Interneta ni nekaj, kar bi lahko v strnjenih blokovskih naseljih bilo zlahka dosegljivo. Originalna različica spletnega radija omogoča prenos signala spletnega radija le preko brezžičnega omrežja Wi-Fi; vendar lahko v medijih skoraj mesečno beremo, slišimo in vidimo novice, ki nas prepričujejo v to, da skoraj nobeno brezžično omrežje za hekerje ni neprebojno. Z omogočanjem brezžičnega dostopa do spleta spletnemu radiju, ga posredno odpremo tudi za druge naprave, oziroma s tem odpremo možnost hekerskega vdora v naše domače računalniško omrežje, s tem pa se izpostavimo veliki pravni in kazenski odgovornost v primeru, da krivca za morebitna zlorabe spleta preko našega modema ne bi bilo mogoče odkriti, oziroma bi morebitni heker opravljal pravna dejanja v spletu z našimi poverilnicami in preko naših računalniških naprav, pri čemer bi po dejanju dobro zakril sledi. Veliko bolje je ostati pri ožičenem dostopu do interneta preko domačega Ethernet omrežja. Prav to pa omogoča spremenjena različica radija, ki ima dodan Ethernet modul. Slednji zagotavlja tudi hitrejšo in zanesljivejšo povezljivosti. Ostale funkcionalnosti radija so enake kot pri originalni različici, le da se lahko z njim povežemo le prek ožičenega Etherneta. Deluje sorazmerno dobro, čeprav kaže, da je v originalni programski kodi še kar nekaj pomanjkljivosti pa tudi pomanjkanje preverjanj pravilnosti zapisanih ukazov, s katerimi v nastavitvah prednastavljamo radijske postaje in učinkovanje kod za upravljanje z daljinskim upravljalnikom.
Po drugi strani, za Wi-Fi navdušence vseeno povejmo, da je mogoče novo različico radija z spremembo ali dopolnitvijo programske opreme spremeniti tudi v preprost omrežni usmerjevalnik med ožičenim in brezžičnim Ethernetom. A ta projekt prihranimo za kdaj drugič…
ESP32-CAM v praksi
Ko sem končeval zgodbo o spletnem radiju, sem bolj po naključju kot ne, začel novo zgodbo o ESP32-CAM. Izkazalo se je namreč, da ima kamera v praksi zelo veliko drobnih težav, vsaj če naložimo ljubiteljsko vgrajeno programsko opremo, za katero je na voljo izvorna koda, in pripadajoče programske knjižnice. Nemalo težav povzročajo, očitno še ne dovolj preizkušene, programske knjižnice, v katerih pogosto kar mrgoli drobnih napak. Velja izpostaviti merjenje časa in časovne zakasnitve na osnovi 32-bitnega števca števila mikrosekund od začetka delovanja ESP32. Programerji programskih knjižnic bi morali za merjenje časa in računanje časovnih razlik dosledno uporabljati nepredznačena cela števila (npr. unsigned long ali uint32_t), ker pa temu pogosto ni tako, se nemalokrat zatakne pri računanju časovnih zakasnitev. Če programer hote ali nehote uporabi celo predznačeno število (npr. long ali int32_t) bo komunikacija med ESP32 in OV2640 v težavah takoj, ko bo števec presegel vrednost nekaj več kot 2 milijardi, kar je polovica obsega 32-bitnega časovnika, saj bo vrednost časa pri prenosu iz vrednosti števca z ukazom millis() negativna.
Ne verjamete? Pri predznačenih 32-bitnih številih prvi bit pomeni predznak (0 = »+«, 1 = »-«), pri nepredznačenih pa so vse vrednosti do nekaj več kot 4 milijarde na pozitivne od 0 naprej. Če 32-bitnov vrednost števca časovnika z nekaj več kot 2 milijardi naložimo v predznačeno 32-bitni število, bomo dobili negativno vrednost, ki bo nekoliko manjša kot -2 milijardi. Kar pa je vsekakor narobe…
Če namesto tega računamo z neprednačenimi števili bo pri prekoračitvi obsega pri seštevanju ali odštevanju razlika števil še vedno pravilna. Denimo 4 000 000 000 – 3 999 999 000 = 1000 prav tako pa bo 1000 tudi 999 – 4294966294, saj pri odštevanju zaradi prekoračitve obsega ne bo vrednosti nekaterih najbolj pomembnih bitov. Kakorkoli! Rezultat je pravilen le, če uporabljamo nepredznačena števila, če pa bi vseeno hoteli uporabljati predznačena, bi morali uporabiti zmogljivejši 64-bitni podatkovni tip, denimo int64_t, potem pa se kar precej pozabavati s kodo, da bi bila rezultat pravilen tudi, ko bi se vrednost 32-bitnega števca mikrosekund prevrtela.
K sreči na GitHubu tudi za slednje najdemo izvorno kodo. In prav tu se lahko veliko naučimo, če obenem beremo tudi programerske bloge, v katerih pogosto naletimo napake v zvezi z zajemom slik s kamere (npr. vrstici 1344 datoteke Camera.c). Ko namestimo celotno izvorno kodo za kamero in pozabimo na že prevedene programske knjižnice, lahko dejansko konkretno napako tudi odpravimo.
Načrt ESP32-CAM
Čeprav bi se mukotrpne analize tiskanega vezja ESP32-CAM lahko lotili tudi sam, sem k sreči v internetu našel podrobno električno shemo, ki je namenjena predvsem razumevanju delovanja modula, pogrešamo pa načrt položitve elementov na tiskanino. Tu sem si pomagal s fotoaparatom, s katerim sem detajlno poslikal ESP32-CAM z obeh strani. Na sliki je potem sorazmerno enostavno označiti posamezne SMD upore in tranzistorje ter njihove ključne priključke.
ESP32-CAM ima vgrajen P-MOSFET tranzistor, ki deluje kot stikalo za vklop napetostnih regulatorjev za napetosti DVDD (1,2 V) in AVDD (2,8) za napajanje kamere, medtem ko je napajanje vhodni-izhodnega vmesnika (3,3 V) stalno priključeno. V nasprotnem bi med izklopom DVDD in AVDD tvegali poškodovanje kamere. Vendar je zanimivo, da se signal za reset kamere sproži samodejno le ob zagonu ESP32-CAM, ne pa tudi ob resetu ESP32. Zato moramo kameri ob naložitvi nove vgrajene programske opreme prekiniti napajanje in ga nato ponovno vzpostaviti. Denimo, če se sinhronizacijski signal VSYNC ne vzpostavi tako ne pomaga, če izklopimo in ponovno priklopimo DVDD in AVDD. Ponastavitev vrednosti vseh notranjih registrov kamere v začetno stanje lahko dosežemo preko signala za reset. Če nas ne zanima varčevanje z energijo, lahko pustimo napajanje kamere vključeno v celoti ter za njen ponovni zagon uporabimo samo reset signal, ki je aktiven v nizkem stanju. Morda o P-MOSFETu povejmo še to, da ima tri priključke, pri čemer je zmotno misliti, da so vrata (G) na tisti strani, kjer je en sam priključek. Tam je krmilni izhod, oziroma ponor (D), z druge strani zgoraj je izvor (S), kamor pripeljemo vhodno napetost, spodaj pa so vrata (G). Če hočemo tranzistor krmiliti z drugim virom, si lahko pomagamo tako, da prispajkamo dodatni signalni kabel.
Ko že omenjamo napajanje povejmo še, da je za varnost in pravilnost delovanja kamere zelo pomembna konstantna napajalna napetost, 3,3 V (DOVDD), ki jo proizvede napetostni regulator AMS1117, ki zmore tokovno obremenitev okoli 1 A. Nihanje glavne napajalne napetosti, ki ga lahko ob premalo zmogljivem napajalniku povzroči tudi prižgana LED, lahko trajno poškoduje kamero. Po drugi strani lahko stabilnost vhodne napetosti zagotavljamo s sorazmerno velikimi elektrolitskimi kondenzatorji ter filtrirnimi kondenzatorji (100 nF), s pomočjo katerih iz napajanih vodov izločamo motnje, ki jih pri svojem delovanju povzročajo čipi. Kakorkoli, moram poudariti, da ESP32 in MCP2200 nista povzročala težav, saj odlično delujeta, a potrebno je bilo zagotoviti ustrezne delovne pogoje tudi za kamero. Vsekakor si tu želimo bistveno zanesljivejšega delovanja brez prekinitev po nekaj urah. Čeprav ima tu največ težav že omenjena vgrajena programska oprema, so motnje, neustrezno filtrirano napajanje in premalo zmogljivi napetostni regulatorji na drugem mestu.
Denimo, napetostni regulator LM7805 za +5 V mora v konicah zagotavljati okoli 1 A, kar je njegova vrhnja zmogljivost. Opcijsko lahko vgradimo močnejši regulator, vendar lahko potem razmišljamo tudi o nadomestitvi +3,3 V AMS1117 regulatorja z zmogljivejšim. Kakorkoli, veliko težav si boste prihranili tudi, če boste uporabili baterijsko napajanje, ki pa je manj uporabno, saj se klasične akumulatorske baterije sorazmerno hitro spraznijo.
Optimizacija zgradbe ESP32-CAM
Avtorji spletnih projektov, ki uporabljajo mikroSD kartico ESP32-CAM, so hitro ugotovili, da je vezje namerno narejeno tako, da se pri delu z njo venomer prižiga močna bela svetilna LED. Le kdo si je izmislil to neumnost? Domnevam, da zato, ker so bili pri Ai-Thinkerju morebiti prisiljeni upoštevati zakonodajo, ki nalaga, da mora biti morebitno snemanje videa jasno razvidno iz delovanja kamere. Tako so nesrečni P-MOSFET za napajanje svetilne LED vezali kar na GPIO4, ki pri vzporednem 4-bitnem prenosu podatkov na mikro SD kartico služi kot HS2 DATA1 signal. Potem ni čudno, da LED divje utripa ter obenem porabi še zelo veliko energije.
Avtorji spletnih projektov zato predlagajo odspajkanje priključka (D) P-MOSFETa, ki napaja svetilno LED. Vendar mi je kmalu postalo jasno, da to morda ni najboljša rešitev, razen če imamo sokolje oko (falcon’s eye) ali imamo pri roki povečevalno lečo in dober spajkalnik s kar se da majhno konico. Tranzistor torej lahko pustimo kot je in raje nedaleč stran odspajkamo ustrezen SMD upor. V praksi se namreč izkaže, da se iz strani, na kateri ima samo 1 priključek, odspajkani P-MOSFET tranzistor kaj rad odlomi še iz druge strani in tako ostanemo brez njega. Potem LED težko vklopimo iz drugega vira kadar bi jo potrebovali.
Ko se lotevamo bolj zaresne aplikacije, lahko Ai-Thinkerjevemu ESP32-CAM modulu še marsikaj očitamo. Med drugim tudi to, da noben od šestnajstih nožic modula ne prenaša signala za reset, na voljo je le mikrostikalo, ki pa je precej nerodno nameščeno na spodnjo stran modula in ga moramo zato poiskati s prstom, ob čemer ne smemo imeti predebelih prstov. A z gumbom ne moremo resetirati tudi kamere in moramo zato po naložitvi nove vgrajene programske opreme pogosto odklopiti napajanje in ga ponovno priklopiti.
Po dolgem premisleku, sem se odločil, da na dodatni 4-nožični priključek EN na vgrajenem modulu ESP32 povežem na poseben priključek, ki sem ga izdelal iz stebričkov in majhnega koščka prototipne tiskanine, saj na ESP32-CAM sicer ni dovolj prostih stebričkov. Podobno sem dodal tudi signala za reset in vklop kamere ter dodatni priključek za +3 V napajanje, saj se je izkazalo, da originalni prevečkrat nima zadovoljivega stika.
Kljub temu sem GPIO33, na katerega je vezana tudi rdeča signalna LED, uporabil še za upravljanje kamere, tako da sem s sorazmerno enostavno žično prevezavo namesto +3.3 V ali 5 V napajanja na ta priključek pripeljal GPIO33. Slednji lahko tako deluje tudi kot opcijski digitalni vhod, če ga ustrezno sprogramiramo. Tako pri nizkem stanju vhoda rdeča dioda sveti, pri visokem pa je ugasnjena. Vsekakor se splača na opcijski vhod zaporedno vezati tudi 330 ohmski upor, s katerim preprečimo morebitno poškodovanje ESP32, če GPIO33 v nizkem stanju, vhod pa v visokem.
Morda še nekaj besed od tem, kako naredimo priključek za reset kamere. Naj takoj povem, a slednje ni enostavno, saj zahteva mirno roko in ostro oko in/ali povečevalno steklo. Na sliki vidimo, da sta k sreči 4,7-kiloohmski upor in 100 nF kondenzator na tiskano vezje prispajkana skupaj, hkrati pa sta s strani, ki je obrnjena prosti konektorju za kamero, povezana skupaj. Zato lahko kabel pritrdimo kar na oba in s tem zagotovimo večjo trdnost priključka. Hkrati za krmiljenje priključka niso potrebni dodatni upori. Krmilimo ga lahko iz zunanjega vezja, lahko pa ga povežemo tudi z GPIO33, ki je v tem primeru v visokem stanju, ko kamera obratuje, pri čemer rdeča LED ne sveti. Vendar to ni tragedija, saj lahko dodamo še negator in zunanjo LED (npr. zeleno), ki služi za indikacijo delovanja. Druga možnost je, da P-MOSFET za upravljanje napajanje kamere premostimo in za krmiljenje signala za reset uporabimo GPIO32. S tem sicer porabimo nekoliko več energije, vendar pa ponovni zagon po naložitvi nove vgrajene programske opreme ni več problematičen. V zagonski podprogram v ESP32 lahko namreč vgradimo reset kamere z ustreznimi zakasnitvami, še preden se zažene konfiguracijski podprogram kamere.
Možnosti je še veliko. Če potrebujemo dodatne krmilne priključke, si lahko privoščimo dodaten čip z digitalnimi vrati (t.i. port extender), s katerim ESP32 komunicira s protokolom I2C, kjer sta dva prosta priključka vse, kar potrebujemo. Nenazadnje lahko port extender izdelamo tudi sami iz katerega od Microchipovih PIC-ov (npr. PIC18). Vsekakor pa bi za port extender uporabili tudi Microchip MCP2200, ki je sicer vmesnik USB-RS232, če bi imeli na voljo izvorno kodo vgrajene programske opreme, ali napisali bi svojo. Nalašč nisem napisal PIC18, saj je MCP2200 dovolj zmogljiv, da ga lahko uporabimo tudi za programiranje in upravljanje ESP32 s prenosnimi hitrostmi do 921600 baudov, kar je več kot dovolj hitro za udobno prototipiranje vgrajene programske kode. Z dodatkom MCP2200 dobi ESP32-CAM precej več funkcionalnosti kot ESP32-EYE, da pri tem niti ne omenjamo možnosti priklopa zmogljivejše antene za Wi-Fi, ki je ESP32-EYE nima.
Udobno programiranje ESP32-CAM
Običajno programiranje ESP32-CAM zahteva (začasno) montažo mostu USB-RS232 in prestavljanje mostička, s katerim povemo, ali želimo ESP32 uporabljati ali programirati. Če poleg ESP32-CAM na tiskanino vgradimo tudi MCP2200 in vzpostavimo ničelno modemsko vezavo z ESP32-CAM prek priključkov U0T in R0T, moramo še vedno z mostičkom ročno preklapljati signal za programiranje (GPIO0). Če hočemo elektronski preklop, moramo upoštevati, da po zagonu ESP32 GPIO0 služi kot taktni signal CSI MCLK, ki poganja OV2640 ali drugo združljivo kamero. Zato ga ne moremo enostavno vezati na običajen digitalni izhod, temveč lahko uporabimo le izhod z odprtim kolektorjem, ki ga za vsak primer vežemo na GPIO0 premo 330 ohmskega upora.
No, sam sem uporabil kar čip ULN2803, ki ga sicer lahko uporabimo tudi za krmiljenje relejev, pa tudi za zaščito občutljivih digitalnih vezij, oziroma prilagajanje napetostnih nivojev. Za več informacij predlagam, da v spletu poiščete načrt priljubljene stare Vellemanove razvojne plošče P8255N, na kateri najdete dva ULN2803 v obeh vlogah (www.velleman.com). Kakorkoli, povejmo še, da je ULN2803 hkrati uporaben tudi kot prilagodilnik nivojev, s katerim upravljamo MCP2200 reset signal (RST). Slednji mora namreč delovati pri +3.3 V, če naj komunicira z ESP32, pri tej napajalni napetosti pa na vhod RST ne smemo pripeljati +5 V napajalne napetosti iz priključka USB, ki sicer služi za indikacijo povezanosti in delovanja USB. MSP2200, tako kot vse druge USB naprave, ne sme napajati USB vodila, ki ga lahko napaja le gospodar. Tako uporabimo ULN2803 tudi kot prilagodilnik napetostnih nivojev, za kar bi lahko uporabili tudi NPN tranzistor, a čip že imamo in zakaj, ga ne bi izkoristili. Pri tem je potrebno poudariti, da za vse skupaj potrebujemo še 4,7 kiloohmski upor na napajanje, s katerim krmilimo še en zaporedno darlingtonski par tranzistorjev in tako dobimo vezje z negacijo negacije, kar pa je tudi povsem pravilno, saj mora biti MCP2200 v resetu, ko je priključek USB brez napajanja.
No, zdaj pa še nekaj besed o udobnem programiranju. MCP2200 ima poleg RX, TX, ~CTS in ~RTS še veliko splošno-namenskih izhodov (GPIO0-GPIO7), ki jih lahko uporabimo za ustvarjanje krmilnih signalov za ESP32-CAM. A pri tem se splača biti nadvse previden, če želimo ESP32-CAM uporabljati tudi, ko je MCP2200 v resetu, oziroma USB ni povezan. Večino uporov s potegom proti napajanju (t.i. pullups) je realiziranih že v programju ESP32, oziroma na tiskanini ESP32-CAM, sami pa moramo zagotoviti 4,7 kiloohmska upora proti napajanju za signala RST in camera reset.
Brez pretikanja kablov in mostičkov
Ko sem naredil vse omenjeno, se je ESP32-CAM lepo zagnal, namesto v način za programiranje pa je navadno raje zahajal v nedokumentirani način za zagon ESP32 preko UART (RS232) in v način za nalaganje nove vgrajene programske oprem, kar me je dodobra presenetilo. Pomagalo je ponovno podrobno prebiranje navodil in kmalu sem ugotovil, da moram za zagon v klasičnem načinu za nalaganje programske opreme z ULN2803 proti masi »tiščati« tudi GPIO02, ki je sicer uporabljen za HS2 DATA0 pri komunikaciji z mikro SD kartico. No, tu ni potrebno dodati upora za poteg vhoda ULN2803 navzgor, saj je signal aktiven samo v visokem stanju, v nedefiniranem stanu (ko je MCP2200 v resetu) pa ni dovolj toka za aktivacijo daringtona, zato ta ne prevaja in ne vpliva na delovanja GPIO2. Zato pa je pametno za zaščito zaporedno vgraditi 10 kiloohmski upor. Vleko slednjega na maso seveda uporabljamo samo, ko želimo ESP32 programirati.
Ponovimo korake, ki so potrebni za preklop ESP32 v način za programiranje, programiranje in ponovni zagon: 1. poveži vodilo USB, 2. MSP2200 se aktivira in poveže s PC kot RS232 vrat in kot splošna naprava HID za krmiljenje digitalnih izhodov, 3. zaženi program za upravljanje krmilnih signalov MCP2200, 4. zaženi razvojno okolje Arduino in odpri monitor za serijske komunikacije (vgrajeno terminalsko okno), 5. programsko aktiviraj ESP32 reset (signal EN) ter nastavi digitalne izhode MCP2200 tako, da sta GPIO0 in GPIO2 v nizkem stanju, 6. deaktiviraj ESP32 reset, 7. preveri izpis v terminalskem oknu, da se je ESP32 zagnal v načinu za nalaganje strojne opreme, 8. prevedi in zaprogramiraj novo vgrajeno programsko opremo v ESP32, 9. aktiviraj ESP reset, 10. deaktiviraj nizko stanje GPIO0 in GPIO2, 11. aktiviraj in nato deaktiviraj reset kamere, 12. deaktiviraj ESP32 reset, 13. ESP32 se zažene z novo programsko opremo, ne da bi morali ročno priklopiti kable ali prestaviti kak mostiček.
Dodatna napetostna zaščita in omejevanje segrevanja napetostnih regulatorjev
Proizvajalci napetostnih regulatorjev svarijo pred uporabo velikih kondenzatorjev (več kot kakih 1000 µF), če pa jih uporabimo, priporočajo dodatno napetostno zaščito, ki jo lahko realiziramo z diodami, vezanimi v inverzni smeri. Sam sem imel pri roki nekaj starih 10 A diod za 1000 V, od katerih sem uporabil dve. Prvo sem vezal med napajanja za +3,3 V in 5 V, drugo pa med maso in +3,3 V. Namen obeh je preprečiti negativne napetostne nivoje in tako zaščititi ESP32-CAM, še posebej kamero, ki poleg +3,3 V uporablja tudi zelo majhni napajalni napetosti, +1,2 V in +1,8 V. Dodatno bi se dalo zaščititi tudi USB priključek MCP2200, a morda je še najboljša rešitev uporaba ne predolgega kabla USB 2.0.
Prihodnjič
Če se boste odločili realizirati katero od idej v tem članku, vse električne sheme in podrobna navodila najdete na spletni strani sites.google.com/site/pcusbprojects. Tokrat nam če žal zmanjkalo prostora, da bi se lotili že naprednega razvoja pametnega polnilnika akumulatorskih baterij, se pa tega zagotovo lotimo prihodnjič.