Search code examples
pythonpython-3.xserializationpyserialbbc-microbit

How to set up serial communication with micro:bit using PySerial?


I'm currently trying to send accelerometer data from my microbit to a python program running on my computer. I've decided to use uart and pyserial to attempt to do this.

from microbit import *

while True:
    x = accelerometer.get_x()
    uart.write(str(x))

    msg_bytes = uart.read()
    print(str(msg_bytes)[:-4])

However, I have never used pyserial so I'm not sure how I can use the module to extract the msg_bytes data from the microbit onto my computer.


Solution

  • There are two parts to reading the acceleromter data on the microbit and displaying the data on the device you connect your microbit to.

    A micropython script for the microbit, then a python script to run on the device you connect your microbit to.

    Please find some code below which I tested with a microbit connected to my Thinkpad X230 running Python 3.7.3 under Debian. The Python script should run on Windows as well. I used the the Mu editor to flash the micropython to the microbit.

    micropython to load on to the microbit:

    from microbit import *
    
    while True:
        x = accelerometer.get_x()
        y = accelerometer.get_y()
        z = accelerometer.get_z()
        print("x, y, z:", x, y, z)
        display.show(Image.YES)
        sleep(250)
        display.show(Image.NO)
        sleep(250)
    

    Python script to display the accelerometer data. The script finds the microbit using the VID and PID of the device, connects using pyserial then displays data. You will need to run 'pip3 install pyserial --user' if you do not already have the pyserial library installed.

    import serial
    import serial.tools.list_ports as list_ports
    
    
    PID_MICROBIT = 516
    VID_MICROBIT = 3368
    TIMEOUT = 0.1
    
    
    def find_comport(pid, vid, baud):
        ''' return a serial port '''
        ser_port = serial.Serial(timeout=TIMEOUT)
        ser_port.baudrate = baud
        ports = list(list_ports.comports())
        print('scanning ports')
        for p in ports:
            print('port: {}'.format(p))
            try:
                print('pid: {} vid: {}'.format(p.pid, p.vid))
            except AttributeError:
                continue
            if (p.pid == pid) and (p.vid == vid):
                print('found target device pid: {} vid: {} port: {}'.format(
                    p.pid, p.vid, p.device))
                ser_port.port = str(p.device)
                return ser_port
        return None
    
    
    def main():
        print('looking for microbit')
        ser_micro = find_comport(PID_MICROBIT, VID_MICROBIT, 115200)
        if not ser_micro:
            print('microbit not found')
            return
        print('opening and monitoring microbit port')
        ser_micro.open()
        while True:
            line = ser_micro.readline().decode('utf-8')
            if line:  # If it isn't a blank line
                print(line)
        ser_micro.close()