Forum: Mikrocontroller und Digitale Elektronik Probleme mit TCP und UDP beim ESP


von Peter S. (durze)


Lesenswert?

Hallo zusammen,

ich habe ein Gyroskop an ein ESP angeschlossen und möchte die Daten über 
WLAN an meinen PC übertragen um sie dort weiter zu verarbeiten.
Diese Daten umfassen - fertig formatiert - einen 17-stelligen String.

Testweise habe ich die Daten seriell ausgelesen und ausgewertet, das hat 
wunderbar geklappt und zwar laut Labview mit einer Zykluszeit von etwa 
50ms.
Code: http://pastebin.com/BJ6QNqUn

Dann wollte ich auf dem ESP einen TCP-Server aufmachen und von dort aus 
die Daten über mein WLAN an Labview senden, hat auch geklappt, aber mit 
schwankenden Zykluszeiten zwischen 250ms und bis zu 1800ms.
Mit solchen Taktzeiten kann ich natürlich nicht arbeiten, das verhunzt 
einem ja jedes Integral.
Code: http://pastebin.com/xCqj2hSQ

Also dachte ich mir, UDP ist eventuell besser für solche Aufgaben 
geeignet.
Doch damit kriege ich keinerlei Kommunikation hin und weiss auch nicht 
so recht wo es happert.
Kann auch sein, dass ich die Dokumentation von NodeMCU falsch verstehe
http://nodemcu.readthedocs.org/en/dev/en/modules/net/

Ich dachte mit ausserdem, eventuell kann ich meinen PC (bzw Labview) als 
Server laufen lassen und das ESP als Client.
Das hat auch nicht funktioniert.

Meine Frage also: Wo liegt mein Fehler? Eine so hohe Übertragungszeit 
kann doch eigentlich nicht sein, dass ich stellenweise nur auf 
17Byte/Sekunde komme.

Und falls UDP die Lösung ist: Soll ich den PC oder das ESP als Server 
konfigurieren? Und wie mache ich das?

Achja: Das Forum habe ich natürlich durchforstet, aber leider nichts 
passendes gefunden. Falls ich einen Thread übersehen haben sollte, dann 
immer her damit.

von Max D. (max_d)


Lesenswert?

Also ich würde den Daten einfach einen zeitstempel verpassen (kannst ja 
per ntp die genaue Zeit holen, oder einfach incremental durchgehen). 
Dann ist die Laufzeit egal.
Die hohen Laufzeiten bei WLAN sind nicht so ungewöhnlich, der Kram muss 
durch so viele Engpässe durch, da gibt es immer delay

von Peter S. (durze)


Lesenswert?

Ich hätte vielleicht noch erwähnen sollen:
Ich brauche die Daten in Echtzeit, denn ich möchte über das Gyroskop 
eine Neigung auslesen und diese live auf dem PC anzeigen.

von (prx) A. K. (prx)


Lesenswert?

Nur so aus Neugierde: Was ist ein ESP?

von Peter S. (durze)


Lesenswert?

A. K. schrieb:
> Nur so aus Neugierde: Was ist ein ESP?

Ein SoC (System on a Chip) mit WLAN.

www.mikrocontroller.net/articles/ESP8266

Edit:
Oder war diese Frage ein Aprilscherz?

: Bearbeitet durch User
von (prx) A. K. (prx)


Lesenswert?

Peter S. schrieb:
> Oder war diese Frage ein Aprilscherz?

Nö. Das wärs gewesen, wenn du damit aussersinnliche Wahrnehmung meinst. 
Ist einfach so, dass nicht jeder Leser jede DBA sofort passend übersetzt 
kriegt. Besonders, wenn sie verkürzt ist. ;-)

von Max M. (jens2001)


Lesenswert?

Peter S. schrieb:
> Und falls UDP die Lösung ist

Ich würd UDP benutzen. Erzeugt weniger Overhead als TCP.

> Soll ich den PC oder das ESP als Server
> konfigurieren?

Auf UNP-Protokollebene gibts erstmal keinen Server oder Client sondern 
nur einen Sender und einen Empfänger.

> Und wie mache ich das?

Keine Ahnung. Kenn ESP nicht.

von Reginald L. (Firma: HEGRO GmbH) (reggie)


Lesenswert?

Kenne deine Hardware nicht, aber ich übertrage daten in meiner anwendung 
per ethernet von einem stm32f4 auf den PC über udp. Da habe ich 
teilweise delays von 0.1ms

von Klaus (Gast)


Lesenswert?

Peter S. schrieb:
> Dann wollte ich auf dem ESP einen TCP-Server aufmachen und von dort aus
> die Daten über mein WLAN an Labview senden

"Server" und "Daten senden" geht bei mir nicht richtig zusammen. Ein 
Server ist vom Prinzip her passiv, tut gar nichts. Seine Aufgabe ist 
Fragen zu beantworten oder Aufträge auszuführen. Dabei sendet er 
natürlich Daten, aber nicht ungefragt. Das sieht man auch schön an 
vielen Beispiele, die in etwa so gehen

> sv=net.createServer(net.TCP, 30)
>
> sv:listen(80,function(c)
>   c:on("receive", function(c, pl)
>     print(pl)
>   end)
>   c:send("hello world")
> end)


Dein Labview sollte also der Server sein und der ESP der Client.

> Diese Daten umfassen - fertig formatiert - einen 17-stelligen String.

Ich bin zwar ein UDP-Fan, in diesem Fall ist das aber egal. Die 
Mindespaketlänge bei Ethernet ist wesentlich größer als die paar Byte 
und der sonstige TCP Overhead spielt auch keine wirkliche Rolle. Der 
Sendebuffer beim ESP ist IMHO 1400 Byte, da sind deine 17 Byte eher ein 
Rundungsfehler.

