Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Decimal to hex in python

So I have kind of a ignorant (maybe?) question. I'm working with writing to a serial device for the first time. I have a frame [12, 0, 0, 0, 0, 0, 0, 0, 7, 0, X, Y] that I need to send. X and Y are checksum values. My understanding in using the pyserial module is that I need to convert this frame into a string representation. Ok that's fine, but I'm confused on what format things are supposed to be in. I tried doing

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

But my confusion comes from the fact that X and Y, when using chr, transform into weird strings (assuming their ascii representation). For example if X is 36, chr(x) is '$' instead of '\x24'. Is there a way I can get a string representing the '\xnn' value instead of the ascii code? What's confusing me is that 12 and 7 convert to '\x0b' and '\x07' correctly. Am I missing something?

Update:
So it might be that I'm not quite understanding how serial writes are being done or what my device is expecting of me. This is a portion of my C code that is working:


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

Am I going about this the right way? Obviously you can't tell exactly since it's device specific and I can't really give too many specifics out. But is that the correct format that serial.send() expects data in?

like image 508
Falmarri Avatar asked Oct 15 '22 01:10

Falmarri


1 Answers

It's perfectly normal for ASCII bytes to be represented by single characters if they can be printed, and by the \x?? notation otherwise. In both cases they represent a single byte, and you can write strings in either fashion:

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

However if you're using Python 2.6 or later then you might find it easier and more natural to use the built-in bytearray rather than messing around with ord or 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')

You can convert to a str (or bytes in Python 3) just by casting, and can index the bytearray to get the integers back.

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

As to your serial Python code, it looks fine to me - I'm not sure why you think there is a problem...

like image 152
Scott Griffiths Avatar answered Oct 17 '22 22:10

Scott Griffiths