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?
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
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
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.
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.
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.
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?
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
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.
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.
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.
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.