mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik ESP32 Arduino Serial.print() interrupt driven?


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
Autor: Bert S. (kautschuck)
Datum:

Bewertung
-1 lesenswert
nicht lesenswert
Hi,

Ich versuche mit einem ESP32 über RS485 Daten zu schicken, dazu muss ich 
ja den DE Pin auf HIGH setzen und nach dem senden wieder auf low. Nun 
stelle ich fest, dass wenn ich folgendes Programm ausführe und mit dem 
Oszi messe, der DE Pin sehr schnell wieder auf LOW ist, während die 
Daten noch nicht gesendet sind.
  digitalWrite(UART1_DE, HIGH);
  SERIAL1.print("12345678abcdefgh\n");
  digitalWrite(UART1_DE, LOW);

Jemand eine Idee, ob Serial.print() aus der Arduino Library irgend einen 
Buffer verwendet, der dann mit Interrupts abgearbeitet wird? Gibt es 
eine Möglichkeit dies irgendwie zu umgehen?

: Bearbeitet durch User
Autor: Michael U. (amiga)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

Bert S. schrieb:
> Jemand eine Idee, ob Serial.print() aus der Arduino Library irgend einen
> Buffer verwendet, der dann mit Interrupts abgearbeitet wird? Gibt es
> eine Möglichkeit dies irgendwie zu umgehen?

ja, ist so.
Serial.flush(); sollte warten bis alles gesendet ist.

Gruß aus Berlin
Michael

: Bearbeitet durch User
Beitrag #5409566 wurde vom Autor gelöscht.
Autor: Bert S. (kautschuck)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Michael U. schrieb:
> Serial.flush(); sollte warten bis alles gesendet ist.

Irgendwie modifiziert mir das die Daten.

Autor: Michael U. (amiga)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

Bert S. schrieb:
> Michael U. schrieb:
>> Serial.flush(); sollte warten bis alles gesendet ist.
>
> Irgendwie modifiziert mir das die Daten.

"Irgendwie" ist irgendwie nicht so aussagekräftig...
Ich habe nicht nachgeschaut ob es da beim ESP32 Probleme macht.
Beim ESp8266 gab es den Zustand, daß flush() etwas zu früh zurückkam und 
das letzte Byte zerhackte.
https://github.com/esp8266/Arduino/issues/2536

Die Routinen wurden ziemlich 1:1 übernommen.
Sowohl der ESP8266 als auch der ESP32 haben mich da mal geschafft:
beide können ab 230kBaud nicht mehr zuverlässig seriell Daten empfangen 
wenn es keine Pausen in den Daten gibt, also 
Startbit/Daten/Stopbit/Startbit/Daten/Stopbit usw. Bis 115200 ist es bei 
beiden stabil.
Ein Mega32 u.ä. kann es mit Baudratenquarz fehlerfrei. 32 byte gelesen, 
x-tausend Bytes nur mitgezählt, dann wieder 32Byte gelesen passt immer 
100% zu den gesendeten Daten.

Gruß aus Berlin
Michael

Autor: Bert S. (kautschuck)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Es scheint, als hätte der ESP32 einen TX Buffer bestimmter Grösse (etwa 
128 Bytes), welcher bei einem flush ganz raus geschrieben wird, also 
auch der ganze Müll, der noch darin liegt.

Autor: Arduino Fanboy D. (ufuf)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du könntet dir mit Serial.availableForWrite() was basteln....
(wurde vor 26 Tagen hinzugefügt)

Autor: Frank M. (ukw) (Moderator) Benutzerseite
Datum:

Bewertung
1 lesenswert
nicht lesenswert
Arduino F. schrieb:
> Du könntet dir mit Serial.availableForWrite() was basteln....

Das scheint aber auch nur zu checken, ob der TX-FiFo leer ist, wenn ich 
den Source richtig interpretiere.

Das ist aber u.U. zu früh, denn das letzte Byte kann zu dieser Zeit noch 
physikalisch unterwegs sein. Normalerweise implementiert man das mit 
einem TX-Empty-Interrupt des UARTs. Davon ist im Source aber nichts zu 
sehen.

