Hi, Was passiert eigentlich, wenn ich einen Arduino Uno extern versorge und trotzdem Serial.print() verwende, ohne angeschlossenes Serial Interface? Der Arduino verwendet ja den Interrupt zum senden und somit werden die Daten alle in einen Buffer geschrieben. Ist dies überhaupt ein Ring Buffer, oder was passiert wenn dieser voll ist? Ich habe nämlich ein Problem mit einem Arduino Uno, der sich nach etwa 3 Wochen aufhängt, wobei ich festgestellt habe, dass ich ein Serial.print("...") vergessen habe, wo aber nur ein paar mal am Tag aufgerufen wird.
:
Bearbeitet durch User
Beitrag #5415357 wurde von einem Moderator gelöscht.
Die Serielle Schnittstelle hat keine Empfangsquitierung. Dein Serial.print() sollte ungehört verhallen und sich nichts irgendwo ansammeln.
yesitsme schrieb: > Die Serielle Schnittstelle hat keine Empfangsquitierung. Dein > Serial.print() sollte ungehört verhallen und sich nichts irgendwo > ansammeln. Gilt aber nur wenn das keine USB-Serielle ist, also USBSerial oder wie das hieß. Die wartet sehr wohl auf Bestätigung/Abholung... P.Loetmichel schrieb im Beitrag #5415357: > Ich würde ja BASCOM nehmen. Schön für dich; es gibt Leute die können nicht nur solche Baby-Sprachen. > Da funktioniert die serielle immer! Das hat nichts mit der Programmiersprache zu tun.
Bert S. schrieb: > Was passiert eigentlich, wenn ich einen Arduino Uno extern versorge und > trotzdem Serial.print() verwende, ohne angeschlossenes Serial Interface? Vermutlich nix besonderes, die Daten werden einfach in's Nirvana gesendet, erscheinen also ganz normal am Ausgangspin, nur halt ohne, dass sich irgendwer dafür interessiert... Irgendwas anderes käme überhaupt nur im Falle eines aktiven Handshake-Mechanismus in Frage.
Wenn der TX-Buffer voll ist, dann blockt HardwareSerial::write() (und damit auch Serial.print() ) so lange, bis genug Platz ist um die Daten in den Buffer zu schreiben. Für Details siehe auch https://github.com/arduino/Arduino/blob/master/hardware/arduino/avr/cores/arduino/HardwareSerial.cpp#L213 P.Loetmichel schrieb im Beitrag #5415357: > Ich würde ja BASCOM nehmen. > > Da funktioniert die serielle immer! Deine ständige Schleichwerbung für BASCOM ist mittlerweile einfach nur noch lächerlich.
Christopher J. schrieb: > Wenn der TX-Buffer voll ist, dann blockt HardwareSerial::write() (und > damit auch Serial.print() ) so lange, bis genug Platz ist um die Daten > in den Buffer zu schreiben. Für Details siehe auch > https://github.com/arduino/Arduino/blob/master/hardware/arduino/avr/cores/arduino/HardwareSerial.cpp#L213 Dr. Sommer schrieb: > Gilt aber nur wenn das keine USB-Serielle ist, also USBSerial oder wie > das hieß. Die wartet sehr wohl auf Bestätigung/Abholung... Ok, danke, dann liegt das in der Tat daran, dass ich auf die USB-Serial schreibe.
:
Bearbeitet durch User
meine Erfahrungen sind so das es egal ist ob was angeschlossen ist oder nicht. Da es keinen warte befehl gibt. Der arduino sendet es einfach egal ob die gegen stelle bereit ist oder nicht. ich frage zb mit einen 2560 alle 40 ms eine Spannung ab und sende sie an einen PC. Und das auch mal 10 stunden lang. Es spielt dabei aber keine rolle ob der PC läuft oder nicht die Daten werden gesendet und fertig.
Dr. Sommer schrieb: > Gilt aber nur wenn das keine USB-Serielle ist, also USBSerial oder wie > das hieß. Die wartet sehr wohl auf Bestätigung/Abholung... Nicht soweit mir bekannt.... Oder anders gesagt: Meine tun das nicht. Und ich werde ihnen auch nicht sagen, dass sie es tun sollen. Die gesendeten Daten landen im Nirvana! So wie beim 328P, als auch beim 32U4 Wenn man sie nicht im Nirvana haben möchte, sollte man (beim 32U4) eine Blockade einführen. while(!Serial); Blockiert den 32U4 solange, bis vom PC ein Port geöffnet wird.
Frank schrieb: > Nein. Ein Fdti an RX-TX: > https://www.arduino.cc/en/uploads/Main/arduino-uno-schematic.pdf Nöö.. Ein ATMega16U2. (oder ganz alt, ein 8U2) Es gibt einige UNO kompatible mit anderen Serial Wandlern. Aber mit FTDI ist mir keiner bekannt.
Hallo, es ist egal was man da sendet, der AVR schiebt es ben zum TX raus und damit ist das Thema für ihn erledigt. Hier laufen auch Sachen, wo ich einfach vergessen habe, meine Debug-Ausgaben abzuschalten und da wird dann noch einges mehr an Daten ins Nichts geschickt. Die Ausgaben bremsen natürlich den Programmablauf etwas, wenn sie erfolgen. Da ich allerdings die Serielle ohnehin immer auf 115200 setze ist auch die Wartezeit auf Platz im seriellen Buffer gering falls es mal mehr als die 64 Byte Buffer sind. Solche Aufhänger sehen immer nach knapp werdendem Ram aus oder falscher Arraygröße, wo nur selten über die Grenze geschrieben wird, oder... Gruß aus Berlin Michael
:
Bearbeitet durch User
Bert S. schrieb: > Was passiert eigentlich, wenn ich einen Arduino Uno extern versorge und > trotzdem Serial.print() verwende, ohne angeschlossenes Serial Interface? Man sieht die Tx-LED flackern, weiter nichts, es läuft einfach. Gedanken habe ich mir gemacht, einen ProMini möglichst schnell wieder schlafen zu legen, da frage ich einen Pin ab (Brückenstecker) und sende nur, wenn dieser auf "Debugmode" gesteckt ist. Arduino F. schrieb: > Ein ATMega16U2. (oder ganz alt, ein 8U2) > Es gibt einige UNO kompatible mit anderen Serial Wandlern. > Aber mit FTDI ist mir keiner bekannt. Natürlich nicht, weil FTDI unverschämte Preise nimmt und sich damit der ChinUNO preislich verdreifachen würde. Mit FTDI ist mir nur der Gravitech-Nano bekannt, den ich nicht bereit bin, zu bezahlen.
Hast du vielleicht irgendwas im Code wie: //mach alle paar Millisekunden irgendwas if (millis() > last + x){ //mach irgendwas last = millis(); } Das kann beim Überlauf von millis() (etwa nach 50 Tagen) dazu führen das der Code im if-Statement nicht mehr ausgeführt wird. Falls du dann noch für dein millis in einem long statt unsigned long zwischenspeicherst o.Ä. würde das sogar mit deinen drei Wochen etwa hinkommen. Das Problem wird auch hier beschrieben: https://forum.arduino.cc/index.php?topic=285280.0 Lösung: if (millis() - last > x)
:
Bearbeitet durch User
Bert S. schrieb: > Ist dies überhaupt ein Ring Buffer, oder was passiert > wenn dieser voll ist? Ich habe nämlich ein Problem mit > einem Arduino Uno, der sich nach etwa 3 Wochen aufhängt, > wobei ich festgestellt habe, dass ich ein Serial.print("...") > vergessen habe, wo aber nur ein paar mal am Tag aufgerufen wird. Warum sollte ein Buffer voll laufen. Solange die Schnittstellengeschwindigkeit höher als deine mittlere Datenrate ist, klötern die Bits schneller am TX raus, als du sie rein schreibst. Der ATmega328 des Arduino Uno weiss nicht, was hinter seinem TX Ausgang kommt und ob sich jemand für die gesendeten Inhalte interessiert. Guck mal mit einem Oszi/LA auf TX (DIO1). Da kommen die Bits rausgepurzelt, egal wie du den Uno versorgst. https://www.arduino.cc/en/uploads/Main/Arduino_Uno_Rev3-schematic.pdf
Arduino F. schrieb: > Nicht soweit mir bekannt.... Kann sein dass sich meine Erinnerung hier auf die STM32 Arduino Implementation bezieht... Es ist natürlich schon so dass ein Controller der direkt an die "echte" USB Schnittstelle angeschlossen ist merkt wenn Daten vom USB aus abgefragt werden. Ob er bei Nicht-Abfragen blockiert oder Daten löscht ist eine Implementations Frage...
Joschua K. schrieb: > Hast du vielleicht irgendwas im Code wie: > > //mach alle paar Millisekunden irgendwas > if (millis() > last + x){ > //mach irgendwas > last = millis(); > } > > Das kann beim Überlauf von millis() (etwa nach 50 Tagen) dazu führen das > der Code im if-Statement nicht mehr ausgeführt wird. Falls du dann noch > für dein millis in einem long statt unsigned long zwischenspeicherst > o.Ä. würde das sogar mit deinen drei Wochen etwa hinkommen. > > Das Problem wird auch hier beschrieben: > https://forum.arduino.cc/index.php?topic=285280.0 > > Lösung: > if (millis() - last > x) Sehr gut das du das erwähnst. Ich verwende eine Timer library namens "TimerObject.h". https://playground.arduino.cc/Code/ArduinoTimerObject Im Code ist da sehr viel mit millis():
1 | #include "TimerObject.h" |
2 | |
3 | TimerObject::TimerObject(unsigned long int ms){ |
4 | Create(ms, NULL, false); |
5 | }
|
6 | |
7 | TimerObject::TimerObject(unsigned long int ms, CallBackType callback){ |
8 | Create(ms, callback, false); |
9 | }
|
10 | |
11 | TimerObject::TimerObject(unsigned long int ms, CallBackType callback, bool isSingle){ |
12 | Create(ms, callback, isSingle); |
13 | }
|
14 | |
15 | void TimerObject::Create(unsigned long int ms, CallBackType callback, bool isSingle){ |
16 | setInterval(ms); |
17 | setEnabled(false); |
18 | setSingleShot(isSingle); |
19 | setOnTimer(callback); |
20 | LastTime = 0; |
21 | }
|
22 | |
23 | void TimerObject::setInterval(unsigned long int ms){ |
24 | msInterval = (ms > 0) ? ms : 0; |
25 | }
|
26 | |
27 | void TimerObject::setEnabled(bool Enabled){ |
28 | blEnabled = Enabled; |
29 | }
|
30 | |
31 | void TimerObject::setSingleShot(bool isSingle){ |
32 | blSingleShot = isSingle; |
33 | }
|
34 | |
35 | void TimerObject::setOnTimer(CallBackType callback){ |
36 | onRun = callback; |
37 | }
|
38 | |
39 | void TimerObject::Start(){ |
40 | LastTime = millis(); |
41 | setEnabled(true); |
42 | }
|
43 | |
44 | void TimerObject::Resume(){ |
45 | LastTime = millis() - DiffTime; |
46 | setEnabled(true); |
47 | }
|
48 | |
49 | void TimerObject::Stop(){ |
50 | setEnabled(false); |
51 | |
52 | }
|
53 | |
54 | void TimerObject::Pause(){ |
55 | DiffTime = millis() - LastTime; |
56 | setEnabled(false); |
57 | |
58 | }
|
59 | |
60 | void TimerObject::Update(){ |
61 | if(Tick()) |
62 | onRun(); |
63 | }
|
64 | |
65 | bool TimerObject::Tick(){ |
66 | if(!blEnabled) |
67 | return false; |
68 | if(LastTime > millis()*2)//millis restarted |
69 | LastTime = 0; |
70 | if ((unsigned long int)(millis() - LastTime) >= msInterval) { |
71 | LastTime = millis(); |
72 | if(isSingleShot()) |
73 | setEnabled(false); |
74 | return true; |
75 | }
|
76 | return false; |
77 | }
|
78 | |
79 | |
80 | unsigned long int TimerObject::getInterval(){ |
81 | return msInterval; |
82 | }
|
83 | |
84 | unsigned long int TimerObject::getCurrentTime(){ |
85 | return (unsigned long int)(millis() - LastTime); |
86 | }
|
87 | CallBackType TimerObject::getOnTimerCallback(){ |
88 | return onRun; |
89 | }
|
90 | |
91 | bool TimerObject::isEnabled(){ |
92 | return blEnabled; |
93 | }
|
94 | |
95 | bool TimerObject::isSingleShot(){ |
96 | return blSingleShot; |
97 | }
|
Soweit ich das auf die schnelle überblicken kann, sollte die Timer Klasse funktionieren. Du verwendest eine veraltetete Version. Aber auch das ist kein Drama. Mir gefallen die "unsigned long" da nicht. Das ist für AVR, angemessen, aber auf 32 Bit Modellen dürfte das dann unnötiger Weise 64 Bit nutzen. Schlussendlich, dürfte die Klasse ok sein. Und nicht deinen Fehler verursachen. Die Serielle Ausgabe ist nicht dein Problem. --------- Auch wenn du es nicht hören möchtest: Aus meiner Sicht hast du ein anderes Problem im Code!
Arduino F. schrieb: > Auch wenn du es nicht hören möchtest: > Aus meiner Sicht hast du ein anderes Problem im Code! Sehe ich genauso. Drei Wochen sind auch deutlich weniger als 49 Tage. Da ist was anderes Faul.
Arduino F. schrieb: > Mir gefallen die "unsigned long" da nicht. > Das ist für AVR, angemessen, aber auf 32 Bit Modellen dürfte das dann > unnötiger Weise 64 Bit nutzen. long ist auf den meisten Plattformen 32 bit... So ein Ratespiel vermeidet man durch Nutzung von uint32_t & Konsorten.
Hatte mir die tage das zurecht Geklöppelt. Zwar nicht schön, aber erfüllt seinen Zweck. Wenn D2 nicht mit GND gebrückt, gibt es keine/kaum Serielle Ausgabe.
> Mir gefallen die "unsigned long" da nicht. > Das ist für AVR, angemessen, aber auf 32 Bit Modellen dürfte das > dann unnötiger Weise 64 Bit nutzen. Zumindest beim ARM ist unsigned long ebenfalls 32bit.
> Wenn D2 nicht mit GND gebrückt, gibt es keine/kaum Serielle Ausgabe.
Für solche Zwecke benutze ich manchmal einen Jumper, den ich mitten auf
den 6 Poligen ISP Anschluss stecke.
Stefanus F. schrieb: >> Wenn D2 nicht mit GND gebrückt, gibt es keine/kaum Serielle Ausgabe. > > Für solche Zwecke benutze ich manchmal einen Jumper, den ich mitten auf > den 6 Poligen ISP Anschluss stecke. Und wozu? Ich habe mindestens drei Anwendungen, wo serial.print aktiv, aber nichts angeschlossen ist, es passiert genau garnichts! Ich teile diese Ansicht: yesitsme schrieb: > sollte ungehört verhallen Ich habe eine Anwendung mit dem ProMini, wo ich Strom sparen will, da gibt es einen Brückenstecker (aka Jumper) "debug". Diesen frage ich ab und gebe nur serielle Daten aus, wenn er gesetzt ist, damit ich im Regelbetrieb schnell wieder in den Schlaf komme.
> Und wozu? Um die Zeit zu sparen, die Debug Ausgaben kosten. Wenn das für die Anwendung irrelevant ist, dann braucht man natürlich auch keinen Jumper. > Ich habe eine Anwendung mit dem ProMini, wo ich Strom sparen will, da > gibt es einen Brückenstecker (aka Jumper) "debug". Diesen frage ich ab > und gebe nur serielle Daten aus, wenn er gesetzt ist, damit ich im > Regelbetrieb schnell wieder in den Schlaf komme. Das wäre mein Grund Nr 2 gewesen. Ich bin verwirrt, das du nach einem Grund gefragt hast und direkt danach selbst einen geliefert hast. Irgend etwas muss ich da missverstanden haben.
Bei meinem indischen Motorrad hat sich der Hersteller was interessantes ausgedacht:
1 | Tx o---[===]---------o-+ |
2 | | |
3 | Gnd o----------------o-+ |
Und zwar hat es einen seriellen Ausgang, wo man eine LED anschließen kann. Diese gibt dann allerlei Diagnose-Infos als eine Art Morsecode aus. Fahren kann man in diesem Zustand nicht. Im Fahrbetrieb zieht man die LED ab und steckt einen Brückenstecker auf. Dadurch wird die Ausgabe der Diagnosemeldungen deaktiviert.
Stefanus F. schrieb: > Bei meinem indischen Motorrad hat sich der Hersteller was > interessantes > ausgedacht:Tx o---[===]---------o-+ > | > Gnd o----------------o-+ > > Und zwar hat es einen seriellen Ausgang, wo man eine LED anschließen > kann. Diese gibt dann allerlei Diagnose-Infos als eine Art Morsecode > aus. Fahren kann man in diesem Zustand nicht. > > Im Fahrbetrieb zieht man die LED ab und steckt einen Brückenstecker auf. > Dadurch wird die Ausgabe der Diagnosemeldungen deaktiviert. Und der Kurzschluss von TX nach GND stört nicht?
npn schrieb: > Und der Kurzschluss von TX nach GND stört nicht? Ich seh gerade, das ist wohl ein Widerstand in der TX-Leitung? Dann hat sich meine Frage erledigt. Sorry :-)
Stefanus F. schrieb: >> Und wozu? > > Um die Zeit zu sparen, die Debug Ausgaben kosten. Wozu? Für gesparte Clockticks gibt's kein Geld zurück ;-)
> Wozu? Für gesparte Clockticks gibt's kein Geld zurück
Wie gesagt, der Motor meines Motorrades kann zum Beispiel nicht laufen,
wenn diese Debug Meldungen des Steuermoduls aktiviert sind.
Wenn die Ausgaben in der konkreten Anwendung nicht stören, würde ich
auch auf eine Deaktivierung verzichten.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.