Serielle Kommunikation mit 2 Schnittstellen

Für ein Projekt benötige ich 2 serielle Schnittstellen. Ich möchte gerne den Nano verwenden.
Schnittstelle 1 ist an PIN 0,1 (Standart) und Schnittstelle 2 an PIN 2,3.

An Schnittstelle 1 wird ein Zeichen empfangen. Anschließend wird auf Schnittstelle 2 ein fester Datensatz gesendet. Danach soll auf Schnittstelle 2 auf empfangene Zeichen gewartet werden und diese empfangen und bearbeitet an Schnittstelle 1 zurückgesendet werden.

Leider scheitere ich an den ersten Tests mit dem Empfangen und Senden. Das Problem liegt darin dass ich die Zeichen 1 x sende zur Schnittstelle 1 und 4 x an Schnittstelle 2 empfange. Habe verschiedene Varianten ausprobiert. Serial.print auf der Empfangsseite oder auch Sendeseite. Immer wieder 4 x wird der Datensatz gesendet obwohl ich nur 1 x sende. In der Anlage der erste Code. Vielleicht kann jemand einen Fehler erkennen oder weis an was das liegen kann. Ich habe auch schon delays eingefügt. Es werden immer 4 Datensätze mit 0x02 RN 0x03 gesendet.

#include <SoftwareSerial.h>

//SoftwareSerial portOne(0,1);
SoftwareSerial portTwo(2,3);
char A []= {'\2','R','N','\3'};


void setup() {
  
  Serial.begin(9600);
  portTwo.begin(9600);
  Serial.setTimeout (200);
  portTwo.setTimeout (200);
}

void loop() {
  
  portTwo.listen();
    
  if (portTwo.available() > 0) {
    char inByte = portTwo.read();
    delay (500);
    Serial.print(A);
    
     }
   }

Also ein Partner der Kommunikation ist der PC über Serial. Richtig?

Du kannst ein Array nicht einfach über print senden.
Da es anscheinend ein Char-Array (Zeichenkette) sein soll, könntest Du Dich mal über Zeichenketten schlau machen.

Gruß Tommy

Wenn du Zeichenketten verschicken willst, solltest du ein Linefeed als Endzeichen senden. Dann kann der Empfänger auf das Linefeed abfragen um festzustellen ob das Ende des Strings da ist.
Da kann man einfach println() nehmen. Das sendet CR + LF und das CR ignoriert man

Aber wenn du print/println(char*) verwendest muss der String unbedingt Null-terminiert sein! Wenn nicht musst du write() nehmen und dabei die Größe des Arrays angeben. Serial.print(A) kann so nicht richtig funktionieren

Und was soll ‘\2’ sein? \ ist für Escape-Sequenzen:

Das compiliert und geht so, aber macht sicherlich nicht genau was du denkst.

Das sollen wohl STX(0x2) und ETX(0x3) sein.

Gruß Tommy

Ok, kann sein. Aber das schreibt man dann normal nicht Oktal, sondern Hex. Mit so kleinen Zahlen geht es noch, aber mit größeren liegt man da schnell falsch.
Wenn man das als Endzeichen hat braucht man auch nicht unbedingt ein LF. Vielleicht kommuniziert auch mit etwas was ein festgelegtes Protokoll hat.

Der Hauptfehler liegt eben in der fehlenden Terminierung und falschen Verwendung von print(char*)

Danke für die Info.

\2 bedeutet 02Hex also STX. Das lässt sich anders nicht übermitten da es Steuerzeichen sind. Genauso wie \0 als Nullterminierung..

Der PC sendet eine Anfrage. Diese Anfrage wird konvertiert in STX RN ETX und über eine zweite serielle Schnittstelle zu einem Steuergerät gesendet. Daraufhin antwortet das Steuergerät mit einem festen Datensatz und 80! Zeichen. Diese werden zerlegt und zu einem festen Datensatz zusammengefügt.
Anschließend über die serielle Schnittstelle zum PC gesendet.
Ich belese mich mal über Zeichenketten und probiere mal den Write Befehl.

Vielen Dank bis später.

Gruß Camillo

Wenn die Zeichenkette fest ist, kannst Du auch schreiben:
const char antwort[] {0x2,'R','N',0x3,'\0'}.
Dann kannst Du auch Serial.print(antwort) benutzen, weil ‘\0’ hinten dran ist. Das ist dann eine Zeichenkette.
‘\2’ und ‘\3’ ist nicht standardisiert.

Gruß Tommy

Habe gerade ein paar Sachen getestet. Also Nullterminierung und Array Größenangabe hat nix gebracht.
Ich habe anstelle des Print Befehl den Write Befehl genutzt → kein Erfolg. Wenn ich ein festen Text in die Printausgabe oder Writeausgabe schreibe wird dieser auch 4 x gesendet. Also liegt das Problem nicht an dem Char sondern generell an der Funktion.

#include <SoftwareSerial.h>

//SoftwareSerial portOne(0,1);
SoftwareSerial portTwo(2,3);
//char A []= {'R','N',};


void setup() {
  
  Serial.begin(9600);
  portTwo.begin(9600);
  Serial.setTimeout (200);
  portTwo.setTimeout (200);
}

void loop() {
  
  portTwo.listen();
    
  if (portTwo.available() > 0) {
    char inByte = portTwo.read();
    delay (500);
    Serial.write("A");
    
     }
   }

Beschreibe doch mal genauer, was das eigentlich werden soll. Mit den Angaben in meiner Antwort sollte das so rüber kommen, wie Du es beschrieben hast, die hast Du aber völlig ignoriert (Ich sehe nichts davon in Deinem Code). So wirst Du nicht zu einer Lösung kommen.

Gruß Tommy

DonCamillo:
\2 bedeutet 02Hex also STX. Das lässt sich anders nicht übermitten da es Steuerzeichen sind.

Mein Punkt ist dass \2 Oktal ist. Das geht in dem Fall. Aber etwas sauberer ist 0x02 oder '\x02'. \8 z.B. wäre schon was anders als man annimmt. Ist aber eine Kleinigkeit und noch kein Fehler.

Ich habe anstelle des Print Befehl den Write Befehl genutzt

Das sind keine Befehle, sondern Methoden. C++ hat keine Befehle

 Serial.write("A");

Ist das gleiche wie print("A"). Es gibt da von beiden Methoden verschiedene Versionen mit unterschiedlichen Datentypen. Ich meinte das:

const char antwort[] = { 0x2,'R','N',0x3 };

...

Serial.write(anwort, sizeof(antwort));

Wenn man nicht-terminierte Arrays versendet muss man die Größe angeben

char inByte = portTwo.read();

Das liest ein Byte an. Wenn die Anfrage der Gegenseite länger als ein Byte ist reicht das nicht. Du musst das schon komplett einlesen. Wenn die Anfrage z.B. 4 Bytes hat, dann wird dein Code natürlich auf 4 mal ausgeführt.