Forum: Mikrocontroller und Digitale Elektronik ESP8266 WLAN


von Hali H. (ratendix)


Lesenswert?

Hallo,
ich habe eine Frage wegen dem WLAN-Modul ESP8266.
Es funktioniert soweit recht gut, ich kann auch Daten über ein serielles 
Terminal an einen eingerichteten Server senden und mir dort korrekt 
anzeigen lassen.
Jedoch bekomm ich nach einer gewissen Zeit immer die Meldung "Error 
Unlink" und die TCP Verbindung wird getrennt.
Woran könnte es liegen? Irgendein Adresskonflikt, Portkonflikt?
Ich hab vom Laptop aus ein WLAN-Hotspot eingerichtet und dieser dient 
als AP für den ESP.
Strom bekommt der ESP auch genügend von extern. Somit ist dieser gern 
gemachte Fehler ausgeschlossen.

Vielen Dank.

von Hali H. (ratendix)


Lesenswert?

Vermutlich habe ich den Fehler schon gefunden...
anscheinend kommt der ESP nicht mit TCP klar, mit dem einfachen UDP 
gehts aber bisher ohne "Unlink"

von Stefan F. (Gast)


Lesenswert?

Ich glaube, das ist kein Fehler sondern Absicht. Das WLAN Modul trennt 
Verbindungen nach einer gewissen Zeit ohne Aktivität.

von Hali H. (ratendix)


Lesenswert?

Aber schon nach einer Minute oder so? Das fand ich merkwürdig...

von dunno.. (Gast)


Lesenswert?

dass bei udp kein unlink kommt, könnte auch daran liegen, dass udp 
verbindungslos ist? ;)  - es gibt nichts zum unlinken.

von Hali H. (ratendix)


Lesenswert?

dunno.. schrieb:
> dass bei udp kein unlink kommt, könnte auch daran liegen, dass udp
> verbindungslos ist? ;)  - es gibt nichts zum unlinken.

Hehe, da ist was dran ;)
ne andere Frage: Der ESP geht jetzt soweit, nun will ich das aber nicht 
von der Konsole aus steuern sondern das ganze über ein Controller. Hab 
ein STM32 Board von Nucleo. Habe aktuell Probleme, die At Commandos zu 
versenden. Also über UART versendet kann ich die Befehle am seriellen 
Monitor am PC sehen, aber wenn ich die Kommandos über denselben 
UART-Port an den ESP schicke, bekomme ich keine Antworten...
Denke, dass evtl noch paar Einstellungen am Stm board nicht passen. Das 
Handbuch ist nicht die große Hilfe...
Muss man grundsätzlich, wenn man über Uart Daten verschickt, diese 
getrennt von dem Programmierport (Usb) machen oder kann ich das über 
dieselben Pins laufen lassen ?
Also ist was bei externen Uart-Verbindungen zu beachten?

Danke!

von Udo (Gast)


Lesenswert?

Hast du vom Controller am Ende des Befehls
CR und LF gesendet ? Sonst geht es nicht.

von Hali H. (ratendix)


Lesenswert?

Udo schrieb:
> Hast du vom Controller am Ende des Befehls
> CR und LF gesendet ? Sonst geht es nicht.

\r\n, ja habe ich:) man kann ja an der blauen led vom esp erkennen ob er 
was macht.
bei der konsoleneingabe blinkt es jedes mal auf wenn man ihm ein 
Kommando gibt.
vom controller aus ist nur die rote PowerLed an und bei blau tut sich 
leider nichts...

von Udo (Gast)


Lesenswert?

TX, RX richtig verbunden ? Gedreht ?
Bisschen schwer ohne Schaltplan.

von Franz Schlüter (Gast)


Lesenswert?

Hast Du Dir die Signale mal mit einem Oszi angeguckt?
Baudrate passt?

von Harry L. (mysth)


Lesenswert?

Das Laptop-WLAN geht in den Sleep-Mode.
Warum verbindest du den ESP nicht direkt mit deinem Netz/WLAN-Router?

von Hali H. (ratendix)


Lesenswert?

Udo schrieb:
> TX, RX richtig verbunden ? Gedreht ?
> Bisschen schwer ohne Schaltplan.