Dein Problem liegt ganz woanders. Nodemcu ist eine asynchrone 
Programmierumgebung. Da sehen Programme anders aus als in den üblichen 
synchronen Umgebungen. Wenn dort irgendetwas passiert, ist es durch ein 
Ereigniss getriggert. Das ist schon am Beispiel oben zu sehen. Das 
createServer führt diese Funktion aus, danach passiert nichts mehr. Erst 
mit dem listen wird ein callback beim receive registriert, der als 
Antwort auf eine Empfangene Nachricht mit "hello world" antwortet.

Wenn du ein solches Programm auf nodemcu startest, hast du gleich wieder 
einen Prompt, während "gleichzeitig" ein anderer Rechner sich sein 
"hello world" bei dir abholen kann. Diese System kann man leicht 
kaputmachen, wenn man den Prozessor in eine Endlosschleife zwingt. Auf 
der lua-Ebene gibt es eigentlich nur eine Funktion, mit der man das 
kann: tmr.delay()

> --out = string.format(%f;%f;%f, Gyro, AccX, AccZ)
> print(readdata())
> tmr.delay(10)     <-------------
> end

Die Docu sagt dazu:

> tmr.delay()
>
> Busyloops the processor for a specified number of microseconds.
>
> This is in general a bad idea, because nothing else gets to run,
> and the networking stack (and other things) can fall over as a result.
> The only time tmr.delay() may be appropriate to use is if dealing with
> a peripheral device which needs a (very) brief delay between commands,
> or similar. Use with caution!

Du mußt also mit einem Timer arbeiten. Wenn du aus dem ESP mit nodemcu 
wirklich etwas herausholen willst, solltest du dich mit asynchroner 
Programmierung auseinandersetzen, mindestens aber dies

http://www.esp8266.com/wiki/doku.php?id=nodemcu-unofficial-faq

lesen. Hier mal ein Einstieg in "Asynchronous programming"

http://www.i-programmer.info/programming/theory/6040-what-is-asynchronous-programming.html

MfG Klaus

von Fitzebutze (Gast)


Lesenswert?

Hi,

zeig doch mal ein Bild deines Moduls. Wenn du Pech hast, hast du eins 
mit einer richtig miesen Funkcharakteristik.
Manche der esp8266-Module tun besser, wenn die Sender-Empfänger-Distanz 
grösser ist. Oder man mit Daumendruck auf den Chip etwas Dämpfung 
reinbringt :-)

Aber abgesehen davon hast du auch dann mit allen Systemen, die auf dem 
esp-proprietären "Scheduler" (der keiner ist) keinen Spass, wenn du eine 
garantierte Latenzzeit willst. Fazit: Es funktioniert einfach nicht, 
auch wenn inzwischen die Software etwas stabiler läuft. Espressif ist 
nun der Meinung, sie kriegen das mit einem Dual-Core besser hin. Dabei 
würden sie besser mal ihre Software offenlegen.

Auch mit FreeRTOS und non-TCP hast du da nur bedingt Glück, wenn die 
Pakete aus irgend einem Grund (verworfenes Paket auf Link layer, also 
schlechte Radioverbindung) nicht ankommen. Dann hast du eine Menge 
Resends, die Verbindung wird langsam, bzw die Latenzen beliebig hoch.
Dazu kommt noch, dass die LWIP Integration in den meisten 
Firmware-Varianten ziemlich grottig gemacht ist, teils findet man da 
laufend malloc/free-Zyklen.
LWIP ist von der Performance her nicht sonderlich gut, und wenn das 
ganze System noch von hinten durch die Brust designt ist, taugt es 
gerade mal zum Basteln. Siehe auch 
Beitrag "Re: Möchte IoT-Erfahrung aufbauen".

D.h. für robuste Anwendungen nicht zu gebrauchen. Für die 
Funk-Gyro-Applikation würde ich mir die guten alten cc430-Uhren mal 
ansehen..

von Peter S. (durze)


Angehängte Dateien:

Lesenswert?

Danke für die Antworten!
Ich hatte letzte Woche leider keine Zeit zu antworten.


Max M. schrieb:
> Auf UNP-Protokollebene gibts erstmal keinen Server oder Client sondern
> nur einen Sender und einen Empfänger.

Das Problem das ich habe ist, dass wenn ich den PC als Empfäanger und 
das ESP als Acess-Point konfiguriere, der PC ja erst einmal connecten 
muss und dann das ESP zu der IP die dem PC zugeteilt wird (oder die ich 
ihm konfiguriere) senden muss. Das hat bisher irgendwie nicht 
funktioniert.
Ich muss dabei fast beschämend zugeben, dass ich in der Technikerschule 
Netzwerktechnik belegt habe aber trotzdem damit Probleme habe ._.


Reginald L. schrieb:
> ich übertrage daten in meiner anwendung
> per ethernet von einem stm32f4 auf den PC über udp. Da habe ich
> teilweise delays von 0.1ms

Ja eben, es muss ja so schnell gehen. Die Zykluszeit die ich erreiche 
(zwischen 200ms und 1,8s) ist ja lächerlich. Ich sehe meinen Fehler 
allerdings nicht.
>per Ethernet
heisst mit Kabel? Weil ich möchte ja Kabellos übertragen.


Klaus schrieb:
> Peter S. schrieb:
>> Dann wollte ich auf dem ESP einen TCP-Server aufmachen und von dort aus
>> die Daten über mein WLAN an Labview senden
>
> "Server" und "Daten senden" geht bei mir nicht richtig zusammen. Ein
> Server ist vom Prinzip her passiv, tut gar nichts. Seine Aufgabe ist
> Fragen zu beantworten oder Aufträge auszuführen. Dabei sendet er
> natürlich Daten, aber nicht ungefragt. Das sieht man auch schön an
> vielen Beispiele, die in etwa so gehen
>
>> sv=net.createServer(net.TCP, 30)
>>
>> sv:listen(80,function(c)
>>   c:on("receive", function(c, pl)
>>     print(pl)
>>   end)
>>   c:send("hello world")
>> end)
>
>
> Dein Labview sollte also der Server sein und der ESP der Client.

