ThatsRightJack
ThatsRightJack

Reputation: 751

Encode/decode data from RS232 serial port

This is the first time I've had to connect to a device via RS232 serial to read/write data and I'm stuck on the encoding/decoding procedures.

I'm doing everything in Python 3 using the library "pyserial". Here is what I've done so far:

import serial

ser = serial.Serial()
ser.port = '/dev/ttyUSB0'
ser.baudrate = 115200
ser.bytesize = serial.EIGHTBITS
ser.parity = serial.PARITY_NONE
ser.stopbits = serial.STOPBITS_ONE
ser.timeout = 3

ser.open()

device_write = ser.write(bytearray.fromhex('AA 55 00 00 07 00 12 19 00'))

device_read = ser.read_until()

The connection/communication appears to be working as intended. The output of device_read is

b'M1830130A2IMU v3.2.9.1 26.04.19\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x0527641\x00\x00\x00IMHF R.1.0.0 10.28.2018 td:  6.500ms\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x14\x00'

and this is where I'm stuck. I don't know how to interpret this. Attached is an image from the datasheet which explains what the output is suppose to represent.

enter image description here

The datasheet says "fields in bytes 98 to 164 are empty" for the device I have. Can someone help me understand what needs to be done to convert the output of ser.read_until() to a form that is "human readable" and represents the data in the image? I don't need someone to write the code for me, but I'm not even sure where to start. Again, this is my first time doing this so I'm a bit lost on what is going on.

Upvotes: 2

Views: 8181

Answers (2)

martineau
martineau

Reputation: 123501

This isn't an answer, just @ozangds' idea fleshed-out (might save you some typing):

def decode_bytes(data, start, stop):
    return data[start:stop+1].decode('ascii').rstrip('\x00')


device_read = b'M1830130A2IMU v3.2.9.1 26.04.19\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x0527641\x00\x00\x00IMHF R.1.0.0 10.28.2018 td:  6.500ms\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x14\x00'

ID_sn = decode_bytes(device_read, 0, 7)
ID_fw = decode_bytes(device_read, 8, 47)
Press_sens = device_read[48]
IMU_type = device_read[49]
IMU_sn = decode_bytes(device_read, 50, 57)
IMU_fw = decode_bytes(device_read, 58, 97)

label_fmt = '{:>10}: {!r}'
print(label_fmt.format('ID_sn', ID_sn))
print(label_fmt.format('ID_fw', ID_fw))
print(label_fmt.format('Press_sens', Press_sens))
print(label_fmt.format('IMU_type', IMU_type))
print(label_fmt.format('IMU_sn', IMU_sn))
print(label_fmt.format('IMU_fw', IMU_fw))

Output:

     ID_sn: 'M1830130'
     ID_fw: 'A2IMU v3.2.9.1 26.04.19'
Press_sens: 2
  IMU_type: 5
    IMU_sn: '27641'
    IMU_fw: 'IMHF R.1.0.0 10.28.2018 td:  6.500ms'

Upvotes: 3

Ozan Bellik
Ozan Bellik

Reputation: 483

If you are trying to write a single byte with hex value 12 (decimal 18), I believe what you need to do is ser.write(bytes([0x12])), which is equivalent to ser.write(bytes([18])).

It looks like your output is 154 bytes rather than 98, and much of it non-human-readable. But if you did have the data described in the graph, you could break it up like this:

ID_sn = device_read[0:8].decode('ascii')
ID_fw = device_read[8:48].decode('ascii')
Press_Sens = device_read[48]

and so on.

Upvotes: 4

Related Questions