# data[].attributes.headline
2 way communication between microbit and pi

# data[].attributes.subject
2 way communication between microbit and pi

# data[].attributes.body
https://micromag.cc/serial-communications-with-micro-bit-raspberry-pi/

# data[].attributes.attachment_link.readable_text
In 2019 my family and I entered the annual Pi Wars competition in Cambridge with a robot called Sputnik. Although the main controller had to be a Raspberry Pi, we also wanted a way of displaying which operating mode the robot was in, and also have a way of changing modes on the robot in case we had issues with remote control on the day.

This is where the micro:bit came in. It has a simple display for showing the operating mode of the robot - and 2 buttons to allow us to change modes. Also, I hoped to be able to use the compass on the micro:bit to see which direction the robot was facing.

So the next issue was how to communicate between the Raspberry Pi and the micro:bit. The simplest answer was to use the USB port for serial communications. The same cable could also be used to power the micro:bit from the Raspberry Pi.

This article shows how you can achieve simple communication between a Raspberry Pi and a micro:bit using a USB cable.

What you will need

micro:bit

Raspberry Pi with Python 3 installed

micro USB cable to connect the micro:bit to the Raspberry Pi

Objectives

We're going to develop a simple project that shows how to set up serial communications between the micro:bit and a Raspberry Pi using the USB cable. We'll create a simple protocol for sending the data and look at some of the pitfalls that you may come across.

In this project, the 'A' and 'B' buttons on the micro:bit will be used to request the time and date respectively from the Raspberry Pi. When the time or date are received they'll be displayed on the LED display.

The Raspberry Pi will also request the current compass heading periodically.

The Protocol

When communicating between any 2 processors, they both need to be speaking the same language in order to know what the individual messages mean. This is the communications protocol.

For this project we're going to have a simple protocol that consists of a 3 character message type and optional value, separated by a colon character.

So if the when the micro:bit want's to ask the raspberry pi for the time it sends a message "TIM:" and the Raspberry Pi will respond with a message "TIM:11:34".

We'll use the message types:

TIM - request and response for current time

DAT - request and response for current date

CMP - request and response for current compass heading.

We can easily add message types for other data values - such as the micro:bit accelerometer values.

The micro:bit code

Step 1
The Serial blocks are in the 'Advanced' section of the make code editor. On startup we need to tell the micro:bit to send all the serial data to the USB port using an 'on start' block.

This also sets the baud rate to 19200. This is the rate at which bits are sent down the USB cable. This can be any setting but must be the same as that used on the Raspberry Pi.

Step 2
Create forever loops to handle serial writes and message displays. These use list variables as queues. The serial write task ensures that we're only trying to output messages to the serial device one at a time so they don't get corrupted. The message display task ensures that we can display a message in the background, and then go back immediately to reading messages from the serial device.

The 'serial write line' block will write any messages on the send queue to the serial device.

Step 3
When the A button or B button are pressed, we add a message to request the time or date to the serial send queue so that the background task created in Step 2 will send it to the serial device.

Step 4
Now we add another forever background task to read messages from the serial device.

'serial read until new line' will wait for a message terminated by a new line character to be received.

We then check that the message is long enough and has a colon in the right place. It is possible for messages to get corrupted, so this gives us some confidence it's a valid message.

The substring blocks extract the message type and the message data from the message.

