"SOLVED" serial send and receive via 2 serial interfaces serial & serial1, hangs

Hi.

I have tried a lot of different approaches, to try to solve this.

The project is partly working. The main task is to get a lot of Int's (analog values from joystick,etc) from one arduino to another via serial.

I have also found a sample code that works, with just forwarding data from one serial port to another. (but this is just for debugging, not my main goal)
When i change that code, so i can save the variables to the plc before sending to other serial port it hangs.

This code works without hangs. But this is just forwarding.

void setup() {
  // initialize both serial ports:
  Serial.begin(9600);
  Serial1.begin(9600);
}

void loop() {
  // read from port 1, send to port 0:
  if (Serial1.available()) {
    int inByte = Serial1.read();
    Serial.write(inByte);
  }

  // read from port 0, send to port 1:
  if (Serial.available()) {
    int inByte = Serial.read();
    Serial1.write(inByte);
  }
}

I had different aproaches.

  1. To line up all the int's in one long string and send it to the other, for sorting the long sting back into seperate int's.
    (Have seen example code of this with comma separated values)
    I have also used this method with success on an industrial plc. but there i had available function blocks to get the job done easily.

  2. To send each int in separate string with an starting address. (my current example)
    This is now partly working. I think the problem occurs when i also send this data on the second serial line to my pc. because im not receiving any packages as long as the serial between the 2 arduinos are connected. but once i disconnect the TX on the arduino with 2 serials, it sends the buffered packages to the pc terminal. This happens everytime i connect/disconnect RX TX.
    so it seem like the receiving serial are preventing the sending serial from working.

Here is the code for the sending arduino. (arduino uno in my case)

#include <SoftwareSerial.h>

String stringOne, stringTwo, stringThree, sendstring, endstring;

SoftwareSerial mySerial(0, 1); // RX, TX

void setup() {
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }
  } 

void loop() {
// read the input on analog pin 0:
  int sensorValue1 = analogRead(A0);
// read the input on analog pin 1:
  int sensorValue2 = analogRead(A1);
// read the input on analog pin 2:
  int sensorValue3 = analogRead(A2);

  stringOne   = sensorValue1;
  stringTwo   = sensorValue2;
  stringThree = sensorValue3;
 
  endstring = "x";

  sendstring = "A";
  sendstring = sendstring  + stringOne + endstring;
  Serial.println(sendstring);    // prints  A followed by sensorvalue
 delay(1000);
  sendstring = "B";
  sendstring = sendstring  + stringTwo + endstring;
  Serial.println(sendstring);    // prints  B followed by sensorvalue
 delay(1000); 
  sendstring = "C";
  sendstring = sendstring  + stringThree + endstring;
  Serial.println(sendstring);    // prints  C followed by sensorvalue
 delay(1000); 
 
}

Here is the code for the receiving arduino (also the one with 2 serial ports in use, Arduino mega in my case)
The var incomingintA & incomingintB are the ones i will use internally in this plc.

String stringOne, stringTwo, sendstring, incomingString;

void setup() {
  // initialize both serial ports:
  Serial.begin(9600);
  Serial1.begin(9600);
}

void loop() {
 
  
 if (Serial1.available() > 0) {
incomingString = Serial1.readStringUntil("x");
delay (10);
 } 
 
if (incomingString.startsWith("A")) {

    String incomingA = incomingString.substring(1);
    
Serial.println(incomingA.toInt());
 int incomingintA = (incomingA.toInt());
 
 }

if (incomingString.startsWith("B")) {

    String incomingB = incomingString.substring(1);
    
Serial.println(incomingB.toInt());
 int incomingintB = (incomingB.toInt());

incomingString = ("0");
 
 }
}

Thanks in advance if anyone finds a solution for this :slight_smile:

SoftwareSerial mySerial(0, 1); // RX, TXwhy would you use the hardware Serial Port as Software Serial? why is that there since you don't use it?

Read Serial Input Basics to have some ideas on how to handle a Serial flow

Hi J-M-L

Thanks for fast response :slight_smile:

I made it after many hours of reading, testing and failing.

at first i use native serial. but when uploading it failed because it interrupted USB transfer.
then i tried softwareserial at pin 10,11. but somthing failed then and i switched back to native serial. and forgot to remove the softwareserial from the code.
but however that did not fix anything though.

why would you use the hardware Serial Port as Software Serial? why is that there since you don't use it?

And to your comment "Read Serial Input Basics to have some ideas on how to handle a Serial flow".

i had actually "read" it before. But didnt see how it could help me then.
but you made me read it all again throughly, and that really helped :slight_smile: Thanks

