Micro:bit as computer input output device

Picture this: You're trying to spice up your computer setup without breaking the bank, so you decide to add some old speakers to the mix. But there's a catch - the amp is tucked away under your desk, making it a real hassle to turn on and off every time you're not using your computer.

Now, you could have taken the easy route and just bought a newer, more energy-efficient amp. But where's the fun in that? You wouldn't be able to play tapes anymore! Instead, I set out to build a contraption that will turn your amp off when you're not using it - saving you money on energy bills and making your life a whole lot easier. 

Embark on this tutorial about one example of how you could use your Micro:bit as an input and output device for your computer.

(5th March 2022)

IMPORTANT NOTE: after making this project I had a lot of problems where the hub will stop supplying power to the Micro:bit over USB when the device has been disconnected. This is probably easily solvable by powering the servo and Micro:bit  separately, so the USB cable is only used for data. However, I can't test this for you because my Micro:bit broke :(

What you will need:

Step One - The software for you computer:

The project is going to work by having your computer ping a message to a Microbit over a serial USB connection The computer will stop sending the messages when it is asleep or powered off, so the Microbit knows to turn the stereo or other device off. This the code I wrote in python for to do this. Make sure python is installed on your computer (google how to that). If you are worried about the CPU usage of the program, on Process Explorer it uses less than 0.01% of CPU once every 3 seconds and only takes up a few megabytes of RAM.

# set up serial connection

import time

import serial


while True:

    try:

        # Try to establish connection.

        ser = serial.Serial('The name of your serial port goes here', 9600, timeout=1)


        while True:

            # send message

            print("message sent")

            ser.write(b' ')


            # wait for 3 seconds

            time.sleep(3)

    # If there's any error on the serial line, wait for 3 seconds and try again. e.g. micro bit losses power.

    except serial.SerialException:

        print("could not sent seral message")

        time.sleep(3)




You need to change the code to show the serial port of your Micro:bit. Note I have only tested this on Windows.

On windows Plug in the Micro:bit., open "Device Manager" and under "Ports (COM & LPT)" look for "USB Serial Device". In Windows the name is likely to be called "COM" followed by a number.

On MacOS Plug in the Micro:bit and open a new terminal window. Type ls /dev/cu.* to get a list of connected serial devices; your Microbit will look like /dev/cu.usbmodem1422 (the exact number depends on your computer).

On Linux plug in the micro:bit and open a new terminal window and find which device node the Micro:bit was assigned to with the command ls /dev/ttyACM* 

Image showing the Micro:bit as a serail device in windows device manager.

You might want to compile the code so that it doesn't open a terminal window when it runs. There are lots of ways to do this, But what I did in Windows was run the following command in my Terminal pip install pyinstaller. If it doesn't work, try installing pip first (google how to). Then in the directory of you python file with your code, type this in the Terminal pyinstaller name_of_you_python_file.py --onefile -w. The -w is important as it mean it compiles without the Terminal opening when it runs. Now it should have created a folder called "dist" that should have the executable you created.

On windows to make sure that you script is one of the startup programs. press the Windows logo key + R, type shell:startup, then select OK. This opens the Startup folder. Now you can add your python file, compiled executable or a shortcut to either of these in the folder.

On Mac to make sure that you script is one of the start up programs, choose Apple menu  > System Settings, click General  in the sidebar, then click Login Items on the right. (You may need to scroll down.) I haven't test this.

Google how to do this on Linux as I don't understand Linux.

Step Two - using a USB hub:

This a optional step for people who are using a laptop with no spare USB A port. I recommend you buy a second-hand dell DW15 USB 3 hub as it also has a line out port for sending the audio signal to your stereo if that the device you are controlling. Also you can find used ones from offices for about £40 on eBay and they have lots of other useful ports.

Step Three - Code for your microbit:

