The Raspberry Pi micro:bit Crane
You could easily be forgiven for thinking that we have a bit of a crane fixation here. We’ve had a crane controlled by a Raspberry Pi and Astro Pi unit, and a crane controlled by 2 micro:bits.
For our next crane themed project we’ve taken our micro:bit crane, and altered the code for the controller micro:bit so that it can receive instructions from a Raspberry Pi (using a serial connection) and transmit them (using the micro:bit radio) to the micro:bit that drives the motors in the crane. This might seem like a rather odd way of doing things; but there is method in our madness.
— PiMinister (@PiMinister) April 5, 2017
Our original intention was to see if we could control the micro:bit motor driver directly from the Raspberry Pi using Bluetooth. Although this is theoretically quite feasible, we quickly found that trying to use Bluetooth between a Raspberry Pi and a micro:bit is not as simple as it might sound. Despite ensuring we had the latest Bluetooth stack installed on the Raspberry Pi, and following quite a few different instructional blogs, we had no luck in getting the Raspberry Pi to reliably connect and communicate with the micro:bit. Note, if anyone out there has any thoughts or pearls of wisdom regarding this, we’d be really happy to hear from you.
Having no luck using Bluetooth between our Raspberry Pi and micro:bit, we decided to have a bit of a re-think. We already knew that we could use the micro:bit radio to communicate from one micro:bit to another. We also surmised that it should be fairly simple to communicate between a Raspberry Pi and a micro:bit using serial communication. With this in mind, we decided to try using the Raspberry Pi to communicate with a micro:bit using the USB serial connection, and then use that micro:bit to communicate with our crane micro:bit using the micro:bit radio.
Serial Communication (Sending)
Serial communication from the Raspberry Pi to a micro:bit is quite straightforward. When a micro:bit is connected to the Raspberry Pi using a USB to micro USB cable, a virtual device is created which is referenced as ‘/dev/ttyACM0’. Sending serial data to this device using the Python programming language requires a few very simple lines of code; as shown in the following code snippet:-
import serial # Open the serial port for sending at speed 115200 bits/second device = serial.Serial('/dev/ttyACM0', 115200) # Write string to serial port, and terminate with a line feed character device.write("22\n") # Close serial port device.close()
Using these lines of code as the basis for our program, we wrote a program using the Python pygame library that accepted key strokes from the keyboard and then wrote the appropriate control code strings to the serial port.
Serial Communication (Receiving)
Because we had originally used micro Python on our micro:bit to write our code to send radio data to our micro:bit crane, we initially tried using micro Python to receive the serial communication data. However, each time we tried loading our micro Python program to our micro:bit, we kept getting syntax errors displayed on the micro:bit.
Unable to find much help relating to serial communications using micro Python, we instead turned to using the PXT programming language for our serial receiver program. Receiving serial data using PXT requires a single block of code:-
This meant that our controller micro:bit code could be wrapped up in a very few blocks of code:-
As you can see from the code blocks, at the start of the code the radio is set up. Note, that we had to set the radio group to have a value of ’42’, and we use the same group number on the radio receiver micro:bit that is controlling the crane motors. Following the radio set up, a single string control code ’22’ is sent. This is to ensure that the crane motors are initially set to stopped. Following this, the program will simply wait for the receipt of serial data and will then send the same serial data string to the crane, using the radio.
Crane Radio Receiver
Although, in theory, our original crane radio receiver program would require no modification, this turned out not to be the case. It turns out that when PXT sends radio data, by default it also sends the serial number of the micro:bit, and some timing information. Although our PXT code sets the sending of the serial number to be ‘false’, the timing information is still sent. This meant that our micro Python program running on the crane micro:bit would be receiving more data than the actual control code string that we sent from the controller micro:bit.
The timing information sent in the radio string is appended to the beginning of the string that is sent. This meant that in our micro Python code running on the crane micro:bit, we needed to strip all but the last 2 characters of any string that is received. This is fairly simple using micro Python, using the following code:-
recv_string = radio.receive() if recv_string != None: try: if len(recv_string) > 2: # PXT radio sends device timing information at beginning of string # so we need to strip all but last 2 characters recv_string = recv_string[-2:] recv_int = int(recv_string) x = recv_int // 10 y = recv_int % 10 except: # Handle any exception from above x = 2 y = 2
This code will check the length of the received radio string, and if the length of the string is greater than 2 it will strip all but the last 2 characters. This leaves the program compatible with our original micro:bit crane program which used micro Python to send radio data.
We also added in a try/except block to prevent any spurious data from causing our micro:bit program to crash.
All the code for this crane project is available on our GitHub micro:bit crane page.