We then decide what to do depending on the message type. For 'TIM' and 'DAT' messages we add the data to the display queue so that the time or date can be displayed. (This is where the queue comes into its own - we don't need to wait for the message to be displayed before receiving the next serial message).

For 'CMP' requests, we construct a message with the current compass heading and put it on the send queue to be sent to the Raspberry Pi.

Any other message types we ignore.

Raspberry Pi Code

Now that the micro:bit is all set up we can move to the Raspberry Pi.

When you plug a serial device into one of the USB ports on the Raspberry Pi, it creates a device file link in the /dev/serial/by-id folder.

Using the pySerial python library, we can read and write messages using this link. For Sputnik, we went through the list of links in this folder and created a thread to read from each one, since we also communicated with an Arduino using the same code. However, for simplicity we'll assume here that we only have a single micro:bit connected, and we'll handle both the reading and writing in the same thread.

One thing to note is that the serial python library works with the bytes datatype rather than strings. The micro:bit uses ASCII strings, so we need to encode and decode using the 'ascii' character set when converting.

So here is the code in full:

import os import time from datetime import datetime from serial import Serial nextCompassPoll = 0.0 ; serialDevDir='/dev/serial/by-id' if ( os.path.isdir(serialDevDir) ): serialDevices = os.listdir(serialDevDir) if ( len(serialDevices) > 0 ): serialDevicePath = os.path.join(serialDevDir, serialDevices[0]) serial = Serial(port=serialDevicePath, baudrate=19200, timeout=0.2) while( True ): receivedMsg = serial.readline() if ( (len(receivedMsg) >= 4) and (receivedMsg[3] == b':'[0])): msgType = receivedMsg[0:3] msgData = receivedMsg[4:] if ( msgType == b'TIM' ): timeString = datetime.now().strftime('%H:%M') sendMsg = b'TIM:' + timeString.encode('ascii') serial.write(sendMsg + b'\n') elif ( msgType == b'DAT' ): dateString = datetime.now().strftime('%d-%b-%Y') sendMsg = b'DAT:' + dateString.encode('ascii') serial.write(sendMsg + b'\n') elif ( msgType == b'CMP' ): print('Compass Bearing = ' + msgData.decode('ascii')) currentTime = time.time() if ( currentTime > nextCompassPoll ): serial.write(b'CMP:\n') nextCompassPoll = currentTime + 2.0 else: print('No serial devices connected') else: print(serialDevDir + ' does not exist')

Lines 46-52
If the micro:bit is not plugged in when we start the python program then we display a warning and exit immediately.

Running the code

Install the code onto the micro:bit and connect to the Raspberry Pi using a USB cable.

Run the python code on the Pi and you should see the compass heading displayed on the console output every 2 seconds. Press one of the buttons and the date or time should show up on the micro:bit!

# data[].attributes.attachment_link.title
Serial Communications with micro:bit + Raspberry Pi

# data[].attributes.attachment_link.description
In 2019 my family and I entered the annual Pi Wars competition in Cambridge with a robot called Sputnik. Although the main controller had to be a Raspberry Pi, we also wanted a way of displaying which operating mode the robot was in, and also have a way of changing

# data[].attributes.body
We could control the robot using our phone and use a camera to see what the robot is seeing. We could create our own app for this

# data[].attributes.body
mettle mesh to stop sparks igniting the gas/ stopping the flame from spreading.

# data[].attributes.attachment_link.description
The Davy lamp is a safety lamp for use in flammable atmospheres, invented in 1815 by Sir Humphry Davy. It consists of a wick lamp with the flame enclosed inside a mesh screen.

# data[].attributes.body
have the robot drive in with a pen attached to a servo and have the pen set down so as the kitronik bot drives in it draws a line. Once the raspberry pie and gas sensor detects gas it will tell the micro chip to spin the robot 180 degrees and it follows the line out backtracking it's step.

# data[].attributes.body
we may want something more then just sound as a way of notifying. buzzer, spinning insanely when it finds a person. not everyone has the ability to hear.

# data[].attributes.body
We could potentially use WiFi or Bluetooth to contact something or someone if it either finds gas or encounters an error so we make it efficient

# data[].attributes.body
Making a loud sound when it detects something in case a person does not notice it.

# data[].attributes.body
We could set the robots to be aware of its surroundings and is able to move around on its own. It can detect everything it sees

# data[].attributes.body
We could set the Kitronik robot to follow a line in and out of a danger area