Питон в своём подходе к обработке данных ни разу не походит на классические языки программирования типа Си/C++, и этим объясняется одна из трудностей, почему Си-шники его не очень жалуют.
Тем, кто хочет сразу узнать суть, я рекомендую не читать всё, а сразу прокрутить в конец статьи.
В Си всё просто. Например, у вас есть какие-то байты, которые лежат на своих адресах в памяти, и а уж как их интерпретировать — это зависит от контекста задачи. Эти байты могут представлять собой коды печатных символов (буквы, цифры, знаки препинания). А могут быть составляющими элементами (младший байт, старший байт) чисел.
Ещё пример. Последовательный порт передаёт байты. Просто байты. Обезличенные. Это задача программы — как их понимать и как с ними работать. То есть вы сначала набираете (принимаете из последовательного порта) последовательность этих байтов, а потом эту последовательность представляете как целое число или число с плавающей точкой. А может быть это будет ASCIIZ-строка символов. Всё просто!
В Питоне всё намного запутаннее.
Мне тут намедни понадобилось написать небольшую прогу для работы с микросхемой трансмиттера CC2520 по последовательному каналу — комп должен был играть роль терминала для этой микросхемы. Задача ни о чём!
Я взял микроконтроллер STM32, с одной стороны подключил к нему CC2520 по SPI, с другой — подключил CH340G по USART.
На стороне компа у меня работает прога, которая по нажатию на кнопки отправляет заданные байтовые последовательности в микроконтроллер.
Байтовые последовательности — это, так называемые, пакеты. Пакеты имеют незатейливую структуру. Первым байтом у них идёт размер пакета (без учёта этого самого байта), далее — собственно сама последовательность байт, составляющих команду и её параметры.
В обратном направлении (от STM32 в комп) поступают ответы. Структура ответных пакетов похожа на командные пакеты.
Сложность (если так можно выразиться!) стояла в том, как сформировать данные, которые представляют собой команды.
Ещё одна сложность была в том, что уровень бизнес-логики программы общается не напрямую с последовательным портом, а через класс-посредник. В этом классе посреднике нужно из последовательности байт, представляющих собой команду, сформировать пакет для передачи в микроконтроллер.
Суть.
Где-то в программе формируем такой код:
# Создаем команду СС2520 (MEMRD) для чтения регистра VERSION (адрес 0x0042) cmd = b"\x10\x42\x00" # Отправляем команду в МК send_cmd(cmd) ... # В классе-посреднике: def onSend(self, cmd): pack = bytearray(1) # Создаём байтовый массив длиной один байт pack[0] = len(cmd) # В нулевой байт массива помещаем длину # Копируем в массив байты команды. # При этом размер массива будет автоматически увеличиваться. # При желании в конец пакета можно также дописать контрольную сумму. pack[1:] = cmd ser.write(pack) # Теперь пакет можно отправлять
Это довольно просто решение, но оно не очевидно для Си-шников. Да и я, сам о нём не всегда помню. Особенно после длительных перерывов по работе с Питоном.
Ладно. Пусть будет! Может кому-нибудь сгодится.
В 12 строке очепятка: bytearray.
В 18 строке можно просто присваивать cmd.
Спасибо, Руслан!
Сейчас поправлю.
крутое))