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?
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...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With