Oldal: 1 / 1

NodeMCU + megszakítás + WiFi

Elküldve: 2018. január 3. szerda, 12:32
Szerző: MorzsaProf
Sziasztok!

A NodeMCU dolgozza fel az érzékelőktől jövő adatokat, majd wifi-n továbbítja. Akkumulátorról dolgozik. Egy Arduino Pro Mini figyeli az akku feszültség szintjét. Mikor eléri a kritikus alsó értéket, akkor megszakítást küld a NodeMCU felé. Itt a megszakítás kezelő rutinban beállítok egy flaget, majd wifin keresztül továbbítanám a szerver felé, majd egy relé segítségével lekapcsolom az akkut.
A probléma az, hogy mikor beérkezik a megszakítás, akkor nem tud konnektálni a szerver felé. A NodeMCU az a V3-s.
Az idevágó program részlet:

#include <ESP8266WiFi.h> //wifi

// hálózat
const char* ssid = "xxxx";
const char* password = "xxxx";
const int FeszRiaszt = D3; // bemenet, alacsony fesz érzékelés
const int FeszLED= D5; // alacsony feszültség relé vezérlő
volatile int flag = 0;


void setup() {

pinMode(FeszLED,OUTPUT); // alacsony fesz. relé vezérlő
pinMode(FeszRiaszt,INPUT); // alacsony fesz érzékelés

digitalWrite(FeszLED,HIGH);
digitalWrite(FeszRiaszt,HIGH);

Serial.begin(9600);
Serial.println("");
Serial.print("Csatlakozas ");
Serial.print(ssid);
Serial.println(" halozathoz....");

attachInterrupt(0,al_fesz(),CHANGE); // megszakítás, alacsonyfeszültségnél

} //void setup vege

void loop()
{
Serial.println("dolgozom ");
tovabbit(); // WiFi-n továbbítom az adatokat
} // void loop vége


// megszakitas kezeles
void al_fesz()
{
flag=2;
Serial.println("Hivom a szubrutint ... ");
tovabbit();
} // al_fesz vége




void tovabbit()
{
int i =0;
int varakozas = 5;

// Hálózat indítása

WiFi.begin(ssid, password);
delay(2000);
while (WiFi.status() != 6)
{
delay(500);
Serial.print(".");
Serial.println("WiFi retry...");
WiFi.begin(ssid, password);
delay(2000);
}
delay(3000);
Serial.println("sikerult!");
Serial.print("IP: ");
Serial.println(WiFi.localIP());
delay(2000);

// adatok tovabbitasa

Serial.print("IP: ");
Serial.println(WiFi.localIP());

WiFiClient client;
client.connect("192.168.0.48", 80);
Serial.println("Nem sikerult ");
Serial.print("konnekt eredmeny : ");
Serial.println(client.connected());
Serial.println("Sikerult !");
delay(1000);
client.print("GET /php/meresek.php?helyiseg=");
client.print("WC");
client.print("&ertesit=");
client.print(flag);
client.println(" HTTP/1.1");
client.println("Host: 192.168.0.48");
client.println("Connection: close");
client.println("");

digitalWrite(FeszLED,LOW); // alacsony az akku feszültsége
} // tovabbit() vege

Tudnátok segíteni, hogy a megszakítási részben is tudjak adatokat továbbítani a szerver felé?

Előre is köszönöm a segítségeteket:

Gábor

Re: NodeMCU + megszakítás + WiFi

Elküldve: 2018. január 3. szerda, 19:26
Szerző: SanyiSay
Egy tipp (pár hiba észrevétel) hobbista szemmel.

Megszakítás rutinba, csak egy állapot jelző változót tegyél amit bekapcsolsz megszakításkor. Loop-ban meg figyeld a kapcsoló állapotát, és minden hosszabb időt igénylő folyamat ott legyen. delay() nem a barátunk azt loop-ban már ne használd ha nem muszáj.

Időzítésre, várakoztatásra, delay helyett Tickert használunk. Nem egyszerű elsőr ránézésre, de ha megszokja az ember akkor már kézre áll. Megéri egy kis energiát belefektetni.
https://github.com/esp8266/Arduino/tree ... ies/Ticker
https://arduino-esp8266.readthedocs.io/ ... tml#ticker
Itt is írják hogy a megszakításon belül nagy dolgokat ne vigyünk véghez.