Also normal sollte ja TX vom Controller mit RX vom ESP und entsprechend 
RX mit TX verbunden sein. Aber auch TX->TX und RX->RX hat nicht 
geklappt.
Baudrate muss passen (9600) sonst würde ich die serielle Ausgabe der 
Kommandos nicht auf dem Terminal sehen?
Ich versuch mal einen zweiten USART-Port nur für den ESP zu nehmen.
Hier die USART Konfiguration:
1
static void MX_USART2_UART_Init(void)
2
{
3
4
  huart2.Instance = USART2;
5
  huart2.Init.BaudRate = 9600;
6
  huart2.Init.WordLength = UART_WORDLENGTH_8B;
7
  huart2.Init.StopBits = UART_STOPBITS_1;
8
  huart2.Init.Parity = UART_PARITY_NONE;
9
  huart2.Init.Mode = UART_MODE_TX_RX;
10
  huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
11
  huart2.Init.OverSampling = UART_OVERSAMPLING_16;
12
  if (HAL_UART_Init(&huart2) != HAL_OK)
13
  {
14
    Error_Handler();
15
  }
16
17
}

Hier meine seriellen Ausgaben:
1
char esp8266_CWMODE3[]  = "AT+CWMODE=3\r\n";
2
char esp_Connect[] = "AT+CIPSTART=\"UDP\",\"IP-Adresse\",Port\r\n";
3
char esp_sendData[] = "AT+CIPSEND=4\r\n";
4
char esp_Data[] = "abcd\r\n";
5
char esp8266_reset[]    = "AT+RST\r\n";
6
7
send_ATCommand(esp8266_reset,2000);
8
  HAL_Delay(1000);
9
  send_ATCommand(esp_Connect,2000);
10
  HAL_Delay(1000);
11
  send_ATCommand(esp_sendData,2000);
12
  HAL_Delay(1000);
13
  send_ATCommand(esp_Data,2000);
14
15
static void send_ATCommand(char *cmd, uint32_t esp_timeout)
16
{
17
  if(esp_timeout > 2000)
18
    esp_timeout = 2000;
19
   
20
  uint16_t cmd_len = strlen(cmd);
21
 
22
  HAL_UART_Transmit(&huart2, (uint8_t *)cmd, cmd_len, esp_timeout);
23
}

Vielleicht sieht einer noch ein Fehler

: Bearbeitet durch User
von Hali H. (ratendix)


Lesenswert?

Update: mit einem eigenen USART-Port blinkt die blaue LED mehrmals nach 
Ausführen des Programms. Schon mal ein gutes Zeichen. Jedoch weiterhin 
keine Ausgabe am Server.
Und jetzt hab ich nicht mehr die serielle Konstrolle am Terminal, weil 
der USART-Port nicht mit dem USB-Hub verbunden ist.
Anscheinend ist der USB-USART auch nur für USB bestimmt.

von Hali H. (ratendix)


Lesenswert?

Es läuft! ein anderen USART-Port zu nehmen war die Lösung!
Wie viele Charakter kann der ESP auf einmal senden? Glaub waren 1024 
oder?
Die Spezifikationen vom ESP muss man sich immer in Foren 
zusammenlesen...

von Michael U. (amiga)


Lesenswert?

Hallo,

ich weiß nicht, ob die AT-Software da eingreift, es werden sonst pro 
Client 2 Buffer a 2290 Byte reserviert, wie auch immer diese Größe 
zustande kommt.

Im Notfall ausprobieren. Eigentlich wartet die Routine, wenn man Daten 
zum Client schickt und noch kein Platz im Buffer ist. Allerdings hat mir 
das damals ein paar nette Stack-Traces beschert...

Moglich, daß das Problem im aktuellen SDK längst behoben ist, die 
AT-Software nutze ich nicht, programmiere lieber selber. ;)

Gruß aus Berlin
Michael

von Stefan F. (Gast)


Lesenswert?

> Wie viele Charakter kann der ESP auf einmal senden?

Hängt von der Firmware Version ab. Mit maximal 1024 Bytes bist du auf 
der sicheren Seite, denn das kann jede Firmware Version.

Mit dem Befehl AT+CIPSTO=10 kannst du den Timeout für die automatische 
Trennung der Verbindung auf 10 Sekunden einstellen. 0=kein Timeout.

von Hali H. (ratendix)


Lesenswert?

Stefan U. schrieb:
>> Wie viele Charakter kann der ESP auf einmal senden?
>
> Hängt von der Firmware Version ab. Mit maximal 1024 Bytes bist du auf
> der sicheren Seite, denn das kann jede Firmware Version.
>
> Mit dem Befehl AT+CIPSTO=10 kannst du den Timeout für die automatische
> Trennung der Verbindung auf 10 Sekunden einstellen. 0=kein Timeout.

