Če gradite nekakšno napravo za nadzor z WiFi povezljivostjo, je bil ESP8266 v preteklosti priljubljena izbira. Medtem ko je novejši ESP32 (v več različicah) veliko bolj zmogljiva naprava, je v mnogih primerih cenejši ESP8266 še vedno povsem ustrezen.
Avtor: Brian Millier
E-pošta: bmillier1@gmail.com
2022-306-25
Če pa uporabljate takšno napravo na baterijsko napajanje, je treba upoštevati veliko stvari, da bi pripravili ustrezen dizajn in vedeli, kako velika baterija bo potrebna.
- Upoštevati je treba tri glavne teme in vse so do neke mere medsebojno povezane:V kakšnem intervalu mora biti enota popolnoma operativna za izvedbo naloge? (ESP8266 je lahko v stanju globokega spanja ali pa je ves drugi čas popolnoma izklopljen).
- Katere ukrepe je mogoče sprejeti, da čim bolj zmanjšate mirovni tok, ki ga naprava porabi med časom »spanja« med cikli?
- Kateri WiFi protokol bo uporabljen za komunikacijo z gostiteljem? Ali je za vsak merilni/kontrolni cikel potrebna povezava z gostiteljem, ali se to lahko zgodi manj pogosto?
Očitno je, da je točka 1 v celoti odvisna od aplikacije, zato je ni mogoče obravnavati neposredno v tem članku, razen navajanja nekaj primerov v izračunih, ki jih ponujam. Oglejmo si točki 2 in 3.
Ta vsebina je samo za naročnike
Poraba toka ESP8266 v režimih spanja
Tabela 1 prikazuje porabo energije ESP8266 v različnih načinih delovanja. Vidite lahko, da med prenosom WiFi signala uporablja do 400 mA toka. Upati je, da se to ne dogaja prepogosto in o tem bom govoril kasneje. Ko prejme WiFi signal ali samo izvaja kodo, bo ESP8266 še vedno črpal okoli 80 mA. Tudi ta nižja vrednost bi bila za LiPo baterijo precejšen zalogaj, če bi se to dogajalo ves čas.
Način dela Poraba
Način dela | Poraba |
Oddajanje Wi-Fi signala | 170-400 mA |
Sprejem Wi-Fi signalaaliaktivno stanje | 55-80 mA |
Modem način spanja | 15 mA |
Lahek način spanja | 0.5 mA |
Globok način spanja | 10 -20 µA |
Tabela 1: Poraba ESP8266 modula v različnih načinih delovanja
Za dolgotrajno delovanje LiPo baterije je resnično uporaben le način globokega spanja. V bistvu se v tem načinu napajajo samo ULP (procesor z ultra nizko porabo energije), ura realnega časa (RTC) in nekaj RTC RAM-a. S temi funkcijami lahko napravo zbudite s spremembo stanja na GPIO ali timerjem spanja ESP8266. Timer spanja ESP8266 ima najdaljšo periodo 232 mikrosekund (71 minut). Uporabite lahko tudi RTC RAM ESP8266 za shranjevanje nekaterih spremenljivk iz ene periode globokega spanja v drugo.
V večini časa, ko je ESP8266 v globokem režimu spanju, bo porabil približno 20 µA. Vendar pa morate tej številki dodati mirovni tok katerega koli regulatorja, ki ga uporabljate, da zmanjšate napetost baterije na 3,3 V, ki jih zahteva ESP8266.
Če bi na primer uporabili običajni LM1117MPX-3.3, je njegov mirovni tok 5 mA, kar bi preseglo 20 µA tok globokega spanja ESP8266. Vendar pa lahko izberete 3,3 V LDO, ki ima veliko nižji mirovni tok, kot je MCP1702, ki črpa le 2,0 µA mirovnega toka. Kasneje bom opisal svojo uporabo regulatorja MIC5323 LDO, ki ima mirovni tok le približno 1 µA in omogoča tudi popoln odklop napajanja ESP8266 – s čimer se odpravi njegov 20 µA tok globokega spanja.
Drugi porabniki toka so lahko kateri koli senzorji, ki jih uporabljate. V nekaterih primerih ti senzorji ne trošijo več kot 5 mA, ki jih lahko zagotovi GPIO priključek na ESP8266. Torej, če za napajanje tega senzorja namenite GPIO priključek, bo trošil energijo samo v času, ko ga ESP8266 napaja za izvedbo meritve.
Drug vir porabe toka bo odvisen od tega, kako boste ESP8266 vključili v svoj dizajn. Če uporabljate zgolj ESP8266 (kot ga najdete na Espressif WROOM-02 modulu), potem ni drugih porabnikov toka. Če pa uporabljate veliko trenutno razpoložljivih “razvojnih” ESP8266 modulov, bodo običajno vgrajene tudi druge naprave, ki trošijo tok.
Na primer, številne plošče vsebujejo USB-UART čip (CP2102 ali CH341) za programiranje/razhroščevanje napak. Te naprave porabijo veliko več energije kot ESP8266 v načinu globokega spanja in jih ne morete zlahka izolirati od črpanja energije. Nekatere plošče imajo tudi LED-ice za napajanje in celo majhna, slabo osvetljena LED-ica lahko porabi 1 mA, kar spet odpravlja nekatere prednosti načina globokega spanja ESP8266.
Prav tako večina razvojnih plošč ne uporablja LDO z najnižjim mirovnim tokom, kot so tisti, ki sem jih omenil zgoraj. V tem članku bom uporabil modul WROOM-02, prikazan na sliki 1.
Z uporabo modula WROOM-02, načina globokega spanja in regulatorja z nizkim mirovnim tokom lahko dosežete tok globokega spanja v območju 20-25 µA. Če vam ESP8266 ni treba prepogosto zbuditi in vam tudi ni treba pogosto komunicirati z WiFi gostiteljem, potem je vredno raziskati načine, kako lahko zmanjšate porabo 20-25 µA celo na manj. Z drugimi besedami, višji kot je odstotek časa, ko je vaš projekt lahko v načinu »spanja«, pomembnejše je zmanjšati ta tok »spanja«.
Slika 2 prikazuje pričakovano življenjsko dobo baterije, ki napaka ESP8266 z uporabljenim načinom globokega spanja in LiPo baterijo 1000 mAh. Predpostavlja, da se bo ESP8266 povezal z WiFi dostopno točko v časovnem intervalu, prikazanem na osi X. Povezava z WiFi dostopno točko bo trajala 3-5 sekund – podrobnosti o tej trenutni porabi bom opisal kasneje v članku. Upoštevajte, da se timer globokega spanja ESP8266 lahko podaljša le do 71 minut, zato je zgornji del grafa teoretičen – ni ga mogoče doseči samo z načinom globokega spanja ESP8266.
Da bi še dodatno zmanjšal porabo energije v stanju mirovanja, sem se odločil za uporabo MIC5323-3.3 LDO regulatorja z omogočeno linijo, glejte shemo na sliki 3. To omogočeno linijo nadzorujem z izhodnim priključkom alarma čipa ure realnega časa MCP79401 (napaja se neposredno iz LiPo celice). Če to storite na ta način, se ESP8266 popolnoma izklopi, kar sem prej omenil kot model “spanja”.
Zdaj je skupni mirovni tok le približno 4 µA: 1 µA troši regulator MIC5323-3.3, 1 µA troši MCP79401 in 2 µA, ki teče skozi 2,2 megohmski vlečni upor linije Enable, ko MCP79401 RTC ohranja LDO v onemogočenem načinu. Interval »spanja« zdaj nadzoruje funkcija alarma v MCP79401 RTC in ni omejen na dolžino časa mirovanja, ki ga je mogoče programirati.
Moja izbira Microchip MCP79401 Real-Time Clock čipa ni bila poljubna. Na voljo je veliko RTC čipov in v preteklosti sem uporabljal RTC Dallas in NXP (Philips). Vendar ima MCP79401 kombinacijo funkcij, ki niso prisotne v teh drugih čipih in so potrebne za to vezje:
MCP79401 bo deloval pri Vcc do 5,5 voltov. To je potrebno, če projekt napajate neposredno iz LiPo celice, ki pri popolnoma napolnjeni bateriji znaša približno 4,1 volta (ali 3 alkalne baterije, ki imajo približno 4,8 voltov). MCP79401 ima zelo vsestransko funkcijo alarma. Najpomembnejša lastnost je, da ga je mogoče programirati za alarmni izhod aktivno-visoko ali aktivno-nizko. MIC5323 LDO regulator potrebuje aktivni visoki signal, da ga omogoči. Večina RTC ne bo delovala tukaj, saj imajo samo izhod z odprtim kolektorjem, ki spusti priključek alarma nizko, ko se alarm sproži.
Vsebuje 64-bajtov SRAM-a. To trajno shranjevanje lahko uporablja ugnezdena programska oprema za spremljanje števila ciklov ponovnega zagona, ki so se zgodili, in drugih vrednosti, ki morajo biti trajno shranjene. Njegova poraba toka je le 1,2 µA pri 3,3 volta – nekoliko višji je pri polni LiPo bateriji.
Poglejmo, kako deluje MCP74901 v tem vezju. Dokler MCP79401 nima konfiguriranega alarma, bo njegov MFP priključek z odprtim ponorom (večfunkcijski priključek) deloval kot nepriključeno vezje. Zato bo Enable na MIC5323 v visokem stanju, zaradi česar bo regulator deloval.
To zagotavlja 3,3-V za ESP8266 in katero koli drugo vezje, ki ga napaja MIC5323 regulator. ESP8266 se bo zagnal in naredil, kar je potrebno za določeno ponovitev vklopa. Po tem bo nastavil trenutni čas na neko fiksno vrednost, nato pa nastavil čas alarma za toliko časa, kolikor ga želite med ponovnimi zagoni ESP8266. Obseg tega intervala ponovnega zagona je v bistvu neomejen – za razliko od časovnika mirovanja ESP8266, ki ima največje obdobje 232 mikrosekund (71 minut).
Ko je alarm omogočen, se MFP priključek MCP79401 spusti na nizko za čas tega intervala ponovnega zagona, kar izklopi napajanje ESP8266 in vseh drugih vezij, ki jih napaja regulator. Po intervalu ponovnega zagona, ko se sproži alarm, bo MFP priključek postavil na visoko in cikel se bo začel znova. V svoji ugnezdeni programski opremi vzdržujem spremenljivko, imenovano rebootCount, ki je shranjena v SRAM-u v MCP79401. Ob vsakem ponovnem zagonu se število rebootCount poveča in ugnezdena programska oprema se lahko odloči, katere funkcije naj se izvajajo glede na to številko cikla ponovnega zagona.
Rutine za dostop do MCP79401 so vsebovane v moji Arduino skici in se začnejo s predpono RTC_. Obstajajo rutine za nastavitev trenutnega časa, nastavitev časa alarma in omogočanje alarma. Obstajajo tudi rutine, ki berejo in pišejo v SRAM pomnilnik MCP79401, prav tako z uporabo predpone RTC_.
Ugotovil sem, da je bilo treba branje RAM pomnilnika MCP79401 zakasniti za 100 milisekund po vklopu ESP8266 in izvajanju zagonske kode. Če tega nisem storil, so bile prebrane vrednosti RAM-a napačne. Sumim, da je temu tako, ker se I2C vodilo napaja iz MIC5323 LDO regulatorja.
Ker ESP8266 med oddajanjem potegne 350-400 mA tokovne konice, sem na izhod regulatorja postavil kondenzator 470 µF za obvladovanje teh konic. To nekoliko upočasni dvig 3,3-voltne napajalne napetosti in pričakujem, da moram zato počakati 100 milisekund, preden preberem RAM MCP79401. Če ne bi uporabljali RTC RAM-a, bi lahko to zamudo odpravili (vrstica 84 v skici) in skrajšal čas izvajanja programa ESP8266 za 100 milisekund, kar ni nepomembno.
Ko načrtujete projekt z baterijskim napajanjem, morate na splošno imeti možnost spremljati napetost baterije, da jo lahko zamenjate, preden vaš projekt preneha delovati. Morda je bolj pomembno v zvezi z LiPo celicami to, da jim ne smete dovoliti, da se izpraznijo pod približno 3 volte, sicer so lahko uničene. Pri majhnih LiPo baterijah v obliki vrečke je ta težava običajno označena z dejstvom, da se napihnejo. To sem večkrat videl v prejšnjih projektih, ki niso ščitili pred prekomerno izpraznjeno LiPo baterijo.
Ker je med LiPo in EPS8266 LDO regulator, ne morete samo izmeriti 3,3-voltnega izhoda LDO in iz tega natančno predvideti stanje baterije. Namesto tega morate meriti napetosti baterije pred LDO regulatorjem. ADC ESP8266 ima celoten obseg 1,0 volt, zato potrebujete uporovni napetostni delilnik, da zmanjšate 4,1-voltno napetost polno napolnjene LiPo baterije. Na sliki 3 lahko vidite, da imata upora R13 (2,2 megohma) in R14 (470 k) razmerje 5,7, kar zmanjša napetost polno napolnjene LiPo baterije na 0,72 V, kar je v območju 1,0 V celotnega obsega ADC.
Odločil sem se za uporabo visoko vrednih 2,2 megaohm in 470k uporov za napetostni delilnik, ker bi te visoke vrednosti uporovnega delilnika trošile manj kot 2 µA iz LiPo celice. To je pomembno, ker je uporovni delilnik ves čas povezan z LiPo.
Vendar pa bo v mnogih MCU-jih ADC med merjenjem trošil visok tok. Zaradi tega bodo njihovi podatkovni listi pogosto navajali, da izvorna impedanca ne glede na to, kar se meri, ne sme biti večja od 10 k, da se doseže razumna natančnost. ESP8266 je drugačen: predstavlja visoko impedanco na svoji vhodni liniji ADC in rezultati, ki sem jih opazil, so bili v bistvu enaki, kot če napetostnega delilnika R13/R14 sploh ne bi imel ESP8266 za obremenitev, čez R14 uporovnega delilnika.
Vzporedno z R14 sem vezal 0,1 µF kondenzator, da bi filtriral kakršen koli šum, saj je to vezje z visoko impedanco. Čudno je, da je ADC vhodni priključek v podatkovnem listu ESP8266 označen kot Tout – morda ga je mogoče konfigurirati tudi kot izhodni priključek timerja, vendar tega nisem preučil. Mimogrede, veriga delilnika za spremljanje napetosti baterije doda < 2 µA porabo toka k prej omenjeni številki porabe 4 µA za to vezje. Z MCP79401 RTC smo dosegli zelo nizek tok v režimu spanja, pa tudi v bistvu neomejen čas “spanja”. Vendar boste opazili, da sem dodal priključni blok X3, ki se povezuje na linije Vin in EN MIC5323. Če bi želeli to vezje uporabiti za spremljanje takojšnjih varnostnih alarmnih stikal (brez časovne zakasnitve mirovanja), lahko priključite normalno odprto stikalo na priključni blok X3.
Potem bi se ESP8266 vklopil takoj, ko bi bila takšna stikala zaprta. Če bi program EPS8266 preveril in ugotovil, da čas alarma NI dosežen, bi vedel, da je bilo varnostno stikalo sproženo.
Zagotovil sem Arduino skico z naslovom “ESP8266_NOW_MCP79401”. To je zelo osnovna skica, ki zažene MCP79401 RTC, nastavi trenutni čas na fiksno vrednost in alarm na čas 1 minuto pozneje. Nato izmeri napetost baterije s pomočjo ESP8266 ADC-ja in njeno vrednost pošlje na serijska vrata.
Ta skica vključuje 100 milisekundno zakasnitev, potrebno za pravilno branje RAM-a v MCP79401, kar sem že omenil. Za shranjevanje spremenljivke z imenom RebootCount uporabljam enega od bajtov MCP79401 RAM-a. Ob vsakem vklopu se vrednost poveča in prikaže. Ko doseže 12, se ponastavi na nič.
To je samo za primer – omogoča vam, da izberete, koliko obdobij vklopa preteče, preden naredite nekaj, kar je treba izvajati manj pogosto (na primer prenos podatkov gostitelju preko WiFi).
Med 100 milisekundno zakasnitvijo vgrajeni zvočnik piska samo za namene razhroščevanja. Zadnja stvar, ki jo skica naredi, je aktiviranje RTC alarma. To postavi MFP priključek na MCP79401 na nizek nivo in to odklopi napajanje ESP8266 (in vse ostalo, kar napaja 3,3-voltni regulator).
Upoštevajte, da ko naložite to skico in jo začnete izvajati, se bo ESP8266 vklopil le za nekaj sto milisekund, ko se sproži alarm MCP79401 (s čimer se dvigne MFP priključek in omogoči LDO regulator). Kako lahko ponovno programirate ESP8266 v tem stanju?
Najlažji način je, da izklopite sponki 1 in 2 na X3, zaradi česar bo regulator MIC5323 ves čas omogočen – s čimer bo napajanje ESP8266 neprekinjeno. Nato ga lahko preklopite v programski način na običajen način, tako da držite pritisnjeno stikalo PROG, medtem ko preklapljate RESET.
Ena stvar, ki sem jo opazil, ko sem eksperimentiral s to ploščo je, da ESP8266 izvaja kodo približno 70 milisekund, preden dejansko zažene vašo skico. Glejte sliko 4 za obseg zajema trenutne porabe (napetost, izmerjena na uporu 0,22 Ω v seriji z negativnim priključkom LiPo celice). V začetnem intervalu 70 ms ESP8266 črpa približno 36 mA. Na točki 100 ms je kratek 270 mA tokovni skok za prenos WiFi in dve drugi zelo kratki 400 mA konici pozneje – čeprav v skici ne zahtevam nobene WiFi dejavnosti.
V zgoraj omenjeni skici uporabljam funkcijo millis(), da določim, koliko milisekund je preteklo od zagona. Vedel sem, da bo ta čas odvisen od tega, kdaj je bil milisekundni časovnik ESP83266 inicializiran na nič in zagnan. Vendar nisem pričakoval, da bo preteklo 70 milisekund, preden se je ta časovnik zagnal in ko je bila vaša skica izvedena.
Tega sem se zavedal, ko sem izmeril dejanski čas, ko je bila moč uporabljena na ESP8266. Na ‘scope capture’, prikazanem na sliki 4, skupni čas vklopa energije znaša 338 ms. Vendar pa je funkcija millis(), ki je bila poklicana tik pred aktiviranjem MCP79401 alarma (ki izklopi ESP8266), vrnila 268 ms, kar je razlika 70 ms.
Zato morate domnevati, da bo ESP8266 deloval 70 ms in v povprečju porabil približno 36 mA, ne glede na to, kako hitro vaša skica opravi svojo zahtevano funkcijo in nato preklopi ESP8266 v način globokega spanja ali ga popolnoma izklopi, z uporabo MCP79401 RTC.
Tudi z nameščenim MCP79401 RTC vezjem in pravkar omenjenimi podrobnostmi o porabi energije je še vedno problem visoke porabe energije ESP8266 za relativno dolgo časovno obdobje, ki je potrebno za povezavo z vašo WiFi dostopno točko. Med prejemanjem ali drugim izvajanjem kode sem izmeril, da ESP8266 porabi približno 80 mA pri 3,3-V.
V tem načinu je njegovo VF vezje (WiFi/Bluetooth) napajano in lahko sprejema ne glede na vrsto VF signala, za katerega je bila enota konfigurirana: WiFi ali BLE, vendar NE oboje. Ko ESP8266 oddaja signal, se bo ta poraba toka dramatično povečala s številnimi kratkimi “oddajnimi” močnimi konicami približno 350-400 mA.
Povprečna poraba toka ni blizu največjega toka teh konic. Vendar pa se pri vzpostavljanju povezave z domačim WAP-om ti skoki pogosto pojavljajo v 3-5 sekundah, potrebnih za dokončanje povezave. Ta dolg čas povezave je posledica zapletenega WiFi protokola, ki se izvaja, in dodatnih rutin zaradi varnostnih razlogov.
Slika 5 prikazuje trenutno porabo med tipično povezavo z mojo WiFi dostopno točko. Vidite lahko konice med oddajo, vendar so tako ozke, da je težko natančno izmeriti njihov prispevek k skupni trenutni porabi. Medtem ko lahko moj digitalni multimeter meri povprečni enosmerni tok, opravi le eno ali dve meritvi na sekundo, njegovi odčitki med trajanjem povezave močno nihajo.
Vendar pa bi iz slike na osciloskopu ocenil, da bi oddajne konice lahko dodale približno 15 % k povprečnemu toku 80 mA, ki ga črpa ESP8266, ko ne oddaja WiFi signala. Ta tok sem izmeril preko padca napetosti na uporu 0,25 Ω v negativnem napajalnem kablu. Oddajne konice dosežejo približno 400 mA, poraba energije med sprejemom pa je približno 80 mA.
Iz serijskega izhoda programa, ki se izvaja na ESP8266, lahko ugotovim, da je WiFi povezava trajala približno 3-5 sekund. Vendar pa na sliki 5 lahko vidite, da prenosi vztrajajo približno 8 sekund – čeprav je program v zanki in ne počne nič drugega, kot da pošilja sporočilo na serijska vrata vsako sekundo po vzpostavitvi WiFi povezave. Ne vem, zakaj je temu tako, vendar ima to za posledico veliko porabo energije, tudi če program uporabnika ne zahteva nobene WiFi dejavnosti.
Iz zgornjega je očitno, da bo povprečni tok približno 92 mA (80 + 15%) črpal 3-5 sekund samo za vzpostavitev začetne povezave z WAP. Predpostavimo, da bi lahko ESP8266 popolnoma izklopili za daljša časovna obdobja med meritvami/povezavo z WiFi in se vprašajmo, kako dolgo bi zdržala majhna LiPo celica? Slika 6 prikazuje rezultate spletnega kalkulatorja življenjske dobe baterije za scenarij, v katerem je bil ESP8266 popolnoma izklopljen med tako imenovanim intervalom »spanja« in deluje le enkrat na vsakih 15 minut, da odčita in pošlje podatke do gostitelja prek WiFi.
Izračun pokaže 109 dni, kar ni zelo dolgo časovno obdobje in upoštevajte, da predvidevam, da ESP8266 sploh ne troši energije, razen ko dejansko izvaja program, ki izvaja meritve/prenos podatkov. Ta spletni kalkulator je na voljo na:
https://www.of-things.de/battery-life-calculator.php
Če upoštevate, da ESP8266 v načinu globokega spanja troši 20 µA in dodate še 1 µA za MCP1702 LDO regulator in ko znova zaženete izračun, dobite 102 dni. Tudi pri prej omenjenem vezju, ki temelji na MCP79401 (4 µA porabe v stanju spanja), ponovni izračun pokaže nekoliko daljšo življenjsko dobo baterije, ki znaša 107 dni.
Če analizirate to, lahko vidite, da je največji prispevek k porabi energije v tem scenariju poraba toka ESP8266 približno 92 mA za 3-5 sekund, potrebnih za povezavo z vašim WiFi WAP-om. Če si lahko privoščite podaljšanje časa med cikli prebujanja na eno uro, so stvari videti veliko bolje: rok trajanja baterije zdaj znaša 408 dni z uporabo vezja, ki temelji na MCP79401, in 328 dni z uporabo ESP8266 v načinu globokega spanja in MCP1702 LDO regulatorja.
Če je v vašem projektu mogoče zbirati podatke vsakih “n” minut, in te odčitke sporočati gostitelju prek WiFi-ja vsakih “m” ciklov, lahko dosežete nekaj izboljšanja življenjske dobe baterije – vendar ne toliko, kot bi morda pomisli. Pri vseh tistih »bujenjih«, pri katerih vam ni treba posredovati podatkov gostitelju prek WiFi-ja, je lahko čas delovanja EPS8266, potrebnih za povezavo z vašo WiFi dostopno točko, veliko krajši od 3-5 sekund.
Vendar bo še vedno najmanj 70 ms, kot je bilo omenjeno prej. Temu morate dodati še čas, ki bi lahko trajal za merjenje vseh uporabljenih senzorjev. Z drugimi besedami, tudi če med ciklom samo merjenja ne uporabite stavka WiFi.begin(), bo ESP8266 še vedno vklopil svoj VF modem in bo prišlo do aktivnosti oddajanja, čeprav tega niste zahtevali.
Upoštevajte, da če uporabljate vezje, ki temelji na MCP79401, ki sem ga opisal, boste morali podatke za vse tiste cikle, v katerih se ne povezujete z gostiteljem, shraniti v MCP79401 RAM pomnilnik. Kot sem že omenil, morate po vklopu omogočiti zakasnitev 100 ms, preden preberete SRAM MCP79401.
ESP-NOW protokol
ESP-NOW protokol je razvil Espressif, da omogoči nizke stroške brezžičnega prenosa podatkov med ESP člani MCU družine. Protokol ESP-NOW oddaja v istem pasu 2,4 GHz kot WiFi, vendar ni vzpostavljena nobena povezava z vašim WiFi WAP in ne moti običajnega WiFi delovanja v vašem domu.
Prihranek energije ni dosežen z zmanjšanjem moči VF oddajnika, temveč s poenostavitvijo protokola povezave, s čimer se zmanjša čas, potreben, da se ena enota poveže z drugo in nato prenese podatkovni paket. Krajši kot je čas celotnega prenosa, manj energije potrebujete. Protokol ESP-NOW je prilagojen za majhne pakete podatkov: največ 250 bajtov. Če bi morali prenesti velike bloke podatkov, veliko krajši čas povezave protokola ESP-NOW ne bi bil tako ugoden, saj bi tako ali tako večino časa porabili za prenos dejanskih podatkovnih paketov.
Espressif ne zagotavlja zelo izčrpne dokumentacije tega protokola. Na svoji spletni strani ponujajo povezavo do uporabniškega priročnika ESP-NOW, vendar je dolg le 5 strani in ni posebej uporaben. Ne nudijo nobenega primera kode in ker morate napisati MCU kodo za obe strani prenosa podatkov, je težko začeti.
Uporabljam Arduino IDE za razvoj kode za ESP8266 in ESP32. Obstajajo primeri ESP-NOW, ki prihajajo s podpornim paketom plošč ESP32 za Arduino, vendar zahtevajo spremembe, če uporabljate ESP8266. Predvidevam, da je bralec teh vrstic že namestil podporni paket za ESP8266 ploščo v Arduino IDE, saj ta paket vključuje knjižnične datoteke ESP-NOW, prilagojene za ESP8266 (čeprav ni na voljo nobenih primerov).
V preteklosti sem te ESP-NOW primere, ki temeljijo na ESP32, prilagodil za prejšnji projekt (ki je uporabljal več daljinskih ESP8266 upravljalnikov in ESP32 krmilnik). Vendar pa bom za ta članek opisal drugo kodo, ki sem jo našel na spletu in ki strogo obravnava dvosmerno komunikacijo med dvema ESP8266 z uporabo protokola ESP-NOW.
V tem članku uporabljam dve ESP8266 plošči. Vsaka plošča je sposobna sprejemati in pošiljati podatke drugi plošči, in katere senzorje boste uporabili za zagotavljanje teh podatkov in kako jih boste prikazali na drugi plošči, je odvisno od bralca. Obe plošči bosta vsebovali v bistvu enaki ESP-NOW skici. Vendar bom zaradi jasnosti v tem članku eno od plošč označil za glavno, drugo pa za podrejeno, čeprav obe pošiljata in prejemata podatke ter jih pošiljata (prek serijskih vrat).
Če bi želeli narediti centralno krmilno vozlišče, ki bi lahko komuniciralo z več daljinci, je tudi to mogoče z ESP-NOW. Moj prejšnji projekt, ki je vseboval ESP32 krmilnik in več daljinskih upravljalnikov, bi samodejno iskal vse oddaljene naprave, ki so prisotne/vklopljene, in bi se samodejno povezal s temi napravami (postopek, imenovan »uparjanje«).
Da bi to delovalo, morate konfigurirati RF modem ESP8266 na vseh oddaljenih enotah, da so v načinu dostopne točke, sicer jih skeniranje ne bi videlo. Kot dostopne točke bodo oddajale SSID, ki ga je mogoče poimenovati, da opiše funkcijo, ki jo izvaja oddaljena enota. Rutina skeniranja vrne tudi MAC naslove vseh ESP-NOW plošč, ki jih najde.
Vendar pa je za konfiguracijo dveh plošč postopek veliko enostavnejši, saj skeniranje ni potrebno. Vendar pa mora vsaka od teh plošč namesto svojega mesta poznati tudi MAC naslov druge. Vsak ESP8266 modul vsebuje dva trdo kodirana MAC naslova – enega za način postaje in enega za način dostopne točke. V tem primeru se uporablja Station način, tako da lahko MAC naslov poiščete s kratkim programom, kot sledi:
#include <ESP8266WiFi.h> void setup() { // Init Serial Monitor Serial.begin(115200); // Set device as a WiFi Station WiFi.mode(WIFI_STA); Serial.println(); Serial.print("MAC address in STATION mode = "); // NOTE: MAC address for STA and AP mode are different !!! Serial.println(WiFi.macAddress()); } loop() { }
Zapišite MAC naslove za vsako od plošč – ustreznega morate vstaviti na začetek kode skice za ustrezno ploščo, kot sledi:
// REPLACE WITH THE MAC Address of the other board in the set uint8_t broadcastAddress[] = {0x5C, 0xCF, 0x7F, 0x88, 0xEE, 0xD2};
Oglejmo si serijo stavkov, ki jih morate vključiti v vašo rutino namestitve, da konfigurirate ESP-NOW protokol. Kot smo že omenili, moramo najprej postaviti ESP8266 v način postaje z uporabo ukaza:
WiFi.mode(WIFI_STA);
Po tem naredimo nekaj protinagonskega: pokličemo funkcijo WiFi.disconnect(). S tem onemogočite sklad ugnezdene programske opreme, ki bi se običajno uporabljal za standardno WiFi povezavo z vašo WiFi dostopno točko. To pomeni, da ko uporabljate protokol ESP-NOW, niste povezani z našim domačim WAP in zato ne morete izvajati običajnih internetnih operacij.
Nato moramo ESP-NOW funcionalnost inicializirati, kot sledi:
if (esp_now_init() != 0) { Serial.println("Error initializing ESP-NOW"); return; }
To bo natisnilo zgornje sporočilo o napaki, če funkcije ESP-NOW ni mogoče inicializirati. Ne vem, kaj bi lahko šlo narobe zaradi tiskanja tega sporočila, saj tega v praksi še nisem videl.
Nato morate določiti vlogo za ploščo. Obstajajo 3 vloge, pod katerimi lahko deluje ESP-NOW naprava:
ESP_NOW_ROLE_CONTROLLER ESP_NOW_ROLE_SLAVE ESP_NOW_ROLE_COMBO
Prva dva sta samoumevna. Tretja, COMBO vloga je način, v katerem lahko naprava deluje tako kot daljinec ali kot krmilnik. Ugotovil sem, da če je naprava oddaljena, lahko sprejema sporočila, ne pa jih pošilja. Če je postavljena v način COMBO, lahko sprejema in pošilja sporočila. Za ta program bomo uporabili COMBO način, saj nameravamo imeti dvosmerno komunikacijo podatkov med ploščama:
esp_now_set_self_role(ESP_NOW_ROLE_COMBO);
API ESP-NOW ima nekatere funkcije, ki jih izvajajo rutine za povratni klic. V tem primeru so povratni klic rutine, ki jih pokliče ESP-NOW koda, ko so podatki bodisi sprejeti, bodisi poslani. Natančneje, zagotovite kodo za dva povratna klica:
OnDataSent: se pokliče, ko je bilo poslano odhodno sporočilo.
OnDataRecv: se pokliče, ko so bili prejeti nekateri podatki ESP-NOW.
Vaš program mora definirati (registrirati) rutine, ki bodo poklicane za vsako od teh dveh situacij. To se naredi na naslednji način:
esp_now_register_send_cb(OnDataSent); esp_now_register_recv_cb(OnDataRecv);
V svoji skici morate nekje v programu zagotoviti rutini OnDataSent in OnDataRecv. Rutina za povratni klic OnDataSent bo poklicana kmalu po tem, ko pošljete sporočilo. Vrnila bo 0, če je cilj prejel sporočilo (in oddal potrditev), ali 1, če potrditev ne bo prejeta v časovnem intervalu. Rutina za povratni klic OnDataRecv bo poklicana, ko so bili prejeti ESP-NOW podatki.
Na tej točki ste pripravljeni upariti oziroma “združiti” plošči:
esp_now_add_peer(broadcastAddress, ESP_NOW_ROLE_COMBO, CHANNEL, NULL, 0);
Oglejmo si parametre, posredovane tej rutini:
- Naslov za oddajanje – ta je bil glava programa opredeljen kot MAC naslov druge plošče, na katero se povezujete.
- Vloga te plošče – kot je opisano prej.
- Kanal. Vsi primeri, ki sem jih videl, definirajo številko kanala (1-15), ki je enaka za vse plošče. Kanal 0 pomeni, da kanal ni definiran. Ugotovil sem, da NI nujno, da se številka kanala ujema s ploščami, s katerimi bi lahko komunicirali. Ne vem zakaj je tako.
- Ključ – za enkripcijo, ki tukaj ni uporabljena.
- Dolžina ključa – 0 ki tukaj ni uporabljena.
Ko je protokol ESP-NOW inicializiran in sta napravi seznanjeni, je pošiljanje/prejemanje podatkov preprosto.
ESP-NOW oddaja
Podatke je mogoče poslati tako, da preprosto pokličete naslednjo rutino:
esp_now_send(broadcastAddress, (uint8_t *) &DHTReadings, sizeof (DHTReadings));
Parametri so:
Kazalnik na 6-bajtno polje, ki vsebuje MAC številko sprejemne naprave
Kazalnik na strukturo DHTReadings, ki vsebuje vrednosti, ki jih je treba poslati
Velikost te strukture (največ 250 bajtov)
(Ime strukture DHTReadings je poljubno – uporabljeno je bilo v primeru, ki je imel vgrajen senzor temperature/vlažnosti DHT21).
Ta rutina bo vrnila nič, če je bilo sporočilo uspešno poslano (vendar ni nujno, da ga je cilj prejel). Ker funkcija povratnega klica OnDataSent() zagotavlja status prejema potrditvenega sporočila od prejemnika, ni veliko smisla vedeti, ali je bilo sporočilo poslano. Zato ne zbiram vrnjene vrednosti te rutine.
Prenosi podatkov ESP-NOW so popolnoma agnostični glede vrste podatkov: pošiljate lahko poljubne vrste spremenljivk, če je dolžina sporočila manjša od 250 znakov, v 3. parametru pa morate posredovati ustrezno dolžino sporočila.
ESP-NOW sprejem
Kadar koli prejmete ESP-NOW sporočila, bo poklicana rutina povratnega klica, ki jo je registrirala naslednja rutina:
esp_now_register_recv_cb(OnDataRecv);
V vaši skici mora biti funkcija z oznako »OnDataRecv« za obdelavo vhodnih podatkov. Ta rutina prejme naslednje 3 parametre:
Kazalec na 6-bajtno polje, ki vsebuje MAC naslov naprave, ki je poslala sporočilo.
Kazalec na podatkovni medpomnilnik, ki vsebuje sporočilo. Uporabite rutino memcpy(), da te podatke premaknete v strukturo, ki jo uporabljate za shranjevanje teh podatkov, in tako sprostite ESP-NOW medpomnilnik za nadaljnja dohodna sporočila.
Velikost prejetega sporočila v bajtih. Če bi prejemali sporočilo niza, bi ta velikost vključevala znak za konec niza (običajno 0x00).
Običajno bi ta funkcija povratnega klica izgledala takole:
void OnDataRecv(uint8_t * mac, uint8_t *incomingData, uint8_t len) { memcpy(&incomingReadings, incomingData, sizeof(incomingReadings)); Serial.print("Bytes received: "); Serial.println(len); incomingTemp = incomingReadings.temp; // this just copies the value to a non-structured var. incomingHum = incomingReadings.hum; // '''' }
Za sprejemanje in prenos podatkov definirate podatkovno strukturo, ki vsebuje spremenljivke, ki jih želite prenesti. Kot smo že omenili, je prenos podatkov agnostičen – lahko pošljete poljubne vrste podatkov, dokler skupna struktura ni večja od 250 bajtov. V tem primeru so ti opredeljeni na naslednji način:
//Structure for the packet to send/receive //This structure must be identical on the other board! typedef struct struct_message { float temp; float hum; } struct_message; // This DHTReadings structure holds the sensor readings taken on this board struct_message DHTReadings; // The incomingReadings structure holds incoming readings from the other board struct_message incomingReadings;
Vse, kar še ostane, je pošiljanje in prejemanje ESP-NOW paketov, kar se naredi v Loop() zanki naše skice:
void loop() { //Get new readings getReadings(); // populate the ESP-NOW structure that will be sent DHTReadings.temp = temperature; DHTReadings.hum = humidity; // Send out these readings esp_now_send(broadcastAddress, (uint8_t *) &DHTReadings, sizeof(DHTReadings)); // Print incoming readings printIncomingReadings(); // send the values of incomingTemp and incomingHum variables // out the Serial port delay(5000); // repeat every 5 seconds }
Upoštevajte, da je ESP-NOW komunikacijski protokol mogoče izvesti s šifriranjem. Če se uporablja šifriranje, je mogoče povezati samo 10 naprav, sicer pa največ 20. Dokumentacije o šifriranju ni veliko.
Ponujam Arduino skico z imenom ESP8266_NOW_Slave_SE, ki je primer zgornje kode. Lahko naredite še eno kopijo tega programa z imenom ESP8266_NOW_Slave_SE in vsako spremenite tako, da vključuje MAC številko druge plošče v kompletu.
Če želite nadalje raziskati protokol ESP-NOW na ESP8266, je spodaj dobra povezava za poskus:
Getting Started with ESP-NOW (ESP8266 NodeMCU with Arduino IDE)
ali za ESP32:
ESP-NOW poraba pri nizki moči
Kot sem že omenil v članku, je zmanjšanje porabe energije ESP8266 z načinom globokega spanja (ali popolnim izklopom) le polovica zgodbe. Čas, ki ga mora ESP8266 porabiti za prenos teh podatkov na gostitelja prek WiFi, je druga polovica zgodbe. Prej sem napisal, da bo ESP8266 potreboval 3-5 sekund, da se poveže z WiFi usmerjevalnikom, če uporabljate ta način komunikacije.
Na sliki 5 lahko vidite, da ves ta čas ESP8266 troši približno 80 mA in da obstaja veliko 350 mA ali višjih oddajnih konic. Ocenjujem, da bi oddajne konice k tem 80 mA ali 92 mA dodale približno 15 %.
Protokol ESP-NOW je zasnovan tako, da je hiter v primerjavi z zgoraj omenjenimi problemi povezovanja z WiFi dostopno točko. Na sliki 7 lahko vidite sliko oscilograma zajema obsega trenutne porabe z uporabo zgoraj opisane ESP-NOW metode. Ta posnetek je bil posnet takoj po pritisku gumba RST na ESP8266 plošči.
Na začetku vidite približno 15 milisekund visoke porabe toka, kar ustreza temu, da ESP8266 inicializira protokol ESP-NOW in se “združuje” z drugo ploščo. Na sliki 8 lahko vidite trenutno porabo za en paketni prenos, ki se zgodi vsakih 5 sekund v funkciji Loop(). To traja manj kot 0,2 milisekunde.
Ti dve sliki kažeta, da če bi postavili ESP8266 v način globokega spanja ali če bi ga popolnoma izklopili, lahko pri uporabi protokola ESP-NOW pričakujete približno 10 milisekund visoke konice porabe toka (približno 300+ mA). Imeli bi tudi porabo nizkega toka (~ 36 mA) približno 70 ms, omenjeno prej v članku.
Majhna poraba energije izredno kratkega prenosa (prikazano na sliki 8) je veliko manjša od te, vendar bi to veljalo le, če bi ESP8266 deloval med paketnimi prenosi – kar ne velja, če ga izklopite na en ali drug način za izjemno dolgo življenjsko dobo baterije. Kljub temu je celo profil porabe energije 10 milisekund veliko manjši od moči, ki jo porabi ESP8266 v 3-5 sekundah, ki jih potrebuje, ko se poveže z vašo WiFi dostopno točko.
Vezje
Slika 3 prikazuje shemo majhnega tiskanega vezja, ki sem ga zasnoval za delovanje ESP8266 v načinu spanja, ki sem ga opisal prej. Slika 9 je fotografija te plošče. MIC5323 LDO in MCP79401 RTC sta nameščena v zgornjem desnem kotu plošče. 3-pin rumena letvica je priklop za serijska vrata, ki se uporablja pri programiranju in razhroščevanju. Za uporabo teh vrat potrebujete USB-UART kabel z 3,3-voltnimi logičnimi nivoji.
Dvopolni konektor pod MIC5323 je vtičnica X3. Za vklop ESP826 lahko uporabite mostiček X3, tudi če je MCP79401 onemogočil MIC5323 med programiranim intervalom izklopa. 2-pinska in skrajna leva 4-pinska konektorja omogočata dostop do GPIO 12, 13, 14 in 16.
4-pinska letvica na desnem dnu se lahko uporablja za povezavo I2C naprave in ima razpored priključkov ustrezen za neposredno povezavo s senzorjem temperature/vlažnosti AM2320. Zraven je J2, nezaspajkano mesto za QWIIC vtičnico. Številni Adafruit in Sparkfun senzorski moduli so opremljeni s tem priključkom, ki vsebuje 3,3 V in I2C signale. Piezo piskač spodaj levo je lahko preprost piezo element ali takšen, ki že vsebuje gonilnik. Če uporabljate preprost piezo element, bi ga morali poganjati z naslednjo vrstico:
Tone(12,frequency, time (ms);
Če izbrani piezo vsebuje gonilnik, upoštevajte polariteto pri priklopu. Poganjate ga lahko s standardnimi ukazi digitalWrite(12,LOW) in digitalWrite(12,HIGH). Če niste že programirali v skici, ki aktivira MCP79401 alarmno vezje, bo MFP MCP79401 odprt, MIC5323 LDO bo omogočen in ESP8266 bo vklopljen ter pripravljen za ponovno programiranje, če bo potrebno. Ko pa prenesete skico, ki aktivira alarm in onemogoči MIC5323/izklop ESP8266, boste morali postaviti stikalo ali mostiček čez terminale X3, da vklopite ESP8266 za nadaljnje ponovno programiranje.
Primeri skic za ta članek, kot tudi Eagle datoteke za TIV, so na voljo na spletni strani revije Svet elektronike.
Software and files