Forum: Mikrocontroller und Digitale Elektronik Teile vom eingelesenen UART stream extrahieren


von Fritz Huber (Gast)


Lesenswert?

Hallo!

Ich verwende die C-Library von Peter Fleury zum Datenaustausch via UART.

Ich möchte gerne bei dem angehängten ESP8266 den String einlesen, wenn 
der Client eine Anfrage an den ESP8266 schickt, zb. einen GET-Request.

Dabei interessiert mich aber eigentlich nur, welche Anfrage und welche 
zugehörigkeit zum Link Kanal.

Wie kann ich am einfachsten nach "IPD," suchen ( danach folgt der Kanal 
) und danach nach "GET" suchen ( danach folgt die Anfrage was der Client 
möchte ).

Muss ich tatsächlich bei jedem empfangenen Byte eine Abfrage nach "I" 
machen, wenn das erfüllt ist, eine Abfrage nach "P" und wenn das erfüllt 
ist eine Abfrage nach "D" usw. ? Oder gibt es dafür fertige, sparsame 
und effektive Routinen? Oder bin ich komplett am Holzweg und ihr habt 
eine bessere Lösung für mein Problem?

Liebe Grüße
Fritz Huber

von Peter II (Gast)


Lesenswert?


von Fritz Huber (Gast)


Lesenswert?

Danke!

hab übersehen, dass es die Funktionen auch für die AVRs gibt.

Habt ihr noch eine Idee wie ich das löse, dass ich während des sendens 
sehr sehr viele Bytes vom ESP8266 empfange?

Ich würde gerne nur das "SEND OK" abfragen, bzw. wenn dazwischen GET 
Requests kommen müsste ich diese auch mit Kanal + Anfrage abfangen und 
speichern, um sie danach zu beantworten.

Mein AtMega läuft auf 16MHz.

Ist dies überhaupt so zu bewerkstelligen, oder sollte ich mich eher um 
die direkte Programmierung des ESP8266 eigenen µC kümmern?

Danke für die Hilfe

von Karl H. (kbuchegg)


Lesenswert?

Fritz Huber schrieb:

> Habt ihr noch eine Idee wie ich das löse, dass ich während des sendens
> sehr sehr viele Bytes vom ESP8266 empfange?

Zwischenspeichern.

> Ich würde gerne nur das "SEND OK" abfragen

danach wird wahrscheinlich ein \n kommen, oder?

D.h. du brauchst nur Zeilen (alles bis zum \n) speichern, die in der 
Länge maximal deiner Maximallänge entsprechen. Alles was länger ist, 
kannst du also getrost schon während des Empfangs verwerfen.

> bzw. wenn dazwischen GET
> Requests kommen müsste ich diese auch mit Kanal + Anfrage abfangen und
> speichern, um sie danach zu beantworten.

Zwischenspeichern.

Der übliche Weg ist es, erst mal alles was an Zeichen reinkommt in einem 
Buffer zwischenzuspeichern. Und zwar so lange, bis ein \n reinkommt. Ist 
dieses erkannt (oder ist der zur Verfügung gestellte Speicher 
aufgebraucht), dann wird an das Ende der Zeichen noch ein \0 als 
String-Terminator drann gehängt und man hat einen normalen C-String vor 
sich. Auf den geht man dann mit den String Funktionen los.

von Fritz Huber (Gast)


Lesenswert?

Hallo,

genau das habe ich versucht, vielleicht bin ich zu doof, oder der µC hat 
zuwenig Zeit alles zu verarbeiten.

Aktuell schicke ich die html Seite, und danach kommt der Befehl:
1
do
2
{
3
  do{
4
  c = uart_getc();
5
  if ( c & UART_NO_DATA ) 
6
        { 
7
        }
8
  else
9
  {   if ( c & UART_FRAME_ERROR ) {}
10
      if ( c & UART_OVERRUN_ERROR ) {}
11
      if ( c & UART_BUFFER_OVERFLOW ) {}
12
      buffer1[i]=(c&0xFF);
13
      i++;
14
      if(i>=100)
15
      i=0;
16
  }
17
  
18
}while(buffer1[i]!=13);

Das heißt es liest eine Zeile ein, bis ein "\n" kommt.
Das Problem ist, der ESP8266 returned automatisch alles was er empfängt, 
das heißt er schickt gleich 1800 Bytes auf einmal zurück, während der µC 
noch sendet, ich vermute dass beides gleichzeitig den µC etwas 
überfordern wird oder?

Danke für die Hilfe Karl Heinz :)

von Fritz Huber (Gast)


Lesenswert?

Hallo!

Ich habe zum Beispiel folgenden Code:
1
uart_puts("AT+RST\r\n");
2
   
3
   do{ 
4
     i=0;
5
     do{
6
       c = uart_getc();
7
       if ( c & UART_NO_DATA ) {}
8
       else
9
       {   buffer[i]=(c&0xFF);
10
         i++;
11
         if(i>=100)
12
         i=0;
13
       }
14
     }while(buffer[i]!=13);
15
   }while(!strstr(buffer,"ready"));
Das hier passiert am UART:
1
AT+RST<\r><\r><\n>
2
<\r><\n>
3
OK<\r><\n>
4
<\r><\n>
5
 ets Jan  8 2013,rst cause:4, boot mode:(3,7)<\r><\n>
