ESP8266 két párhuzamosan futó loop()? - nem probléma

ESP8266, ESP32 chipek és az ESP-xx modulok. Programozási nyelvek, trükkök, hardware tippek.
Avatar
csabeszq
Bitfaragó
Hozzászólások: 659
Csatlakozott: 2012. szeptember 5. szerda, 6:00

ESP8266 két párhuzamosan futó loop()? - nem probléma

HozzászólásSzerző: csabeszq » 2017. október 9. hétfő, 23:39

Az ESP8266 a megszokott Arduino-khoz képes egy 32 bites brutál erős állat, amit mi sem mutat jobban, minthogy 2 loop()-ot is tud párhuzamosan futtatni.
Az egyik loop()-ban mondjuk delay-jel vársz, vagy web szervert vezérelsz, a másik loop meg közben csinál amit szeretne.

Nem interruptról van szó. A rendszer úgy van kitalálva, hogy amikor nincs adat, vagy delay-en vár, átadja az ESP a vezérlést egy másik feladatnak WiFi-t, vagy mást kezelni. Minket persze semmi sem akadályoz abban, hogy saját feladatot indítsunk, saját loop()-pal. Onnan látni, hogy nem interrupt-os, hogy bárhol végtelen ciklust csinálsz, a másik feladat is megál. Ez háttér feladat inkább, ami akkor hívódik meg, ha a loop() kilép, vagy a rendszer várakozik.

Két loop() esetén azért nem olyan egyszerű az élet, az Arduino nem erre van kitalálva, a delay a loop2()-ben nálam azonnal fagyott.

Igazából miközben web-et szolgálok ki, aközben kellene SPI-vel adatokat fogadnom, erre kellett a cucc. A gond, hogy a web-szerver várt az adatra, eközben az SPI is állt. Dual core-nál (ESP32) egyszerűbb a buli, viszont az ESP8266 is képes limitált párhuzamosságra.

A példaprogramban a loop() a delay-en vár, miközben a loop2() azért írogat ezt azt a képernyőre. Komolyan ne vegyétek a kódot, inkább vicces.

Kód: Egész kijelölése

extern "C" {
  #include "user_interface.h"
}

// változók
int loop1Szamlalo = 0;
int loop2Szamlalo = 0;
uint32_t loop2Millis;

// loop2 varázslás

#define LOOP2_PRIORITAS        2
#define LOOP2_ESEMENYSOR_MERET 1

os_timer_t loop2Timer;
os_event_t loop2Esemenysor[LOOP2_ESEMENYSOR_MERET];

void loop2TimerHivas(void *pArg) { // periodikus timer hívás, ami a loop2 feladatot indítgatja
  system_os_post(LOOP2_PRIORITAS, 0, 0); // loop2 feladat indítása
}

void loop2Csomagolo(os_event_t *events) {
  loop2();
}

// indulás és a 2 párhuzamosan futó loop

void setup() {
  Serial.begin(115200);

  system_os_task(loop2Csomagolo, LOOP2_PRIORITAS, loop2Esemenysor, LOOP2_ESEMENYSOR_MERET);
  os_timer_setfn(&loop2Timer, loop2TimerHivas, NULL);
  os_timer_arm(&loop2Timer, 10, true); // minden 10ms után loop2 feladat indul
}

void loop() {
  Serial.print("Loop1:");
  Serial.println(loop1Szamlalo++);
  delay(1000);
}

void loop2() {
  if(( millis() - loop2Millis) > 1000 ) {
    Serial.print("Loop2:");
    Serial.println(loop2Szamlalo++);
    loop2Millis = millis();
  }
}

Avatar
csabeszq
Bitfaragó
Hozzászólások: 659
Csatlakozott: 2012. szeptember 5. szerda, 6:00

Re: ESP8266 két párhuzamosan futó loop()? - nem probléma

HozzászólásSzerző: csabeszq » 2017. október 10. kedd, 13:28

