The FaderPhone microbit musical instrument

Today I made a (sort of) electronic musical instrument with a BBC microbit and an old BBC radio studio fader.

It’s wired up like I did previously, only I used pin 1 in place of pin 0 – as pin 0 is used for connecting the speaker.

Here’s the Python code, all 8 lines of it – perhaps someone musical can give me better arpeggiator numbers!

from microbit import *
import music

while True:
    fader_reading = pin1.read_analog()
    display.scroll(str(fader_reading),wait=False)
    music.pitch(fader_reading, 100)
    music.pitch(fader_reading+100, 100)
    music.pitch(fader_reading+200, 100)

UPDATE

I’ve now wired up the green cue switch to change the tempo and tweaked the arpeggio notes a bit. The cue switch on the BBC DK4/19 mixing desk was insanely clever. This totally analogue desk let you assign any source to any channel using a rotary selector. The cue switch would then put the appropriate green cue light on if a microphone was selected, start a tape machine if a tape machine was selected, fire off a cart if a cart machine was selected, or signal an outside source (e.g. give a remote studio a red light and put their desk in transmission mode).

Anyway, I digress… I’ve also made the A and B buttons on the microbit stop and start the thing as it does get annoying very quickly.

The circuit now looks a bit like this:

Here’s the new Python code:

from microbit import *
import music
c = 131
e = 165
g = 196
duration = 150
started = False

while True:
    if button_a.was_pressed():
        started = True
    while started:
        if pin2.read_digital() == 1:
            duration = 100
        else:
            duration = 150
        fader_reading = pin1.read_analog()
        music.pitch(fader_reading, duration)
        music.pitch(fader_reading+c, duration)
        music.pitch(fader_reading+e, duration)
        music.pitch(fader_reading+g, duration)
        if button_b.was_pressed():
            started = False
Posted in Uncategorized | Tagged , , | Leave a comment

Add a potentiometer to your microbit

I had a 10k potentiometer lying around that I saved from some junked electronics – it may have been a volume control or something, I can’t remember. Today I found a use for it when I found this excellent web site called Microbit Playground. This shows you how you can hook a pot straight up to a microbit and take readings with a bit of Python. You connect the centre pin of the potentiometer to microbit pin 0, and the other 2 pins are connected to GND and 3v on the microbit. I just used some crocodile clip leads.

I found the code to change the brightness of a dot on the screen needed an int() adding to line 5 so it reads
brightness = int((pin0.read_analog() / 1023) * 9)

I decided to play around with this and did the following:

First I made the display get dimmer or brighter depending on the position of the potentiometer:

Then I made a level graphic go up or down depending on its position in 10 increments:

Next I made a phone-style wedge that goes up & down when you wiggle the knob (just a little bit).

Then with just ONE line of Python I added an analogue paddle controller to my totes awesome Kettle Run game to make… PotKettleRun! (See what I did there? I’m here all week.)

Finally, I wired up a microbit to a fader from an old BBC radio studio mixing desk. This was the main gain fader from BBC World Service studio S36 in Bush House, London. This was a lovely BBC-designed and built DK4/19 mixing desk which we auctioned off for charity in bits when it was dismantled. Note the non-linearity of the fade – one of the nice things about this desk was the sensitivity at low levels allowing for tasteful fades when some other faders fall off a cliff as you get close to 0.

In the highly unlikely event you have a Penny & Giles type 1520/C136/188 fader which you want to wire up to a microbit, the white wire goes to pin 0, green to GND and the brown one to 3v on the microbit:

All Python code at the end of this post. If you make a 2-player Pong game with real physical paddles before me, let me know!

All the Code that’s Fit to Print

Brighter/dimmer screen:

from microbit import *

img0 = Image("00000:"
             "00000:"
             "00000:"
             "00000:"
             "00000")

img1 = Image("11111:"
             "11111:"
             "11111:"
             "11111:"
             "11111")

img2 = Image("22222:"
             "22222:"
             "22222:"
             "22222:"
             "22222")

img3 = Image("33333:"
             "33333:"
             "33333:"
             "33333:"
             "33333")

img4 = Image("44444:"
             "44444:"
             "44444:"
             "44444:"
             "44444")

img5 = Image("55555:"
             "55555:"
             "55555:"
             "55555:"
             "55555")

img6 = Image("66666:"
             "66666:"
             "66666:"
             "66666:"
             "66666")

img7 = Image("77777:"
             "77777:"
             "77777:"
             "77777:"
             "77777")

img8 = Image("88888:"
             "88888:"
             "88888:"
             "88888:"
             "88888")

img9 = Image("99999:"
             "99999:"
             "99999:"
             "99999:"
             "99999")            

