Senden und Empfangen über Rx und Tx Arduino Uno

Hallo zusammen ! :slight_smile:

Ich versuche mit einem Arduino Uno eine serielle Kommunikation mit einer Platine herzustellen.

Ich nehme schonmal vorweg :

  • Ich habe KEINE schematische Zeichnung oder Ähnliches.
  • Ich weiss nicht explizit welcher IC verbaut ist, da alles weggekratzt wurde

ZUR PLATINE:
-Bei der Platine mit der ich eine Kommunikation herstellen will handelt es sich um eine Impendanzmessplatine.
-Sie hat folgende Anschlüsse : RX TX 5V GND und die 2 Sensoren Pins
-Rx und Tx Kommunikation erfolgt über TTL Spannungspegel.
-Kommunikation erfolgt über das senden von 0x01, also für den Beginn der Messung
-Die Antwort/ Das Messergebnis wird automatisch gesendet.
-Es wird eine 8n1 mit 9600 Baudrate vorausgesetzt

Bisher habe ich mit Docklight über einen RS232/TTL Wandler mit der Platine kommunizieren (0x01 senden ) können und die Anwort der Platine erhalten.
Der Wandler den ich genutzt habe ist dieser hier :
Pollin Wandler

Nun möchte ich dasselbe mit dem Arduino tun und bei Erhalt der Antwort die Daten zukünftig loggen.

Mein Problem ist, dass ich keine Antwort erhalte und nicht weiss woran es liegt.

Ich habe im Code die Baudrate auf 9600 gesetzt und laut Internet ist die default Konfiguration der Serial Bibliothek auf 8n1 gesetzt.
Ich habe den Arduino sowohl and Usb als auch am Netz hängen und versorge die Platine über die 5V des Ardiono Pins.
Die Masse der Platine ist ebenfalls mit der Masse des Arduino verbunden und die Rx ist mit Tx und vice versa verbunden.

Hier mein Code in welchem ich 0x01 sende und 2 sekunden warte, damit die Platine antworten und den Seriellen Puffen mit der Antwort füllen kann... :

const unsigned int MAX_MESSAGE_LENGTH = 50;

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

void loop() {

Serial.write(0x01);
Serial.println();
delay(2000);

int i = Serial.available();
Serial.println(i);


 //Check to see if anything is available in the serial receive buffer
 while (Serial.available() > 0)
 {
   //Create a place to hold the incoming message
   static char message[MAX_MESSAGE_LENGTH];
   static unsigned int message_pos = 0;

   //Read the next available byte in the serial receive buffer
   char inByte = Serial.read();

   //Message coming in (check not terminating character) and guard for over message size
   if ( inByte != '\n' && (message_pos < MAX_MESSAGE_LENGTH - 1) )
   {
     //Add the incoming byte to our message
     message[message_pos] = inByte;
     message_pos++;
   }
   //Full message received...
   else
   {
 //Add null character to string
 message[message_pos] = '\0';

 //Print the message (or do other things)
 Serial.println(message);

 //Reset for the next message
 message_pos = 0;
   }
 }
 delay(2000);
}

Hier ist ein Screentshot meiner Ausgabe wo man sehen kann dass 0x01 ( der Kasten ? ) gesendet wird und meine Abfrage nach dem Inhalt des Seriellen Puffers nach 2 Sekunden gleich Null entspricht, also ist der Puffer leer und der Arduino nie eine Antwort erhalten...

Ich hoffe jemand kann mir hier weiterhelfen worans liegt oder liegen kann :slight_smile:

Danke !

Der UNO hat eine UART, wo Du zwei Teilnehmer, USB und den Sensor anschließt. Das ist keine gute Idee!

Verwende einen Arduino mit mehreren UARTs wie den Mega2560 oder nutze SoftwareSerial.

Hänge Deinen RX/TX nicht an 0/1 an den Arduino.
Bei einem UNO nimm z.B. 2/3.
Dann zusätzlich Code umbauen:

const unsigned int MAX_MESSAGE_LENGTH = 50;
#include <SoftwareSerial.h>

