Arduino Forum

Products => Arduino Due => Topic started by: dgelman on Feb 23, 2015, 08:36 pm

Title: Serial.read Signed Integers
Post by: dgelman on Feb 23, 2015, 08:36 pm
Hello Community,

For this application, I am using C# in Visual Studio to send values ranging from -1000 to 1000, to an Arduino Due via serial port. On the Due, I have it echoing back.

The only numbers that work well is between 0 - 255, which to me is obvious because Serial.read() reads one byte of data. How do I implement (preferably on the Arduino side) to read and construct signed integers with the range that I mentioned?

First, I would like to just learn how to send a signed byte via Serial.read() from -128 to 127. I seem to not be able to get that to work :-(.

Nothing too much to see, but on the Arduino side, the following code is being used:

Code: [Select]
void setup()
{
Serial.begin(115200);
}

byte inByte = 0;

void serialEvent() {
inByte = Serial.read();
Serial.println(inByte);
}



void loop()
{
}
Title: Re: Serial.read Signed Integers
Post by: Robin2 on Feb 23, 2015, 08:54 pm
You are reading bytes or chars. Assuming you are sending the numbers as text -1000 is 5 chars.

You need to read all the chars into a char array and then use the atoi() function to convert them to an int. There are examples for all this in serial input basics (http://forum.arduino.cc/index.php?topic=288234.0).

...R
Title: Re: Serial.read Signed Integers
Post by: econjack on Feb 23, 2015, 08:57 pm
One way to avoid the Endian problem is to use a union. Do something like:

Code: [Select]

union inUnion {
   byte fromVS[2];
   int val;
} myUnion;



The issue is that C# has ints that are 4 bytes long. I would try sending a short int from C#, as those are 2 bytes. Then:

Code: [Select]

int index;
int myInt;
//
index = 0;
if (Serial.available() > 0) {
   myUnion.fromVS[index++] = Serial.read();
   if (index == 2)   // We've read 2 bytes
   {
      myInt = myUnion.val;   // We should have an int now
      index = 0;
   }
}
   


If myInt looks wrong, you may have to read the C# int "backwards" by setting index equal to 1 before the if test and decrement it after each Serial.read() call. When it's -1, you've read 2 bytes and you should be done. Kind of a hack, but it may work.
Title: Re: Serial.read Signed Integers
Post by: dgelman on Feb 23, 2015, 09:15 pm
You are reading bytes or chars. Assuming you are sending the numbers as text -1000 is 5 chars.

You need to read all the chars into a char array and then use the atoi() function to convert them to an int. There are examples for all this in serial input basics (http://forum.arduino.cc/index.php?topic=288234.0).

...R
Thank you Robin, perhaps I should have added. My C# code is very long, but how I send data to the Due is in the following lines.

Code: [Select]


// The "data" variable is assigned as int
                      
byte[] b = BitConverter.GetBytes(data.Magnitude);
serialPort1.Write(b, 0, 1);


As far as I am aware, C# runs on 32 bit integers. With that said I do not think sending a -1000 is 5 characters. Please correct me if I am wrong. I am trying my best to understand data structures.

The issue is that C# has ints that are 4 bytes long. I would try sending a short int from C#, as those are 2 bytes.
I am not sure why going from 4 bytes to 2 bytes would solve anything. I understand Arduino Due uses 32-bit integers.
Title: Re: Serial.read Signed Integers
Post by: Delta_G on Feb 23, 2015, 09:19 pm
Lots of times data gets printed over the serial line in ascii.  In that case it would be '-' , '1' , '0' , '0' , '0' .  That's where the 5 characters thing is coming from.  Sometimes it is easier to communicate that way because not every device sizes its types the same way or has the same endianess, but everyone can understand ascii.