Signed Int Werte per RS232 zwischen Arduinos austauschen

Hallo,

Ich habe ein Problem mit der Kommunikation. Normalerweise verwende ich immer eine Byteweise Kommunikation zwischen Arduinos, diesmal benötige ich aber höhere Zahlenwerte. Dabei kommt es zu folgendem Fehler:

Bis jetzt habe ich immer ein Byte losgeschickt, welches den Start einer Nachricht bedeutet und den Wert 0b11111111 hatte Danach habe ich dann die Werte in ein Array geschrieben. Aber mir ist aufgefallen, dass es manchmal zu problemen führt, Ich fürchte, dass die RS232 Schnittstelle dann zu langsam ist, sodass beim Startbyte angefangen wird, das Array zu füllen, aber mittendrin dann der Puffer leer ist, weil es nicht schnell genug nach kommt.

Gibt es eine universale Lösung, um dem zu entgehen? (Nicht Baudrate erhöhen)

Im Internet finde ich immer nur die Kommunikation mit dem Computer, das hilft mir leider nicht weiter.

Mein Ziel ist es, ein Array zu senden und genau diesen Inhalt in ein Array auf einem anderen µC bekomme.

Diesen Fall habe ich auch noch für ein anderes Projekt mit I2C...

Vielen Dank für die Hilfe

Lasse Dir vom Empfänger einen Code für "Ich habe empfangen" oder "nochmal" senden und baue darauf Deine Kommunikation auf. Erst wenn der Empfänger geantwortet hat, kannst Du neue Daten senden.

Gruß Tommy

Ich fürchte, dass die RS232 Schnittstelle dann zu langsam ist, sodass beim Startbyte angefangen wird, das Array zu füllen, aber mittendrin dann der Puffer leer ist, weil es nicht schnell genug nach kommt.

Der Harwareserial Buffer ist 64 Byte groß, da wird doch ein Integer rein passen, oder?

Nee… du hast da einen ganz anderen Bock geschossen!

Hallo,

ich habe auch eine Befürchtung. Durch fehlendes Protokoll wird dein Startbyte bestimmt irgendwann als Datenwert angesehen und es kommt Müll raus. Zum Bsp. wenn dein Startbyte zufällig auch einem Datenbyte entspricht. Wenn man nicht nur einzelne Bytes sendet sollte man sich ein Protokoll überlegen. Mit nur einer Kennung wäre laut meiner Meinung die Endekennung besser. Hier muss man dann zwingend ein Steuerzeichen verwenden was nicht im normalen Datenstrom vorkommt. Wenn man auf Nummer sicher gehen möchte mit Start- und Endekennung. Das wäre dann beliebig ausbaubar mit irgendwelchen prüfbaren Angaben über einfache Prüfsummen bis hin zu CRC.

Über eine Empfangsquittierung wie Tommy schon meinte sollte man auch nachdenken. Man sollte nicht wild drauflos senden in der Hoffnung es wird schon alles ankommen. Alle Prüfverfahren dienen nur dazu dem Empfänger eine Möglichkeit in die Hand zugeben das er entscheiden kann ob die Datenübertragung an sich okay oder fehlerhaft waren. Das Ergebnis sollte er dem Sender mitteilen. Dieser muss dann wiederum entscheiden was er dann macht. Klingt auf den ersten Blick kompliziert, auf den zweiten wirds besser.

Hm… Ich dachte das Startbyte ist das Protokoll… Natürlich habe ich bis jetzt immer dafür gesorgt, dass die Datenbytes niemals 0b11111111 sein dürfen. Das ging bis jetzt auch “gut”.

Die RS232 Kommunikation hat doch schon ein Protokoll mit Startbit und Paritätsbit, daher sollte es ja ankommen.

Aber das ist doch kein spezielles Problem, es muss doch schon etliche fertige Lösungen geben, wie:

Sender:

int senden[10], i;

void setup()
{
Serial.begin(9600);
Senden[0] = -2147483647;
}


void loop()
{
for(i=0,i<=9,i++)
Serial.print(Senden[0]);
}

Empfänger:

#define RS232IN 9
int empfangen[9], i;

void setup()
{
Serial.begin(9600);
}


