I want to acquire data from a thermometer, which should give me the data in hex, but isn't always hex (somehow). ascii doesn't work, because the values are greater than 128. This is the sheet of the thermometer: https://asset.conrad.com/media10/add/160267/c1/-/en/000100518DS01/datenblatt-100518-voltcraft-k204-temperatur-messgeraet-200-1370-c-fuehler-typ-k-datenlogger-funktion.pdf
I want to decode the bytes, but because it isn't really hex and switches to something "weird" in between, I am not sure what to use
My code:
import serial
ser = serial.Serial('COM1',
baudrate=9600,
parity='N',
bytesize=8,
stopbits=1,
rtscts=True,
dsrdtr=True,
timeout=1) # open serial port
ser.write(b'A') # send command 'A' to be able to receive data from VOLTCRAFT K204, see sheet
bytes=ser.readline() # read all 45 bytes
print(bytes)
selected_bytes=s[7:9]# slice to get the 8th and 9th value, see sheet
print(selected_bytes)
value= selected_bytes.decode('ascii') #doesn't work, because the value is out of range
print(value)
ser.close()
Output for 23.2°C, which is also shown on the thermometer: b'\x02\x80\x80\x01\x02\x02\x02\x00\xe8\x7f\xff\x7f\xff\x7f\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0e\x00\x00\x00\x0e\x03'
b'\x00\xe8'
UnicodeDecodeError: 'ascii' codec can't decode byte 0xe8 in position 1: ordinal not in range(128)
Output for ~30.5°C, which is also shown on the thermometer: b'\x02\x80\x80\x01\x02\x02\x02\x012\x7f\xff\x7f\xff\x7f\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0e\x00\x00\x00\x0e\x03'
b'\x012'
"unknown character"2
=> Not only did those 2 bytes become 1, but what exactly is b'\x012' and what can I use to decode both types of bytes?
If I only take one byte (because the other is 0) and let 'utf-8' decode it, I get values that are expected until I increase the temperature again and those 2 bytes become 1 again. Basically as soon as the thermometer uses the second byte I can't decode it
You are receiving raw binary data. b'\x00\xe8'
is merely the text representation of that binary value.
The binary value in bytes can be converted to an integer using the int.from_bytes
method:
raw = b'\x00\xe8'
temp = int.from_bytes(raw,'big') / 10 # 23.9
Since those are temperatures, unless they are in Kelvin, I would expect that they can be negatives so you may want to use the signed option:
raw = b'\xff\xef'
temp = int.from_bytes(raw,'big', signed=True) / 10 # -27.3