SoftwareSerial mySerial(2, 3); // RX, TX

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

void loop()
{
  mySerial.write(0x01);
  mySerial.println();
  delay(2000);
  while (mySerial.available() > 0)
  {
    //Create a place to hold the incoming message
    static char message[MAX_MESSAGE_LENGTH];
    static unsigned int message_pos = 0;
    //Read the next available byte in the serial receive buffer
    char inByte = mySerial.read();
    //Message coming in (check not terminating character) and guard for over message size
    if ( inByte != '\n' && (message_pos < MAX_MESSAGE_LENGTH - 1) )
    {
      //Add the incoming byte to our message
      message[message_pos] = inByte;
      message_pos++;
    }
    //Full message received...
    else
    {
      //Add null character to string
      message[message_pos] = '\0';
      //Print the message (or do other things)
      Serial.println(message);
      //Reset for the next message
      message_pos = 0;
    }
  }
  delay(2000);
}

Reine Idee - ungetestet.
Das könnte ggfls gehen.
Darauf achten, das RX7TX nicht vertauscht sind.
Und dann mal sehen, der Code sieht mir verbesserungswürdig aus :wink:

Danke für deine Antwort!

Achso zählt der USB schon als ein Uart Teilnehmer ? Das war mir nicht bewusst.

Mit Mega2560 meinst du den Arduino Mega ?
Inwiefern würde das ggf. mein Problem lösen ? Kannst du da vielleicht bisschen ins Detail gehen ?
Wäre ich dann in der Lage USB und mein Sensorboard zu verwenden und die Daten im seriellen Monitor zu begutachten ? :smiley:

Danke auch für deine Antwort ! :slight_smile:
Wieso soll ich SoftwareSerial nehmen ?
Wäre ich damit in der Lage die Daten zu nutzen und ggf. im Seriellen Monitor anzuzeigen?

Genau darum!
Der SerielleMonitor ist sowohl Ein- als auch Ausgabemedium um Dir (auf dem computer Deiner Wahl) eine Schnittstelle zu bieten.

Du brauchst eine zweite Strecke, die sowohl Ein- als auch Ausgabe macht, die unabhängig von der Darstellung ist.
Dein Gerät wartet auf eine Eingabe und antwortet darauf.

Bei 9600 ist SoftwareSerial noch gut bei.

1 Like

Ja.

Nö, den Arduino Mega 2560 Rev3

Der hat vier UARTs, Serial für USB, Serial1 bis Serial3 sind frei verwendbar.

Ja.

Es gibt preiswerte Alternativen :slightly_smiling_face:

Aber auch SoftwareSerial mit dem UNO sollte funktionieren.

1 Like

Ersetze sollte durch wird.
:wink:
96008N1 gehen damit immer.
Ausser wenn da irgendwer mit delay irgendwas bastelt.

Vielen Dank euch beiden !!!
Ich werde mal SoftwareSerial ausprobieren
Im Notfall kauf ich den Mega 2560 Rev3 :sweat_smile:

Wenn es funktioniert melde ich mich obs klappt

und wenn nicht auch :slight_smile: :sweat_smile:

Was genau meinst du mit dem delay basteln?
Sollte ich keinen benutzen und du beziehst dich auf meine 2 delays?

Die habe ich ja drinnen weil die Platine etwas braucht um die Daten zu senden.
Dass das nicht instantan ist habe ich ja gesehen als ich mit dem RS232/TTL Wandler und dem Pc damit kommuniziert habe :slight_smile:

NÖ!
Meld Dich auch wenns nicht klappt!
Dann gibts Hilfe...

Wenn Du Pech hast, dann ist der Puffer voll und ein delay verhindert das abholen der Inhalte. Der Sender schiebt aber immer weiter - Dir gehen dann Inhalte verloren.

1 Like

:heart_eyes: die kann ich gebrauchen

war da echt bissl am verzweifeln :sweat_smile:

ich meld mich auf jeden Fall !