img_list = [img0,img1,img2,img3,img4,img5,img6,img7,img8,img9]           

while True:
	brightness = int((pin0.read_analog() / 1023) * 9)

	display.show(img_list[brightness])
	sleep(10)

Levels going up & down

from microbit import *

img0 = Image("00000:"
             "00000:"
             "00000:"
             "00000:"
             "00000")

img1 = Image("00000:"
             "00000:"
             "00000:"
             "00000:"
             "55555")

img2 = Image("00000:"
             "00000:"
             "00000:"
             "00000:"
             "99999")

img3 = Image("00000:"
             "00000:"
             "00000:"
             "55555:"
             "99999")

img4 = Image("00000:"
             "00000:"
             "00000:"
             "99999:"
             "99999")

img5 = Image("00000:"
             "00000:"
             "55555:"
             "99999:"
             "99999")             

img5 = Image("00000:"
             "00000:"
             "99999:"
             "99999:"
             "99999")             

img6 = Image("00000:"
             "55555:"
             "99999:"
             "99999:"
             "99999")  

img7 = Image("00000:"
             "99999:"
             "99999:"
             "99999:"
             "99999")  

img8 = Image("55555:"
             "99999:"
             "99999:"
             "99999:"
             "99999")      

img9 = Image("99999:"
             "99999:"
             "99999:"
             "99999:"
             "99999")    

img_list = [img0,img1,img2,img3,img4,img5,img6,img7,img8,img9]           

while True:
	brightness = int((pin0.read_analog() / 1023) * 10)

	display.show(img_list[brightness])
	sleep(10)

Signal-strength type wedge display:

from microbit import *

img0 = Image("00000:"
             "00000:"
             "00000:"
             "00000:"
             "00000")

img1 = Image("00000:"
             "00000:"
             "00000:"
             "00000:"
             "50000")

img2 = Image("00000:"
             "00000:"
             "00000:"
             "00000:"
             "90000")

img3 = Image("00000:"
             "00000:"
             "00000:"
             "05000:"
             "95000")

img4 = Image("00000:"
             "00000:"
             "00000:"
             "09000:"
             "99000")

img5 = Image("00000:"
             "00000:"
             "00500:"
             "09500:"
             "99500")             

img5 = Image("00000:"
             "00000:"
             "00900:"
             "09900:"
             "99900")             

img6 = Image("00000:"
             "00050:"
             "00950:"
             "09950:"
             "99950")  

img7 = Image("00000:"
             "00090:"
             "00990:"
             "09990:"
             "99990")  

img8 = Image("00005:"
             "00095:"
             "00995:"
             "09995:"
             "99995")      

img9 = Image("00009:"
             "00099:"
             "00999:"
             "09999:"
             "99999")    

img_list = [img0,img1,img2,img3,img4,img5,img6,img7,img8,img9]           

while True:
	brightness = int((pin0.read_analog() / 1023) * 10)

	display.show(img_list[brightness])
	sleep(10)

PotKettleRun game

# PotKettleRun: guide your ship using a potentiometer
# Guide your ship to home port and put the kettle on.
# Can you do the Kettle Run in less than 12 parsecs?
# Sound commands & buttons from original game commented out

from microbit import *
import random
#from music import play, NYAN, POWER_UP, FUNERAL, JUMP_UP, JUMP_DOWN

# edit terrain blocks to make game harder

teacup1 = Image("00000:"
                "99999:"
                "99909:"
                "99999:"
                "99900")

teacup2 = Image("05000:"
                "99999:"
                "99909:"
                "99999:"
                "99900")

teacup3 = Image("00500:"
                "99999:"
                "99909:"
                "99999:"
                "99900")

def teacup_animate(times):
    for x in range(times):
        display.show(teacup1)
        sleep(500)
        display.show(teacup2)
        sleep(500)
        display.show(teacup3)
        sleep(500)

def build_terrain(length):
    canyon_lines=["00000:00005:00055:00555:00055:00005:",
    "50000:55000:55500:55550:55000:",
    "50005:55005:50055:50005:00005:",
    "00055:00555:00005:55000:55005:50005:"]
    terrainString = "00000:00000:00000:00000:"
    for i in range(length):
        z = random.randint(0,3)
        terrainString = terrainString + canyon_lines[z]
    terrainString = terrainString + "50005:55055"
    terrainImage = Image(terrainString)
    return terrainImage

def game_run():
    global level
    global crash
    global speed
    terrain = build_terrain(2+(level*2))
    image_height = terrain.height()
    ship_height = 4
    for i in range(image_height):
        ship_height = int((pin0.read_analog() / 1023) * 5)