The code below is for the Micro:bit. Note that I wrote it for a continuous micro servo but the code can be adapted to use a normal servo however I found it made to much noise when idle. Also you will need to experiment with different timings and strengths of the servo to make sure it reliably pushes the of button on the device you are controlling. There is more about the wiring servo in the next step.

I found that when connecting the Micro:bit editor to Micro:bit via WebUSB it couldn't receive the serial messages from the python program. To solve this download the program as a hex file and drag in onto the Micro:bit in you file manager.

This is the code for the Micro:bit in python. You can try modifying it for other microcontrollers but note that you might need to change it as it uses specific libraries for the micro bit.

# Used to trigger the servo to turn device on or off.

#You will need to change this so it reliably pushes the button on your device.

def on_or_off():

    # Move the servo to the ON position

    servos.P0.run(100)

    basic.pause(100)

    # Move the servo to the OFF position

    servos.P0.run(-71)

    basic.pause(100)

    # Stop the servo

    servos.P0.stop()


# Trigger the on_or_off function when button A is pressed

def on_button_pressed_a():

    on_or_off()

input.on_button_pressed(Button.A, on_button_pressed_a)


# This function is triggered when data is received over serial

# Trigger the on_data_received function when data is received over serial

def on_data_received():

    global power, ping

    # If the device is currently OFF, turn it ON

    if power == False:

        power = True

        on_or_off()

    # Show a pattern on the LEDs to indicate that data has been received

    basic.show_leds("""

        . . . . .

                . . . . .

                . . # . .

                . . . . .

                . . . . .

    """)

    basic.clear_screen()

    # Increment the ping counter

    ping += 1

serial.on_data_received(serial.delimiters(Delimiters.SPACE), on_data_received)


# Used to display the current power status of the device

def on_button_pressed_b():

    # Show whether the device is ON or OFF

    basic.show_string("" + str(power))

    basic.pause(2000)

    basic.clear_screen()

input.on_button_pressed(Button.B, on_button_pressed_b)


"""


initialize variables


"""

ping = 0

power = False

servos.P0.stop()

# Set up the serial communication with the computer

serial.redirect_to_usb()

serial.set_baud_rate(BaudRate.BAUD_RATE9600)


# Check every minute to see if any data has been received over serial

def on_every_interval():

    global power, ping

    # If no data has been received and the device is ON, turn it OFF

    if ping == 0 and power == True:

        power = False

        on_or_off()

    ping = 0

loops.every_interval(60000, on_every_interval)




Step Four - Pressing the button on the device your controlling:

You need to find a way of turning your device on and off using a servo. This could either be the button on a remote or the power button on the device. another way you could do this by wiring a IR led onto you Micro:bit or buying a IR module for it but I haven't tried this. A useful tip I found for trouble shooting IR controllers was to use my phone camera to see when IR light is being emitted by the controller.

If you choose to control a remote you might find that it runs on 3 volt which can be provided by the micro bit as it's the same voltage it gives to the micro servos. You can see the way all the wires need to be connected on the diagram at the top of the page. To interface between the crocodile clips and the servo you can just use 3 small thin pieces of wire and fold the end over if they need to be thicker to fit in the servo connector without falling out.

I found when using a continuous servo, it is important to physically constrain its movements so that it doesn't end up not pressing the button by having its arm move to far away from the button.


Step Five- Admire your work and take it further:

Welcome to the exciting world of Micro:bit programming! With a constant connection between your computer and the Micro:bit, you have the power to unleash your creativity and make amazing things happen. Imagine pressing a button on your Micro:bit and having your favourite playlist start playing on Spotify! Or setting up your Micro:bit to open all the apps you need for the day with just a press of a button.

But it doesn't stop there! With the Micro:bit's microphone, you could create your very own DIY RGB lighting system that reacts to sound and turns off when your computer goes to sleep. And if that's not enough, you could even use a second Micro:bit as a remote control for the first one, giving you endless possibilities for projects and automations!

Hope you enjoyed it!