Multiple serial message formats in the same sketch?

Would it be possible to receive different message formats in the same sketch with different start and stop bits?
For example one might be <int, int, int>, and the other might be ~string; .

Obviously I would need to parse each one separately.

Before you ask, the reason I’m doing this is that I need to display a very large number (±897,587,224,200.000) that is too large to store as numericon an UNO. I don’t need to do anything other than display it on an indicator, however, I need to do math on the other message.

What do you mean by "different start and stop bits" ? Changing those is not very practical. Or do you mean different start and stop bytes ? Not the same thing.

The examples in serial input basics will do what you want - possibly the second example. You can increase the size of the array for received data by changing the constant numChars

There is no restriction of receiving different data - just parse each piece appropriately.

...R

Robin2:
The examples in serial input basics will do what you want - possibly the second example. You can increase the size of the array for received data by changing the constant numChars

There is no restriction of receiving different data - just parse each piece appropriately.

…R

I actually started this based on that post, thank you, by the way. It was helpful.

I actually got it figured out and working, but I have a weird issue. The pull from buffer loop never gets any data, or more precisely, the conditionals don’t seem to do anything. I had to add a Delay(1); to each conditional in the Serial.read loop to get it to work. Without those delay statements, I get nothing as if the variables have no data in them. I wonder if I’m hitting a compiler issue with nested loops and nested conditionals or if there is some kind of timing issue…

Geneticus0:
but I have a weird issue.

So have I. :slight_smile:
I can’t see the code you are talking about.

…R

Robin2:
So have I. :slight_smile:
I can’t see the code you are talking about.

…R

heh, yeah. I wanted to give it a few more tries before I gave up and crawled here for help on that…
So, here I am :stuck_out_tongue:

I seem to have made things worse. Before My ParseDoubleMessage method was working, now I seem to be looping the parse methods. My sample messages are:
~1, Here is a first string to parse^
<234, 467, 4587, 125>
<1234, 9467, 4587, 6125>
~2, Here is a second string to parse!^
~3, Here is a third string to parse^
<945, 7, 28, 1159>
~496, Here is a fourth string to parse!^

/*-----( Import needed libraries )-----*/

/*-----( Declare Constants and Pin Numbers )-----*/
int led13 = 13;
int led12 = 12;
/*-----( Declare objects )-----*/

/*-----( Declare Variables )-----*/
const byte numChars = 64;
char receivedChars[numChars];
boolean message = false;
char startMarkerUsed= '.';

void setup() 
{
  pinMode(led13, OUTPUT);      // sets the digital pin as output
  pinMode(led12, OUTPUT);      // sets the digital pin as output
  Serial.begin(115200);  //set serial to 115200 baud rate
}

void loop() 
{                       
 recvData();
 
 switch(startMarkerUsed)
 {
    case '<':
    //message = true;
    startMarkerUsed = '.';
	parseDoubleMessage();
     
    break;
    
    case '~':
    //message = true;    
    startMarkerUsed = '.';
    parseStringMessage(); 
    break;

    case '.':
    //do nothing
    break;
    
    default:
    DebugPrint("Default case: ", 1);
    break;
  
 }
	
}
void DebugPrint( char *debugMessage, int Var1)
{                          
      Serial.print (debugMessage);
      Serial.print (Var1,DEC); 
      Serial.println(); 
}   
void recvData() 
{
	static boolean recvInProgress = false;
	static byte index = 0;
	//char startMarker = 0x2;
	//char endMarker = 0x3;
	char startMarker = '<';
	char endMarker = '>';
	char startMarkerString = '~';
	char endMarkerString = '^';
	char rc; 
	  
    while (Serial.available() > 0 && message == false)
        {
		      rc = Serial.read();
			  if (rc == startMarker){ startMarkerUsed = rc; Serial.println(startMarkerUsed); }
			  else if (rc == startMarkerString){ startMarkerUsed = rc; Serial.println(startMarkerUsed); }
		      if (recvInProgress == true) 
		      {
             delay(1);
			 
			 //Serial.print(rc);
			 
			      if (rc != endMarker || rc != endMarkerString ) 
			      {              
             delay(1);
				      receivedChars[index] = rc;
				      index++;
				      if (index >= numChars)
				      {
					      index = numChars - 1;
				      }
			      }
    			else 
    			{           
					delay(1); 
					Serial.println();
					Serial.println("Terminating read");
    				receivedChars[index] = '\0'; // terminate the string
    				recvInProgress = false;					
    				index = 0;
    				message = true;
					Serial.print("All Characters reveived: ");
					Serial.println(String(receivedChars));
					Serial.println();
          
    			}
    		}
		    else if (rc == startMarker || rc == startMarkerString) 
		    {             
			    startMarkerUsed = rc;
			    recvInProgress = true;
         delay(1);
		    }
	    }
}

