Чтение / преобразование байтоподобных шестнадцатеричных объектов из PySerial - PullRequest
0 голосов
/ 16 мая 2018

Я пытался найти решение этой проблемы в различных связанных потоках, но я не могу заставить их работать вместе.Многие посты, которые я нахожу, имеют дело с ascii / бинарными значениями, и моя проблема связана с переводом шестнадцатеричных значений.Я новичок в Python, и я боролся с синтаксисом.

Система: Windows 10. Python 3.6.IDE - это Spyder.

Проблема: я связываюсь с устройством через последовательный порт RS232, который общается только в шестнадцатеричном формате.Мне удалось успешно отправить команду на устройство с помощью модуля pySerial и получить ответ, но я не могу понять, как преобразовать ответ в анализируемый формат для следующего шага в моем рабочем процессе.

Код до сих пор:

import serial
import sys

port = "COM3"
baud = 9600
bytesize=8
parity='N'
stopbits=1
timeout=10 # this timeout is large due to another problem I'm having, but 
             didn't want to complicate this post with.

# Commands

# open the serial port
ser = serial.Serial(port, baud, bytesize, parity, stopbits, timeout)

if ser.isOpen():
    print(ser.name + ' is open...')

# Query. This sends an 'are you awake' message to the device.
ser.write(bytearray.fromhex("23 00 00 80 B0 00 00 01"))        

Вышеуказанная команда отправляется на устройство в виде «байтового объекта» в соответствии с Python, который отображается в формате: b '\ x23 \ x00 \ x00 \x80 \ xb0 \ x00 \ x00 \ x01 '

print('Receiving...')

# wait for timeout before displaying what was read. The device returns a 
variable number of bytes each time it communicates, and I haven't figured 
out a way to handle that yet.
    out = ser.read()

print(out)
ser.close()
print(port+' is closed.')

Вот где моя проблема.ser.read () возвращает другой байтоподобный объект.Например, из приведенной выше команды ser.write (): b '\ x13 \ x11'.На самом деле это значения, которые я ожидаю от этой команды (шестнадцатеричные значения «13» и «11»), я просто не знаю, как с ними обращаться сейчас.

Что я хочу сделать, так эторазбирать длинную строку возвращаемых шестнадцатеричных символов (когда я отправляю команду, не являющуюся запросом, это будет 250+ символов, разделенных символом "\ x") в отдельные элементы массива, которые я затем могу манипулировать / заменять / преобразовывать обратно в десятичные целочисленные значения,В конечном итоге я захочу преобразовать эти шестнадцатеричные значения в их десятичные эквиваленты и записать эти десятичные значения в текстовый файл CSV, чтобы потом можно было отобразить значения.

Я пробовал (они не последовательныекоманды, это список предпринятых команд):

out = ser.readline()    

out.split("\x")
out.split("\")
out.split("\\")

out_string = out.decode("utf-8")

binascii.hexlify(out)
binascii.hexlify(bytearray(out))

...and others I can't remember.  

Пожалуйста, любая помощь, которую вы можете предложить, будет принята с благодарностью.Такое чувство, что это должно быть простым делом, и на моем бедном компьютере не хватает памяти со всеми открытыми вкладками.Заранее благодарю всех, кто отвечает.

1 Ответ

0 голосов
/ 16 мая 2018

Ваш выход - это последовательность байтов.Если вы хотите считать только определенное количество байтов, вы можете просто использовать

out = ser.read(n) # where n is the number of bytes you want e.g. n = 8

Ваш вывод должен выглядеть примерно так:

out = b'\x21\x45\xed\xca\xfe' # I chose random values here

Итак, чтобы получить список целых чиселможно сделать:

for b in out:
  int_list.append(b)

или

int_list = [b for b in out]

Если вам нужны пары байтов, которые вы можете сделать (хотя не уверен, что это лучший способ):

for i in range(0,len(out),2): # loop to every second value
  pair = out[i].to_bytes(1,'little')+out[i+1].to_bytes(1,'little') # the first argument refers to the number of bytes and the second to the endianess.
  print(pair)

Это производит для меня следующее:

>>> b = b'\x32\x34\xe8\x90\x32\xab'
>>> for i in range(0,len(out),2):
...     pair = out[i].to_bytes(1,'little')+out[i+1].to_bytes(1,'little')
...     print(pair)
...
b'24'
b'\xe8\x90'
b'2\xab'

если вы ищете конкретные байты ошибки, например, e = b '\ xff', вы можете сделать

if e in out:
  do_substitute(e with your byte value)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...