Mindenesetre lehet, hogy az ESPAsyncWebServer jobb választás. Hihetetlen, hogy mekkora selejt az Arduino default WebServer-e és WebClient-e. Nem győzi az ember mellőzni a kódból.

Idáig az ESPAsyncTCP-t használtam kliensnek, elégedett voltam vele. Nem blokkolt véget nem érő ideig. A webserver is jónak tűnik, de még tesztelem.

Nem biztos, hogy kell varázsolni, lehet hogy elég az Arduino-s webszemetet lapátra tenni.

Avatar
SanyiSay
Elektronbűvölő
Hozzászólások: 998
Csatlakozott: 2009. február 28. szombat, 7:00
Tartózkodási hely: Budapest
Kapcsolat:

Re: ESP8266 két párhuzamosan futó loop()? - nem probléma

HozzászólásSzerző: SanyiSay » 2017. október 10. kedd, 19:10

Na, mire van időm kérdezni, már válaszoltál is rá.
Mondjuk az meglep hogy eddig nem használtad az ESPAsyncWebServer-t, pont te aki az aszinkron megoldások "megszállottja". :)
Na de nézzük a jó oldalát, én csak használom te viszont gondolom érteni is fogod az új szervered. Kíváncsian várom a kritikákat. Én csak ajánlani tudom, bár lehetőségeinek csak igen kis részét használom.

Avatar
csabeszq
Bitfaragó
Hozzászólások: 659
Csatlakozott: 2012. szeptember 5. szerda, 6:00

Re: ESP8266 két párhuzamosan futó loop()? - nem probléma

HozzászólásSzerző: csabeszq » 2017. október 10. kedd, 21:38

A könyvtári szerver hellyel közzel ment, a kliens sehogy.

Az async szerver egész jónak tűnik, de még tesztelem.

Avatar
csabeszq
Bitfaragó
Hozzászólások: 659
Csatlakozott: 2012. szeptember 5. szerda, 6:00

Re: ESP8266 két párhuzamosan futó loop()? - nem probléma

HozzászólásSzerző: csabeszq » 2017. október 11. szerda, 7:09

Ami furcsa, hogy elsőre sokkal lassabbnak tűnt, mint a régi változat, persze a részletekben van elásva minden.

Alapból a library nem cache-el semmit, ez azt jelenti, hogy minden kérésnél újratöltött mindent, ami rohadt nagy gáz, mert iszonyúan lassú volt.

Kód: Egész kijelölése

  serveStatic("/", SPIFFS, "/").setDefaultFile("index.html").setCacheControl("max-age=3600");


Amint bekapcsoltam rajta a cache-control-t elkezdett húzni, mint állat. WireShark-kal megnézve, kérést sem küldött a böngésző, kiszedte az adatokat a cache-ből. Értelemszerűen a weblapok cache-elve vannak, a JSON válasz nincs, tehát egyszer betölt a cucc mindent, utána már csak json kommunikáció van.

Így azért érezhetően gyorsul minden.

Avatar
SanyiSay
Elektronbűvölő
Hozzászólások: 998
Csatlakozott: 2009. február 28. szombat, 7:00
Tartózkodási hely: Budapest
Kapcsolat:

Re: ESP8266 két párhuzamosan futó loop()? - nem probléma

HozzászólásSzerző: SanyiSay » 2017. október 11. szerda, 19:02

"Extra" fejléceket azt hiszem már az ESP8266WebServer-ben is magunknak kellett megoldani.
Legalább is nálam ott kezdődött a fejlécek hiányának pótlása.

Avatar
SanyiSay
Elektronbűvölő
Hozzászólások: 998
Csatlakozott: 2009. február 28. szombat, 7:00
Tartózkodási hely: Budapest
Kapcsolat:

Re: ESP8266 két párhuzamosan futó loop()? - nem probléma

HozzászólásSzerző: SanyiSay » 2017. október 11. szerda, 19:08

