Serial.write() Issue

If I send a byte array of say 1,2,3 via serial .write as follows

byte arr[3]; arr[0]=1; arr[1]=2; arr[2]=3;

Serial.write(arr,3);

I receive in my c# program with the following code:

while (port.IsOpen) { try { byte[] s = new byte[3]; port.Read(s, 0, 3); int i0 = s[0]; int i1 = s[1]; int i2 = s[2]; string message = i0.ToString() + " " +i1.ToString() + " " +i2.ToString() + "|"; } catch (TimeoutException) { } }

this receives the following 4 byte arrays

1 0 0 2 3 1 2 3 1 2 3 0

Can anyone tell me why I am receiving 4 byte arrays when I only sent 1? Plus why are the bytes mixed up within the 4 arrays?

I can receive a single byte with no problem but as soon as I try to receive an array of them it all goes very wrong....

If I send a byte array of say 1,2,3 via serial .write as follows

Code snippets don't cut it. Post all of your code.

The c# simply replaces what was in your public void Read() method in the code you sent me.

I have also modifed the sendBtn event as follows:

private void sendBtn_Click(object sender, EventArgs e)
{
if (port.IsOpen)
{
byte arrByte=new byte[3];
arrByte[0]=(byte)1;
arrByte[1] = (byte)13;
arrByte[2] = (byte)1;
port.Write(arrByte, 0, 3);
}
}

Although the sketch only uses this currently in order to fire the board into action, I was expecting to send this byte and receive it straight back from the board…

The complete sketch is as follows.

byte arrData[3];
int function=0;

void setup()
{
Serial.begin(9600);
}

void loop()
{
if(Serial.available() > 0)
{
function=Serial.peek();

if(function>0)
{
function=0;
for(int i=0;i<3;i++)
{
arrData*=Serial.read();*

  • }*

  • Serial.flush();*

  • }*

  • if(arrData[0]>0)*

  • {*

  • byte arr[3];*

  • arr[0]=1;*

  • arr[1]=2;*

  • arr[2]=3;*

  • Serial.write(arr,3);*

  • arrData[0]=0;*

  • }*

  • }*
    }

This is interesting. Serial derives from Print, so Serial.write() actually uses Print::write().

void Print::write(const char *str)
{
  while (*str)
    write(*str++);
}

/* default implementation: may be overridden */
void Print::write(const uint8_t *buffer, size_t size)
{
  while (size--)
    write(*buffer++);
}

You are calling the second method, because you are supplying a size. It then calls the first method a number of times.

Because the first method expects a string, and stops sending when a NULL is encounter in the string, you will print data outside the extent of your array, because it is not NULL terminated.

I think that you need to call Serial.write() in a loop, writing one value at a time.

for(byte b=0; b<3; b++)
{
  Serial.write(arr[b]);
}

That is interesting. I assume that means it is actually impossible to send a byte[] back from the arduino in one go? Which also means that I will only ever receive single bytes at a time back from the board?

Would it be better to encode the bytes as a string and then print this back from the board rather than write? Or would these also only come back as individual bytes at a time?

All UARTs (that I've ever heard of anyway) handle 8 bits at a time, there is no such thing as sending an array or any other structure larger that a single bytes at once. This may well be hidden by functions but that's the bottom line.

Which also means that I will only ever receive single bytes at a time back from the board?

That's the nature of the serial beast, things are deconstructed to bytes then reconstructed at the other end.

Would it be better to encode the bytes as a string and then print this back from the board rather than write?

If you mean is it better to use .print() rather than .write() see above.

If your data is already in binary format you're probably better off leaving it that way. Converting to an ASCII representation will double the time it takes to transmit although it can make the protocol easier.


Rob

Thanks,

I am certainly not used to serial comms yet....

I will just have to figure out a way of knowing how many bytes I should be receiving so I can reconstruct them at the other end.