void loop()
{
if (Serial.available()) {
   if(Serial.read()=-2147483647)
      for(i=0,i<=RS232IN,i++)
        empfangen[i]=Serial.read();
}

HA LOL!!! grade beim zusammenkopieren, wie ich das damals mit den bytes gemacht habe den Bug entdeckt, der die genannten Probleme gemacht hat… Serial.begin(9600); an die falsche Stelle geschrieben… OMG… Naja Nichtsdestotrotz besteht ja das int Problem noch.

-2147483647 passt nicht in ein int. Du solltest Dich über Datentypen und deren mögliche Wertebereiche informieren.

Gruß Tommy

Ja, habe das von hier… Einfache Datentypen scheint falsch zu sein…

Beim Arduino ist ein Int mit 0b11111111 11111111 natürlich -32,768

Wie schon gesagt, so große Zahlenwerte brauche ich nicht, mein Maximalwert wird 1023 sein, deswegen sind mir die Obergrenzen relativ egal.

Dem Arduino aber nicht.

Gruß Tommy

Natürlich nicht, der ist da stur.

Jetzt haben wir 4 Replies, ohne voran gekommen zu sein... Hält den Post aber schön oben :slight_smile:

Wenn Du mit Vorankommen meinst, dass Dir jemand den Sketch hinstellt, kann das noch eine größere Weile dauern. Ich finde, das Ausmerzen Deiner Fehler ist auch ein Vorankommen.

Gruß Tommy

Edit: Eigentlich hast Du alle Informationen bekommen, um es zu lösen.

Och ...

Was fertiges gibt's auch wohl.

Der CmdMessenger

Beim Arduino ist ein Int mit 0b11111111 11111111 natürlich -32,768

Falsch, das ist eine -1.
-32768 wäre 0x8000 oder 0b1000000000000000

Natürlich habe ich bis jetzt immer dafür gesorgt, dass die Datenbytes niemals 0b11111111 sein dürfen. Das ging bis jetzt auch “gut”.

Was ist mit 255, 511, 767, 1023 ? ( Die enthalten alle eine Datenbyte mit dem Wert 0xFF )

Sonderwerte für einzelne Bytes sind problematisch, wenn man dadurch einfach und sicher auf den Anfang eines 16bit-Wertes synchronisieren will.

Ein Int mußt Du in 2 Byte zerlegen und diese dann verschicken. Auf der Empfängerseite mußt Du sie wieder zusammensetzen.

lowbyte = int % 256;
highbyte = int / 256;

int = highbyte*256+lowbyte;

Grüße Uwe

McKaiver:
Aber das ist doch kein spezielles Problem, es muss doch schon etliche fertige Lösungen geben, ...

Schau mal bei Nick Gammon How to send and receive numbers. Für mich ist das Gammon Forum immer ein Quell der Erkenntnis.

Die grundsätzliche Frage ist immer: Übertragung als Text oder Binär?

Wenn es universell, direkt lesbar (für Menschen), leicht testbar sein soll, gibt es zig fertige Lösungen, von Nick Gammon bis parseInt, die textbasiert arbeiten.

Wenn es schnell sein soll, hat binäre Übertragung einen Vorsprung, allerdings muss man sich dann um die Details selber kümmern.

Mit RS232 hat der Thread übrigens (bisher) nichts zu tun.

Wenn es universell, direkt lesbar (für Menschen), leicht testbar sein soll, gibt es zig fertige Lösungen, von Nick Gammon bis parseInt, die textbasiert arbeiten.

Wenn es schnell sein soll, hat binäre Übertragung einen Vorsprung, allerdings muss man sich dann um die Details selber kümmern.

Der CmdMessenger kann beide Modi, und man muss sich trotzdem um (fast) nix kümmern.

Hallo,
aus Deinen beiden eingestellten Sketchen könnte man entnehmen das Du eigendich Texbasiert arbeiten willst. Ich denke das ist auch einfacher für den Anfang. Wenn die Anzahl der Zahlenwerte überschaubar und immer gleich ist, würde ich eigendlich zunächst mal alle Werte in einer Zeile ausgeben. Am Anfang eventuell ein Zeichen als Startkennung "S" und dann die einzelnen Werte mit einem Trennzeichen, zB ";" getrennt. Am Ende der Zeile steht dann eine Zeilenendkennung z.B LF (lineFeed)

Beim Empfangen liest Du ,wenn ein S erkannt wurde, alle Zeichen bis das Endeichen kommt in einen C-Zeihenkette ein. Wie man daraus wieder die einzelnen Zahlenwerte macht findest du hier.

Wichtig ist natürlich das der Empfänger schnell genug die Soft-Serial Schnittstelle abfragen kann. Der Dateneingangspuffer ist standard glaube ich 64Byte groß der kann dir bei 10 Integerwerten(ca. 80 byte) überlaufen wenn das übrige Program lange Schleifen oder gar delay() verwendet. Wenn die Schnittstelle mit 9600 betrieben wird sind das etwa 960 Zeichen/s die da kommen können. Damit ist der Eingangspuffer dann nach etwa 60ms voll.

Heinz

Ich habe eine Bibliothek gefunden, die das mit DMX in eine Richtung macht... gibt es nicht sowas bidirektional mit RS232?

McKaiver:
Ich habe eine Bibliothek gefunden, die das mit DMX in eine Richtung macht... gibt es nicht sowas bidirektional mit RS232?

A Arduino Library for sending and receiving DMX

Jetzt ziehe doch nicht die Dinge an den Haaren herbei.
DMX ist ganz was anderes, als du offensichtlich benötigst.

DMX kann man benutzen, wenn man DMX benötigt.
Der Standard für Bühnenbeleuchtung.

Baust du Beleuchtungseinrichtungen für Veranstaltungen?
Nein?
Dann vergiss DMX.

Darf ich dich fragen, was dir am CmdMessenger nicht schmeckt?

einen text sollte man Standardisieren
und als zeile übertragen
mit konstantem trenner
kennung#block1#block2mitziffern#block3mitzahlen

alles überprüfbar dann knappt das mit der übertragung auch sehr schnell
83zeichen empfangen ACK zurück