关于串行端口:如何在python中将一个整数的两个字节转换回一个整数?

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

我目前使用的是一个Arduino,它通过串行(使用pySerial)将一些整数(int)输出到一个python脚本,我正在为Arduino编写该脚本,以便与X-Plane进行通信,这是一个飞行模拟程序。

我设法将原始数据分成两个字节,以便将其发送到脚本,但在重建原始整数时遇到了一些困难。

我尝试使用基本的位运算符(<<,>等),就像我在C++程序中所做的那样,但是它似乎不起作用。

我怀疑这与数据类型有关。在同一个操作中,我可能使用的是带字节的整数,但我不能真正分辨每个变量所持有的类型,因为据我所知,您并不真正在python中声明变量(我对python非常陌生)。

1
2
self.pot=self.myline[2]<<8
self.pot|=self.myline[3]


您可以使用struct模块在整数和表示为字节之间进行转换。在您的例子中,要从一个python整数转换为两个字节并返回,您将使用:

1
2
3
4
5
>>> import struct
>>> struct.pack('>H', 12345)
'09'
>>> struct.unpack('>H', '09')
(12345,)

struct.packstruct.unpack的第一个参数表示您希望如何格式化数据。在这里,我要求它使用>前缀(您可以使用<表示小endian,或者使用=表示本机),以大结束模式,然后我说有一个单无符号短(16位整数)由H表示。

其他的可能性有:有符号字节的b、无符号字节的b、有符号短(16位)的H、有符号32位整数的i、无符号32位整数的i。您可以通过查看struct模块的文档获得完整的列表。


假设存储在myline中的数据的第一个字节是高位字节,那么您基本上认为它应该可以工作:

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

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

否则,如果它是低字节优先,则需要用相反的方法:

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

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


这完全有效:

1
2
3
4
long = 500
first = long & 0xff  #244
second = long >> 8  #1
result = (second << 8) + first #500

如果您不确定"myline"中的类型,请检查堆栈溢出问题如何确定python中的变量类型?.


要将字节或字符转换为它所代表的数字,请使用ord()。下面是一个从int到bytes和back的简单往返过程:

1
2
3
4
5
6
7
>>> number = 3**9
>>> hibyte = chr(number / 256)
>>> lobyte = chr(number % 256)
>>> hibyte, lobyte
('L', '\xe3')
>>> print number == (ord(hibyte) << 8) + ord(lobyte)
True

如果您的myline变量是string或bytestring,您可以使用上面最后一行中的公式。如果它是一个整数列表,那么当然不需要ord