Bedeutet "ungefragt", dass ein Kommunikationspartner die Daten anfordern 
muss?
Also wäre es nicht möglich, in das LUA-Programm des ESPs sagen wir mal 
so etwas wie einen Timer/Alarm zu konfigurieren, der das Senden alle - 
sagen wir mal - 50ms veranlasst?



>> Diese Daten umfassen - fertig formatiert - einen 17-stelligen String.
>
> Ich bin zwar ein UDP-Fan, in diesem Fall ist das aber egal. Die
> Mindespaketlänge bei Ethernet ist wesentlich größer als die paar Byte
> und der sonstige TCP Overhead spielt auch keine wirkliche Rolle. Der
> Sendebuffer beim ESP ist IMHO 1400 Byte, da sind deine 17 Byte eher ein
> Rundungsfehler.
>
> Dein Problem liegt ganz woanders. Nodemcu ist eine asynchrone
> Programmierumgebung. Da sehen Programme anders aus als in den üblichen
> synchronen Umgebungen. Wenn dort irgendetwas passiert, ist es durch ein
> Ereigniss getriggert. Das ist schon am Beispiel oben zu sehen. Das
> createServer führt diese Funktion aus, danach passiert nichts mehr. Erst
> mit dem listen wird ein callback beim receive registriert, der als
> Antwort auf eine Empfangene Nachricht mit "hello world" antwortet.
>
> Wenn du ein solches Programm auf nodemcu startest, hast du gleich wieder
> einen Prompt, während "gleichzeitig" ein anderer Rechner sich sein
> "hello world" bei dir abholen kann. Diese System kann man leicht
> kaputmachen, wenn man den Prozessor in eine Endlosschleife zwingt. Auf
> der lua-Ebene gibt es eigentlich nur eine Funktion, mit der man das
> kann: tmr.delay()
>
>> --out = string.format(%f;%f;%f, Gyro, AccX, AccZ)
>> print(readdata())
>> tmr.delay(10)     <-------------
>> end
>
> Die Docu sagt dazu:
>
>> tmr.delay()
>>
>> Busyloops the processor for a specified number of microseconds.
>>
>> This is in general a bad idea, because nothing else gets to run,
>> and the networking stack (and other things) can fall over as a result.
>> The only time tmr.delay() may be appropriate to use is if dealing with
>> a peripheral device which needs a (very) brief delay between commands,
>> or similar. Use with caution!

das tmr.delay(10) ist noch ein Überbleibsel aus dem urspründlichem 
Programm, als ich die Daten seriell an den PC übertragen habe. Da musste 
ich diesen kleinen Delay einfügen, da mein ESP sonst nach wenigen 
Sekunden die Hufe hochgenommen hat. (Ich nehme mal an die Zykluszeit war 
zu gering, der TWI-Treiber hat sich dann wohl aufgehangen)


> Du mußt also mit einem Timer arbeiten. Wenn du aus dem ESP mit nodemcu
> wirklich etwas herausholen willst, solltest du dich mit asynchroner
> Programmierung auseinandersetzen, mindestens aber dies
>
> http://www.esp8266.com/wiki/doku.php?id=nodemcu-unofficial-faq
>
> lesen. Hier mal ein Einstieg in "Asynchronous programming"
>
> 
http://www.i-programmer.info/programming/theory/6040-what-is-asynchronous-programming.html
>
> MfG Klaus

Asynchrone Programmierung ist mir insofern geläufig, als dass ich damit 
ja die TWI Schnittstelle zum Sensor programmiert habe. Habe das auch 
schonmal in Assembler gemacht weil ich ursprünglich vor hatte, einen AVR 
zwischen Sensor und ESP zu schalten, bis ich auf die Möglichkeit 
gestoßen bin, dass man durch ein Firmware-Update ja auch das ESP 
TWI-fähig machen kann.
Aber danke trotzdem für die Quellen, ich werde es mir mal ansehen.


Fitzebutze schrieb:
> zeig doch mal ein Bild deines Moduls.
Bitteschön

Und zum Rest deinen Posts: Ja ich habe das ESP mittlerweile auch satt. 
Anfangs schien mir das eine coole Sachen, aber gibts mir dann doch 
entschieden zu viele Bugs bzw. läuft das ganze Teil für meinen Geschmack 
zu istabil

von Steven M. (8023)


Lesenswert?

Peter S. schrieb:
>> Dein Labview sollte also der Server sein und der ESP der Client.
>
> Bedeutet "ungefragt", dass ein Kommunikationspartner die Daten anfordern
> muss?
> Also wäre es nicht möglich, in das LUA-Programm des ESPs sagen wir mal
> so etwas wie einen Timer/Alarm zu konfigurieren, der das Senden alle -
> sagen wir mal - 50ms veranlasst?

das hängt von deinem programm ab...
du kannst bei UDP die ganze zeit blind daten senden... du musst halt nur 
dafür sorgen, das beim zielsystem ein serverdienst läuft, der auf dem 
zielport auch zuhört... der server muss bei UDP auch nicht mal 
antworten, wenn du das aus timinggründen nicht brauchst...

auf kofigurationsdaten zum beispiel kannst du ja ggf auf anwendungsebene 
antworten

von Fitzebutze (Gast)


Lesenswert?

Hi,

das blaue esp01 ist das mit der miesesten Funkcharakteristik, läuft 
definitiv nicht stabil auf Dauer. Das ESP201 z.B. ist elektrisch etwas 
robuster, aber würde wohl auch keinen EMV-Test bestehen.
Für ein bisschen mehr Geld gibts schon ein Linkit mit einem stabilen 
OpenWRT port...da ärgere ich mich mit dem esp-Mist nicht mehr rum.

von Klaus (Gast)


Lesenswert?

Peter S. schrieb:
> Asynchrone Programmierung ist mir insofern geläufig, als dass ich damit
> ja die TWI Schnittstelle zum Sensor programmiert habe.