void parseDoubleMessage() 
{
          char delimiter[]= ",";
          char* valPosition; 
          double doublearray[5];
          int dataType = 0;
          int item = 0;
          double CurrentValue = 0.0;
          double MaxValue = 0.0;
          int i=0;          
          
          Serial.println("Parsing Double Message:");         
          
	if (message == true) 
        {
			Serial.print("RecievedChars: ");
			Serial.println(receivedChars);
            valPosition = strtok(receivedChars, delimiter);
                         
                    while(valPosition != NULL)
                    {                    
                    doublearray[i] = atoi(valPosition);
                    valPosition = strtok(NULL, delimiter);
                    DebugPrint("Item Index: ", i);                                        
                    DebugPrint("Loop Value: ", doublearray[i]);
                    i++;                    
                    }
					doublearray[i] = '\0';
                    DebugPrint("Current Item1: ", doublearray[0]);
                    DebugPrint("Current Item2: ", doublearray[1]);
                    DebugPrint("Current Item3: ", doublearray[2]);
                    DebugPrint("Current Item4: ", doublearray[3]);
                    String serialDebug = "";
                    serialDebug = " Array of ";
                    serialDebug +=  i,DEC ;
                    serialDebug += " doubles created.";
                    Serial.println(serialDebug);                   

					dataType = (int)doublearray[0];                   
					item = (int)doublearray[1];            
					CurrentValue =  doublearray[2];                 
					MaxValue =  doublearray[3];
					//DebugPrint("DataType: ", dataType);
					//DebugPrint("item: ", item);
					//DebugPrint("CurrentValue: ", CurrentValue);
					//DebugPrint("MaxValue: ", MaxValue);                  
					message = false;
					
    //Message received:
                digitalWrite(led13, HIGH);   // turn the LED on (HIGH is the voltage level)
                delay(1000);               // wait for a second
                digitalWrite(led13, LOW);    // turn the LED off by making the voltage LOW
                delay(1000);               // wait for a second
	}
}
void parseStringMessage()
{
          char delimiter[]= ",";
          char* valPosition; 
          int ItemType = 0;
          char ItemText[64];
          int i=0;       
          
          Serial.println("Parsing String Message:");        
          
  if (message == true) 
        {
			Serial.print("RecievedChars: ");
			Serial.println(receivedChars);                
          valPosition = strtok(receivedChars, delimiter);
          ItemType = atoi(valPosition);
          valPosition = strtok(NULL, delimiter);  
          strcpy(ItemText, valPosition); 
		  
         }
		  
            DebugPrint("Item Type: ", ItemType);                    
            String serialDebug = "";
            serialDebug = "String received: ";
            serialDebug += String(ItemText);
            Serial.println(serialDebug);                  
            digitalWrite(led12, HIGH);   // turn the LED on (HIGH is the voltage level)
            delay(1000);               // wait for a second
            digitalWrite(led12, LOW);    // turn the LED off by making the voltage LOW
            delay(1000);               // wait for a second
			message = false;
			Serial.println("End of String Parsing");
}

with this message: <123,568,9101,11213> I get:
~
Parsing String Message:
Item Type: 0
String received: Here is a first string æغ6

End of String Parsing
~
~
Parsing String Message:
Item Type: 0
String received: Here is a first string æغ6œŽr2

End of String Parsing
~
Parsing String Message:
Item Type: 0
String received: Here is a first string æغ6œŽ <----This repeats until I reset the controller.

