1

I am a beginner with the microbit and I have tried to copy some code from different tutorials/code examples. I am just trying to set up the serial communication between a computer and the microbit. My plan is to have the microbit just echo every line it receives and send it back for now. But the lines are split and I am not sure if it is the microbit or the computer doing the splitting. I have tried from two different computers with the same result.

Here is the microbit code:

from microbit import *

uart.init(baudrate=115200)

msg_str = ""
while True:
    msg_bytes = uart.readline()
    if (msg_bytes):
        print(msg_bytes)

My computer code, a Python program with pyserial:

import serial
import serial.tools.list_ports as list_ports

def find_microbit_comport():
    ports = list(list_ports.comports())
    for p in ports:
        if (p.pid == 516) and (p.vid == 3368):
            return str(p.device)

if __name__ == '__main__':
    ser = serial.Serial()
    ser.baudrate = 115200
    ser.timeout = 1
    ser.port = find_microbit_comport()
    ser.open()
    ser.write(b'testing')
    text = ser.readline()
    while text != b'':
        print(text.decode('utf-8'))
        text = ser.readline()
    ser.close()

The problem I have that is that it prints out this:

b'te'

b'sting'

I was expecting it to print b'testing' in one word. I could write code to combine the text, but I could then get out of sync.

1 Answers1

1

I replicated your results using python 3.5 on Linux and a microbit.

I modified the Python code slightly. Please find this below:

import serial
import serial.tools.list_ports as list_ports

def find_microbit_comport():
    ports = list(list_ports.comports())
    for p in ports:
        if (p.pid == 516) and (p.vid == 3368):
            return str(p.device)

if __name__ == '__main__':
    print('running code')
    ser = serial.Serial()
    ser.baudrate = 115200
    ser.timeout = 1
    ser.port = find_microbit_comport()
    ser.open()
    ser.write('hello there\n')
    ser.close()
    ser.open()
    text = ser.readline()
    while (1):
        print(text.decode('utf-8'))
        text = ser.readline()
    ser.close()

Try this as the micropython on your microbit:

from microbit import *

uart.init(baudrate=115200)

msg_str = 'out: '.strip()
while True:
    new_byte = (uart.read(1))
    if new_byte == None:
        continue
    new_char = str(new_byte, 'UTF-8')
    msg_str += new_char
    if ("\n" in msg_str):
        print(msg_str)
        msg_str = ''

Output:

running code
out:hello there

This reads one byte at a time until a newline character is found, appending each byte onto the output string. The danger is that the newline character is dropped during transmission through the serial port. It is robust over a wired connection. If using wireless transmission, characters are easily corrupted or missed.

I would like to adjust the uart.init timeout parameter to see if this would fix the issue. This is not available in micropython on the microbit at this time.

Oppy
  • 2,662
  • 16
  • 22
  • but why did the OP's implementation not work correctly? the documentation states that readline() waits for a newline character. so, why it returns before a newline is found? – obe Feb 03 '20 at 22:53
  • It might be something to do with the uart timing out. The timout parameter for uart.init is not available with the implementation of micropython on the microbit to test this. – Oppy Feb 04 '20 at 13:39
  • I thought about that, but https://microbit-micropython.readthedocs.io/en/latest/uart.html says: "Return value: the line read or None on timeout.". So in case of timeout I'd expect "None"... – obe Feb 04 '20 at 13:42
  • thanks, it at least fixes my problem. I do not completely understand why my code did not work but your answers above might be the correct – RustyJuggler Feb 08 '20 at 14:27