Die UARTs verwenden Interrupts und lesen daher auch Daten während eines delays. SoftwareSerial wird durch jedwede Verzögerung behindert, weshalb eine blockadearme Programmierung Pflicht ist.

Zum Probieren, ob Du eine Kommunikation zustande bekommst, ist SoftwareSerial auf jeden Fall geeignet.

Mega Board von Conrad

Wäre dieses Board auch ok ? Da steht jetzt nicht Rev3..
Und wenn ich dieses Board verwende könnte ich delays im code nutzen, da die serielle Kommkunikation nichtmehr softwarebasiert ist ?

bei mir steht da: Arduino® Mega 2560 Platine Rev3 :wink:

Nein.
Wenn der Fifo voll ist, nimmt er keine neuen Daten auf. Das habe ich oben schon geschrieben.

oh .. wer lesen kann... :sweat_smile: :sweat_smile:

Wenn eine Antwort komplett in den Empfangspuffer (64 Zeichen) passt, ist das delay kein Problem.
Allerdings ist delay völlig überflüssig. 9600 Ist so langsam, dass dein Sketch einfach immer wenn mal ein Zeichen angekommen ist, das auch verarbeiten kann (hier also auf Serial protokollieren kann. Serial kann übrigens der Einfachheit halber deutlich schneller als 9600 eingestellt werden).
Um zu erkennen, dass du seit 2000 ms keine '\001' mehr gesendet hast, brauchst du auch kein delay

ja ich verstehe dass der Speicher voll werden kann.
Worum es mir geht ist, dass der Arduino im moment zu schnell Daten sendet.
Wenn ich kein Delay nach dem mySerial.write() nutze bekomme ich das durcheinander:

gibberish

Wenn ich einen 100ms delay einsetze bekomme ich :

richtig

Ich dachte der delay stoppt den Code und somit die softwarebasierte serielle Kominikation vollständig, also sodass KEIN EMPFANG mehr möglich ist ?
Dennoch kriege ich Daten, auch wenn ich nach der Anforderung mit 0x01 einem 10 Sekunden Delay? Also wird wohl die Kommunikation nicht angehalten?

Ich versuche nochmal zu erläutern:
pro 0x01 senden bekomme ich EINE Antwort zurück welche auch nicht instantan ist. Wahrscheinlich misst die Platine erst nach dem Befehl und sendet anschließend die Messdaten.
Weil ich nur EINE Antwort bekomme und keinen Antwortstrom besteht die Gefahr nicht, dass der Speicher während dem Delay überfüllt wird und nicht ausgelesen oder falsche Werte sich ergeben. Er muss nicht geleert werden weil die Antwort endlich ist. Ich benötige nur das Zeitfenster der Messung und dem Empfang genug Zeit zu geben, da sonst Durcheinander in den Puffer übergeben wird. Habe ich deine Besorgnis verstanden? Solange ich dann den Speicher leere bevor ich die nächste Anfrage sende dann kann ja der Speicher nie überfüllt werden?
Ich KANN NICHT eine loop ohne eine Art des delays betreiben da ich sont "miss los" "miss los" "miss los" sende. Dann kommt sowas wie im oberen Screenshot raus. Mit dem delay von 100ms nach dem senden kommt der zweite screenshot raus der schon sehr nach dem gewünschten Ergebnis aussieht aber die Zahlen sind nicht in der richtigen Formatiereung. Das Format müsste so aussehenen :

Wie man sieht kommt nach jedem 5er Zahlenpaar ein HT = Horizontal Tabulator.
(Docklight Screenshot)

Somit habe ich die MAX_MESSAGE_LENGH auf 24 gesetzt und also 4x5+4 und jetz schauts so aus:

Done

Ich verwende nun einen delay von 100ms nach dem write befehl da sonst nix funktioniert.
Nachdem ich jetz genauer drauf eingegangen bin seht ihr dieses Vorgehen immernoch als problematisch an oder passt das für meinen " Anwendungsfall" mit dem delay ? :slight_smile:

Wie wäre es damit, den Code nicht 100mS zu pausieren, sondern mySerial.write(); nur aller 100mS auszuführen?