Search code examples
bbc-microbit

microbit serial communication splits text into lines


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.


Solution

  • 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.