Serial Communication

I’m having problems getting the Arduino to process a stream of bytes being sent to it over the USB connection from a Windows computer. The application that generates the stream is written in C#.

The general format of the stream is:

<command code (1 byte)> []

For example, the byte sequence:

100 1

Should cause the Arduino to echo back the following two bytes:

1 1

The sequence:

100 2

Should cause the Arduino to echo back three bytes as follows:

2 1 2

The algorithm is “echo back the number of bytes being sent, and then create a consecutive sequence of that number of values”. :slight_smile: It’s very simple at this point. But I’m using it as a way of learning how to get the Arduino to respond to more complex input from the Windows machine.

The sketch I use to do this is as follows:

#include “dispatcher.h”

#define BAUD_RATE 57600

USBCommandDispatcher commands[5]; // defined in dispatcher.h

void setup()
{
Serial.begin(BAUD_RATE);

commands[0].cmdCode = 65;
commands[0].cmd = identify;

commands[1].cmdCode = 66;
commands[1].cmd = read_clock;

commands[2].cmdCode = 67;
commands[2].cmd = set_clock;

commands[3].cmdCode = 100;
commands[3].cmd = echo_data;

commands[4].cmdCode = 101;
commands[4].cmd = echo_ff;
}

void loop()
{
unsigned char curCmd = 0;

if( Serial.available() )
{
curCmd = Serial.read();

for( int idx = 0; idx < sizeof(commands) / sizeof(USBCommandDispatcher); idx++ )
{
if( commands[idx].cmdCode == curCmd )
commands[idx].cmd();
}
}
}

void echo_data()
{
byte bytesToEcho;

if( Serial.available() )
{
bytesToEcho = Serial.read();

Serial.write(bytesToEcho);

for( int idx = 0; idx < bytesToEcho; idx++ )
{
Serial.write(idx + 1);
}
}
}

I’ve left out the code for the other commands (e.g., identify) for clarity’s sake.

My problem is that echo_data() never sends back anything, implying there are no bytes in the receive buffer. Yet I’m pretty sure my C# program is working, because the Arduino responds to various other “single byte” commands (e.g., identify).

I’ve read various articles on the web that hint at interesting buffering problems that can crop up when moving serial data over USB. Is there some trick to getting my approach to work? Or is it just not possible for some reason?

  • Mark

The Arduino calls loop in an endless loop. Depending on the serial communication speed, the 2nd byte of a multi-byte command may not have been received before the attempt to receive the 2nd byte occurs.

If you know that a command is a multi-byte command, you need to wait for the remaining bytes to arrive. The echo_data function does not do that.

Try adding

while(Serial.available() < 1)
{
}

to the top of echo_data. This is a do-nothing-until type of construct that does nothing until there is a byte to read.

Thanks!