Как в Python преобразовать целое число от 0 до 255 в один байт без знака?

На моем ноутбуке работает программа Python, которая считывает данные с джойстика и отправляет команду скорости на Arduino, который, в свою очередь, управляет двигателем игрушечной машинки. Для этого программа преобразует целое число со значениями от 0 до 255 в один байт без знака, который отправляет через последовательное соединение на Arduino.

Этот код работает для этого:

           if event.axis == axis:
                speed = int((event.value + 1.0) / 2.0 * 255.0)
                speedCommand = bytearray(b'\x00')
                speedCommand[0] = speed
                speedCommand = bytes(speedCommand)
                ser.write(speedCommand)
                print(speed, speedCommand)

Хотя этот код работает, он не очень элегантный. Я хотел бы найти однострочную инструкцию, которая делает то же самое, что и три строки, начинающиеся с speedCommand. Я пробовал это, например:

            speedCommand = chr(speed).encode()

Но это работает только для значений от 0 до 127. Любое число выше 127 кодируется двумя байтами [, поскольку символ рассматривается как байт со знаком, а значения выше 127 являются отрицательными].

ОТРЕДАКТИРОВАНО ДЛЯ ДОБАВЛЕНИЯ: Мое предположение о том, что символ рассматривается как подписанный байт со значениями выше 127, являющимися отрицательными, может быть неверным.


person Daanii    schedule 10.04.2021    source источник
comment
поскольку символ рассматривается как байт со знаком, а значения выше 127 являются отрицательными. Я не думаю, что это то, что происходит, в любом случае, я дал ответ   -  person juanpa.arrivillaga    schedule 11.04.2021
comment
FYI speed = chr(speed).encode('latin1') решит вашу проблему с кодировкой. Кодировка по умолчанию utf8 в противном случае   -  person Mark Tolonen    schedule 11.04.2021
comment
Марк Толонен, это chr(speed).encode('latin1') решение действительно работает в моей программе. Хорошо знать.   -  person Daanii    schedule 11.04.2021


Ответы (2)


Вам просто нужно:

speed_command = bytes([speed])

Конструктор bytes принимает итерируемый объект int, поэтому просто поместите его в список, когда вы передаете его конструктору.

person juanpa.arrivillaga    schedule 10.04.2021

Вы можете использовать метод pack из встроенного модуля struct. Он принимает в качестве первого аргумента формат, а в качестве следующих аргументов значение (или несколько значений), которое нужно упаковать в этот формат. Для unsigned char требуется формат B. Модуль поддерживает множество других форматов, которые могут быть полезны для отправки других данных на Arduino. См. документацию по struct модулю для получения дополнительной информации, включая список символов формата.

>>> import struct
>>> speed = 255
>>> struct.pack('B', speed)
b'\xff'
person luuk    schedule 10.04.2021
comment
Этот модуль struct хорошо знать при отправке данных в Arduino. Я могу использовать его в нескольких других местах в моей программе. Спасибо. - person Daanii; 11.04.2021