Forum: Mikrocontroller und Digitale Elektronik Arduino Serial.begin(9600);


von Al. K. (alterknacker)


Lesenswert?

Was passiert wenn Serial.begin(9600);
auskommentiert wird.

Das Programm läuft ja anstandslos weiter,  es werden nur keine seriellen 
Ausgaben gemacht??

von Georg (Gast)


Lesenswert?

Al. K. schrieb:
> es werden nur keine seriellen
> Ausgaben gemacht??

Das kann nur sauber funktionieren, wenn alles gestrichen wird, was mit 
seriell zu tun hat, sonst tauchen wahrscheinlich Fehlermeldungen auf.

Georg

von Mario M. (thelonging)


Lesenswert?

Wenn der Sendebuffer voll ist bleibt Serial.write hängen.

von Amateur (Gast)


Lesenswert?

Wird Serial.begin (...) auskommentiert, so passiert gar nichts!
Das ist so, als wenn Du den Deckel auf dem Objektiv lässt. Das hat auch 
keine Folgen.
Interessant wird es erst, wenn Du versuchst etwas fotografieren oder im 
Sourcecode irgendeinen seriellen Zugriff durchzuführen.
Wartet Dein Programm auf irgendeinen Empfang oder lauscht der 
angeschlossene Empfänger auf etwas, kann es zu lustigen Ergebnissen 
kommen.
Ich kann es im Konkreten nicht sagen, aber wenn ich einen 
Mikrocontroller bauen würde, so würde der die serielle Schnittstelle per 
default deaktiviert haben um die I/O-Pins freizuhalten.

von Amateur (Gast)


Lesenswert?

Ach so, die Sprachkeksperten haben für so etwas u. A. das Konstrukt
#ifdef
...
#enfif
zusammengestümpert.

Bei richtiger Anwendung zur Ausklammerung ALLER seriellen Zugriffe 
sollte Dein Programm auch problemlos funktionieren. Zur Lesbarkeit eines 
solchen Ergusses möchte ich mich aber nicht äußern. Auch nicht dazu, ob 
es noch funktioniert.

von Al. K. (alterknacker)


Lesenswert?

In meinen Falle habe ich nur serielle Ausgaben zum Monitor.
Interessant wäre noch der Zeitfaktor.
Wie schnell ist es mit ser.begin auszukommentieren und wie schnell wenn 
alle Printbefehle auskommentiert werden.
Die Printbefehle müssten doch im Compilierten Code verschwinden?!

von Wolfgang (Gast)


Lesenswert?

Al. K. schrieb:
> Wie schnell ist es mit ser.begin auszukommentieren und wie schnell wenn
> alle Printbefehle auskommentiert werden.

Schreib dir für die serielle Ausgabe ein Makro. Dann musst du nicht 
Überfall rumfummeln, sondern brauchst nur das Makro zu andern.

von Al. K. (alterknacker)


Lesenswert?

Wolfgang schrieb:
> Schreib dir für die serielle Ausgabe ein Makro. Dann musst du nicht
> Überfall rumfummeln, sondern brauchst nur das Makro zu andern.

Es geht mir nicht darum wie ich dies umgehen kann, sondern ich will nur 
wissen was da los ist?

von Einer K. (Gast)


Lesenswert?

Al. K. schrieb:
> Es geht mir nicht darum wie ich dies umgehen kann, sondern ich will nur
> wissen was da los ist?

Mannn....
Dann schau doch mal in den Quellcode, der liegt frei zugänglich auf 
deinem Rechner.

von Sebastian S. (amateur)


Lesenswert?

Das kann Dir niemand sagen (Ein paar Hellseher mal ausgenommen)!

Im Normalfall wird die Initialisierung der seriellen Schnittstelle 
EINMALIG beim Programmstart abgearbeitet und dann NIE wieder aufgerufen.
Der Aufruf wirkt sich somit NICHT auf die Laufzeit aus. Höchstens auf 
die Dauer des Programmstarts.

Während das Programm läuft sieht es so aus:
Wird nichts ausgegeben, so gibt es auch keine Beeinträchtigung.

Dann aber wird es interessant und kompliziert:
Die serielle Ausgabe ist im Grunde genommen ein Kopierbefehl, der die 
gewünschte Zeichenkette in den Ausgabepuffer kopiert. Das geht relativ 
schnell. Dabei kommt meist ein Ringpuffer zur Anwendung, der die 
Ausgabedaten verwaltet. Dieses Stück Software wird von der Hardware 
getriggert, um ein weiters Byte in den Ausgabepuffer zu holen. Somit 
kostet Dich die Pufferüberwachung auch kaum Zeit (Hardware), wohl aber 
das Kopieren des nächsten Bytes in das interne Schieberegister. Das geht 
aber relativ flott.
Die reine Bitschubserei erfolgt durch Hardware und kostet keine 
(Rechen)Zeit.

