Kann ich im Serial Daten reinschreiben ohne das diese sofort gesendet werden?

Soweit mir bekannt, verwendet man im Arduino nicht direkt die UART des Atmega328, sondern eine Bibliothek.
Ist es also möglch div. Bytes per Serial.write() zunächst puffernd zu schreiben und anschliessend zu senden, oder muss ich mich selbst um das puffern kümmern?

mikrotron:
Soweit mir bekannt, verwendet man im Arduino nicht direkt die UART des Atmega328, sondern eine Bibliothek.
Ist es also möglch div. Bytes per Serial.write() zunächst puffernd zu schreiben und anschliessend zu senden, oder muss ich mich selbst um das puffern kümmern?

Arduino verwendet einen Sendepuffer, der bis zu 63 zu sendende Zeichen zwischenpuffert, die dann nach und nach interruptgesteuert im Hintergrund gesendet werden.

Sobald du was auf seriell schreibst, sendet der Arduino sofort in der eingestellten Baudrate los. Der Pufferspeicher ist m.W. nur, damit der Sketch nicht stockt,weil der Sketch i.d.R. Daten schneller liefert, als die serielle Schnittstelle sie übertragen kann.

Du kannst die Daten auch erst in einem eigenen Puffer bereitstellen. Und erst auf Commado absetzen. Warum sollen die Zeichen den nicht direkt gesendet werden?

Serial.write() zunächst puffernd zu schreiben und anschliessend zu senden,
oder muss ich mich selbst um das puffern kümmern?

Genaugenommen wird es doch genau so gemacht wie du das willst (hoffentlich):
Die Bibliothek HarwareSerial kümmert sich um das Puffern.
Serial.write kommt sofort zurück, noch bevor während das erste Zeichen vom UART langsam Bit für Bit auf die Leitung gelegt wird.
Auch die nächsten Serial.write schreiben nur in den Puffer und werden später gesendet, ohne dass du dich darum kümmern musst.

Erst wenn der Puffer voll ist, wartet Serial.write, bis ein weiteres Zeichen in den Puffer passt.

Mein Problem entstand, weil ich laut Protokoll ein Checksum-Byte am Ende eines Datagramms anfügen muss. Dieses muss über alle Bytes berechnet werden (XOR). Jetzt müsste ich also erst alle Bytes in ein Array schreiben, die Checksumme berechnen, anfügen und dann dieses Array an die Serial senden. Diese wiederum schreibt es erstmal in ihren eigenen Puffer und sendet dann.

Ich dachte an die Ressourcenverschwendung dabei. Leider bietet die Hardware-Lib für den UART keine Schnittstelle um auf den Puffer zuzugreifen.

Vielleicht liege ich aber auch total falsch und sollte es einfach so implementieren ohne mir viel Gedanken zu machen...

Kannst du nicht alle Bytes einzeln senden und gleichzeitig die Checksumme berechnen? Am Ende sendest du die Checksumme mit.

mikrotron:
Mein Problem entstand, weil ich laut Protokoll ein Checksum-Byte am Ende eines Datagramms anfügen muss. Dieses muss über alle Bytes berechnet werden (XOR). Jetzt müsste ich also erst alle Bytes in ein Array schreiben, die Checksumme berechnen, anfügen und dann dieses Array an die Serial senden. Diese wiederum schreibt es erstmal in ihren eigenen Puffer und sendet dann.

Sofern Dein "Checksum-Byte am Ende" gesendet werden soll, ist das mit dem zusätzlichen Zwischenpuffern doch völlig unsinnig.

mikrotron:
Dieses muss über alle Bytes berechnet werden (XOR).

Du mußt lediglich

  • vor dem Senden des ersten Bytes aus dem Datagramm Dein Checksum-Byte auf den Startwert setzen (z.B. 0)
  • beim Senden jedes Bytes aus dem Datagramm Dein Checksum-Byte per XOR fortschreiben
  • nach dem Senden des letzten Bytes aus dem Datagramm das Checksum-Byte zusätzlich senden

So what?

Doppelt zwischenpuffern müßtest Du vielleicht, wenn das Checksum-Byte als allererstes Byte gesendet werden soll, aber doch nicht dann, wenn es "am Ende" nach den eigentlichen Nutzdaten gesendet wird.

Wenn ich die Spezifikation des zu sendenden Protokolls genau nehme, muss ich nach jedem Byte prüfen ob dieses auch so gesendet wurde. Der Bus an den ich ankopple ist Halbduplex und hat eine gemeinsame Sende/Empfangsleitung. Hierdurch wird alles gesendete auch automatisch empfangen, wie bei einer lokalen Schleife. Das hat mit dem Checksum garnichts zu tun.

Daher mein Wunsch ein Byte zu senden und den Empfang zu prüfen und zu vergleichen. Versuchte es ein anderer Busteilnehmer zur gleichen Zeit zu senden, oder stimmt was an der Buselektrik nicht, dann kommt das Echo falsch und ich muss sofort mit dem senden aufhören, eine gewisse Zeit warten und erneut senden (Kollisionserkennung halt).

Eigentlich würde ich daher die UART gern selbst programmieren, was aber wohl nicht geht, da der Arduino Include vor allen Programmen geladen wird und somit ein direktes Programmieren der UART verhindert.

mikrotron:
Eigentlich würde ich daher die UART gern selbst programmieren, was aber wohl nicht geht, da der Arduino Include vor allen Programmen geladen wird und somit ein direktes Programmieren der UART verhindert.

Solange du nicht Serial.begin() machst solltest du das auch selbst tun können. Indem du direkt auf die Prozessor-Register zugreifst.

mikrotron:
Eigentlich würde ich daher die UART gern selbst programmieren, was aber wohl nicht geht, da der Arduino Include vor allen Programmen geladen wird und somit ein direktes Programmieren der UART verhindert.

Und warum soll das nicht gehen? Wie hast du das ganze denn bislang versucht.

Wenn ich die Spezifikation des zu sendenden Protokolls genau nehme, muss ich nach jedem Byte prüfen ob dieses auch so gesendet wurde

Da hast du entweder was falsch verstanden, oder du kannst den UART, oder zumindest Serial, gar nicht nehmen.
Der UART sagt zwar, wenn er fertig ist mit einem Zeichen, aber ob dies irgendwo angekommen ist, weiss keiner. Und Serial nimmt dir die Arbeit ab, darauf zu warten und dann das nächste Zeichen zu senden.

Aber was du selbst da besser machen könntest, weiss ich nicht.