6
<\r><\n>
7
wdt reset<\r><\n>
8
load 0x40100000, len 25052, room 16 <\r><\n>
9
tail 12<\r><\n>
10
chksum 0x0b<\r><\n>
11
ho 0 tail 12 room 4<\r><\n>
12
load 0x3ffe8000, len 3312, room 12 <\r><\n>
13
tail 4<\r><\n>
14
chksum 0x53<\r><\n>
15
load 0x3ffe8cf0, len 6576, room 4 <\r><\n>
16
tail 12<\r><\n>
17
chksum 0x0d<\r><\n>
18
csum 0x0d<\r><\n>
19
<\r><\n>
20
[Vendor:www.ai-thinker.com Version:0.9.2.4]<\r><\n>
21
<\r><\n>
22
ready<\r><\n>

Und nichteinmal das schafft er ( bleibt bei ready stehen ).

von Sascha W. (sascha-w)


Lesenswert?

Hallo,

also wenn der ESP schon Zeichen zurücksendet, während du selbst noch 
Daten sendest, musst du den Empfang per Interrupt machen und nicht per 
polling. Im INT speicherst du die Daten in den Puffer (wenn noch Platz 
ist) und prüfst auf CR. Wenn CR empfangen wurde setzt du ein Flag um 
damit in der Mainloop die Auswertung auszulösen.

Kannst du das Echo des ESP nicht ausschalten? ATE0!

Sascha

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Sascha Weber schrieb:
> Kannst du das Echo des ESP nicht ausschalten? ATE0!

Nein, das geht nicht. Und nicht nur das. Die Firmware des ESP8266 ist 
derart besch...eiden, dass es richtig schwierig ist, die Antworten zu 
parsen.

Folgendes macht dem Programmierer das Leben schwer:

 - Echo nicht abschaltbar, man muss alle gesendeten Zeichen
   selbst wieder aus dem Input herausfiltern

 - Die Antwort-Codes sind von der Groß-/Kleinschreibung nicht
   einheitlich, mal "error", mal "Error" usw.

 - Die Anzahl der Zeilen in den Antworten ist variabel. Manche
   Antworten werden mit einem Antwort-Code wie "OK", "error",
   "no such fun" oder ähnlichem abgeschlossen, manche aber nicht.
   Da hilft es nur, mit Timeouts zu arbeiten, um irgendwann
   herauszubekommen, dass die verdammt Antwort nun beendet ist.

 - Manche Antworten enthalten zwar eine Antwort, aber nicht immer
   abschließenden Antwort-Codes, z.B. bei AT+CIFSR: Entweder
   bekommt man "Error" oder man bekommt eine IP-Adresse als
   Antwort, aber niemals ein abschließendes "OK". Man muss daher
   für jedes AT-Kommando eine Extra-Funktion schreiben, die alle
   möglichen Antwortformen für genau dieses AT-Kommando kennt.

 - Wenn das Ding einmal "Busy" meldet, bekommt man es nur noch
   mit einem Hardware-Reset wieder ins Leben zurück.

Das sind nur einige Macken des ESP8266. Aber die können einen schon zum 
Wahnsinn treiben. Die Firmware versucht zwar, einen AT-Standard 
vorzutäuschen, aber der ist unheimlich schlecht umgesetzt. Die heutigen 
Programmierer haben wahrscheinlich nie ein AT-kompatibles Modem in der 
Hand gehabt und wissen gar nicht, wie man so eine Kommunikation derart 
gestatltet, dass ein PC oder µC auch etwas mit den Antworten anfangen 
kann.

von c-hater (Gast)


Lesenswert?

Frank M. schrieb:

> Das sind nur einige Macken des ESP8266. Aber die können einen schon zum
> Wahnsinn treiben. Die Firmware versucht zwar, einen AT-Standard
> vorzutäuschen, aber der ist unheimlich schlecht umgesetzt. Die heutigen
> Programmierer haben wahrscheinlich nie ein AT-kompatibles Modem in der
> Hand gehabt und wissen gar nicht, wie man so eine Kommunikation derart
> gestatltet, dass ein PC oder µC auch etwas mit den Antworten anfangen
> kann.

Aber sie haben das garantiert in C programmiert, da bin ich wirklich 
absolut sicher...

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

c-hater schrieb:
> Aber sie haben das garantiert in C programmiert, da bin ich wirklich
> absolut sicher...

Schlecht programmieren kann man in jeder Sprache. Was genau wolltest Du 
jetzt damit sagen?

von Fritz Huber (Gast)


Lesenswert?

Hallo!

Der Empfang wird eh per Interrupt gemacht, es gibt noch einen Buffer 
dazwischen.

Es läuft nun soweit, dass er während des sendens auch GET Request 
abfängt und mir speichert, damit ich sie danach wieder beantworten kann, 
allerdings gibt es ein großes Problem, wenn ich während des sendens 
einen "Link" bekomme ( ESP8266 schreibt Link raus ), dann hängt sich 
alles auf.

Kennt das jemand? Weiß jemand wie man das umgehen oder beheben oder 
vermeiden kann?

Sehr zum verweifeln, der ESP8266 hängt sich öfter auf als man schauen 
kann.

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.