Ha már fejlécek.
Annó volt egy minta kódom ami az ajax használatot szemléltette ékezetes karakterekkel. Amikor Eclipse-el fordítottam akkor szépen működött amikor Arduino-val akkor egyáltalán nem küldött az esp ékezetes karaktereket. Valahol fordítás közben elvesztek a fránya ékezetek.

Avatar
Robert
Elektronbűvölő
Hozzászólások: 9768
Csatlakozott: 2005. december 9. péntek, 7:00
Tartózkodási hely: Budapest
Kapcsolat:

Re: ESP8266 két párhuzamosan futó loop()? - nem probléma

HozzászólásSzerző: Robert » 2017. október 12. csütörtök, 2:27

Az Arduino a háttérben nem ASCII kóddal operál, hanem UTF-8 kódolással.
http://www.tavir.hu - a gazda :)

Avatar
SanyiSay
Elektronbűvölő
Hozzászólások: 998
Csatlakozott: 2009. február 28. szombat, 7:00
Tartózkodási hely: Budapest
Kapcsolat:

Re: ESP8266 két párhuzamosan futó loop()? - nem probléma

HozzászólásSzerző: SanyiSay » 2017. október 12. csütörtök, 5:21

Köszönöm.
Na még egy strigula az Arduino fordító ellen. :)

Avatar
csabeszq
Bitfaragó
Hozzászólások: 659
Csatlakozott: 2012. szeptember 5. szerda, 6:00

Re: ESP8266 két párhuzamosan futó loop()? - nem probléma

HozzászólásSzerző: csabeszq » 2017. október 12. csütörtök, 5:28

Lehet, hogy durva, de az async web server ugyanolyan kieséseket produkál, mint a könyvtári. Láthatóan nem gyorsabb.

Simán 100ms-re megáll az élet. Mondjuk jó lenne tudni, hogy mi a fenét csinál 0.1s-ig és miért nem jön vissza a vezérlés a loopba?

Azt még kipróbálom, hogy timerrel olvasom az SPI-t.

Avatar
csabeszq
Bitfaragó
Hozzászólások: 659
Csatlakozott: 2012. szeptember 5. szerda, 6:00

Re: ESP8266 két párhuzamosan futó loop()? - nem probléma

HozzászólásSzerző: csabeszq » 2017. október 12. csütörtök, 22:35

A fenti hozzászólást kiegészíteném:
- az ESPAsyncWebServer gyors, húz mint atom, maxon 30ms időkieséseket produkált. 50Hz-en még bírja az Attiny memóriája ezt a kiesést
- az SPIFFS nevű csoda vacak, ami SD kártya fájlrendszer, nos az sebességben minden lehetőséget alulmúlott, onnantól a 120ms késés sem volt ritka, sebességben lassabb volt, mint a régi szerver, csigul rendesen.

A legjobb megoldás értelemszerűen az ESPAsyncWebServer, ami a flash alsó 1 MByte-jából gzippelt lapokat ad vissza. Ez repül mint a szél.

A request->send_P-vel és társaival lehet memóriából lapokat visszaadni.

Avatar
Robert
Elektronbűvölő
Hozzászólások: 9768
Csatlakozott: 2005. december 9. péntek, 7:00
Tartózkodási hely: Budapest
Kapcsolat:

Re: ESP8266 két párhuzamosan futó loop()? - nem probléma

HozzászólásSzerző: Robert » 2017. október 13. péntek, 18:37

http://www.tavir.hu - a gazda :)

Avatar
csabeszq
Bitfaragó
Hozzászólások: 659
Csatlakozott: 2012. szeptember 5. szerda, 6:00

Re: ESP8266 két párhuzamosan futó loop()? - nem probléma

HozzászólásSzerző: csabeszq » 2017. október 13. péntek, 21:47

A nagy érdeklődésre való tekintettel egy videó, hogy mit csinálok (WebKonnektor):
https://www.youtube.com/watch?v=zJYBmkaj_FE

