As discussed earlier, I'm expecting to be starting a new Code Club in September, at a secondary rather than primary school. This will be more challenging, I hope and expect, because of the age range and increasing teenager-ness.
Friday, 5 August 2022
Starting a Code Club!
Washing Machines as a topic for CC exploration
I'm about to start a Code Club at a local secondary school, courtesy of a couple of days as part of the STEM Network. That involved working with Year 7 students on a "make a security device/container" project, using microbits. One of the staff involved asked me if I was interested in supporting a Code Club, what could I say?? Anyway, some ideas for entertainment may be required...
And in respect of that, how about designing/building a washing machine?? Not a fully functional one of course, but at least getting the kids to think about what the requirements for a washing machine are, how they could be met, and programming/building some of the more interesting aspects.
Ideas include:
- Water Temperature (variable)
- Heating control
- Washing powder/softener/pre-wash release
- Water valve controls, water height/volume
- Motor speed, intermittent vs spin cycle
- Wash Programmes (separate value settings vs. validity, or "packaged" programmes?)
- All the interlocks (doors, water height, stop/start/reset etc)
- Timers of all sorts
- Front panel display and controls (content, complexity, UI aspects, warning sounds/signals etc)
- The future of washing machines?? Online interface? Security concerns? Phone control app (using
Tuesday, 13 July 2021
Microsoft MakeCode Arcade 3D effects and Kitronik Arcade
I wanted to create a simple game for a granddaughter to play on the Kitronik Arcade which involved hiding a sprite behind various objects using the direction keys. However, I had no idea how to get one sprite to go behind another!!
The Kitronik Arcade is a pretty neat piece of kit which runs the downloaded code from Arcade, and includes a "proper" set of GameBoy-like control buttons with a very neat colour screen, a piezo speaker and a vibrator motor for haptic effects. It's great to run your own code on a real handheld device instead of an emulator.
It turns out 3D is pretty simple. Here's my code, stolen largely from an excellent post in the MakeCode Forum, with the addition of jumping on button B, and "mooing" on button A! The main thing is to set the "z" parameter on all the sprites, using a suitable algorithm or choice of values. So the example sets the z value of the two physical object sprites to their "bottom" value, and the moving sprite z value to its "bottom". Then the moving sprite "disappears" behind the object when it overlaps it, because its lowest point is either greater than (in front of) or less than (behind) the object. There's some more code for making sure it walks around the object by removing ambiguous values.
This was so much fun I decided to make a spaceship orbiting a planet... Here's the code. This uses the formula for an ellipse to move the moving sprite around the planet sprite. The spaceship Z is set to its current Y location, and that of the planet to its horizontal centreline. The cunning bit is using A and B buttons to accelerate/decelerate the ship and change the orbit - faster is lower, slower is higher. The really hard bit was getting an image of the Earth into the Arcade environment - I followed the instructions in the manual, which results in a .ts file that you copy into your JavaScript in Arcade. Yeah, JavaScript, sadly Blocks/PXT doesn't seem to support imported images. The video is of the emulator on my computer, not the Kitronik Arcade.
Wednesday, 16 June 2021
Micro:bit Sensory Extension aka The Directional Hat
I listened to a very interesting podcast the other day which was talking about sensory extensions for humans - basically, detecting something which is currently outside human sensory range and mapping it to one of our existing senses. For example, glasses which map UV frequencies to visible light, or - more possibly - magnetic fields e.g. a compass bearing, to little vibrators. The latter was the prime example on the podcast, with a university research project based on a belt with 16 vibrators connected to a microcontroller, that cooperated with one's smartphone to always indicate North, or to use GPS to buzz the motor in the direction one was to turn.
Time for the sensory hat - an idea nicked from the podcaster, but hey, why not?
Compass - microbit!! It has a compass, and digital ports - what could possibly go wrong? Port maximum output 5mA, at 3V.
Vibrator - tiny 12000 rpm 3V DC motor, which draws about 60mA when running. Problem - motor can generate huge back EMF, which would wipe out the microbit port, so we need to bypass that with a diode.
Since the microbit ports can't handle the current draw of the motor, we need a switch of some sort. Let's use a transistor!! I haven't done this before, but conceptually it's pretty simple. That requires a resistor between the base of the transistor and the microbit port, so we don't exceed the microbit current limit.
Let's get the motor running, so to speak...
![]() |
| Test Motor connection |
Circuit diagrams courtesy of DigiKey's excellent (for free!) web-based circuit diagrammer tool. I am very impressed.
from microbit import *
display.show(Image.HEART)
pin0.write_digital(0)
buzz = False
while True:
if button_a.was_pressed():
buzz = not buzz
if buzz:
display.show(Image.HEART_SMALL)
pin0.write_digital(1)
sleep(100)
display.show(Image.HEART)
pin0.write_digital(0)
sleep(500)
That worked ok, although the ludicrously tiny and short wires of the motor are a total PitA. It is possible to modify the motor speed a bit using an analog output pin, but it's better to use short bursts of a digital pin, which are of course a long burst versions of the PWM analog pins!
However, I want to control lots, possibly 8 motors. This is tricky because the microbit only supports 6 "proper" i.e. unencumbered ports, viz. 0, 1, 2, 3, 8, 12 and 16. Now I could do 8 from 6 by multiplexing the pins' output, say 2 rows of 4 columns, with a pin driving each row/column. That requires something like two switches at each node of the 2x4 grid... like a transistor! Time for the AND gate...
![]() |
| Test hardware AND gate |
This layout combined with the following code actually worked pretty much first time! The 1K resistors are required to limit the current from the microbit pins.
from microbit import *
display.show(Image.HEART)
pin1.write_digital(0)
pin2.write_digital(0)
# Allow experimenter to see the "I'm working!" HEART
sleep(500)
display.clear()
a_on = False
b_on = False
while True:
# Flip A&B states if buttons have been pressed
if button_a.was_pressed():
a_on = not a_on
if button_b.was_pressed():
b_on = not b_on
# If a state is on, turn on the port and
# a helpful display pixel :-)
# The AND gate does the summing in hardware
if a_on:
display.set_pixel(0, 0, 9)
pin1.write_digital(1)
else:
display.set_pixel(0, 0, 0)
pin1.write_digital(0)
if b_on:
display.set_pixel(4, 0, 9)
pin2.write_digital(1)
else:
display.set_pixel(4, 0, 0)
pin2.write_digital(0)
# Let's give it a rest
sleep(500)
And now... the multiplexer!
![]() |
| Multiplexer circuit |
This eventually worked on the breadboard - lots of problems just because I had to get some kind of sensible physical arrangement of all the wires, and I used an incorrect resistor value in one row location that caused the entire row to stay dark with insufficient base current. Cool though! I'm not sure how easily I'll be able to make this into a hat... and currently I've only got 6 motors!
from microbit import *
def setPin(pin_no: int, pinOn: bool):
pin_no = pin_no % 8 # Make sure we haven't been slipped a dud
col = pin_no % 4
row = pin_no // 4
cols[col].write_digital(1 if pinOn else 0)
rows[row].write_digital(1 if pinOn else 0)
display.set_pixel(col, row, 9 if pinOn else 0)
cols = [pin0, pin1, pin2, pin8]
rows = [pin12, pin16]
display.show(Image.HEART)
for i in range(0, len(cols)-1):
cols[i].write_digital(0)
for j in range(0, len(rows)-1):
rows[j].write_digital(0)
# Allow experimenter to see the "I'm working!" HEART
sleep(500)
display.clear()
a_on = False
b_on = False
count = -1
while True:
# Flip A&B states if buttons have been pressed
if button_a.was_pressed():
a_on = not a_on
if button_b.was_pressed():
b_on = not b_on
# If a state is on, turn on the port and
# a helpful display pixel :-)
# The AND gate does the summing in hardware
display.clear()
if a_on:
count = count+1
if count > 7:
count = 0
setPin(count, True)
sleep(1000)
setPin(count, False)
# Let's give it a rest
sleep(500)
![]() |
| Patch wire madness |
Saturday, 6 February 2021
Micro:bit Message Scroller (or hat) Part 2
I couldn't resist fiddling about.
V4
I've
- Put an array ("list") of messages in the scroller code
- Press A+B to select the next message, or back to the start of the message list if already at the last
- Set a "changeMsg" flag in the A+B pressed and the "receive name value" blocks
- Put the message switching code into a function, called switchMsg
- Check the "changeMsg" flag in the main forever loop; if it's set, then invoke the message switch function
- Any microbit can be used to switch message
- Enabled MBs to switch message before they are configured with an ID - this required an additional "configured" flag, distinct from the "readyToGo" display control flag
![]() |
| Initialisation |
![]() |
| Main loop - only really works for ID = 0 |
![]() |
| Code for ID > 0 - character index code needs tidying! |
![]() |
| Button and change message signal processing |
Micro:bit Scrolling Message Board (or Hat!)
It's been impossible to run Code Clubs and so on in these COVID-19-y times. However, I've just volunteered for a series of online Code Clubs with the Oxford Science Centre, and I thought I'd do something to introduce myself. What better than a scrolling message hat??
A simple idea - an array of microbits that scroll a message.
V1
Set up a displayString with the message to display. Assign each microbit an ID (1 -> n-1, string of length n), then using "radio send number", have the first (0) microbit send the index of the letter it's displaying to the others. They then subtract their ID to get the index of the letter they should be displaying, and display it.
- MB 0 - Forever; For index = 0 to displayString.length -1; radio send number index; show displayString[index]; end For; end Forever
- MB >0 - On radio receive number; If number - ID >=0 show displayString[number - ID]
Important point: I had to make sure I did "radio send index" before starting to display the current character, otherwise the later microbits in the chain didn't get the message until the first microbit had moved on :-/.
V2
Added some code to check if anything has been displayed yet, and if not, use number-ID to check for displayability; if previously displayed something, then use (number+displayString.length-ID) mod displayString.length to determine what character to display.
V3
It was really boring having N versions of the code to get a different ID into each microbit. So I used "press button A N times" to set the ID, and "press button B" to indicate I'd finished configuring the ID. The main loop and on radio receive number code were prevented from executing until the ID was configured by using a "readyToGo" boolean that was set to TRUE by the "press button B" code. Nice. Easy to have 10 microbits now!
V4
Having the same message all the time is really boring. I modified the scroller code to include "on radio received string" which would receive a new string, reset things, and start again, thereby changing the message.
I also created a "send new message" microbit, with an array of messages, selected by pressing button A repeatedly, and then pressing buttons A+B to send the radio message with the new string.
This seemed to be cutting the string short, and I eventually discovered that the maximum string length for radio send string is 19 characters, or I think 18+terminator. So keep those messages short!
![]() |
| The latest scroller code |
![]() |
| The current message setting code |
Possible enhancements
- Have all the messages in the scroller code, and have the ID 0 microbit do the triggering to all the others, so they use the identified message in the list; could be a timer or a number of repeats before changing; this avoids the radio send message length limitation
- The above, with a simple trigger microbit to tell them all to switch to the next or specific one. Nice for a stupid Stephen Hawking style message hat (simple words like Yes, No, Maybe, What?).
- With, say, 10 MBs, you could display individual words statically, or if too long, scroll them. Use an array of words rather than entire messages. That would be easier to read!
Tuesday, 10 November 2020
Micro:bit Bluetooth communications with RaspberryPi
I have acquired a number of micro:bits for a primary school Code Club - currently in abeyance because of COVID-19 constraints - and I've been thinking about useful experiments and instrumentation.
One of the basic models is collect data over a period of time and then look for patterns, make associations and draw conclusions. A microbit doesn't really have a means to store data over an arbitrary length of time, let alone process it in any meaningful way. For that you need a "proper" computer. So how do you get machine-readable data off a microbit?
The first way is to write the data down a serial link over a USB connection to a PC. Then since that requires a terminal program to "catch" the serial data, the terminal program has to write it to a file. Then what if you want to use multiple microbits? That means multiple USB connections, wires etc., multiple terminal program instances and so on. Of course, you could write a Python program to do all that...
It seemed more interesting to use Bluetooth if possible. No wires!! So I've been investigating python-bluezero, which provides a handy Python interface to the Linux BlueZ Bluetooth software. It also includes a microbit interface, which is extremely handy. In fact, the software includes 3 different levels of interaction with BlueZ, all based on the Linux d-Bus IPC mechanism, requiring greater or lesser (in my case!) knowledge of the underlying mechanism.
Well, dear reader, it works. Certainly the simple, polling-style interfaces seem to work just fine. You can scan the microbit for temperature, button state, LED state etc., and also set LED state and send max. 20 character text strings to display. Pretty handy! I've got it working with a single microbit, and will have a go at interfacing to 2+ microbits simultaneously. Python allows for multiple instances of the Microbit class, so I can presumably handle each one separately in a single Python process. That would allow for, for example, differential temperature measurements across a room, or inside/outside, taken simultaneously. Nice.
One strange behaviour I've noticed is that the callback for Button presses doesn't seem to work. This is in microbit.py:
def _decode_btn_a(self, *button_values):"""Decode button A state and pass on to user callback."""
if 'Value' in button_values[1]:
self.user_btn_a_callback(int(button_values[1]['Value'][0]))
def subscribe_button_a(self, user_callback):
"""
Execute user_callback on Button A being pressed on micro:bit
:param user_callback: User callback method receiving the button state
:return:
"""
self.user_btn_a_callback = user_callback
self._btn_a_state.add_characteristic_cb(self._decode_btn_a)
self._btn_a_state.start_notify()
Basically, you call subscribe_button_a with your routine to be called when Button A is detected to have changed state e.g.
def buttonA_pressed (action):
print('Button A: ', action)
This is effected by
- Saving the user callback in the Microbit class
- Installing _decode_btn_a as the callback from the dBus messaging service
- When that is called, decoding the notification and Button action value from the dBus message
- Invoking the saved user callback with a single parameter, the action value
- Go to GitHub and get the code that corresponds to what you think you are supposed to be running
- Do sudo python3 -m pip install <installable_thing> - that way it gets installed in the right environment












