Go Down

Topic: Serial.read Signed Integers (Read 1 time) previous topic - next topic

dgelman

Feb 23, 2015, 08:36 pm Last Edit: Feb 23, 2015, 08:46 pm by dgelman
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()
{
}
Dialup is the future.

Robin2

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.

...R
Two or three hours spent thinking and reading documentation solves most programming problems.

econjack

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.

dgelman

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.

...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.
Dialup is the future.

Delta_G

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. 
|| | ||| | || | ||  ~Woodstock

Please do not PM with technical questions or comments.  Keep Arduino stuff out on the boards where it belongs.

Go Up