Super danke!
Mal ein Frage zu C: Wenn ich ein int-Array habe und möchte das über den 
ESP versenden, muss ich das Array in character umwandeln.
Das klappt mit char array[j] = int array[j] + '0' ja leider nur bis zu 
Zahl 9..
danach gibt er mir die ASCII zeichen aus.
Und mit dieser itoa funktion, die man so findet gehts auch nicht.
Hat da jemand ne Idee?

von Stefan F. (Gast)


Lesenswert?

Itoa ist aber genau dafür da. Oder utoa, falls es unsigned int Variablen 
sind.

von Hali H. (ratendix)


Lesenswert?

dann muss ich da weiter rumexperimentieren...

ich hatte so eine ausgabe: 
0123456789111111122222223333333344444444555556666666 usw
für ein uint16_t array gefüllt von 0 bis 100.

von Stefan F. (Gast)


Lesenswert?

Dir ist aber schon klar, dass die Zahl 10 ein Byte belegt aber zwei 
Zeichen? Da ist es mit einer so simplen for-Schleife nicht getan.

Du brauchst einen größeren Puffer in den die größten Zahlen zusammen 
rein passen, die zu erwartest. Und du musst die Längen beachten.

Wenn z.B. die erste Zahl 120 ist, dann darfst du die nächste Zahl nicht 
nach puffer[1] schreiben, sondern sie muss bei puffer[3] abgelegt 
werden. Sonst überschreibst du ja zwei Ziffern von der ersten Zahl.

Aber welchen Sinn ergibt es, einfach eine Reihe Zahlen mit variabler 
Länge zu verketten? Wie willst du die am anderen Ende der 
Übertragungsstrecke wieder zerlegen?

14354362346436436236345

Woher soll der Empfänger wissen, wie viele Zahlen das sind, und wo 
welche beginnt? Mach Dir mal Gedanken über ein Übertragungsprotokoll.

Mit snprintf() kommst du eventuell einfacher ans Ziel, allerdings belegt 
snprintf() ziemlich viel Flash Speicher.

von 8266_unbelesen (Gast)


Lesenswert?

Hali H. schrieb:
> muss ich das Array in character umwandeln.

Warum sollte man keine binäre Daten senden können/dürfen?

Ich dachte mit dem Teil kann man UDP und TCP Verbindungen
aufbauen, dann muss doch auch ein Binärblock sendbar/
empfangbar sein.

von Michael U. (amiga)


Lesenswert?

Hallo,

Du kannst mit dem ESP schicken, was Du willst.
char ist hier letztlich nur eine Vereinbarung für int8_t.
Daß es signed ist, interessiert auch nur den, der es interpretiert.
Gesendet werden eben die Werte von 0x00 bis 0xFF.
Natürlich kann man uint16_t mit var & 0xFF und (var >> 8) & 0xff in 
seine beiden Bytes zerlegen und (notfalls als char gecastet) 
rausschicken.
Muß man dann "drüben" wieder zusammenbauen.
Es gibt für die ESP-Seite keine unzulässigen Byte-Werte und es wird von 
ESP-Seite auch nicht als String mit 0x00 am Ende behandelt.

Ich habe aber, wie schon erwöhnt, mit der AT-Software nichts gemacht, 
wenn da mehr als nötig intern gewandelt wird.
Es war letztlich einfacher, sich nur mit den Eigenarten des ESP 
rumzuärgern, außerden ist vieles mit 40k Ram eben besser zu handhaben 
als mit z.B. den 2k des Mega328.

Gruß aus Berlin
Michael

von Stefan F. (Gast)


Lesenswert?

Die AT Firmware kann wirklich beliebige Rohdaten senden. Man ist da 
nicht auf ASCII Zeichen (oder so) eingeschränkt. Deswegen muss man vor 
dem Senden eines Paketes auch immer schön angeben, wie viele Bytes es 
denn sein werden.

von Hali H. (ratendix)


Lesenswert?

Stefan U. schrieb:
> Die AT Firmware kann wirklich beliebige Rohdaten senden. Man ist da
> nicht auf ASCII Zeichen (oder so) eingeschränkt. Deswegen muss man vor
> dem Senden eines Paketes auch immer schön angeben, wie viele Bytes es
> denn sein werden.

