hexadecimal numbers over UART

General discussions and questions abound development of code with MicroPython that is not hardware specific.
Target audience: MicroPython Users.
BL007
Posts: 16
Joined: Wed Sep 02, 2020 6:38 am

hexadecimal numbers over UART

Post by BL007 » Tue Oct 27, 2020 4:59 pm

Hello,


how can I send hexadecimal numbers via UART?
If I try 'hex(0xEE)' then I get an error from µPython. '238' also. 'bytes([283])' or 'bytes([0xEE)' sends a 0x00.

I use the UART lib from µPython.

cgglzpy
Posts: 47
Joined: Thu Jul 18, 2019 4:20 pm

Re: hexadecimal numbers over UART

Post by cgglzpy » Tue Oct 27, 2020 6:12 pm

Hi BL007

What you are looking for is 'struct' see: http://docs.micropython.org/en/latest/l ... truct.html and https://docs.python.org/3/library/struct.html

Code: Select all

>>> import struct
>>> struct.pack('B', 238)
b'\xee'
>>> struct.pack('B', 0xEE)
b'\xee'
To decode

Code: Select all

>>> struct.unpack('B', b'\xee')
(238,)
>>> val,=struct.unpack('B', b'\xee')
>>> val
238
Just be aware of the type of numbers (signed, integer/float, size...) you want to send. So adjust the encoding/decoding format and that's it.

BL007
Posts: 16
Joined: Wed Sep 02, 2020 6:38 am

Re: hexadecimal numbers over UART

Post by BL007 » Sun Nov 01, 2020 9:44 am

Thanks!
The conversion from str to hex is clear. It works with de-/encode() also.

But the UART.write() sends ASCII only.

uart.write(b'\xAA')
>>> 0x41
0x41

If I want send 238 as an integer, the µPython brings error. The question ist, can the UART class works with strings only?

User avatar
Roberthh
Posts: 3668
Joined: Sat May 09, 2015 4:13 pm
Location: Rhineland, Europe

Re: hexadecimal numbers over UART

Post by Roberthh » Sun Nov 01, 2020 10:23 am

uart.write() works with objects with buffer protocol, meaning strings, bytes, bytearrays, etc. But not e.g. with single integers, floats, etc. If you want to send the number 238 as the three digit ASCII string "238", you have to convert that first, like with str() or any formatting method.

User avatar
pythoncoder
Posts: 5956
Joined: Fri Jul 18, 2014 8:01 am
Location: UK
Contact:

Re: hexadecimal numbers over UART

Post by pythoncoder » Sun Nov 01, 2020 10:52 am

Also see the int.to_bytes and int.from_bytes methods https://docs.python.org/3/library/stdty ... t.to_bytes.
Peter Hinch
Index to my micropython libraries.

BL007
Posts: 16
Joined: Wed Sep 02, 2020 6:38 am

Re: hexadecimal numbers over UART

Post by BL007 » Mon Nov 02, 2020 6:15 pm

BL007 wrote:
Sun Nov 01, 2020 9:44 am
uart.write(b'\xAA')
>>> 0x41
0x41
That was wrong from me. I recieve the dates from the UART in a PIC. There I forgot that I need a b'\x01' before the actual data. If I send

Code: Select all

uart.write(b'\x01\xAA)
then I recieved 0xAA in the PIC.


That's all good and chic. But it's not the solution of my problem.

I have strings like '53006400C845'. There are 6 btyes. But in a string. I tought I begin to try with one byte. Because 'EE'.
struct.pack need a int and makes a byte. I have a string.
str.encode() makes the ASCII-Code of the letters of chars.

Wich function makes from '53006400C845' => b'\53\00\64\00\C8\45' or leastways from '53' => b'x53'?

User avatar
Roberthh
Posts: 3668
Joined: Sat May 09, 2015 4:13 pm
Location: Rhineland, Europe

Re: hexadecimal numbers over UART

Post by Roberthh » Mon Nov 02, 2020 6:24 pm

Use ubinascii.unhexlify()

BL007
Posts: 16
Joined: Wed Sep 02, 2020 6:38 am

Re: hexadecimal numbers over UART

Post by BL007 » Tue Nov 03, 2020 8:01 am

Thanks!

But that's not it.

This makes the ASCII-Code of the letters. From 'EE' => 4545
I need b'\xee'.

User avatar
Roberthh
Posts: 3668
Joined: Sat May 09, 2015 4:13 pm
Location: Rhineland, Europe

Re: hexadecimal numbers over UART

Post by Roberthh » Tue Nov 03, 2020 9:11 am

You tried hexlify instead of unhexlify.

BL007
Posts: 16
Joined: Wed Sep 02, 2020 6:38 am

Re: hexadecimal numbers over UART

Post by BL007 » Tue Nov 03, 2020 9:15 am

I wrote a function.

This works.

Code: Select all

def str2byte16(strdata):
    from struct import pack
    num8 = str2byte8(strdata[0])
    num16  = str2byte8(strdata[1])
    data16 = (num16 * 16) + num8
    bytedata16 = pack('B',data16)
    return bytedata16 

def str2byte8(strdata):
    numchar = ord(strdata[0]) 
    if numchar > 47 and numchar < 58:
        num8 = numchar - 48
    else:
        if numchar > 64 and numchar < 71:
            num8 = numchar - 55
        else:
            num8 = numchar - 87
    return num8

Post Reply