Have you ever tried to Serial.read() multiple bytes successively with an Arduino, only to have it spit out a bunch of 0xFF or similar nonsense?

I sure have. Check out this section of code from my mood light project:

uint8_t cmd = Serial.read();

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
 
//other stuff here
 
else if (cmd == 0xcc) { //set color 
    currR = Serial.read();
    currG = Serial.read();
    currB = Serial.read();
        
    writeEEPROM(currR, 18); //commit changes to EEPROM
    writeEEPROM(currG, 19);
    writeEEPROM(currB, 20);
        
    currSolidHasChanged = true;
    Serial.println(currR);
    Serial.println(currG);
    Serial.println(currB);
}

The problem here is that the Arduino is fast. Too fast. Once it receives the command byte, it blazes through all three Serial.read()s before all the data has a chance to be read in from the serial terminal. This issue becomes worse when slower baudrates are used.

The solution

Simple! Just wait for the desired number of bytes to be received before going on to process them.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
#define WAIT_FOR_SERIAL(x) while(Serial.available()<x)
 
 
uint8_t cmd = Serial.read();
 
//other stuff here
 
else if (cmd == 0xcc) { //set color 
    WAIT_FOR_SERIAL(3); //Real trap for young players!
    currR = Serial.read();
    currG = Serial.read();
    currB = Serial.read();
        
    writeEEPROM(currR, 18); //commit changes to EEPROM
    writeEEPROM(currG, 19);
    writeEEPROM(currB, 20);
        
    currSolidHasChanged = true;
    Serial.println(currR);
    Serial.println(currG);
    Serial.println(currB);
}

Is it ideal? Probably not. But hey, it works now!

Credits: https://www.gammon.com.au/serial – Without stumbling across this post, I probably would still be banging my head on the table figuring out what was wrong.