串行端口-如何在Python中将整数的两个字节转换回整数



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

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

我尝试使用基本的逐位运算符(<<、>>等),就像在类似C++的程序中一样,但似乎不起作用。

我怀疑这与数据类型有关。我可能在相同的操作中使用带字节的整数,但我真的无法判断每个变量的类型,因为据我所知,你并没有真正在Python中声明变量(我对Python很陌生)。

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

您可以使用struct模块在整数和字节表示之间进行转换。在您的情况下,要从Python整数转换为两个字节并返回,您可以使用:

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

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

其他可能性是b用于有符号字节,B用于无符号字节,h用于有符号短(16位),i用于有符号32位整数,I用于无符号32位整数值。您可以通过查看struct模块的文档来获得完整的列表。

假设存储在myline中的数据首先具有高字节:

myline = [0, 1, 2, 3]
pot = myline[2]<<8 | myline[3]
print 'pot: {:d}, 0x{:04x}'.format(pot, pot)  # outputs "pot: 515, 0x0203"

否则,如果它是低字节的,你需要做相反的方式:

myline = [0, 1, 2, 3]
pot = myline[3]<<8 | myline[2]
print 'pot: {:d}, 0x{:04x}'.format(pot, pot)  # outputs "pot: 770, 0x0302"

例如,使用Big Endian编码:

int.from_bytes(my_bytes, byteorder='big')

这完全有效:

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

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

要将字节或字符转换为它所代表的数字,请使用ord()。这里有一个从int到字节再返回的简单往返:

>>> number = 3**9
>>> hibyte = chr(number / 256)
>>> lobyte = chr(number % 256)
>>> hibyte, lobyte
('L', 'xe3')
>>> print number == (ord(hibyte) << 8) + ord(lobyte)
True

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

最新更新