I need to read and respond to serial data being communicated at 19200bps. The data being transmitted are hex bytes that form commands (Apple Accessory Protocol Commands).
For example:
0xFF 0x55 0x04 0x04 0x00 0x26 0x01 0xD1
is a command to play or pause the current song.
It is formatted as follows:
0xFF 0x55 -> standard header
0x04 -> length of command mode+command+parameters (4 bytes long not including checksum)
0x04 -> command mode (mode 4, advanced control mode. 1 byte)
0x00 0x26 -> command (media control. 2 bytes)
0x01 -> parameter (play. 1 byte)
0xD1 -> checksum (1 byte)
The length of the commands can range from 7 bytes to 512 bytes and sometimes there are garbage bytes that get send.
ie: 0xFF 0x00 0xFF 0xFF 0x55 0x04 0x04 0x00 0x26 0x01 0xD1
where the first 3 bytes need to be ignored.
Most of the time, only one command is being sent at a time. This makes it fairly simple. However, there are times where multiple commands are sent at once, which means that my system has to parse out the commands and decode them one by one to send the appropriate responses. When multiple commands are sent, somewhere around 128 bytes (composed of ~15 commands) are sent.
I have tried reading the bytes one at a time, but on large commands or multiple commands, i end up loosing bytes in the Rx buffer. I switched gears and tried the Serial.readBytes() function. It works better, but I am confused how the Serial.setTimeout() method works. I tried:
char buffer[512];
...
Serial.setTimeout(10);
...
Serial.readBytes(buffer, 512);
Now, does this mean that Serial.readBytes will read bytes into buffer for 10ms OR if 512 bytes are read? Or does it mean that it will read up to 512 bytes into buffer as long as data bytes are being received at lease every 10ms, so that a timeout occurs if there is no Rx receives for 10ms or longer?
Is there a better way to do this in general? My understanding is that Arduino 1.0 and greater utilizes interrupt driven UART, but the Rx buffer is only 64 bytes. this means that I need to be able to pull out all the bytes in a command from the UART buffer, decode the command, generate and send a response very quickly for large commands or if there are multiple commands to prevent data loss. I believe the 8Mhz Arduino I am using can process fast enough to accomplish this, but it looks like there is a great deal of overhead with reading bytes one at a time using Serial.read() and using the polling method ( while(Serial.available() < 7); ) to ensure im reading from the hardware Rx buffer only when data is available.
I guess I can always increase the hardware Rx buffer to 512 bytes by modifying the hardware serial library (which will use 1Kb of program memory for Rx and Tx, but that's OK for my application as its not that big to begin with and i have 16K to play with).
I was hopping for some ideas for a better implementation where i can read one or multiple commands and process them (to remove them from the stock 64 byte buffer) without losing data.
I appreciate the help!