I am trying to decode Can frames with micropython. I miss a lot of functions from python 3.x. I get 8 hex long bytes from the Rx SPI buffer of an MCP2515. For information, I'm on openMV IDE. I would like to extract the 1st and 2nd to make an integer, the 3rd and 4th to make another one, etc...
Along my researches, I found a function that convert a byte to signed integer (as the sign=True argument is not implemented in the from_byte function). The main problem is that the solutions provided on others python's forum are only concerning python 3.x for pc but not micropython and a lot of solutions end with "function doesn't exist".
byte = b'\x12\x34\x56\x78\x9A\xBC\xDE\xFF'
def byte2int(bList, signed:bool=False):
if signed :
r = 0
for i in range(2):
d = 32 - ((i + 1) * 8)
r += bList[i] << d
return r
else : return int.from_bytes(byte, 'big')
Moreover, I don't think that I can trust the print function as print(b) return :
> print(b)
b'\x124Vx\x9a\xbc\xde\xff'
I don't understand why does the 3 vanished and was replaced by a 'V' after the 4 ! Sometime, my MCP2515 return some '|', '?', '.', '>', '<' or '=' when I print the can frames which are not hex characters !? My hypothesis is that these are corrupted frames or SPI transmission.
Please, can someone help me to understand why micropython give me these messy results ?
Thank you very for your help.
I wrote something. Maybe not the best optimization possible, but I have to deal with micropython which is not as advanced than Python 3.x
This is a solution (surely not the most optimal). But it seems to work.
byte = b'\xFF\xC8\x56\x78\x9A\xBC\xDE\xFF'
byte2 = b'\x00\x00\x00@\x00\x00\x00\x00'
def extract(trame, signed:bool=False):
r = [0,0,0,0]
trame = [int(x) for x in bytearray(byte)]
for i in range(len(trame)/2):
val = (trame[i*2]<<8)+trame[i*2+1]
if signed and val > 0x8000 :
r[i] = -(65535-int(val)+1)
else :
r[i] = int(val)
return r
print(extract(byte, True))