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


von Bert S. (kautschuck)


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.
1
  digitalWrite(UART1_DE, HIGH);
2
  SERIAL1.print("12345678abcdefgh\n");
3
  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
von Michael U. (amiga)


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.
von Bert S. (kautschuck)


Lesenswert?

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

Irgendwie modifiziert mir das die Daten.

von Michael U. (amiga)


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

von Bert S. (kautschuck)


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.

von Einer K. (Gast)


Lesenswert?

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

von Frank M. (ukw) (Moderator) Benutzerseite


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.

von Einer K. (Gast)


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.

von Bert S. (kautschuck)


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?

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

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

Ein Bug in der Software?

von Lutz (Gast)


Lesenswert?

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

Der hat FRAM???

von Joachim B. (jar)


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

von Bert S. (kautschuck)


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
von Christopher J. (christopher_j23)


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.

von Christopher J. (christopher_j23)


Angehängte Dateien:

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.

von Bert S. (kautschuck)


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.

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.