Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I convert two bytes of an integer back into an integer in Python?

I am currently using an Arduino that's outputting some integers (int) through Serial (using pySerial) to a Python script that I'm writing for the Arduino to communicate with X-Plane, a flight simulation program.

I managed to separate the original into two bytes so that I could send it over to the script, but I'm having a little trouble reconstructing the original integer.

I tried using basic bitwise operators (<<, >> etc.) as I would have done in a C++like program, but it does not seem to be working.

I suspect it has to do with data types. I may be using integers with bytes in the same operations, but I can't really tell which type each variable holds, since you don't really declare variables in Python, as far as I know (I'm very new to Python).

self.pot=self.myline[2]<<8
self.pot|=self.myline[3]
like image 736
Gepapado Avatar asked Feb 15 '13 21:02

Gepapado


2 Answers

You can use the struct module to convert between integers and representation as bytes. In your case, to convert from a Python integer to two bytes and back, you'd use:

>>> import struct
>>> struct.pack('>H', 12345)
'09'
>>> struct.unpack('>H', '09')
(12345,)

The first argument to struct.pack and struct.unpack represent how you want you data to be formatted. Here, I ask for it to be in big-ending mode by using the > prefix (you can use < for little-endian, or = for native) and then I say there is a single unsigned short (16-bits integer) represented by the H.

Other possibilities are b for a signed byte, B for an unsigned byte, h for a signed short (16-bits), i for a signed 32-bits integer, I for an unsigned 32-bits integer. You can get the complete list by looking at the documentation of the struct module.

like image 88
Sylvain Defresne Avatar answered Sep 22 '22 10:09

Sylvain Defresne


What you have seems basically like it should work, assuming the data stored in myline has the high byte first:

myline = [0, 1, 2, 3]
pot = myline[2]<<8 | myline[3]

print 'pot: {:d}, 0x{:04x}'.format(pot, pot)  # outputs "pot: 515, 0x0203"

Otherwise, if it's low-byte first you'd need to do the opposite way:

myline = [0, 1, 2, 3]
pot = myline[3]<<8 | myline[2]

print 'pot: {:d}, 0x{:04x}'.format(pot, pot)  # outputs "pot: 770, 0x0302"
like image 30
martineau Avatar answered Sep 21 '22 10:09

martineau