#       if button_a.was_pressed():
#            play(JUMP_UP, wait=False)
#           ship_height -= 1
#           if ship_height < 0:
#               ship_height = 0
#       if button_b.was_pressed():
#            play(JUMP_DOWN, wait=False)
#           ship_height += 1
#           if ship_height > 4:
#               ship_height = 4
        if terrain.get_pixel(ship_height, 0) == 5:
            crash = True
            break
        terrain.set_pixel(ship_height, 0, 9)
        display.show(terrain)
        sleep(speed)
        terrain = terrain.shift_up(1)

speed = 500
crash = False
won = False
level = 1

display.scroll('Kettle Run')

while level < 6:         # increase this number to add more levels
    display.show(str(level))
    sleep(1000)
    game_run()
    if crash:
#        play(FUNERAL, wait=False)
        break
    else:
#        play(POWER_UP, wait=False)
        teacup_animate(2)
        display.scroll('Tea up!')
        level += 1
        speed -= 20       # increase this number to speed up more on each level

if not crash:
#    play(NYAN, wait=False)
    display.show('YOU WIN')
    sleep(1000)
else:
    display.show('GAME OVER')
    sleep(1000)

while True:
    display.scroll('Press reset to play again')
Posted in computers | Tagged , | Leave a comment

Dice maths investigation using Scratch

This week I did a maths investigation I recall doing myself when I was at primary school – and that was a long time ago! It’s the one where you find out which total scores, if any, are more likely when you roll 2 dice.

My modern twist was to combine this with a Computer Science lesson and some Scratch programming. You could do this in almost any KS2 class I think, with varying amounts of support.

I asked what we’d expect to find if we roll one die – most assumed we’d get a fairly even spread of numbers, though some thought 6 would be less likely. We soon found great variation, some groups never rolled a 5, another group rolled 1 way more than any other number. We had a discussion about why this might be – were our dice rolls really fair? Generally, though, we agreed the probability of getting any particular score from 1 to 6 was… 1 in 6. How could we get better results? By rolling the die more often! It was getting a bit tedious, though…

We then tried rolling 2 dice, added them and tallied how many of each possible score from 2 to 12 we got. We soon found that 6, 7 and 8 seemed to crop up more than any other number. To find out why that might be we wrote out every possible way of making each total:

Now it’s clear that there are more ways of making 7 than any other number.

To prove this we then used a Scratch project I made (though with more time I’d get the pupils to make it themselves). We used it to simulate 10,000 dice rolls!

(Embedded Scratch project below requires Flash)

We drew rough and ready bar charts on scrap paper to record our findings – and saw that the distribution spookily mirrored the chart we made of the possible ways of making each total:

I’ve since tweaked the Scratch project so it actually plots bar charts using turtle graphics. Click the green flag to reset, then choose if you want to roll 1 or 2 dice. This works well with up to about 2000 throws.

(Embedded Scratch project below requires Flash)

There are loads of ways of extending this. Can you work out what the ratio is of the number of 7s you make and the total number of throws? You’ll find that the more rolls you do, the closer this approaches a certain ratio. What is it? Why is this? Could the gifted coders in the class remix the project so that it scales the bar charts to fit the screen depending on how many throws you make?

If you use this activity or remix the Scratch project, let me know! It’s a Scratch version 1.4 project for maximum compatibly and Raspberry Pi-friendliness. Here’s a chunk of the lobster’s code blocks:

Posted in education, ICT | Tagged , | Leave a comment

Upcycling old netbooks

My school has a large number of old Asus eeePC 1001PX netbooks. They originally had WindowXP on, which obviously is no longer supported so their use was limited. Our IT department had rebuilt them with LXDE Linux for use in controlled assessments. Controlled assessments are a thing of the past now, so the netbooks were about to be chucked out to save space.

Now I can’t stand seeing things like this being thrown away, so I took one away on a school trip and found it perfectly serviceable for reading my school web mail, and even blogging on our VLE, uploading photos from the netbook’s built-in SD card reader. Our coach had wifi, so I could even do this on the road.

I’ve since played around a bit more and found a whole heap of possible uses for these. We are going to run this as a project to get the pupils to find the best uses and to see if they can identify a group that might like to be given a set of these netbooks.

I wiped one clean and installed Lubuntu – a lightweight version on Ubuntu. It’s friendlier than LXDE was, I think pupils will find the UI more familiar, and it runs quite well on the eeePC.

Focuswriter is a distraction-free word processor that gives you a blank sheet of paper, basic formatting and it can save in .rtf format. Could be useful (with internet disabled in the bios!) for forcing pupils (or staff) to get on and write!

Programming tools could make a set of laptops for a code club or class use: Scratch, IDLE/Python, Sonic Pi are all easily installed. Having trouble getting Mu to install though… There’s also a logic gate simulator Logisim and a whole heap of educational software for other subjects, especially maths and sciences. Plus there are apps like Inkscape which is a lovely free vector graphic design tool like Adobe Illustrator.