Was aber gerne vergessen wird ist die Aufarbeitung der Zeichenketten:
Hierfür werden gerne fprintf oder seine Kumpels verwendet. Diese 
Routinen brauchen relativ viel Platz (FLASH) und auch RECHENZEIT. Vor 
allem, wenn noch jede Menge Konvertierungen, zur Ausgabeformatierung, 
verwendet werden.

Die echte Zeit lässt sich also, ohne konkretes Beispiel nicht 
voraussagen und hängt vor allem vom Datenvolumen ab. Bei 9600 Baud ist 
hier natürlich auch ein natürlicher Flaschenhals vorhanden.
Letzterer greift natürlich erst, wenn der Schreibpuffer voll ist. Dann 
kann es zu völlig unvorhersehbaren Ereignissen kommen. Je nach 
Programmstruktur kann es nämlich jetzt passieren, dass die 
Schreibroutine nicht "zurückkommt", bevor der Puffer die aktuellen Daten 
aufgenommen hat. Ein guter Hellseher kann aber so etwas voraussehen.
Ein guter Programmierer hat hier die Möglichkeit Fehler zuzulassen 
(zerstückelte Ausgabe) oder es noch einmal zu versuchen.

Noch etwas, das gerne vergessen wird:
Ein Zeichen sind nicht gleich 8 Bit!
Üblicherweise kommen noch ein bis zwei Stopbit dazu, ein Paritätsbit 
sowie das obligatorischen Startbit. Somit ist ein Zeichen oft mehr als 
12 Bit lang.
Von den (9600 Baud) 1200 Zeichen pro Sekunde, mit denen viele rechnen 
werden bleiben weniger als 800 Zeichen pro Sekunde, die man auf diesem 
Wege loswird.

Ich hoffe ich habe nicht allzuviel vergessen.

von Einer K. (Gast)


Lesenswert?

Sebastian S. schrieb:
> Hierfür werden gerne fprintf oder seine Kumpels verwendet.
Im Fall der AVR Arduinos nicht.
Aber recht aufwändig bleibt es dennoch.

Sebastian S. schrieb:
> Flaschenhals vorhanden.
> Letzterer greift natürlich erst, wenn der Schreibpuffer voll ist.
Dann blockieren die Serial.print Methoden, bis sie ihre Daten los 
geworden sind.

Sebastian S. schrieb:
> Somit ist ein Zeichen oft mehr als
> 12 Bit lang.
> Serial.begin(9600);
1 Start + 8 Daten + 1 Stopp, keine Parität
Also 10 Symbole pro Byte.
Keine sonstigen Pausen, die Symbolfolgen grenzen unmittelbar aneinander.

von Christoph M. (mchris)


Lesenswert?

Al. K. schrieb:
> Es geht mir nicht darum wie ich dies umgehen kann, sondern ich will nur
> wissen was da los ist?

Bitteschön:

https://github.com/arduino/ArduinoCore-avr/blob/master/cores/arduino/HardwareSerial.cpp

von Stefan F. (Gast)


Lesenswert?

Bitte mache nicht den fehler, davon auszugehen, dass sich alle Arduino 
Cores gleich verhalten. Der obige Link ist vom AVR Core.

Beispiel wo es anders ist:
Beim alten STM32Duino von Roger Clark war Serial mit dem USB Port 
verbunden und benötigte keinen Aufruf von Serial.begin().

von Christoph M. (mchris)


Lesenswert?

>Bitte mache nicht den fehler, davon auszugehen, dass sich alle Arduino
>Cores gleich verhalten

Das ist mir völlig klar. Ich gehe davon aus, das er die 
Standard-Arduinos mit ATMEGA328 verwendet.

von Sebastian S. (amateur)


Lesenswert?

@Stefan F.

Was hat euch denn nur die arme Serial.begin () getan?

Die wird einmalig, am Programmanfang aufgerufen und nur wenn jemand 
nichts besseres zutun hat oder die Baudrate ändern will, wird sie 
nochmal durchlaufen. Auch wenn ein anderer Prozessor verwendet wird und 
andere Befehle abgearbeitet werden, ändert sich prinzipiell hieran 
nichts.

Also: Laufzeit praktisch = Null.

Übrigens: Vor dem eigentlichen Programmstart tut sich sowieso so 
einiges, was für Otto Normal Programmierer unsichtbar bleibt, was ja 
auch einige Zeit dauert.
Unabhängig davon was die Arduino-Umgebung noch alles benötigt. Angeblich 
müssen die ganzen Schnittstellen - so verwendet - initialisiert werden. 
Aber auch nur einmalig.

von Manfred (Gast)


Lesenswert?

Al. K. schrieb:
> Was passiert wenn Serial.begin(9600);
> auskommentiert wird.
>
> Das Programm läuft ja anstandslos weiter,  es werden nur keine seriellen
> Ausgaben gemacht??

Ich würde es ausprobieren.

Ich habe in mehreren Anwendungen serielle Ausgaben drin, im fertigen 
Gerät aber kein Terminal (USB) dran, das stört den Ablauf nicht. Ich 
weiß, dass ich damit ein paar Millisekunden unnütz verplempere, aber die 
Masse meiner Anwendungen ist nicht so zeitkritisch.