Das reicht nicht, um das Konzept "Asynchrone Programmierung" wirklich 
verinnerlicht zu haben. Es geht um mehr, als nur eine Schnittstelle. Das 
ganze Programm besteht aus der event Loop, wobei dein Programmteil nur 
einige Callbacks darin sind. Andere sind der Netzwerkstack und 
Systemfunktionen. Eine der Konsequenzen ist, daß du z.B. aus einem Call 
von "send" sofort zurückkehrst, obwohl noch nichts gesendet wurde. Das 
könnte ja auch bei TCP zusammen mit der Quittung etwas dauern.

> Habe das auch schonmal in Assembler gemacht weil ich ...

Daß du ein solches System schon mal in Assembler gebaut hast, will ich 
mal bezweifeln, aber lies erst mal was.

Peter S. schrieb:
> Also wäre es nicht möglich, in das LUA-Programm des ESPs sagen wir mal
> so etwas wie einen Timer/Alarm zu konfigurieren, der das Senden alle -
> sagen wir mal - 50ms veranlasst?

Ja natürlich, und nur mit einem Timer und auf keinen Fall mit einem 
delay. Aber schon die Frage läßt mich etwas aufhorchen, Lua ist eine 
vollständige Programmiersprache und die Netzwerksocket Implementation 
scheint mir auch ziemlich komplett zu sein, da kann man alles 
programmieren.

Peter S. schrieb:
> das tmr.delay(10) ist noch ein Überbleibsel aus dem urspründlichem
> Programm, als ich die Daten seriell an den PC übertragen habe.

Hier deutet sich schon mal ein Missverständniss an: der ESP ist ein 
Knoten in einem Netzwerk, nicht der Ersatz für eine Direktverbindung. 
Auf einer darüberliegenden Ebene kann man dann eine Direktverbindung 
realisieren, wie es z.B. telnet macht.

Was Server ist und was Client hat etwas mit Netzwerkkonzepten und nicht 
mit Lua/ESP zu tun. Ein Server, ein Webserver, ein Datenbankserver .. 
ist still und lauscht, ob ihn einer etwas fragt, einen Auftrag gibt. Das 
ist das