A videón 230V-ot kapcsolgatok és áramváltó tekerccsel mérem az áramát. A web-et ESP8266 adja, a mintavételezést Attiny84 csinálja. Az Attiny azért tuti, mert képes differenciális ADC-t mérni 20X gain mellett. Jelen mérésnél az áram kicsi, ezért a 20X be volt kapcsolva amikor a videó készült.

Az Attiny84 memóriája 512 byte, 16 bites ADC értékből 120-at tud eltárolni. Ez durván 5 teljes szinusz periódus, ami maximum 100ms puffert jelent, de a valóságban egy kicsit kevesebbet. Ha az ESP8266 nem olvassa ki az adatot, az Attiny nem lesz képes letárolni. Ha az ESP SPIFFS-sel idétlenkedik olvasás helyett, az adatok elvesznek.

Mi látszik a videón:
- egy hagyományos izzó
- izzó ellenállása tisztán ohmos, ezért szinuszos árama van
- látszik a csapott fejű szinusz (az egyenirányítók a pufferkondenzátorok miatt kizárólag a szinusz csúcsán fogyasztanak áramot. A szolgáltató a csúcson már nem képes tartani a szinusz formát, a pufferkondik győzedelmeskednek és reszelőként lecsapják a szinusz fejét)
- a kedvencem az köbös Bézier interpolátor. Átküldöm a mintavételi adatokat, a javascript kiszámolja a pontok pozícióit a böngészőablak függvényében, kiszámolja kontroll pontokat és felrajzolja a görbét. Iszonyatosan frankón néz ki.

Avatar
SanyiSay
Elektronbűvölő
Hozzászólások: 998
Csatlakozott: 2009. február 28. szombat, 7:00
Tartózkodási hely: Budapest
Kapcsolat:

Re: ESP8266 két párhuzamosan futó loop()? - nem probléma

HozzászólásSzerző: SanyiSay » 2017. október 14. szombat, 8:41

Hát nem semmi vagy, gratula. :)

Akkor ha jól tippelem javascript rögzíthetné is az adatokat.
Egyébként az SPIFFS nem csak egyszer van használatban amikor átküldi a kliensnek a weboldlalt?
Utána már csak adatforgalom van ha jól tippelek.

Nálam az ESP-k nem is nagyon tárolnak weboldalakat, csak adatkommunikáció van. Javítsatok ki ha tévedek, de az esp mint szerver nem sokat tud hozzátenni a weboldalhoz, csak a kliens oldal dolgozik, nem kapok többet mint amikor esp-n kívül offline tárolom az oldalt.
Innen nézve a fájlrendszer kikapcsolható, ha nagyon bezavar, vagy gátja lenne egy komolyabb feladatnak.

Avatar
csabeszq
Bitfaragó
Hozzászólások: 659
Csatlakozott: 2012. szeptember 5. szerda, 6:00

Re: ESP8266 két párhuzamosan futó loop()? - nem probléma

HozzászólásSzerző: csabeszq » 2017. október 14. szombat, 9:38

De igen, reloadnál jön a probléma, menet közben nem.

A javascript nem ment el adatokat. Megjeleníti és teljesítmény monitor is lesz benne.

A cucc feladata túláram esetén leállítani a szivattyút. Van egy abszolút határ, ami felett leáll a szivattyú és relatív határ, hogy ha X időnél többet tölt benne, akkor kapcsol ki. Bekapcsolásnál a relatív határ lép érvénybe, ha annyit fogyaszt, akkor X perc után kapcsol ki. Rövid időt tölthet benne.

Ha már áramot mérek, ha mintavételezek, akkor általánosra csinálom a cuccot. Ne csak az öntözőrendszerben, hanem másra is lehessen használni.

A web szerver ugyanez, igyekszek jó cuccokat összeszedni, hogy későbbi munkában is jó legyen. A 100ms késleltetés SPIFFS-nél átlépte a toleranciaküszöbömet. Igazából a 30ms sem mondható jónak, csak lusta vagyok tovább faragni.


Vissza: “ExpressIf WiFi”

Ki van itt

Jelenlévő fórumozók: nincs regisztrált felhasználó valamint 3 vendég