Two's compliment byte array to int16 - confusing results. - General Discussion - Netduino Forums
   
Netduino home hardware projects downloads community

Jump to content


The Netduino forums have been replaced by new forums at community.wildernesslabs.co. This site has been preserved for archival purposes only and the ability to make new accounts or posts has been turned off.
Photo

Two's compliment byte array to int16 - confusing results.


  • Please log in to reply
7 replies to this topic

#1 Crispin

Crispin

    Advanced Member

  • Members
  • PipPipPip
  • 65 posts
  • LocationLondon, England, Earth

Posted 27 April 2014 - 09:11 PM

Hi Folks,

 

I've got something which is really confusing me and I'm lost.

 

I'm talking to a camera via a serial connection. To get the serial number from the camera, I send a command and it replies with the serial number.

 

From the camera's documentation: 

Two’s-complement numbering is used for all signed values. Big-endian ordering is employed

 

For the serial number it says I will get back a 4 byte array which is the equivalent of this:

byte[] buff = new byte[8] { 0x00, 0x01, 0x36, 0xeb, 0x00, 0x0c, 0x45, 0xe3};

The number I am looking for is 79595 (real serial number of the camera)

 

 

I am lost as to how to get this. I've tried bitconvertor but it returns 13825 and 235, flipped it simply negates them and adds 1 (expected)

 

'elp please - I'm lost. How do I convert byte arrays back to meaningful numbers? 

 

 

Thanks

Crispin


--
Take a seat, I'll be right with you.

#2 Crispin

Crispin

    Advanced Member

  • Members
  • PipPipPip
  • 65 posts
  • LocationLondon, England, Earth

Posted 27 April 2014 - 10:18 PM

further confusion - 

 

