Search code examples
parsingarduinoserial-portdmx512

Arduino Serial read and parse HEX


I'm trying to create an Arduino interface for the DMX software Freestyler, but struggling to parse the data received due to knowing the encoding of the data received.

The image bellow is a serial monitor I've attached to Freestyler to see the incoming data, the format is very simple 3 bytes per channel. 1st byte is the startOfMessage, 2nd byte is the channel number, 3rd byte is the channel value.

The serial monitor displays as hexadecimal and decimal.

For testing, I'm trying to switch on an led when the startOfmessage (which is a constant) is correctly parsed.

byte myByte; 
void setup(void){
Serial.begin(9600); // begin serial communication
pinMode(13,OUTPUT);
}

void loop(void) {
if (Serial.available()>0) { // there are bytes in the serial buffer to     read
  while(Serial.available()>0) { // every time a byte is read it is   expunged 
  // from the serial buffer so keep reading the buffer until all the bytes 
  // have been read.
     myByte = Serial.read(); // read in the next byte

  }
  if(myByte == 72){
    digitalWrite(13,HIGH);
  }
  if(myByte == 48){
    digitalWrite(13,HIGH);
  }
  delay(100); // a short delay
  }

 }

Could anyone set me in the right direction?

Serial Monitor Snap Shot


Solution

  • You must detect startOfMesage and with it, read channel and value. So, read byte from serial until you detect '0x48'

    byte myByte, channel, value;
    bool lstart = false; //Flag for start of message
    bool lchannel = false; //Flag for channel detected
    void setup(){
        Serial.begin(9600); // begin serial communication
        pinMode(13,OUTPUT);
    }
    
    void loop() {
       if (Serial.available()>0) { // there are bytes in the serial buffer to read
          myByte = Serial.read(); // read in the next byte
          if(myByte == 0x48 && !lstart && !lchannel){ //startOfMessage
             lstart = true;
             digitalWrite(13,HIGH);
          } else {
             if(lstart && !lchannel){ //waiting channel
                 lstart = false;
                 lchannel = true;
                 channel = myByte;
             } else {
                if(!lstart && lchannel){ //waiting value
                   lchannel = false;
                   value = myByte;
                } else {
                   //incorrectByte waiting for startOfMesagge or another problem
                }
             }
          }
       }
    }
    

    Not very elegant but could work.