How to combine this 2 Serial.read

Hi guys,
My project make use of 2 arduino, the Arduino MASTER send some value and receive a value from the Arduino SLAVE.
Inside the program i’ve used the function recvWithStartEndMarkers() written by Robin2 to send several value and to parse/use them as variable on the receveing arduino.

Now i would to send some value using that function and need to send some other singular char via Serial.print but there is a problem when adding this part:

    while (Serial.available() > 0) {
        incomingByte = Serial.read();

that seems to interferes with this part inside the function:

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

How i can write it without to add my part inside your recvWithStartEndMarkers() function?
because if i rename my incomingByte to rc it ask me to add the variable rc and vice versa if i rename the variable rc to incomingByte it doesn’t work anyway
How i can convert one of the 2 to be one format to be called 2 times and without to have to delete one of them?

TX

#include <PS3USB.h>
#include <PS3BT.h>
#include <usbhub.h>

#ifdef dobogusinclude				// Satisfy the IDE, which needs to see the include statment in the ino too.
#include <spi4teensy3.h>
#include <SPI.h>
#endif

USB Usb;

BTD Btd(&Usb);						// You have to create the Bluetooth Dongle instance like so
PS3BT PS3_BT(&Btd);					// This will just create the instance
PS3USB PS3_USB(&Usb); // This will just create the instance

bool printAngle;

#include <SoftwareSerial.h>
SoftwareSerial XSerial(9, 8); // TX, RX

const byte numChars = 32;
char receivedChars[numChars];

const int led_tx =  2;      // the number of the LED pin

// char endMarker = '>';
boolean newData = false;

//	variable values to be received and to hold the parsed data
char messageFromCAR[32] = {0};
float floatFromCAR = 0.0;

int shock = 0;

// variable values to be sent
int servo = 55;
int esc = 96;
int led1 = 0;
int led2 = 1;


void setup() {
	pinMode(led_tx, OUTPUT);
    Serial.begin(57600);
    Serial.println("<Arduino Controller is ready>");

	XSerial.begin(57600);
	XSerial.println("Hello, car?");

#if !defined(__MIPSEL__)
  while (!Serial); // Wait for serial port to connect - used on Leonardo, Teensy and other boards with built-in USB CDC serial connection
#endif
  if (Usb.Init() == -1) {
    Serial.print(F("\r\nOSC did not start"));
    while (1); //halt
  }
  Serial.print(F("\r\nPS3 Bluetooth Library Started"));

}

void loop() {
  Usb.Task();

	if (PS3_BT.PS3Connected || PS3_BT.PS3NavigationConnected) {
	
		servo = map(PS3_BT.getAnalogHat(LeftHatX), 0, 255, 0, 180);
		esc = map(PS3_BT.getAnalogButton(R2), 0, 255, 0, 180);
		  if (PS3_BT.getButtonClick(TRIANGLE)) {
			  led1 = 1;
		  } else {
			  led1 = 0;
				}
		  if (PS3_BT.getButtonPress(CIRCLE)) {
			  led2 = 1;
		  } else {
			  led2 = 0;
				}
	
		if (PS3_BT.getButtonClick(PS)) {
		  Serial.print(F("\r\nPS"));
		  PS3_BT.disconnect();
		}
		else {
		  if (PS3_BT.getButtonClick(TRIANGLE))
			Serial.print(F("\r\nH"));
		  if (PS3_BT.getButtonPress(CIRCLE))
			Serial.print(F("\r\nH"));
		  if (PS3_BT.getButtonPress(CROSS))
			digitalWrite(led_tx, HIGH);
			else digitalWrite(led_tx, LOW);
		  if (PS3_BT.getButtonPress(SQUARE))
			Serial.println(F("digitalWrite(led_rx, HIGH);"));
		}
	}
    recvWithStartEndMarkers();
    showNewData();

	parseData();

	Serial.print("<");
	Serial.print("2.3");
	Serial.print(",");
	Serial.print(servo);
	Serial.print(",");
	Serial.print(esc);
	Serial.print(",");
	Serial.print(led1);
	Serial.print(",");
	Serial.print(led2);
	Serial.print(",");
	Serial.print("Hello CAR");
	Serial.println(">");

	delay(50);	
}

// #########################	FUNCTIONS	#########################

void recvWithStartEndMarkers() {
    static boolean recvInProgress = false;
    static byte ndx = 0;
    char startMarker = '<';
    char endMarker = '>';
    char rc;
 
 // if (Serial.available() > 0) {
    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 showNewData() {
    if (newData == true) {
//	XSerial.print("Data Recieved :");
//	XSerial.println(receivedChars);
        newData = false;
    }
}

void parseData() {

    // split the data into its parts
    
  char * strtokIndx;						// this is used by strtok() as an index
  
  strtokIndx = strtok(receivedChars,",");	// get the first part - the string
  strcpy(messageFromCAR, strtokIndx); 		// copy it to messageFromPC
  
  strtokIndx = strtok(NULL, ",");			// this continues where the previous call left off
  floatFromCAR = atof(strtokIndx);			// convert this part to a float

  strtokIndx = strtok(NULL, ",");
  shock = atoi(strtokIndx);					// convert this part to an integer

}

RX

#include <Servo.h>
#include <SoftwareSerial.h>
SoftwareSerial XSerial(9, 8); // TX, RX

const byte numChars = 32;
char receivedChars[numChars];

int incomingByte;

const int led_rx =  12;      // the number of the LED pin

// char endMarker = '>';
boolean newData = false;

//	variable values to be received and to hold the parsed data
char messageFromPS3[32] = {0};
float floatFromPS3 = 0.0;

int servo = 0;
int esc = 0;
int led1 = 0;
int led2 = 0;

// variable values to be sent
int shock = 14;

void setup() {
	pinMode(led_rx, OUTPUT);

    Serial.begin(57600);
    Serial.println("<Arduino Car is ready>");

	XSerial.begin(57600);
	XSerial.println("Hello, ps3?");
}

void loop() {

    while (Serial.available() > 0) {
        incomingByte = Serial.read();
	
		if (incomingByte == 'H') {
			digitalWrite(led_rx, HIGH);
//      delay(10);
		} else digitalWrite(led_rx, LOW);
	}

    recvWithStartEndMarkers();
    showNewData();

	parseData();
//	showParsedData();

	Serial.print("<");
	Serial.print("Hello PS3");
	Serial.print(",");
	Serial.print("4");
	Serial.print(",");
	Serial.print("5.6");
	Serial.print(",");
	Serial.print(shock);
	Serial.println(">");

	delay(50);	
}

// #########################	FUNCTIONS	#########################

void recvWithStartEndMarkers() {
    static boolean recvInProgress = false;
    static byte ndx = 0;
    char startMarker = '<';
    char endMarker = '>';
    char rc;
 
 // if (Serial.available() > 0) {
    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 showNewData() {
    if (newData == true) {
//	Serial.print("Data Recieved :");
//	Serial.println(receivedChars);
        newData = false;
    }
}

void parseData() {

    // split the data into its parts
    
  char * strtokIndx;						// this is used by strtok() as an index
  
  strtokIndx = strtok(receivedChars,",");	// get the first part - the string
  floatFromPS3 = atof(strtokIndx);			// convert this part to a float

  strtokIndx = strtok(NULL, ",");
  servo = atoi(strtokIndx);					// convert this part to an integer

  strtokIndx = strtok(NULL, ",");
  esc = atoi(strtokIndx);

  strtokIndx = strtok(NULL, ",");
  led1 = atoi(strtokIndx);

  strtokIndx = strtok(NULL, ",");
  led2 = atoi(strtokIndx);

  strtokIndx = strtok(NULL, ",");
  strcpy(messageFromPS3, strtokIndx); 		// copy it to messageFromPC
  
}

void showParsedData() {
 Serial.print("Float ");
 Serial.print(floatFromPS3);
 Serial.print(" - ");
 Serial.print("Servo ");
 Serial.print(servo);
 Serial.print(" - ");
 Serial.print("Esc ");
 Serial.print(esc);
 Serial.print(" - ");
 Serial.print("Led1 ");
 Serial.print(led1);
 Serial.print(" - ");
 Serial.print("Led2 ");
 Serial.print(led2);
 Serial.print(" - ");
 Serial.print("Message ");
 Serial.print(messageFromPS3);
 Serial.println("");
}

How i can write it without to add my part inside your recvWithStartEndMarkers() function?

You can't. Why can't you add the new data between the existing markers? Why can't you define a different set of markers for the different packet type?

Why not use recvWithStartEndMarkers() with the single byte ?

PaulS:
You can't. Why can't you add the new data between the existing markers? Why can't you define a different set of markers for the different packet type?

I've already tried to send all the data between the existing markers and using the same function but after many test i've choosed to send just some value using that functions and the rest using a simple Serial.print().

UKHeliBob:
Why not use recvWithStartEndMarkers() with the single byte ?

Did you mean to send with Serial.write() method that sends the value in a byte as binary data?

but after many test i've choosed to send just some value using that functions and the rest using a simple Serial.print().

The device on the other end can't tell binary data from ASCII data. You MUST know what kind of data is coming in, so you know how to read it.

Since you seem to want to send binary and ASCII data at any point in time, you need to rethink your approach. It will be impossible for the receiving end to guess which bytes are binary and which are ASCII.

jonnys90:
Did you mean to send with Serial.write() method that sends the value in a byte as binary data?

No, I meant simply enclosing the single byte of data within start and end markers and using the same method as the multi byte message to receive and parse it.

When you define a protocol (or use a defined protocol as Robin2's one), you need to adhere to it.

It's very simple. You and I agree that when we speak over the phone we say 'LT' (smaller then) before we start a sentence and say 'GT' (greater than) when once the sentence is completed. So we're talking and all at a sudden (when it's your turn) you don't start with 'LT' but say 'OK'. At that moment I will not have any idea what you're talking about; it's just a word and is probably part of a sentence where I missed the beginning and hence I can't process it and I will ignore it as I don't know the context.

So if you want to send a single character, you still need to use the protocol; the sentence in above explanation will consist of just the single character..

Don't try to receive two different things at different places in your code. You would have to be very lucky if the sender is sending that type of message at that exact moment when you are listening for it.

There should be one central place in your code that reads the serial messages. It can keep track of which type of message is currently in progress. You may use different start markers to indicate different types of message but those markers should only be decoded in one place.

PaulS:
The device on the other end can't tell binary data from ASCII data.

But can i don't need absolutely to send binary data AND ASCII data, i just need to use Robin2's function and add another Serial.read outside the function that send the SAME FORMAT of data like the function, it's not a problem, if that it's possible.

sterretje:
So if you want to send a single character, you still need to use the protocol; the sentence in above explanation will consist of just the single character..

Ok, but can't i even, for example, just define an initial ABC = Serial.read(); and after use it both for the function and for the singular read like

if (incomingByte == 'H') make something....

it's that not possible?

it's that not possible?

Maybe. If a character arrives after the start marker, it is part of a packet. If a character arrives before the start of the start marker, it is not part of a packet. If a character arrives after the end marker, it is not part of a packet. So, handle the part-of-packet characters differently from the not-part-of-a-packet characters.

You will find that is FAR simpler to have two different kinds of packets with two different kinds of markers.

But, there's the wall. Feel free to keep pounding your head against it.

Having two consumers of a stream is going to split the stream into random pieces unless the consumers have some kind of handshake system. I have one program that does it, for the sake of timing. But it only works because I have an easy method to control exactly when one consumer should read, and when the other should. In general, this is a bad idea.

As mentioned above, if you need different parts of the program to read packet type A and packet type B from the same stream, you can create calls to get them from the same decoder (that has a common input from the stream).

aarg:
As mentioned above, if you need different parts of the program to read packet type A and packet type B from the same stream, you can create calls to get them from the same decoder (that has a common input from the stream).

Yeah, maybe this is what i'm looking for, have you some example where i can take a look at it? or you just mean "to have two different kinds of packets with two different kinds of markers" as @PaulS say?

jonnys90:
Yeah, maybe this is what i'm looking for, have you some example where i can take a look at it? or you just mean "to have two different kinds of packets with two different kinds of markers" as @PaulS say?

Sorry, I have no example. But it would likely be a state machine, where packet state A or B is entered depending on the received characters, and relinquished to a "listening" state once a packet is fully decoded.

You can expand the protocol

Currently it looks like

<floatFromPS3,servo,esc,led1,led2,message>

You can add an additional ‘field’ in the beginning

<yourtype,...>

The can be a single character.

You can use e.g. ‘D’ to indicate data and ‘C’ to indicate command (and allows you to send the H command).

<D,floatFromPS3,servo,esc,led1,led2,message>
<C,H>

The first one is the modified version for your current data, the second one can be used to send the H command.
For the second one, you can also create something like

<C, L, 1, 0>

C indicates command, L indicates led, 1 indicates which led and 0 indicates off (1 would indicate on). Your needs determine what you need to implement.

The first step in the parsing is to get the type. Based on the type, you decide how you want to parse the remainder of the data.

sterretje:
You can expand the protocol

Currently it looks like

<floatFromPS3,servo,esc,led1,led2,message>

You can add an additional ‘field’ in the beginning

<yourtype,...>

The can be a single character.

Yes, that’s how i was doing, but it gave me some freeze problems, so after a long reflection and many test i decided to send just from the Arduino A (Master) to the Arduino B (Slave), because in this way everything works perfectly, and in this way it work good also if i send more values without any freeze or garbage data.
So guys thank you very much for your time, i really appreciate it!