and here are a working result if someone else wonders. (couse i couldnt find any examples that helped me without reading a lot)

sending arduino (the one with joysticks)

String stringOne, stringTwo, stringThree, sendstring, startstring, endstring;

void setup() {
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }
  } 

void loop() {
// read the input on analog pin 0:
  int sensorValue1 = analogRead(A0);
// read the input on analog pin 1:
  int sensorValue2 = analogRead(A1);
// read the input on analog pin 2:
  int sensorValue3 = analogRead(A2);

  stringOne   = sensorValue1;
  stringTwo   = sensorValue2;
  stringThree = sensorValue3;

  startstring = "<";
  endstring = ">";
  sendstring = startstring  + ("string") + (",") + stringOne + (",") + stringTwo + (",") + stringThree + endstring ;
  Serial.println(sendstring);    // prints  string
 delay(100); 
}

receiving arduino (the one with servos etc)

#include <Servo.h>
Servo myservo;  // create servo object to control a servo
const byte numChars = 32;
char receivedChars[numChars];
char tempChars[numChars];        // temporary array for use when parsing

      // variables to hold the parsed data
char messageFromPC[numChars] = {0};
int integerFromPC1 = 0;
int integerFromPC2 = 0;
int integerFromPC3 = 0;
float floatFromPC = 0.0;

boolean newData = false;

//============

void setup() {
   myservo.attach(9);  // attaches the servo on pin 9 to the servo object
    Serial.begin(9600);
    Serial.println("This demo expects 4 pieces of data - text, an integer and a floating point value");
    Serial.println("Enter data in this style <HelloWorld, 12, 13, 24>  ");
    Serial.println();
}

void loop() {       // subroutines
    recvWithStartEndMarkers();
    servo();

    
    if (newData == true) {
        strcpy(tempChars, receivedChars);
            // this temporary copy is necessary to protect the original data
            //   because strtok() used in parseData() replaces the commas with \0
        parseData();
        showParsedData();
        newData = false;
    }
}
void recvWithStartEndMarkers() {
    static boolean recvInProgress = false;
    static byte ndx = 0;
    char startMarker = '<';
    char endMarker = '>';
    char rc;

    while (Serial.available() > 0 && newData == false) {
        rc = Serial.read();

        if (recvInProgress == true) {
            if (rc != endMarker) {
                receivedChars[ndx] = rc;
                ndx++;
                if (ndx >= numChars) {
                    ndx = numChars - 1;
                }
            }
            else {
                receivedChars[ndx] = '\0'; // terminate the string
                recvInProgress = false;
                ndx = 0;
                newData = true;
            }
        }

        else if (rc == startMarker) {
            recvInProgress = true;
        }
    }
}

void parseData() {      // split the data into its parts

    char * strtokIndx; // this is used by strtok() as an index

    strtokIndx = strtok(tempChars,",");      // get the first part - the string
    strcpy(messageFromPC, strtokIndx); // copy it to messageFromPC
 
    strtokIndx = strtok(NULL, ","); // this continues where the previous call left off
    integerFromPC1 = atoi(strtokIndx);     // convert this part to an integer

    strtokIndx = strtok(NULL, ","); // this continues where the previous call left off
    integerFromPC2 = atoi(strtokIndx);     // convert this part to an integer

     strtokIndx = strtok(NULL, ","); // this continues where the previous call left off
    integerFromPC3 = atoi(strtokIndx);     // convert this part to an integer

  //  strtokIndx = strtok(NULL, ",");
  //  floatFromPC = atof(strtokIndx);     // convert this part to a float
}

void showParsedData() {
    Serial.print("Message ");
    Serial.println(messageFromPC);
    Serial.print("joystick axis 1 ");
    Serial.println(integerFromPC1);
     Serial.print("joystick axis 2 ");
    Serial.println(integerFromPC2);
     Serial.print("joystick axis 3  ");
    Serial.println(integerFromPC3);
  //  Serial.print("Float ");
  //  Serial.println(floatFromPC);
}

void servo () {  
int servoaxis1 = integerFromPC1; 
  
  servoaxis1 = map(servoaxis1, 0, 1023, 20, 180);     // scale it to use it with the servo (value between 0 and 180)
  myservo.write(servoaxis1);                  // sets the servo position according to the scaled value
 }

regards Muzel

Good start - now that you understand how to handle c-String you can get rid of the Strings (with capital S) in the first Program

You actuallly don’t need to build your send buffer, you code just do

Serial.print(“<“);
Serial.print(analogRead(A0));
Serial.print(“,“);
Serial.print(analogRead(A1));
Serial.print(“,“);
Serial.print(analogRead(A2));
Serial.println(“>“);