Mostani kódodban loop-ban van a
tovabbit();
Amiben nem csak a kliens létrehozása és üzenet küldése van hanem a wifi hállózathoz csatlakozás is. Annak a setup részben a helye, jó esetben.
Vagy loop-ban is lehet de akkor ellenőrzött formában. Mondjuk ha valami okból AP AP-STA STA módok között szeretnél váltogatni menet közben, vagy efféle trükkök esetén tesszük a loop ba. Akkor is feltételes elágazás mögé.

Én ahogy csinálnám:
- tovabbit() ból tedd a wifi csatlakozást tedd a setup-ba
- tovabbit() tedd feltételes elágazásba ahol vizsgálsz egy változót hogy volt e megszakítás ha igen akkor tovabit(), a megszakítás kapcsoló = false
- al_fesz() megszakítás kapcsoló = true, Serial.print- se kell bele.

ui:
Sok client.print sem szerencsés. Szedd össze egy String-be és egybe küld el.

Re: NodeMCU + megszakítás + WiFi

Elküldve: 2018. január 4. csütörtök, 13:29
Szerző: MorzsaProf
Köszönöm!

Eredetileg a Wifi csatlakozás a setupban van/volt. Úgy se működött.
A client.print ötletet köszönöm!
A ticker-t átnézem, a delay() tényleg nem jó, próbálkoztam for ciklussal is, az se nyerő.
A gond leginkább az, hogy muszáj, hogy a megszakításon belül legyen az adat továbbítás. Igazából itt csak egy adatot továbbítok, azt, hogy lemerült az akku. Utána azonnal le is kapcsolom. Nincs arra idő, (ezért kell a megszakítás) hogy a loop-ban majd valamikor ráfut az elenőrzés. Elég terjedelmes, és idő igényesre sikerült a loop. Ugyanis lehetséges, hogy a loop feldolgozása közben elmegy a villany.
Egész pontosan a következő sort nem tudja végrehajtani:

client.connect("192.168.0.48", 80);

itt sokáig vár, és 3-s hibakódot ad vissza.

Esetleg ötlet:

Köszönöm:

Gábor

Re: NodeMCU + megszakítás + WiFi

Elküldve: 2018. január 4. csütörtök, 14:52
Szerző: SanyiSay
Egy kis elmélet. ( ha rossz felé gondolkodnék javítsatok ki :) )
MorzsaProf írta:Eredetileg a Wifi csatlakozás a setupban van/volt. Úgy se működött.
Hát ez nem így működik hogy ha ott se jó akkor ide teszem. :)
Mert hát minek folyamatosan újracsatlakozni a wifi hez, ha egyszer csatlakozott az ember akkor a többit az esp elintézi. Amikor megszakad a kapcsolat az esp automatikusan újracsatlakozik. (ha be van állítva) Ezzel nem kell foglalkozni egy részről, másrészt pedig tudni kell róla hogy ez van, mert pont az ilyen háttér szolgáltatások miatt amik a wifi kiszolgálásér futnak(loop végén vannak elindítva normál esetben), sajnos nem foglalhatjuk le önkényesen a processzor időt. Instabil működés vagy WDT újraindítás lesz a vége. delay() azért működik mert úgy van megírva hogy a miközben várakozik folyamatosan átadja a vezérlést a "háttérfolyamatoknak" nem kel megvárni a loop végét. Ha túl hosszú ciklust csinálunk ugyanez lesz a problémánk. delay(0) vagy yield() beillesztése erre a megoldás. Nekünk kell a "háttérfolyamatoknak" processzor időt biztosítani.
http://arduino-esp8266.readthedocs.io/e ... and-delays

Jó esetben for ciklust sem használunk mert lefogja a loop ciklust. Megint ticker van használatban, elindítjuk, növelünk egy értéket, loopban figyeljük, feldolgozzuk, a végén leállítjuk a tickert.
Kliensből is van aszinkron kliens. Normál kliens használatakor addig nem fut tovább a kódunk a még meg nem jön a válasz a szerver felől vagy le nem telik a türelmi idő, google szervernél ez nekem ez egy perc körüli érték is volt. Aszinkron kliens nem fogja vissza a kódunkat csak kérést indítjuk el, a csatlakozást a "háttérben" megoldja, egyszer csak megjön a válasz, vagy a hiba.

Wifin adatot továbbítani nem gyors folymat, és nem is annyira kiszámítható. pld a sok client.print sem esztétikai okok miatt nem jó, hanem minden küldéskor nyitja és zárja a kapcsolatot, sok print, sok időt vesz igénybe.