The Raspberry Pi PIXEL OS runs like a dream on these machines! I’ve only run it off a USB stick so far but I used this at BETT (below) to take notes and I got about 4 hours of battery life of a laptop destined for the bin. It comes with all the usual coding tools like Python, Java, Sonic Pi and the like. In the photo above you can see me showing Raspberry Pi’s director of education Carrie-Anne Philbin just how awesome their PIXEL OS is running on old netbooks.

Persistence mode means you can keep your work on the PIXEL USB stick – it’s like having your own computer on a stick. It also means that you’ve turned a laptop into a self-contained Raspberry Pi! If the awesome Ryantek RTk.GPIO board works with this you’d have access to all the GPIO pins too for real world physical computing. This saves on money buying screens, power supplies, keyboards, mice. Sure a code club would love a set of these machines? I can’t wait to get a proper PIXEL install on the hard drive!

 

Citrix Receiver

I installed Citrix Receiver without too much difficulty and found I could connect to our school’s Windows VDI pretty much as well as I can on my MacBook – giving me access to all my school data and apps like Microsoft PowerPoint, Excel and Access.

Audio workstations for school radio or theatre

Today I wiped my netbook clean again and installed… WindowsXP! There was method in my madness – there are two old bits of audio software that a) run in Windows and b) remain very useful. One is Adobe Audition 3, which (arguably) Adobe gave away when they stopped supporting it. This is still my favourite tool for editing and mixing speech audio – I used it for many years in the BBC and have made countless radio programmes and packages on it. The other is CoolPlay – no it’s not a Coldplay tribute band. Well it is, but this is a simple program but I have never found anything else that does the same job so well (disclaimer: I designed the splash screen!). CoolPlay allows you to make playlists  of audio files (WAV, MP3 it doesn’t care) which you can play – and here’s the crucial thing – and it then stops at the end of each file by default. Most audio playlist programs keep playing, but in radio you normally want each item to play, stop, then cue the next one. It even tells you the ‘out time’ when any clip will finish. CoolPlay was used a lot on BBC radio and it can be wired up to external remotes on mixing desks for fader or button start.

I may build some of these netbooks as internet-disabled audio workstations with audio mixing/editing software – Audacity could replace Audition on a Linux version – which could be used for school radio or for drama – CoolPlay would be great for playing music and FX in a school play.

Dual-boot WindowsXP and Linux

I’ve made my machine dual-boot WindowsXP and Lubuntu at the moment – I did this the hard way and discovered that installing WindowsXP on a netbook designed to run WindowsXP (lacking the original disks) is much harder than any of the Linux flavours I have tried – not even the ethernet socket worked! I had to download and install a LOT of drivers on top of vanilla WindowsXP Home Edition before I could even activate Windows and get any sound out of it. All the Linuxes I’ve tried have just worked!

A top-tip if you want to build a dual-boot XP/Lubuntu machine – format the whole drive as NTFS and do a clean install of XP if it’s not already on the machine, THEN boot the computer of a Lubuntu USB stick or live CD and choose ‘install alongside Windows’. I have a 20GB WindowsXP partition and the rest of the 160GB drive is given over to Lubuntu.

Posted in Uncategorized | Leave a comment

Lightbulb moment: learning logic gates with switches

I introduced logic gates to year 9 again this year. Last year we did the theory, filled in truth tables and then I got them to built half and full adders in logic.ly – which was fine, they really got into it.

This year though I took a different tack. Inspired by reading Code by Charles Petzold, I decided to introduce the theory of the AND, OR and NOT gates but back this up with some physical creation of the first two of these gates.

I borrowed some modular electronics from the DT department to build first an AND gate. All you need is a power supply, two switches in series and a lightbulb. I got the girls to wire this up from a circuit diagram on the board:

I then let them discover that we could only light the bulb if the first AND second switches are both turned on.

We used this to fill in our truth tables, then I got them to rewire the circuits with the switches in parallel.

This is, of course, now an OR gate as it lights the bulb if the first OR the second switch is turned on:

I didn’t have enough of these circuits, alas, for everyone to have a go, but there were a few (ahem) lightbulb moments that might not have occurred without the physical realisation of quite an abstract concept. Ideally I’d have a big bucket of switches, wires, lightbulbs and power supplies and my class could all build them themselves.

Update:
These modular electronics kits are called Economatics and were made by Omega Electronics. Unfortunately they don’t seem to be made any more – does anyone know of anything similar you can buy today? Needs to be VERY simple: switches, lightbulbs, wires – possibly relays but nothing more.

Posted in computers, education | Tagged , | 2 Comments