How to deal with signed int overflows??

Go To Last Post
7 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi,
 

Brief background first; I have data from CAN bus of a steering angle which is obviously in hex. The steering angle covers two bytes of a message. The specification document I have says that those two bytes form a 16-bit signed int which are the steering angle which a prescaler of 1/1024, that's all I have got (I don't have access to the source). What I am trying to do is to convert those hex values into signed int, however I am not sure how to do it correctly.

A small section of the CAN message within short time period (we are focusing on byte 3 and 4):

 

can0  700   [8]  00 00 99 93 55 0B EF BD
can0  700   [8]  00 00 95 95 10 0C 17 BE
can0  700   [8]  00 00 6F 97 FB 0A 17 BE
can0  700   [8]  00 00 39 99 5C 0A 40 BE
can0  700   [8]  00 00 AD 9A 62 08 EF BD
can0  700   [8]  00 00 EF 9B B5 08 40 BE
can0  700   [8]  00 00 CA 9D 9A 09 17 BE
can0  700   [8]  00 00 3E 9F 55 09 40 BE
can0  700   [8]  00 00 91 A0 ED 09 17 BE

As far as I know, typically, data in CAN messages follow this format: one byte for the actual data, one byte for the number of overflows.

For example, let's take an unsigned int of a value of 2000. Assuming byte #0 is for overflows, byte #1 is for actual data, we get:

 

CAN message -> [07, D0, x, x, x, x, x, x]

07 indicating that there have been 7 overflows, D0 indicating the remainder is 208, therefore:

 

7*255 + 208 = 2000

I understand how to do it with unsigned values. But this time in my scenario I am dealing with signed values. I am assuming one byte is for overflows, one byte is for the remainder, however I am not sure.

 

  1. How are overflows calculated for signed values? Is it overflow += 1 when value > 127 and overflow -= when value < -128? Does it even make sense for overflows to have signedness?

  2. How can I convert these bytes into signed decimal in C/C++? Let's say my byte value in hex is 91. Last time I tried storing it in int and printed it out, it printed out 145 (normal binary) and not -111 (2's complement). How can I enforce 2's complement (if that makes sense) in my code?

  3. Could I be interpreting the byte format wrong? All it says that these two bytes represent the steering angle and that the steering angle is int16_t. I have monitored them change in real time and one of them changes erratically, almost like jumping from 00 to FF, whereas the other one is increasing/decreasing slowly and almost linearly with time. Ideas?

 

I am really stuck here, I don't even know if I am going in the correct direction.. Any suggestions and help are really appreciated!

This topic has a solution.
Last Edited: Sun. Apr 15, 2018 - 01:41 AM
This reply has been marked as the solution. 
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

CAN uses 2s complement just like anything else so just create an int16, store the two bytes (in the right order!) into it and then read as int16. (Hint: the value is negative when the very top bit is set, IOW 0x0000 to 0x7FFF are positive (0 to 32767) and 0xFFFF down to 0x8000 are negative -1 to -32768

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

clawson wrote:

CAN uses 2s complement just like anything else so just create an int16, store the two bytes (in the right order!) into it and then read as int16. (Hint: the value is negative when the very top bit is set, IOW 0x0000 to 0x7FFF are positive (0 to 32767) and 0xFFFF down to 0x8000 are negative -1 to -32768

Well CAN itself can't really use any number formats or representations, can it? The message is sent from a different MCU which I don't have source or access to, which encodes the data in a way it pleases. 

But I see what you mean. It's a little-endian system so byte 2 would be lower half (of a 16-bit int), byte 3 would be a higher half? That does make sense. To be honest I don't know where I got this idea with overflows from.. I just did some research and overflows for signed ints in C is an undefined.. Thank you!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
7*255 + 208 = 2000

Each count of the high byte is worth 256.  Not sure why you use the term overflows , since if we are talking about 16 bit values, overflows don't occur just because the lower 8 bits are used up.

Sounds like you have access to the data generation (steering wheel?).  Do the numbers jump when the wheel is held still?

When in the dark remember-the future looks brighter than ever.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

avrcandies wrote:

7*255 + 208 = 2000

Each count of the high byte is worth 256.  Not sure why you use the term overflows , since if we are talking about 16 bit values, overflows don't occur just because the lower 8 bits are used up.

Sounds like you have access to the data generation (steering wheel?).  Do the numbers jump when the wheel is held still?

Each byte can have 256 unique values, however overflow occurs once a number reaches 255+. Anyway, the numbers don't jump up when stationary, the document clearly says these two bytes are the steering angle. The segment I attached was from rotating the wheel from left to right.

I solved my issues thanks to clawson's advice though, getting perfect -22deg -> 22deg sweep. Thank you for your responses!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

It's not an overflow, it's a "carry". Overflow occurs when there's a carry from the highest byte that no longer fits.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Each byte can have 256 unique values, however overflow occurs once a number reaches 255+. A

Look at regular decimal numbers (0-9)...how do you represent 23?

 

2*10 + 3  or  23

 

How would you represent 1000 in hex (0-255)?

 

That's 256+256+256+232     or 3*256+232, or 0x03 and 0xE8   or 0x03E8  (perhaps stored as 0xE8, 0x03)

 

sounds like you have forged ahead.

 

When in the dark remember-the future looks brighter than ever.