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.