Autor: Arduino Fanboy D. (ufuf)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das stimmt.
availableForWrite() zeigt nur den FiFo Füllungsgrad.
Wie lange der ESP braucht um das letzte Byte raus zu schieben, sollte 
sich hoffentlich ausmessen lasen.

Frank M. schrieb:
> Davon ist im Source aber nichts zu
> sehen.
Und damit nicht erreichbar, falls überhaupt vorhanden.

Autor: Bert S. (kautschuck)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ok, flush scheint doch zu funktionieren, jedoch nur mit UART0 des ESP32. 
Mit dem UART1 wird irgendwie Müll hinzugefügt und UART2 ist sowiso nicht 
frei, da durch den FRAM des ESP32 besetzt.

Jemand eine Idee, was den UART1 des ESP32 Wrovers zumüllt?

Autor: Frank M. (ukw) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Bert S. schrieb:
> Jemand eine Idee, was den UART1 des ESP32 Wrovers zumüllt?

Ein Bug in der Software?

Autor: Lutz (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Bert S. schrieb:
> UART2 ist sowiso nicht
> frei, da durch den FRAM des ESP32 besetzt.

Der hat FRAM???

Autor: Joachim B. (jar)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Frank M. schrieb:
> TX-FiFo leer

ja aber seit in der Arduino IDE auch der ESP32 integriert werden kann 
bin ich auf die Nase gefallen AVR Register abzufragen, z.B. I2C Flag.

Beim ESP32 wollte das einfach nicht mit dem Registernamen vom Atmel 
klappen

Autor: Bert S. (kautschuck)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Lutz schrieb:
> Der hat FRAM???

Ne, PSRAM und Flash, mein Fehler.

Frank M. schrieb:
> Ein Bug in der Software?

Zumindest nicht in meinem Teil, da ich sonst nichts sende. Irgendwas 
scheint aber den UART1 im Hintergrund zu verwenden.

: Bearbeitet durch User
Autor: Christopher J. (christopher_j23)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Bert S. schrieb:
> Mit dem UART1 wird irgendwie Müll hinzugefügt und UART2 ist sowiso nicht
> frei, da durch den FRAM des ESP32 besetzt.

wie kommst du darauf? Wenn ich mir den Schaltplan des WROVER-Boards in 
Verbindung mit dem Pinout des ESP32 anschaue, dann meine ich, dass TXD 
vom UART1 gleich SD3 ist, was als Teil des SDIO-Interfaces sowohl am 
PSRAM, als auch am Flash hängt.

Autor: Christopher J. (christopher_j23)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Habe mal der Vollständigkeit halber ein Pinout des WROOM-Moduls 
angehängt. SD-Data0 bis SD-Data3, sowie SDCMD und SDCLK sind bereits in 
Benutzung durch den Flash, d.h. GPIO6 bis GPIO11 sind quasi schon 
belegt.

Übrigens bezüglich meiner Aussage von oben
> TXD vom UART1 gleich SD3

Das ist so natürlich nicht ganz richtig, weil man die UARTs ja dank 
GPIO-Mux auf beliebige Pins legen kann. Keine Ahnung welchen Pin das 
Arduino-Framework per default nutzt. Falls es wie im angehängten Pinout 
ist, kollidiert es jedenfalls mit dem SDIO-Interface.

Autor: Bert S. (kautschuck)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Christopher J. schrieb:
> UARTs ja dank
> GPIO-Mux auf beliebige Pins legen kann

Genau, ich verwende IO32 und IO33 für das UART1 Mapping von RX und TX. 
Jedoch bleibt das Problem das gleiche. Wenn ich UART0 verwende, wird mit 
Serial1.flash() nur das raus geschrieben, welches ich mit 
Serial1.print("...") senden will. Bei Verwendung von UART1 kommt ein 
String raus, welcher etwa 128 Byte ist, wobei sich der Inhalt bei 
konstantem String nicht ändert. Ich werde Morgen mal nach eine genauere 
Analyse machen.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.