Ezek után a kérdés szerintem:
Amikor megszakításban vagyunk, akkor vajon fut e "háttérszolgáltatás" ami kezelné nekünk a wifit?

Re: NodeMCU + megszakítás + WiFi

Elküldve: 2018. január 4. csütörtök, 15:01
Szerző: MorzsaProf
Köszönöm a gyors választ!
Igen, fut. Ami a megszakításban van, az minden lefut. Kivéve a client.connect -t . (Meg persze ami ehhez tartozik.) Vagy ha jól értem, akkor a client.connect-nek is a setupban kell lennie?

(Bocs, de abszolút kezdő vagyok).

Re: NodeMCU + megszakítás + WiFi

Elküldve: 2018. január 4. csütörtök, 15:40
Szerző: SanyiSay
A client.connect az nem kell a setup ba. Csinálsz egy függvényt amiben van csatlkakozás, küldés, kapcsolatbontás, és ezt loopból meghívod a megfelelő paraméterekkel ha eljött az ideje. Ebben hol a megszakításod? kérdezhetnéd.

Itt is egy leírás hogy használjuk a megszakításokat. Nincs túlbonyolítva mint az enyém, és talán érthetőbb is. :)
https://techtutorialsx.com/2016/12/11/e ... nterrupts/

Viszont elsőre szerintem hagynod kellene a megszakítást és egy tiszta kódot írni ami boot után egyszer csatlakozik a szerverhez.
Ezen az oldalon láthatod hogy csatlakozol legegyszerűbben a wifi hálózatra.
http://arduino-esp8266.readthedocs.io/e ... eadme.html

Re: NodeMCU + megszakítás + WiFi

Elküldve: 2018. január 5. péntek, 8:44
Szerző: MorzsaProf
A linkek nagyon érdekesek. Ezt még át kell alaposan nézni. Köszönöm!
Igazából, lehet, hogy nem értjük egymást. A WiFi kommunikáció teljesen jól működik, ha a loop-ban folytatom le. Ha ugyanezt az eljárást a megszakítási rutinba teszem bele (ami egyébként jól működik), ott nem hajlandó. Ezt nem értem. Miért működik a loop-ban, és miért nem a megszakításon belül.

Gábor

Re: NodeMCU + megszakítás + WiFi

Elküldve: 2018. január 5. péntek, 11:42
Szerző: vargham
Miért működik a loop-ban, és miért nem a megszakításon belül.
Mert az ISR az egészen más kontextus, mint a loop. Például nem fut a többi megaszkítás, mint timerek, wifi kezelés, stb. Az ISR kód kötelezően kicsi, rövid, nem várakozik. A legjobb az, ha egy flag-et állít, ami alapján majd a main loop lekezeli a helyzetet.

Re: NodeMCU + megszakítás + WiFi

Elküldve: 2018. január 5. péntek, 12:51
Szerző: MorzsaProf
Köszönöm!
Most már értem. Ez így szívás.

Re: NodeMCU + megszakítás + WiFi

Elküldve: 2018. január 5. péntek, 15:24
Szerző: vargham
Ez így szívás.
Miért? Minden mikrokontroller így működik. (Majdnem. Kivétel: Parallax Propeller, ahol nincsenek megszakítások, de van 8 mag.)
Ennek ismeretében KELL megtervezni az alkalmazásodat.

Re: NodeMCU + megszakítás + WiFi

Elküldve: 2018. január 11. csütörtök, 19:26
Szerző: csabeszq
Nem szívás, a megszakítás a futó folyamatot állítja meg.

Ha te a megszakításban torrenten letöltöd a Star Wars VIII mp4-et, akkor közben mindenki állni és várni fog, amíg a 3-4 GB lejön.
Arra való a megszakítás, hogy egy hosszú folyamatba rövid kis dolgokat végezz el, nem arra, hogy megoldd a világegyenletet.

Amit te szeretnél, az a szálkezelés: egyik szálon töltesz mondjuk torrenten, a másikon meg mással foglalkozol, például videót enkódolsz. Kétmagos processzoron simán futtathatsz két szálat, de ne gondold, hogy egyszerűbb, mint a megszakításosdi, Az Arduino-kon nincs szálkezelés, azaz párhuzamos végrehajtás. Komolytalan cuccok a mikrovezérlők.

Egyébként rövid megszakításokkal szinte minden megoldható, csak bonyolultabb.