In einer Anwendung habe ich einen Brückenstecker (neudeutsch Jumper) 
eingesetzt und frage vor jeder seriellen Ausgabe ab, ob der Port low 
ist, das dauert nur ein paar wenige Mikrosekunden.

Amateur schrieb:
> Ach so, die Sprachkeksperten haben für so etwas u. A. das Konstrukt
> #ifdef
> ...
> #enfif
> zusammengestümpert.

Das Konstrukt ist bekannt, ich sehe aber als ziemlich sinnfrei an: 
Wenn ein Problem auftritt, will ich den PC anklemmen und gucken, ohne 
zuvor neu zu flashen. An einem ProMini kann ich das, wenn der DTR nicht 
angeschlossen wird und damit kein Reset ausgelöst wird.

von Einer K. (Gast)


Lesenswert?

Manfred schrieb:
> In einer Anwendung habe ich einen Brückenstecker (neudeutsch Jumper)
> eingesetzt und frage vor jeder seriellen Ausgabe ab, ob der Port low
> ist, das dauert nur ein paar wenige Mikrosekunden.

Warum tust du das?
https://www.arduino.cc/reference/en/language/functions/communication/serial/availableforwrite/

von Stefan F. (Gast)


Lesenswert?

Sebastian S. schrieb:
> Was hat euch denn nur die arme Serial.begin () getan?

"Uns" hat sie nicht getan. Aber du hast die Anfrage des TO offenbar 
nicht gelesen oder nicht verstanden.

von Manfred (Gast)


Lesenswert?

Arduino Fanboy D. schrieb:
>> frage vor jeder seriellen Ausgabe ab, ob der Port low
>> ist, das dauert nur ein paar wenige Mikrosekunden.
>
> Warum tust du das?
> 
https://www.arduino.cc/reference/en/language/functions/communication/serial/availableforwrite/

Ich verstehe nicht, was Du mir sagen willst.

Mein µC wacht auf, holt einen Analogwert und geht wieder schlafen. Die 
serielle Ausgabe von Rohwert und gerechnetem Wert samt Zusatztext würde 
meine Wachzeit etwa verdoppeln. Ich gaube nicht, dass ich schneller raus 
komme, als den TestPort abzufragen.

von Einer K. (Gast)


Lesenswert?

Brücke? Wozu?
Egal!

Alles klar, von schlafen war keine Rede, und auch sonst, verstehe ich 
nur Bahnhof von dem Zeugs, was du da laberst.
Einen Bezug zur Eingangsfrage sehe ich auch nicht.

Ich sehe da nur eine  Selbstdarstellung, ohne jeden Zusammenhang.
Sinnfrei.

Versuchs nochmal, mit Zusammenhang, oder lass es.

von Stefan F. (Gast)


Lesenswert?

Arduino Fanboy D. schrieb:
> verstehe ich nur Bahnhof von dem Zeugs

Der TO wollte wissen, wie sich Schreibzugriffe auf den seriellen Port 
verhalten, wenn der Port nicht geöffnet wurde. Seine Idee war, den Port 
nur bei Bedarf zu öffnen, wen Debug Logging gewünscht ist - falls das 
klappt.

Wir haben geklärt, dass das so nicht klappt, weil irgendwann der Puffer 
voll ist und das Programm dann hängen bleibt.

Also schlug jemand vor, Makros zu benutzen, um die Ausgaben beim 
Compilieren auszuschließen.

Manfred schlug als Alternative vor, dass er zum Umschalten einen Jumper 
benutzt, den er zur Laufzeit bei Bedarf umstecken kann.

Mit "labern" und "Selbstdarstellung" hat das nichts zu tun. Der Sinn 
einer solchen Diskussion ist, unterschiedliche Lösungsansätze zusammen 
zu tragen, genau das ist hier auch passiert. Also alles gut.

> Versuchs nochmal, mit Zusammenhang, oder lass es.

Ich denke du bist hier derjenige, der loslassen sollte.

von Einer K. (Gast)


Lesenswert?

Stefan F. schrieb:
> Ich denke du bist hier derjenige, der loslassen sollte.
Du hast (mal wieder) zu schnelle Schlüsse gezogen, und so die Realität 
verbogen.
Ein Irrtum in der Sache, gepaart mit der wohl zwangsläufig folgenden 
Falschdarstellung der Zusammenhänge.

Stefan F. schrieb:
> Wir haben geklärt, dass das so nicht klappt, weil irgendwann der Puffer
> voll ist und das Programm dann hängen bleibt.
Das ist doch völlig falsch.

Ohne Serial.begin(xxxx) landen alle Daten im Nirvana, weil die UART ewig 
und stetig TX-Buffer-Leer liefert. Somit wird der Ringpuffer nie voll.

Zu dem Behufe wurde hier doch ein Link zur *.cpp geliefert. (nicht rein 
geschaut?)
Und das Datenblatt zu den AVR solltest du doch mittlerweile gelesen 
haben.

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.