Пользовательское декодирование байтового массива - PullRequest
0 голосов
/ 05 октября 2018

У меня есть код Python, который читает последовательные данные.Формат, в котором это происходит:

e\x00\x01\x01\xff\xff\xff

То, что на самом деле предполагается хранить здесь, это id определенного компонента, который был выбран на аппаратном устройстве, к которому я получаю доступ черезпоследовательный.Тип id Я считаю, что это целое число, потому что он генерируется автоматически, я не могу изменить его, и он получает значения, как 1, 2, 3 и т. Д. ... для каждого компонента (кнопки).

Мой сериал настроен так:

ser = serial.Serial(port='/dev/serial0',baudrate=9600,timeout=1.0)

Итак, если бы я нажал кнопку с идентификатором 1, я бы получил => e \ x00 \x01 \ x01 \ xff\ xff \ xff

Если я нажал кнопку с идентификатором 2 => e \ x00 \x02 \ x01 \ xff \ xff \ xff

и если идентификатор был 10 => e \ x00 \x0A \ x01 \ xff \ xff \ xff

Всегда есть конечные символы \xff\xff\xff, а начальные e.

Мой вопрос: Как я могу последовательно прочитать такой ввод и извлечь этот бит из всего массива, который приносит мне ценность? Из того, что я увидел в интернете, я мог бы использовать пакет Python struct ираспакуйте такую ​​вещь (e\x00\x01\x01\xff\xff\xff), но для этого мне нужно как-то узнать / определить ее формат.

То, что я хотел бы прочитать, это первые два целых числа (в шестнадцатеричном коде)после e.

Ответы [ 4 ]

0 голосов
/ 05 октября 2018

Я думаю, у @ parasit правильная идея, но я бы немного формализовал вещи и использовал бы код, подобный следующему.Исходный символ формата x в строке формата struct DAT_FMT означает игнорирование первого байта данных (e в примере последовательных данных).

from __future__ import print_function
import struct

DAT_FMT = 'x6B'

for sample in (b'e\x00\x01\x01\xff\xff\xff',
               b'e\x00\x01\x02\xff\xff\xff',
               b'e\x00\x01\x0a\xff\xff\xff'):

    dat0, dat1, id, dat3, dat4, dat5 = struct.unpack(DAT_FMT, sample)
    print(dat0, dat1, id, dat3, dat4, dat5, sep=', ')

Вывод:

0, 1, 1, 255, 255, 255
0, 1, 2, 255, 255, 255
0, 1, 10, 255, 255, 255
0 голосов
/ 05 октября 2018

e\x00\x01\x01\xff\xff\xff является bytes объектом.Обратите внимание на ведущий b, когда вы его инициализируете.Вам не нужно struct для доступа к нему.

Просто получить доступ к отдельным символам, используя их индекс в массиве:

x = b'e\x00\x01\x01\xff\xff\xff'
print(x[0]) # this is the 'e', it's 101 in ascii
print(x[1])
print(x[2]) # this is the value of your button
print(x[3]) 
print(x[4]) 

x = b'e\x00\x0A\x01\xff\xff\xff'
print(x[2]) # now the value of the button is 10
0 голосов
/ 05 октября 2018

Если это представлено в виде строки или вы можете легко получить ее в одну, просто разделите ее на символ '\' и получите доступ к индексам [1] и [2], чтобы получить их.

s = r"e\x00\x01\x01\xff\xff\xff".split(r"\x") # r prefixed the string to avoid having to escape the backslashes
int1 = int(s[1], 16) # the second argument is the base, here, hexadecimal
int2 = int(s[2], 16)
print(int1) # 2
print(int2) # 1

Если это байтовый объект, вы уже можете получить к нему доступ с помощью индексов.Просто

print(s[1])
print(s[2])

, чтобы получить нужные вам значения

0 голосов
/ 05 октября 2018

Может быть, что-то вроде этого поможет вам:

from struct import *
unpack('xbbbbbb','e\x00\x01\x01\xff\xff\xff')
(0, 1, 1, -1, -1, -1)
...