Another property I have has a value of 60 (it's an int). So says the OEM application.

If I query the property I get 2 bytes coming back = 0x00, 0x3c (in int is 00, 60)

 

if I change it (with the OEM app) to 66 I get back  0x00, 0x42 (in int is 00, 66)

 

if I change it (with the OEM app) to 555 I get back  0x02, 0x2b (in int is 2, 43)

 

I'm lost - hoping someone can help?

 

I know this should be / is simple if you understand it all but I'm lost :(

 

Thanks

Crispin


--
Take a seat, I'll be right with you.

#3 Crispin

Crispin

    Advanced Member

  • Members
  • PipPipPip
  • 65 posts
  • LocationLondon, England, Earth

Posted 27 April 2014 - 10:40 PM

further confusion - 

 

Another property I have has a value of 60 (it's an int). So says the OEM application.

If I query the property I get 2 bytes coming back = 0x00, 0x3c (in int is 00, 60)

 

if I change it (with the OEM app) to 66 I get back  0x00, 0x42 (in int is 00, 66)

 

if I change it (with the OEM app) to 555 I get back  0x02, 0x2b (in int is 2, 43)

 

I'm lost - hoping someone can help?

 

I know this should be / is simple if you understand it all but I'm lost :(

 

Thanks

Crispin

 

Endianness... Windows / c# is little, the camera clearly states big. Doh. 

Well, that works now so sure I can understand the serial number now.... Maybe  :unsure:


--
Take a seat, I'll be right with you.

#4 gismo

gismo

    Advanced Member

  • Members
  • PipPipPip
  • 110 posts

Posted 28 April 2014 - 01:11 AM

I think you're onto the right thing... Or maybe I don't follow your question...  For example to get that 555 number and your returned bytes 2 and 43.

 

If you combine those bytes that you're getting back from 555. You need to do  (2<<8) | 43 = 555 .Some simple bit shifting will get you there. The first byte you receive back is the higher byte.

 

If you get 4 bytes back, you need to shift the bytes accordingly and combine into an Int: 

Int serial = Byte[1] <<24 | Byte[2] <<16 | Byte[3]<<8 | Byte[4];//should give you an int(32bits).

ALSO, In windows goto calculator and change the view to "Programmer" and you can play around with bit shifting and combining number to see how it works. (Lsh) with (Or)

 

I hope this helps.



#5 Paul Newton

Paul Newton

    Advanced Member

  • Members
  • PipPipPip
  • 724 posts
  • LocationBerkshire, UK

Posted 28 April 2014 - 06:08 AM

Be careful with the signs.

byte is signed, but when you are combining the bytes all but the most significant needs to be treated as unsigned.

Hence if you multiply by 256 and add the bytes you may get some very interesting answers.

 

Shifting may also present a problem if the shift is carried out before the number is promoted from byte to larger value (you may run out of bits and end up with zero for each shifted byte).

 

Best advice - when you end up with a working solution (especially someone else's library), write a test harness to verify it works over the full range.

 

Have fun - Paul



#6 CW2

CW2

    Advanced Member

  • Members
  • PipPipPip
  • 1592 posts
  • LocationCzech Republic

Posted 28 April 2014 - 07:21 AM

For the serial number it says I will get back a 4 byte array which is the equivalent of this:
byte[] buff = new byte[8] { 0x00, 0x01, 0x36, 0xeb, 0x00, 0x0c, 0x45, 0xe3};
The number I am looking for is 79595 (real serial number of the camera)


Well, there is obviously an error in the documentation or you've pasted incorrect code - it says 4 byte array, yet it has 8 bytes. The number you are looking for 79595 is the first four bytes in the array: 
int serialNumber = (int)(buff[3] | (buff[2] << 8) | (buff[1] << 16) | (buff[0] << 24));
// 0xEB | 0x3600 | 0x010000 | 0x00 = 0x0136EB = 79595


#7 Crispin

Crispin

    Advanced Member

  • Members
  • PipPipPip
  • 65 posts
  • LocationLondon, England, Earth

Posted 28 April 2014 - 09:35 PM

thanks folks!

 

CW2 - sorry, I should have said, it gives back 8 bytes which is 2 4-byte values. The second set of 4 bytes there is a second serial number.

 

So, your way works perfectly :D

I understand what you're doing but not why. I last did this stuff in school some 20 years ago and binary has changed so much since then ;) (TiC!)

I'll write it all down and understand it. Thanks for the help.

 

 

Lazy question - is there a lazy-man's wrapper in csharp which could have done this for me?

 

Cheers,

Crispin


--
Take a seat, I'll be right with you.

#8 gismo

gismo

    Advanced Member

  • Members
  • PipPipPip
  • 110 posts

Posted 29 April 2014 - 09:07 PM

 

Lazy question - is there a lazy-man's wrapper in csharp which could have done this for me?

 

Cheers,

Crispin

 

There is a bit converter class that you mentioned above..I don't think it's native in netmf, but there's been some adaptations and I think there's one on the site somewhere.

 

What do you mean, you don't understand why, but you understand what? 

Data is transferred in chunks of bits. 8bits Or One byte at a time. Once you receive all the bytes..Then you must assemble the Bytes into the 32bit (4 byte) value/variable. Imagine you need to arrange and combine the received bytes into the new 32bit int.

Buff[3]<< Buff[2]<< Buff[1]<<  Buff[0]
00000000  00000000  00000000  00000000

This may help to explain what's going on(example if each byte=255):
00000000 00000000 00000000 11111111 buff[0]
00000000 00000000 11111111 00000000 buff[1]<<8
00000000 11111111 00000000 00000000 buff[2]<<16 
11111111 00000000 00000000 00000000 buff[3]<<24
-----------------------------------
11111111 11111111 11111111 11111111

You slide the bits for buff[1]-buff[3] to the left into their correct position By 8 bits, by 16 bits, and lastly by 24 bits. into the 32bit variable. You combine then with a bitwise OR and viola! You get the right 32bit value.






0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users

home    hardware    projects    downloads    community    where to buy    contact Copyright © 2016 Wilderness Labs Inc.  |  Legal   |   CC BY-SA
This webpage is licensed under a Creative Commons Attribution-ShareAlike License.