Do you have control over the way the numbers are sent? If so you might tag each number with its own identifier. Below is some servo test code that uses servo identifiers with each numeric command position.

//zoomkat 11-22-12 simple delimited ',' string parse 
//from serial port input (via serial monitor)
//and print result out serial port
//multi servos added 
// Powering a servo from the arduino usually *DOES NOT WORK*.

String readString;
#include <Servo.h> 
Servo myservoa, myservob, myservoc, myservod;  // create servo object to control a servo 

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

  //myservoa.writeMicroseconds(1500); //set initial servo position if desired

  myservoa.attach(6);  //the pin for the servoa control
  myservob.attach(7);  //the pin for the servob control
  myservoc.attach(8);  //the pin for the servoc control
  myservod.attach(9);  //the pin for the servod control 
  Serial.println("multi-servo-delimit-test-dual-input-11-22-12"); // so I can keep track of what is loaded
}

void loop() {

  //expect single strings like 700a, or 1500c, or 2000d,
  //or like 30c, or 90a, or 180d,
  //or combined like 30c,180b,70a,120d,

  if (Serial.available())  {
    char c = Serial.read();  //gets one byte from serial buffer
    if (c == ',') {
      if (readString.length() >1) {
        Serial.println(readString); //prints string to serial port out

        int n = readString.toInt();  //convert readString into a number

        // auto select appropriate value, copied from someone elses code.
        if(n >= 500)
        {
          Serial.print("writing Microseconds: ");
          Serial.println(n);
          if(readString.indexOf('a') >0) myservoa.writeMicroseconds(n);
          if(readString.indexOf('b') >0) myservob.writeMicroseconds(n);
          if(readString.indexOf('c') >0) myservoc.writeMicroseconds(n);
          if(readString.indexOf('d') >0) myservod.writeMicroseconds(n);
        }
        else
        {   
          Serial.print("writing Angle: ");
          Serial.println(n);
          if(readString.indexOf('a') >0) myservoa.write(n);
          if(readString.indexOf('b') >0) myservob.write(n);
          if(readString.indexOf('c') >0) myservoc.write(n);
          if(readString.indexOf('d') >0) myservod.write(n);
        }
         readString=""; //clears variable for new input
      }
    }  
    else {     
      readString += c; //makes the string readString
    }
  }
}

I have the code cleaned up a bit now. It appears that the Start marker is not getting removed from the Serial buffer.

Updating Code above.....

Geneticus0:
Updating Code above.....

Don't tease ...

Just post when the code is available.

...R

Robin2:
Don't tease ...

Just post when the code is available.

...R

I did. I put in the earlier post.... #5 in this thread.

Geneticus0:
I did. I put in the earlier post.... #5 in this thread.

That's even worse. It destroys the chronological order of the discussion.

Can you set Reply #5 back to its original version and post the new code following this Reply, please

...R

It appears that the Start marker is not getting removed from the Serial buffer.

Why are you using a start marker? Most likely you don't need that and it just adds code issues.

Robin2:
That's even worse. It destroys the chronological order of the discussion.

Can you set Reply #5 back to its original version and post the new code following this Reply, please

...R

If I can borrow your time machine. There were about 30 edits as I continued to work on it.

Geneticus0:
If I can borrow your time machine. There were about 30 edits as I continued to work on it.

Well then just take a “slap on the knuckles” :slight_smile:

For your own sanity you should be keeping copies of the older versions of the code.
A large part of debugging involves comparing one version with a previous version.

You seem to be changing the start markers as a means of distinguishing messages. I suggest you stick to a standard start marker (and end marker) and use the first character of the message to identify the type of message. For example
<a,this is message type a>
<b,12,36,test>

then you can have a single function to receive everything - for example the 3rd example in serial input basics - and just forget about that part of the program.

…R

Maybe so, however, that still doesn't explain how/why the start marker could be left in the serial buffer.
Either Serial.read removes it or it doesn't or I'm doing something that is making it stick around.

Geneticus0:
Maybe so, however, that still doesn't explain how/why the start marker could be left in the serial buffer.

Using my code in serial input basics it will not be

...R