ESP32 Arduino Serial.print() interrupt driven?

OP #5409561
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?
Beitrag #5409566 wurde von einem Moderator gelöscht.
#5409628
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
Moderator Persönliche Seite #5409685
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.
Gast #5409694
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.
#5410179
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.
#5410236
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.
Angehängte Dateien:
OP #5410325
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

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren