Page 1 of 1
UART - working with bytes objects
Posted: Sun Jun 21, 2015 6:45 pm
by mschulz
Hello,
I communicate over UART with an other Komponent to get commands.
At first I check,if there is a message
Then I read the messeage and print it.
Code: Select all
command = self.__uart2.read(9)
print('INFO-YB: read:',command)
This is the result:
b'\x01\x88\x00\x00\x00\x00\x00\x00\x89'
This is coded in Hex.
Now I want to dismantle this in individuals:
01 => irrelevant
88 => 136 (command)
00 => 0 (type)
00 => irrelevant
00 => irrelevant
00 => irrelevant
00 => irrelevant
00 => value with the MSB first, here I need the decimal value to use it.
89 => Checksum(Summe of all)
I do not need the Dec value, but I must calc the Checksum and read some of the values?
Whitch is the best way to dismantle this?
Should I use this?
Or can I dismantle the strinng with command[1,2] etc?
Which, do you think, is the easiest solution?
Thank you very much!
Re: UART -
Posted: Mon Jun 22, 2015 5:27 am
by dhylands
You can use indicies just like with regular strings:
Code: Select all
>>> x = b'ABCDEF'
>>> x[1:3]
b'BC'
>>> x[1]
66
>>> bytes((66,))
b'B'
The difference between read and readinto is that read always allocates a new buffer. With readinto you need to allocate the buffer ahead of time but you can reuse it over and over.
You can use the following to calculate the sum:
Code: Select all
>>> x = b'\x01\x88\x00\x00\x00\x00\x00\x00\x89'
>>> sum(x[0:8])
137
>>> hex(137)
'0x89'
Re: UART -
Posted: Mon Jun 22, 2015 12:57 pm
by mschulz
Thank you for your answer.
when I want to use readinto[buf,9], how I must define the buffer?
To convert from hex to dec work very vel with hex() and int()
To use indices like with regular strings, what is with the '\x'?
Re: UART -
Posted: Mon Jun 22, 2015 2:38 pm
by dhylands
With regular strings and binary strings, you can specify the individual bytes or characters using hex notation. For example, an uppercase A has a hex value of 0x41 or a decimal value of 65.
So you can create a binary string with an uppercase A in a variety of ways:
Code: Select all
>>> b'A'
b'A'
>>> b'\x41'
b'A'
>>> bytes((65,))
b'A'
>>> bytes((0x41,))
b'A'
When printing a binary string, the \x notation is used for characters which are outside the ASCII range. The \x must be followed by 2 hex digits and the 4 byte sequence \x12 used in byte strings to represent a single byte with a value of 0x12 (hexadecimal) or 18 (decimal). Although there are few other special escape sequences as well (\t = TAB = \x09)
Code: Select all
>>> x = b'\x08\x09'
>>> x[0]
8
>>> x[1]
9
>>> x
b'\x08\t'
Re: UART -
Posted: Mon Jun 22, 2015 3:17 pm
by Damien
When you read data from the UART it returns a "bytes" object, which is simply an array of bytes. When printing a "bytes" object Python prints a "b" at the start to indicate that it's bytes. It uses hex notation to display bytes that don't have an associated ASCII character.
To get individual bytes it's best to use the subscript operation:
Code: Select all
data = uart.read(9)
command = data[1]
type = data[2]
value = data[7]
checksum = data[8]
These variables that you assign to will have integer values, eg command = 0x88 = 136 in your example.
A more concise way of extracting the data is to use tuple unpacking:
Code: Select all
_, data, command, _, _, _, _, value, checksum = data
To check the checksum you can use:
Code: Select all
if sum(data[0:7]) == data[8]:
print("checksum passed")
else:
print("checksum failed")
Re: UART - working with bytes objects
Posted: Tue Aug 04, 2015 10:30 am
by mschulz
Thank you,
I check with
newinstruction = self.__uart2.any()
if true I read
message = self.__uart2.read(9)
print(message)
modulard, commandnr, typenr, banknr, value0, value1, value2, value3, checksum = message
Sometimes ist works very well but with some messages I print only 2 parts and so I get an error.
Have sombody an good idea why I lost some parts of the message?
With my WLAN Modul (ESP8266) I have sometimes the same problem, that I lost a part of an message
Thank you