Peter S. schrieb:
> sv:listen(80,function(c)

und dann wird auf das Ereigniss "receive" ein Callback registriert:

>   c:on("receive", function(c, pl) .....

Diese Programm wird nie etwas spontan senden, an wen auch? Es weiß ja 
nicht, wer sich mit ihm verbinden wird.

Peter S. schrieb:
> Das Problem das ich habe ist, dass wenn ich den PC als Empfäanger und
> das ESP als Acess-Point konfiguriere, ....

Warum, hast du kein WLan? Meine ESPs sind Stations in meinem WLan, genau 
wie die Laptops und die anderen Geräte. Und sie verbinden sich, wenn sie 
eingeschaltet werden. Wenn meine Frau sehen will, ob der Rolladen runter 
ist, ruft sie aus ihrem iPhone die URL des Wohnzimmerfensters auf. Wenn 
ich Daten von meiner Wetterstation haben will, muß ich nur seine URL in 
meinem Netzwerk kennen. Und meine Homeserver kennt die URL, mit der er 
die Rolläden runterfahren lassen kann.

Und zu deinem Hauptproblem: du brauchst einen "Labview Server". Der 
erwartet Daten von deinem Messrechner um sie auszuwerten. Das kann 
dieser spontan machen oder nach Aufforderung, so wie halt dein 
Messkonzept ist. Und selbstverständlich geht das so schnell, wie es dein 
WLan zuläßt. Wenn nicht gerade jemand Filme in HD in deinem WLan 
streamt, sind ein bis zweistellige Millisekunden sicher möglich. Ping 
doch mal deinen ESP an und schau auf die Pingzeiten.

Fitzebutze schrieb:
> aber würde wohl auch keinen EMV-Test bestehen.

Verschiede Module haben FCC. Da sind die EMV Regeln eher schärfer als 
bei uns. Das kann man wie CE auch nicht selbst erklären, da müssen 
Messungen eingereicht werden. Und das fälscht niemand, wenn er nicht wie 
Snowden enden will. Die Amis sind da robust. Vor allem, da es um 
ziemlich Stückzahlen geht, die Module kannst du auf Rolle für 
automatische Bestückung kaufen.

MfG Klaus

von Fitzebutze (Gast)


Lesenswert?

Klaus schrieb:
> Verschiede Module haben FCC. Da sind die EMV Regeln eher schärfer als
> bei uns. Das kann man wie CE auch nicht selbst erklären, da müssen
> Messungen eingereicht werden. Und das fälscht niemand, wenn er nicht wie
> Snowden enden will. Die Amis sind da robust. Vor allem, da es um
> ziemlich Stückzahlen geht, die Module kannst du auf Rolle für
> automatische Bestückung kaufen.

Wenn Du mir eine gültige FCC-Nummer für eines dieser Module hast, glaube 
ich Dir das. Bisher habe ich keinen gefunden, der das Ding industriell, 
geschweige für Consumer einsetzt.
Auf dem esp07 ist schlicht ein FCC-Logo aufgedruckt. Wenn sowas die FCC 
schaffen wollte, müsste es ja erst mal den EMV-Normen genügen.
Der Vergleich mit Snowden hinkt da ziemlich arg. Frag mal die Jungs am 
Zoll, was sie täglich gefälschte FCC-Nummern finden.

Ich habe bei einigen Modulen Messungen im Nahfeld gemacht, schon mit 
meinem Billig-Equipment brauche ich da gar nicht weiter hoffen.
Das Modul, was Peter einsetzt, ist extrem mies designt und 'ringt' eine 
Menge rum, wo es nicht sollte. Mit den "FCC"-Modulen ist wenigstens 
etwas Schirmung da, trotzdem ist der Digitalteil immer noch nicht 100% 
robust. Woran das liegt, kann einem aber nicht mal espressif selber 
sagen. Aber man kann sich ja mal das Chip-Layout auf zeptobars.ru 
anschauen. No more comment :-)

So nebenbei zum Test: Einfach mal Daumen auf die Antenne drücken und den 
Effekt auf die Ping-Zeiten beobachten. Wireshark ist auch 
aufschlussreich...

von Klaus (Gast)


Lesenswert?

Geh mal auf diese Seite und roll etwas runter auf die FCC Dokumente. Da 
findest du die Nummern. Und roll noch etwas runter und du findest die 
Modellbezeichnung auch auf dem Blech des ESP. Und sollte der "Notified 
Body Number 1177" (den man in der Fcc Datenbank nachschlagen kann) da 
Mist gemacht haben, kann er den Laden schnell zumachen.

http://www.esp8266.com/wiki/doku.php?id=esp8266-module-family

Fitzebutze schrieb:
> Der Vergleich mit Snowden hinkt da ziemlich arg. Frag mal die Jungs am
> Zoll, was sie täglich gefälschte FCC-Nummern finden.

Das kann doch der deutsche Zoll garnicht beurteilen, der amerikanische 
schon. Der hat direkten Zugriff auf die Fcc Datenbank. Und wenn ein 
amerikanischer Konkurent seine Anwälte losschickt, ist schnell die 
nächste Auslandsreise desjenigen, dessen Name auf den Falschen Papieren 
steht beendet. Schau mal wie es diesem und jenen VW-Mitarbeitern in 
Amerka ergeht, der mit den gefälschten Abgaswerten zu tun hat.

MfG Klaus

von Peter S. (durze)


Lesenswert?

Steven M. schrieb:
> du musst halt nur
> dafür sorgen, das beim zielsystem ein serverdienst läuft, der auf dem
> zielport auch zuhört...

Eben das habe ich bei UDP noch nicht auf die Reihe gekriegt, werde es 
aber nacher noch einmal probieren.


Fitzebutze schrieb:
> Hi,
>
> das blaue esp01 ist das mit der miesesten Funkcharakteristik, läuft
> definitiv nicht stabil auf Dauer. Das ESP201 z.B. ist elektrisch etwas
> robuster, aber würde wohl auch keinen EMV-Test bestehen.
> Für ein bisschen mehr Geld gibts schon ein Linkit mit einem stabilen
> OpenWRT port...da ärgere ich mich mit dem esp-Mist nicht mehr rum.

Ja ich habe auch den Eindruck, dass dieses Teil etwas instabil läuft.
Ich werde dieses Projekt aber wohl trotzdem damit abschliessen, danach 
aber die Finger davon lassen.


Klaus schrieb:
> Es geht um mehr, als nur eine Schnittstelle. Das
> ganze Programm besteht aus der event Loop, wobei dein Programmteil nur
> einige Callbacks darin sind. Andere sind der Netzwerkstack und
> Systemfunktionen. Eine der Konsequenzen ist, daß du z.B. aus einem Call
> von "send" sofort zurückkehrst, obwohl noch nichts gesendet wurde. Das
> könnte ja auch bei TCP zusammen mit der Quittung etwas dauern.

Dank deiner verlinkten Artikel habe ich jetzt eine grobe Vorstellung 
davon. Ich verstehe jetzt auch was du meinst, wobei ich folgendes nicht 
ganz verstehe:

In dem von mir im OP geposteten Programm (Auf das du dich ja beziehst) 
sende ich sozusagen "initial" einmal die Werte. Das Event "sent" sollte 
doch dann getriggert werden, wenn der Sendevorgang abgeschlossen ist, 
oder nicht?
So habe ich mir ja mehr oder weniger "einen Loop konstruiert" in dieser 
asynchronen Umgebung. Da er ja immer wieder das Event "sent" reinkriegt 
und als Eventhandler einfach erneut sendet.
Das funktioniert ja auch, bloß mit absurder Laufzeit.
Ich hoffe ich habe das was du mir vermitteln wolltest umrissen 
(korrigiere mich wenn dem nicht so ist), aber ich sehe wie gesagt den 
Fehler noch nicht
Ich werde es jetzt mal mit UDP probieren, vielleicht ist es ja 
tatsächlich die Quittierung und der größere Overhead, die unterm Strich 
diese lange Zykluszeit verursachen.



Klaus schrieb:
>> Habe das auch schonmal in Assembler gemacht weil ich ...
>
> Daß du ein solches System schon mal in Assembler gebaut hast, will ich
> mal bezweifeln, aber lies erst mal was.

Das war auf die TWI Schnittstelle bezogen.
Habe damals dazu auch einen Thread gemacht:
Beitrag "TWI Library - u.A. Probleme mit STOP"
Aber das nur der Vollständigkeit halber, natürlich könnte ich so etwas 
wie die akutelle Aufgabe nicht in Assembler umsetzten.



Klaus schrieb:
> Peter S. schrieb:
>> Also wäre es nicht möglich, in das LUA-Programm des ESPs sagen wir mal
>> so etwas wie einen Timer/Alarm zu konfigurieren, der das Senden alle -
>> sagen wir mal - 50ms veranlasst?
>
> Ja natürlich, und nur mit einem Timer und auf keinen Fall mit einem
> delay. Aber schon die Frage läßt mich etwas aufhorchen, Lua ist eine
> vollständige Programmiersprache und die Netzwerksocket Implementation
> scheint mir auch ziemlich komplett zu sein, da kann man alles
> programmieren.

Habe ich das nun richtig verstanden:
Für meine Anwendung empfiehlst du mir, einen Timer ein zu richten, der 
ein Alarm-Event auslöst.
Als Handler dieses Events konfiguriere ich die "send" Funktion (Anstatt, 
wie oben beschrieben, das erneute Senden auf das "sent"-Event zu 
triggern)?
So könnte ich natürlich die Zykluszeit über den Timer selbst bestimmen, 
aber was ist, wenn das abarbeiten der Callbackfuntion(?) tatsächlich so 
lange dauert?


Klaus schrieb:
> Hier deutet sich schon mal ein Missverständniss an: der ESP ist ein
> Knoten in einem Netzwerk, nicht der Ersatz für eine Direktverbindung.
> Auf einer darüberliegenden Ebene kann man dann eine Direktverbindung
> realisieren, wie es z.B. telnet macht.

Ich habe es ja bloß als TWI/seriell-Bridge missbraucht, um zu prüfen, ob 
das Auslesen der Daten vom Sensor tatsächlich funktioniert.



Klaus schrieb:
> Peter S. schrieb:
>> Das Problem das ich habe ist, dass wenn ich den PC als Empfäanger und
>> das ESP als Acess-Point konfiguriere, ....
>
> Warum, hast du kein WLan?

Natürlich, aber das fertige Teil möchte ich mit in den Sportverein 
nehmen und dort findet es dann nämlich sporadisch Anwendung, dh es ist 
in keinem WLAN sondern ich verbinde jedesmal ausschließlich ESP und PC 
miteinander.
Das musste ich auch bereits hier ausdiskutieren:
Beitrag "ESP8266 will nicht mit PC-Hotspot verbinden"

: Bearbeitet durch User
von Bastian W. (jackfrost)


Angehängte Dateien:

Lesenswert?

Ich hab mim ESP8266 einen Test in meinem WLAN/LAN gemacht.

Auf dem ESP läuft ein Seriell zu Netzwerk Server. Die Seriellen Daten 
gehen vom ESP über das WLAN und über 3 Switche zum PC und von dorten 
über einen FTDI zum STK 500.

Ich habe über einen Attiny2313 jede Sekunde einen String von 11 Bytes 
gesendet und mit dem Saleae die Zeiten vom Senden bis zum Empfangen 
gemessen.

Die Route war also :

Attiny -> ESP -> WLAN -> 3x Switch -> PC -> FTDI -> STK500

Da ich den Attiny nur mit 8 MHz hab laufen lassen, waren maximal 38400 
Baud drinnen.

Die Firmware auf dem ESP ist so Programmiert das die Daten vom 
Seriellenport nur gesendet werden wenn sie komplett empfangen wurden.

Bei 11 Bytes kommen die Daten 10 ms später an. Bei 110 Bytes sind es 
dann 46 ms.

Das ganze lief über Telnet und mit TCP.

Gruß JackFrost

: Bearbeitet durch User
von Fitzebutze (Gast)


Lesenswert?

> Geh mal auf diese Seite und roll etwas runter auf die FCC Dokumente. Da
> findest du die Nummern. Und roll noch etwas runter und du findest die
> Modellbezeichnung auch auf dem Blech des ESP. Und sollte der "Notified
> Body Number 1177" (den man in der Fcc Datenbank nachschlagen kann) da
> Mist gemacht haben, kann er den Laden schnell zumachen.
>

Die Seite kenne ich. Genau da liest du auch, dass div. Module, z.B. das 
ESP07 keine FCC-Zertifizierung haben. Oh, und das trotz aufgedrucktem 
FCC? Leider gehört die Nr. auch aufs Chassis...
>
> Das kann doch der deutsche Zoll garnicht beurteilen, der amerikanische
> schon. Der hat direkten Zugriff auf die Fcc Datenbank. Und wenn ein
>

Ehm. Jedermann hat Zugriff auf die FCC-Datenbank...
Ich weiss zumindest von einer Alibaba-Lieferung von Modulen, die ihr 
Ziel nicht erreicht hat. Dreimal darfste raten, warum.

Mag sein, dass espressif nun mit dem Wroom endlich durchgekommen ist, 
aber ich frage mich immer noch wie, so richtig glauben will das keiner.
Es wird auch sicher noch 1-2 Chip-Revisionen brauchen, bis die grossen 
Distis das Ding in ihr Programm aufnehmen.

von Klaus (Gast)


Lesenswert?

Meine Filetransferfunktion sieht so aus
1
function SendFile(Filename, client)
2
    Size = filesize(Filename)
3
    if (Size) then -- file exists and has a size > 0
4
        if Filename:find('.pdf') then
5
            buf = 'HTTP/1.1 200 OK\r\nContent-Type: application/pdf\r\n'
6
            .. 'Content-Length: ' .. Size .. '\r\n\r\n'  
7
        elseif Filename:find('.html') then
8
            buf = 'HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n'
9
        elseif Filename:find('.lua') then
10
            buf = 'HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\n\r\n'   
11
        end  -- what if nothing matches ??
12
        file.open(Filename, 'r')
13
        print('open file "'..Filename..'"')
14
        client:send(buf, function(sent)
15
            print('callback from :send')
16
            local buf = file.read(1200)
17
            if (buf) then
18
                client:send(buf)
19
            else
20
                file.close()
21
                print('close file "'..Filename..'"')
22
                client:close()
23
                collectgarbage()
24
            end
25
        end)
26
    else
27
        print('file "' .. Filename .. '" not found')
28
        local buf = 'HTTP/1.1 404 Not Found\r\n\r\n'   
29
        client:send(buf)
30
        client:close();
31
        collectgarbage();
32
    end
33
end
Die Debugprints hab ich mal drin gelassen. Ich messe mit wget über 
50kByte pro Sekunde.

Ich hab aber auch zum Testen via UDP alle 10ms eine fortlaufende Nummer 
an meinen PC geschickt und mit netcat ausgegeben. Da hat keine Nummer 
gefehlt. Lauffähigen Code hab ich nicht mehr parat, ist als Test im 
Bitbucket gelandet.

MfG Klaus

von Klaus (Gast)


Lesenswert?

Fitzebutze schrieb:
> bis die grossen
> Distis das Ding in ihr Programm aufnehmen.

Das "Ding" wird, wie die meißten chinesischen Chips, da gar nicht 
auftauchen, dafür aber in irgenwelchen Gadgets beim Discounter deines 
Vertrauens. Die ersten sind IMHO in WLan gesteuerten Steckdosenleisten 
(Made in China) aufgetaucht.

Der gnadenlos billige Direktvertrieb über Alibaba, Aliexpress und 
inzwischen auch ebay ist dabei, den Distries das Wasser abzugraben.

MfG Klaus

von Peter S. (durze)


Angehängte Dateien:

Lesenswert?

Bastian W. schrieb:
> Bei 11 Bytes kommen die Daten 10 ms später an. Bei 110 Bytes sind es
> dann 46 ms.

Danke für die Info, anderswo scheint es ja zu funktionieren, dann sollte 
ich das auch hinbekommen.

Klaus schrieb:
> Meine Filetransferfunktion sieht so aus

Danke auch für dieses Beispiel, ich werde daraus nur nicht schlau - oder 
besser gesagt, ich wüsste nicht, welche dieser Funktionen mir weiter 
helfen könnte.

Ich habe noch ein wenig recherchiert und das hier gefunden:
http://thoughtaphone.blogspot.de/2015/09/nodemcu-udp-server.html
"UDP servers in NodeMCU seem to be limited to one client at a time:
you create a server, and bind the receive event to get datagrams sent to 
it. When you call send on the server socket, it sends the data to the 
last client to send something to the server. If you create a client UDP 
connection, the server will stop receiving datagrams, and the client 
won't receive any either. The client will be able to send datagrams 
though. I guess this is a bug."

Das erklärt auch, weshalb ich bisher mit UDP nicht mal ansatzweise etwas 
gebacken bekommen habe.
Nun wollte ich Schritt für Schritt einen UDP-Server erstellen und die 
Connection unter Berücksichtigung dessen, was er unter dem Link 
geschrieben hat aufbauen, aber es scheitert schon ganz am Anfang.
Ich bin so langsam am verzweifeln.

Habe jetz folgenden Code aufs ESP geflasht:
1
print("ESP8266 Server")
2
wifi.setmode(wifi.STATIONAP);
3
wifi.ap.config({ssid="test",pwd="12345678"});
4
print("Server IP Address:",wifi.ap.getip())
5
6
7
8
  server = net.createServer(net.UDP, 30)
9
10
  server:listen(61557, function (c)
11
  
12
  c:on("receive", function(c, data)
13
        print(data)
14
    end)
15
end)

Und habe das Labview UDP-Send-Beispielpgrogram geöffnet (siehe Bild).
Aber nicht einmal das funktioniert!
Ich kriege vom ESP keinerlei Meldung über empfangene Daten.
Einen Ping habe ich von 1 bis 2 ms.

Hat jemand eine Idee woran das liegen könnte?


Mein Plan war, sobald dass die Daten ankommen, ich eine "send" funktion 
in die "receive"-Callbackfunction einbaue, sodass ich dann von LabView 
aus, alle 50ms den Befehl gebe, neue Daten senden zu lassen.

: Bearbeitet durch User
von Klaus (Gast)


Lesenswert?

Peter S. schrieb:
> server = net.createServer(net.UDP, 30)
>
>   server:listen(61557, function (c)
>
>   c:on("receive", function(c, data)
>         print(data)
>     end)
> end)

Bei mir sieht das etwas anders aus:
1
srv=net.createServer(net.UDP)
2
3
srv:on("receive", function(srv, pl)
4
   print(pl)
5
   -- srv:send("xxxxx")
6
end)
7
8
srv:listen(PORT)

Die :on("receive", .. Funktion registriert einen callback und darf daher 
nicht selbst ein callback sein.

Ich hab das zwar nicht als AP sondern nur als Station getestet. Ich 
müßte sonst meinen Rechner umkonfigurieren. Aber mit
1
nc -u ESP-IP ESP-PORT
kommt zeilenweise aus der seriellen des ESP, was am Rechner eingegeben 
wird. Versuch doch erstmal in deinem Wlan mit dem ESP zu reden, bevor du 
jetzt anfängst auch noch einen AP mit ihm zu realisieren. Ich würd auch 
nicht mit Labview anfangen, sondern mit simplen Tools wie nc.

Peter S. schrieb:
> Mein Plan war, sobald dass die Daten ankommen, ich eine "send" funktion
> in die "receive"-Callbackfunction einbaue, sodass ich dann von LabView
> aus, alle 50ms den Befehl gebe, neue Daten senden zu lassen.

Genau so gehts, das oben auskommentierte send() aktivieren. Ich hab auch 
das mal probiert: ein µC schreibt über die serielle Messwerte in 
Variable vom ESP. Der PC holt sie mit UDP bei Bedarf ab.

MfG Klaus

von Peter S. (durze)


Lesenswert?

Klaus schrieb:
> Versuch doch erstmal in deinem WLAN mit dem ESP zu reden, bevor du
> jetzt anfängst auch noch einen AP mit ihm zu realisieren.

Das macht doch keinen nennenswerten Unterschied. Ich muss so bloß jedes 
mal zum Testen von meinem WLAN disconnecten und zum ESP connecten, aber 
der Umstand hält sich in Grenzen.


Klaus schrieb:
> Die :on("receive", .. Funktion registriert einen callback und darf daher
> nicht selbst ein callback sein.

Das war ein wichtiger Tipp für mich. Habe jetzt mal folgendes gemacht:
1
server = net.createServer(net.UDP, 30)
2
3
4
server:on("receive", function(server, data)
5
        print(data)
6
    end)
7
8
server:listen(61557)

Und in verschiedenen Taktraten mal an diesen Port Strings geschickt, die 
kamen wunderbar an.


Dann wollte ich das Senden implementieren:
1
server = net.createServer(net.UDP, 30)
2
3
4
server:on("receive", function(server, data)
5
        print(data)
6
  server:send("hello world")
7
    end)
8
9
server:listen(61557)

Habe versucht im LabView zu lauschen, aber konnte nichts empfangen, bin 
mir auch nicht ganz sicher, ob das in LabView so geht wie ich mir das 
vorstelle.
Klaus schrieb:
> Ich würd auch
> nicht mit Labview anfangen, sondern mit simplen Tools wie nc.
Habe allerdings jetzt schon ein knappes Jahr LabView-Unterricht an der 
Techniker Schule genossen, daher finde ich mich in dem Programm intuitiv 
schon ganz gut zurecht, also das kriege ich schon noch hin.

Jetzt dachte ich mir, falls das Senden klappt, ich aber bloß Probleme 
hab die Signale raus zu fischen, dann müsste das ESP mir ja das mit 
callbacks "quittieren" können.

Also:
1
server = net.createServer(net.UDP, 30)
2
3
4
server:on("receive", function(server, data)
5
        print(data)
6
  server:send("hello world")
7
    end)
8
9
server:on("sent", print("gesendet"))
10
11
server:listen(61557)

Aber im seriellen Monitor kamen weiterhin bloß die "data"-prints und 
keine "gesendet" Meldung.


Bin noch auf folgendes gestoßen:
http://www.areresearch.net/2015/09/generic-udp-proxy-for-nodemcu-esp8266.html
und:
http://de.slideshare.net/geekscape/nodemcu-esp8266-workshop-1
[Slide 32 und 33]

Das brachte mich auf die Idee, dass vielleicht, obwohl in der NodeMcu 
documentation steht:
>net.server:send()
>UDP server only: Sends data to remote peer.
Es trotzdem nötig wäre, zum Senden von UDP Messages eine (oder einen?) 
Socket auf zu machen.

Nächster Anlauf:
1
socket=net.createConnection(net.UDP, 0)
2
server = net.createServer(net.UDP, 30)
3
4
server:on("receive", function(server, data)
5
       print(data)
6
       -- server:send("hello world")
7
       socket:connect(61558, "192.168.4.2")
8
       socket:send("hello world")
9
    end)
10
11
    socket:on("connection", function(socket)
12
        print("Verbindung zum PC hergestellt")
13
        end)
14
        
15
    cu:on("sent", print("sent"))
16
17
server:listen(61557)

Aber auch hier wartete Ich vergebens auf die Debug-Prints vom Socket.

Tl;dr:
Empfangen klappt, Senden nicht.


Wo liegt also der Denkfehler? Warum sendet das ESP nicht, obwohl es in 
der Callbackfunction von Receive dazu aufgefordert wird?

von Klaus (Gast)


Lesenswert?

Peter S. schrieb:
> Klaus schrieb:
>> Versuch doch erstmal in deinem WLAN mit dem ESP zu reden, bevor du
>> jetzt anfängst auch noch einen AP mit ihm zu realisieren.
>
> Das macht doch keinen nennenswerten Unterschied. Ich muss so bloß jedes
> mal zum Testen von meinem WLAN disconnecten und zum ESP connecten, aber
> der Umstand hält sich in Grenzen.

Du mußt wissen, was du tust. Mir wäre es zu blöd, meinen Rechner vom 
Netz zu trennen, um einen längeren Test zu machen. Ich wollte eigentlich 
nur sagen, daß ich die gezeigten Programme nur im Station-Mode getestet 
habe. Ich verwende außerdem meisst feste IP-Adressen in meinem Netz, da 
behalte ich besser den Überblick.

Folgender Code funktioniert einwandfrei:
1
PORT = "1234"
2
wifi.setmode(wifi.STATION)
3
wifi.sta.setip({ip="xx.xx.xx.xx",
4
    netmask="255.255.255.0",
5
    gateway="0.0.0.0"})
6
wifi.sta.config("xxxxx","xxxxx")
7
print(wifi.sta.getip())
8
srv=net.createServer(net.UDP)
9
-- ready
10
srv:on("receive", function(srv, pl)
11
  print(pl)
12
  srv:send("echo:"..pl)
13
end)
14
15
srv:listen(PORT)

das liefert auf dem PC
1
$ nc -u xx.xx.xx.xx 1234
2
1
3
echo:1
4
2
5
echo:2
6
3
7
echo:3
8
4
9
echo:4
10
5
11
echo:5
12
gdahdajhdgd
13
echo:gdahdajhdgd

Peter S. schrieb:
> Empfangen klappt, Senden nicht.
>
> Wo liegt also der Denkfehler? Warum sendet das ESP nicht, obwohl es in
> der Callbackfunction von Receive dazu aufgefordert wird?

Woher weiß du, das Senden nicht klappt? Du weißt nur, daß in deinem 
Labview nicht das ankommt, was du erwartest. Ich hab es getestet, der 
ESP sendet. Wenn es mit netcat funktioniert, brauch ich wireshark nicht 
extra anzuwerfen.
1
server:on("receive", function(server, data)
2
       print(data)
3
       -- server:send("hello world")
4
       socket:connect(61558, "192.168.4.2")
5
       socket:send("hello world")
6
    end)

Was bringt dich zu der Annahme, das könnte klappen? Du kennst doch den 
Port des PCs nicht, von dem der sendet. Der ursprüngliche Code war schon 
ok, suche lieber, wo die Datagramme vom ESP versacken.

MfG Klaus

von Falk B. (falk)


Lesenswert?

TCP, UDP und ESP
SoC, MCU is auch OK

;-)

von Peter S. (durze)


Lesenswert?

Es geht!

Klaus schrieb:
> Woher weiß du, das Senden nicht klappt? Du weißt nur, daß in deinem
> Labview nicht das ankommt, was du erwartest.

Ich bildete mir ein, das über die "sent"-Callbackfunction fest zu 
stellen.

Aber ist auch egal, es funktioniert jetzt auf jeden Fall endlich so wie 
ich mir das von Anfang an vorstellte.
Laufe jetzt mit einer Zykluszeit von 50ms, könnte wahrscheinlich auch 
noch weiter runter.

Vielen dank euch Allen für eure Hilfe und vor allem dir, Klaus, alleine 
wäre ich vermutlich nicht drauf gekommen.

von Tester (Gast)


Lesenswert?

Hi,

ich möchte genau das Gleiche machen, einen Messwert vom ESP8266 via UDP 
an LabView senden.
Gibt's inzwischen eine Lösung? Code ESP8266, Code LabView?

VG

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.