Alles klar, arbeite zur Zeit mit sprintf() und bin erstmal soweit 
zufrieden.
Allerding hab ich ein anderes Problem: Der ESP sendet die Daten zu 
langsam.
Dazu mein derzeitiger Stand: Baudrate ist auf 115200 eingestellt.
Ich vergleiche die serielle Ausgabe am Terminal mit der Ausgabe am 
Server.
Wenn ich die delays zwischen den einzelnen Sendebefehle meinetwegen auf 
50ms stelle, fängt der Datenverlust beim WLAN schon an.
Ich sende 10 mal hintereinander dieselben 10 Arraywerte und bei der 
seriellen Ausgabe kommen die Werte immer vollständig und korrekt an! 
Beim ESP fehlt schon eine Ausgabe und manchmal kommen die falschen 
Zeichen.
Das mit den falschen Zeichen wird an UDP liegen, weil ich aktuell vom 
Controller aus TCP nicht zum laufen gebracht habe.

Kann man mit dem ESP überhaupt Daten in Echtzeit senden? Habe das Gefühl 
dass er große Delays zwischen dem Senden brauch....

von 8266_unbelesen (Gast)


Lesenswert?

Stefan U. schrieb:
> Die AT Firmware kann wirklich beliebige Rohdaten senden.

Wenn das so ist dann frage ich mich doch warum darüber philosophiert
wird wie man Integer Werte in ASCII umsetzt.

Hali H. schrieb:
> Mal ein Frage zu C: Wenn ich ein int-Array habe und möchte das über den
> ESP versenden, muss ich das Array in character umwandeln.

Und stefanus antwortet:

Stefan U. schrieb:
> Itoa ist aber genau dafür da. Oder utoa, falls es unsigned int Variablen
> sind.

... ohne offensichtlich zu wissen dass es andere Möglichketen gibt.
Sonst hätte er dies ja gleich erwähnen können ohne sich erst später
schlauer zu machen ....

von 8266_unbelesen (Gast)


Lesenswert?

Hali H. schrieb:
> Das mit den falschen Zeichen wird an UDP liegen,

Ja weil dieses protokoll nicht abgesichert ist und du dich
um die Sicherheit (Handshake, Ack) selbst kümmern musst.

von 8266_unbelesen (Gast)


Lesenswert?

Hali H. schrieb:
> Kann man mit dem ESP überhaupt Daten in Echtzeit senden? Habe das Gefühl
> dass er große Delays zwischen dem Senden brauch....

Weder TCP, UDP noch ein LAN garantieren dir Echtzeit. Das kann
keiner garantieren da niemand weiss wieviel Verkehr auf dem
LAN/WLAN vorhanden ist. Lediglich TCP garantiert dir den
gesicherten Transport bzw. Error-Handling.

von Hali H. (ratendix)


Lesenswert?

8266_unbelesen schrieb:
> Hali H. schrieb:
>> Kann man mit dem ESP überhaupt Daten in Echtzeit senden? Habe das Gefühl
>> dass er große Delays zwischen dem Senden brauch....
>
> Weder TCP, UDP noch ein LAN garantieren dir Echtzeit. Das kann
> keiner garantieren da niemand weiss wieviel Verkehr auf dem
> LAN/WLAN vorhanden ist. Lediglich TCP garantiert dir den
> gesicherten Transport bzw. Error-Handling.

Das ist korrekt,aber wenn angenommen nur der ESP in einem Netz mit dem 
Router kommunziert und kein anderes Gerät aktiv ist, sollte man doch 
sehr schnell Daten versenden können?

von 8266_unbelesen (Gast)


Lesenswert?

Hali H. schrieb:
> Der ESP sendet die Daten zu langsam.

Der hat auch viel zu tun. Er muss WLAN handeln, Pakete ein-/
auspacken, Checksummen generieren/prüfen etc.

Manche Datenübertragungen sind wohl sinnvoller abseits von
WLAN und TCP/UDP abzuhandeln, wie z.B. mit dem NRF24L01.
Dort hat man nicht mit (W)LAN Verkehr zu kämpfen, braucht
sich nicht um Pakete ein/auspacken zu kümmern und hat viele
Kanäle (125) zur Auswahl um eine möglichst Störungsfreie
Kommunikation zu erreichen. Und die 2MBit zum Daten übertragen
(effektive Nutz-Datenrate ca 50KB/sec) sind mit dem ESP8266
sicherlich nicht zu erreichen.

von 8266_unbelesen (Gast)


Lesenswert?

Hali H. schrieb:
> sollte man doch sehr schnell Daten versenden können?

Ja nein, wie gesagt, der ESP hat viel zu tun mit TCP.
Das ist alles Software. Du hast den falschen Ansatz gewählt.

Schneller wird es mit einem Arduino TCP LAN Modul
á la W5100 (Hardware TCP/UDP). Dann bist du aber leider
nicht WLAN-fähig.

