Десятичный в шестнадцатеричный в питоне - PullRequest
5 голосов
/ 25 августа 2010

Итак, у меня есть неосведомленный (может быть?) Вопрос.Я впервые работаю с записью на последовательное устройство.У меня есть кадр [12, 0, 0, 0, 0, 0, 0, 0, 7, 0, X, Y], который мне нужно отправить.X и Y являются значениями контрольной суммы.Мое понимание использования модуля pyserial заключается в том, что мне нужно преобразовать этот фрейм в строковое представление.Хорошо, это нормально, но я запутался в том, в каком формате должны быть объекты. Я пытался сделать

a = [12, 0, 0, 0, 0, 0, 0, 0, 7, 0, X, Y]
send = "".join(chr(t) for t in a)

Но моя путаница связана с тем фактом, что X и Y при использовании chr превращаются в странныестроки (при условии их представления ascii).Например, если X равен 36, chr (x) будет «$» вместо «\ x24».Есть ли способ получить строку, представляющую значение '\ xnn' вместо кода ASCII?Что меня смущает, так это то, что 12 и 7 правильно конвертируют в '\ x0b' и '\ x07'.Я что-то упустил?

Обновление:
Возможно, я не совсем понимаю, как выполняются последовательные записи или что мое устройство ожидает от меня.Это часть моего кода на C, который работает:


fd=open("/dev/ttyS2",O_RDWR|O_NDELAY);
char buff_out[20]
//Next line is psuedo
for i in buff_out print("%x ",buff_out[i]); // prints b 0 0 0 0 0 0 0 9 b3 36 
write(fd,buff_out,11);  
sleep()
read(fd,buff_in,size);
for i in buff_in print("%x ",buff_in[i]); // prints the correct frame that I'm expecting


Python:



frame = [11, 0, 0, 0, 0, 0, 0, 0, 9] + [crc1, crc1]

senddata = "".join(chr(x) for x in frame)



IEC = serial.Serial(port='/dev/ttyS2', baudrate=1200, timeout=0)
IEC.send(senddata)

IEC.read(18) # number of bytes to read doesn't matter, it's always 0

Правильно ли я поступаю?Очевидно, что вы не можете точно сказать, так как это зависит от устройства, и я не могу дать слишком много подробностей.Но тот ли это правильный формат, в котором serial.send () ожидает данные?

Ответы [ 4 ]

3 голосов
/ 25 августа 2010

Вполне нормально, что байты ASCII представляются единичными символами, если они могут быть напечатаны, и с помощью записи \x?? в противном случае.В обоих случаях они представляют один байт, и вы можете писать строки любым способом:

>>> '\x68\x65\x6c\x6c\x6f'
'hello'

Однако, если вы используете Python 2.6 или более позднюю версию, вам может быть проще и естественнее использовать встроенный-in bytearray вместо того, чтобы возиться с ord или struct.

>>> vals = [12, 0, 0, 0, 0, 0, 0, 0, 7, 0, 36, 100]
>>> b = bytearray(vals)
>>> b
bytearray(b'\x0c\x00\x00\x00\x00\x00\x00\x00\x07\x00$d')

Вы можете преобразовать в str (или bytes в Python 3), просто приведя его, и можетеИндексируйте bytearray, чтобы получить целые числа обратно.

>>> str(b)
'\x0c\x00\x00\x00\x00\x00\x00\x00\x07\x00$d'
>>> b[0]
12
>>> b[-1]
100

Что касается вашего последовательного кода Python, он выглядит хорошо для меня - я не уверен, почему вы думаете, что есть проблема ...

1 голос
/ 25 августа 2010

Символ с ASCII-кодом 36 равен '$'. Посмотрите это в любой таблице ASCII. Python отображает шестнадцатеричные экранированные символы только в том случае, если символ недоступен для печати (управляющие символы и т. Д.).

На самом низком уровне, в любом случае, это один и тот же битовый шаблон - независимо от того, печатает ли Python его как шестнадцатеричный escape или как символ с этим значением ASCII.

Но вы можете использовать модуль struct , он позаботится о таких преобразованиях для вас.

0 голосов
/ 25 августа 2010

То, что вы делаете, прекрасно: ваш send - это то, что вы хотите: последовательность байтов со значениями, которые вы хотите (a).

Если вы хотите увидеть, какие шестнадцатеричные коды символов в send, вы можете сделать:

import binascii
print binascii.hexlify(send)

или

print ''.join(r'\x%02x' % ord(char) for char in send)

(если вы хотите \x префиксы).

То, что вы видите при прямой печати repr(send), представляет собой представление из send, которое использует ASCII: 65 представляет «A», но символ 12 - «\ x0c». Это просто соглашение, используемое Python, что удобно, например, когда строка содержит слова: лучше отображать «Hello», чем \ x48 \ x65 \ x6c \ x6c \ x6f!

0 голосов
/ 25 августа 2010

Я думаю, вы хотите struct .

>>> import struct
>>> struct.pack('>B', 12)
'\x0c'
>>> vals = [12, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0xa, 0xb]
>>> ''.join(struct.pack('>B', x) for x in vals)
'\x0c\x00\x00\x00\x00\x00\x00\x00\x07\x00\n\x0b'
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...