Go Down

Topic: Multi-byte serial command - the cleanest way (Read 575 times) previous topic - next topic

Retroplayer

I need to process commands that look like this is serial:

P001 (001-199)
and
V31 (0-31)
V01

The first number is a command, and the second part are values. I need to convert those values to a single byte.

Bonus if I can also recognize P1, P01 as the same thing as P001.

What is the cleanest way to do this? I am messing around with a Union data type, but all I get is 0.

Code: [Select]

#include <serMP3.h>

union serial_data {
   unsigned long number;
   byte read_byte[3];
} data;



serMP3 MP3(11,10);


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

void loop(){
  byte sc = 0;
  byte n =0;
 
  if(Serial.available()){
    sc = Serial.read();   
  }
 
  if(sc == 'p' || sc == 'P'){
   
    while(Serial.available() <=0); // wait for incoming serial data

      if (Serial.available() >= 3)  // wait for four bytes
      {
        for(int i=0;i <=3; i++) data.read_byte[i]=Serial.read();
      }
      n=byte(data.number);
     
   // Serial.print(Serial.available()); 
    Serial.print(n, DEC);
    MP3.play(n);
  }
  if(sc == 's' || sc == 'S'){
    MP3.stop();
  }
 
}

HazardsMind

#1
Feb 14, 2013, 07:19 pm Last Edit: Feb 14, 2013, 07:26 pm by HazardsMind Reason: 1
Try something along the lines of this.

Look at the incoming char P or V, if 'P' read incoming chars and store them in ArrayP, like wise for 'V'. Then convert the arrays to integers. You will need to add a Null terminator to the array, to use "atoi(ArrayP)" this will convert the chars into an actual integer.
My GitHub:
https://github.com/AndrewMascolo?tab=repositories

PaulS

Code: [Select]
    while(Serial.available() <=0); // wait for incoming serial data

      if (Serial.available() >= 3)  // wait for four bytes

Drop out of the while loop as soon as one byte arrives. Then, if 3 or more have arrived (2 would have had to arrive within 100 nanoseconds or so), read them.

There's not a snowball's chance of that if statement ever evaluating to true.

PeterH


I need to process commands that look like this is serial:

P001 (001-199)
and
V31 (0-31)
V01


Those look like ascii character sequences with fixed lengths that can be determined from the first character.

The simplest way to handle them would be to read the first character, work out how many characters are expected to follow and wait until that many were available, then read and process them. Rinse and repeat.
I only provide help via the forum - please do not contact me for private consultancy.

Retroplayer

Actually, it turns out to be extremely simple. lol. So far it is working as I want. Testing it some more to see if I break it

Code: [Select]

void loop(){
 byte sc = 0;
 unsigned long number = 0;
 byte n =0;
 
 if(Serial.available()){
   sc = Serial.read();  
 }
 
 if(sc == 'p' || sc == 'P'){
   number=Serial.parseInt();
   n = byte(number);
   MP3.play(n);
 }
 if(sc == 's' || sc == 'S'){
   MP3.stop();
 }
 
}

Go Up