extract numbers from uart.read #11989
-
I'm using a microbit to read bytes from a serial stream. I'm having a problem with understanding how to extract the byte values.
This is what I see in the serial window: So when I print(content) I see the 4 bytes as numbers - fine. |
Beta Was this translation helpful? Give feedback.
Replies: 3 comments 7 replies
-
Your Something along (in REPL) should help... a = b'26,43,60,77'
numbers = str(a).split(',') # create string+split
numbers[0]
int(str(numbers[0])) Edit: I have no idea why with my Python 3.6.8 |
Beta Was this translation helpful? Give feedback.
-
A The main problem with greeting = b"Hello World"
print(greeting)
# b'Hello World'
# subscription of bytes > int
print(greeting[0])
# 72
# slicing bytes -> bytes
print(greeting[6:11])
# b'World'
# same for bytearray
# same for iteration The square-bracket access (subscription) returns the value of the single byte as an ASCII characters are frequently used for serial protocols and everything else. The same behaviour of greeting = b"Hello World"
print(list(greeting))
# [72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100]
# ASCII representation
print(tuple(greeting))
# (72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100)
for value in greeting:
print(value, type(value))
# 72 <class 'int'>
# 101 <class 'int'>
# 108 <class 'int'>
# 108 <class 'int'>
# 111 <class 'int'>
# 32 <class 'int'>
# 87 <class 'int'>
# 111 <class 'int'>
# 114 <class 'int'>
# 108 <class 'int'>
# 100 <class 'int'> To solve your task, you can do the following steps:
The code could look like this: from microbit import *
# init code
# code is not portable to Micropython
# it used microbit's version of Micropython
def line_reader():
"""
Generator Function which reads uart line by line
split the byte(string) at the ,
and convert each number to an integer
"""
while True:
line = uart.readline()
if line is None:
# timeout, just go back to the top and
# wait for next line
continue
try:
yield list(map(int, line.split(b",")))
# or as a list comprehension
# yield [int(val) for val in line.split(b",")]
except ValueError:
print("Could not convert line to integers:", line)
continue
for values in line_reader():
print(values) |
Beta Was this translation helpful? Give feedback.
-
Thank you, that is very helpful! |
Beta Was this translation helpful? Give feedback.
To extract values from a byte array, you can use struct module and the method struct.unpack() or struct.unpack_from(). You can look at the generic Python manual for instructions, how to use it.
Since you are only interested in DF3 and DF4, which have index 5 and 6 in the bytes/bytearray object, you can access them directly and as two integers as content[5] and content[6]. If these two form a 16 bit number, you can calculate that as e.g. content[5] * 256 + content[6]. That is more efficient than using struct. One would use the latter to unpack all values from the message, which then is more efficient and shorter.