von 8266_unbelesen (Gast)


Lesenswert?

Hali H. schrieb:
> sollte man doch sehr schnell Daten versenden können?

Nein aus einem weiteren Grund: TCP/UDP fähige Geräte kommunizieren
im allgemeinen in einem Zeittakt der nicht beliebig schnell ist.
Will heissen wenn die viele kleine Pakete überträgst hast du
dazwischen Latenzzeiten die die Übertragungsrate stark reduzieren.

Alle TCP/UDP-Übertragungen sind darauf ausgerichtet grosse
Datenmengen in einem Schub zu übertragen, aber nicht kleine
Datenmengen in einem sehr feinen (also schnellem) Zeitraster.

Abhilfe schafft man nur wenn man die beteiligten Partner-Stacks so
konfiguriert dass sie von ihrem groben Zeitraster ablassen. Das
ist wohl nicht immer möglich ....

von Hali H. (ratendix)


Lesenswert?

8266_unbelesen schrieb:
> Hali H. schrieb:
>> sollte man doch sehr schnell Daten versenden können?
>
> Nein aus einem weiteren Grund: TCP/UDP fähige Geräte kommunizieren
> im allgemeinen in einem Zeittakt der nicht beliebig schnell ist.
> Will heissen wenn die viele kleine Pakete überträgst hast du
> dazwischen Latenzzeiten die die Übertragungsrate stark reduzieren.
>
> Alle TCP/UDP-Übertragungen sind darauf ausgerichtet *grosse*
> Datenmengen in einem Schub zu übertragen, aber nicht kleine
> Datenmengen in einem sehr feinen (also schnellem) Zeitraster.
>
> Abhilfe schafft man nur wenn man die beteiligten Partner-Stacks so
> konfiguriert dass sie von ihrem groben Zeitraster ablassen. Das
> ist wohl nicht immer möglich ....

genau daran hatte ich auch gedacht, lieber dann die Daten am Controller 
"sammeln" und im Schub zu senden. Muss dann nur sehen ob mir die 
maximale Paketgröße beim ESP reicht

von Michael U. (amiga)


Lesenswert?

Hallo,

vun und zum SPIFFS überträgt der ESP zwischen 300 und 500kB/s.
Das hat aber nichts mit Echtzeit oder garantierten Antwortzeiten zu tun. 
Er kann sich durchaus ein paat 100ms Denkpause genehmigen, bis er 
antwortet oder mit dem Senden anfängt.
192kBit MP3 als Icecast-TCP-Stream spielt er (mit Hardware-MP3-Decoder) 
stundenlang ohne Aussetzer. Natürlich gibt es da sofort Probleme, wenn 
viel im WLAN los ist und die Antwortzeiten zu lang werden. 16k Buffer 
ist eben nicht sooo viel.

Das ist aber alles aus der Arduino-IDE direkt für den ESP programmiert, 
die obigen 300-500k erreicht er im Down/Upload über den ESP-Webserver, 
die Daten dafür liegen bei mir generell im SPIFFS.
Das war auch mehr ein Test, also über den Webserver ein 250kB JPP 
hochgelanden, dauert ca. 2s incl. Antwortzeit für den Neuaufbau der 
Webseite mit Dateiliste usw.
Download und Anzeige des Bildes passiert in maximal 1s.
Es gibt aber auch dort unberechenbare Denkpausen, es kann scheinbar 
unmotiviert auch 2s länger dauern.

Gruß aus Berlin
Michael

von 8266_unbelesen (Gast)


Lesenswert?

Michael U. schrieb:
> Das hat aber nichts mit Echtzeit oder garantierten Antwortzeiten zu tun.

.... und der TO hat zusätzlich noch den Transfer via RS232
als Bremse .....

von 8266_unbelesen (Gast)


Lesenswert?

Michael U. schrieb:
> es kann scheinbar unmotiviert auch 2s länger dauern.

Dann kämpft er wohl mit Übertragungsfehlern/Störungen.

von Michael U. (amiga)


Lesenswert?

Hallo,

8266_unbelesen schrieb:
> Michael U. schrieb:
>> es kann scheinbar unmotiviert auch 2s länger dauern.
>
> Dann kämpft er wohl mit Übertragungsfehlern/Störungen.

sehr wahrscheinlich hier. Fällt normalerwesie z.B. mit dem Notebook im 
WLAN nicht auf, weil man nicht drauf achtet und bei Streaming-Sachen die 
Puffer merklich größer sind.

Gruß aus Berlin
Nichael

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.