Thursday, 26 November 2015

Snake on MicroBit using MicroPython

I got my hands on one of the BBC's Microbit's as part of ntoll's Micro World Tour.

I used ntoll's upyed website to create my code and download the .hex file which I uploaded to the Microbit.

After a few tests to see if everything was working I decided to see if I could port the code I wrote to make Snake for Minecraft and Raspberry Pi Sense Hat.

I was pretty pleased. If you want to have a go yourself you will find the code here.

The code
import microbit

class SnakeBit():
    UP = 0
    DOWN = 1
    RIGHT = 2
    LEFT = 3
    def __init__(self):
    def startGame(self):
        self.direction = self.UP
        self.length = 2
        self.tail = []
        self.tail.insert(0, [2, 4])
        self.score = 0
        playing = True
        samples = 0
            #keep looping around, if the button is pressed, move the snake immediately, 
            #otherwise move it when the sample time is reached
            buttonPressed = self._handle_buttons()
            samples = samples + 1
            if buttonPressed or samples == self.SAMPLESPERMOVE:
                playing = self.move()
                samples = 0
        microbit.display.scroll("Score = " + str(self.score), 100)

    def _handle_buttons(self):
        buttonPressed = False
        #has a button been pressed
        if microbit.button_a.is_pressed():
            #wait for the button to be released
            while microbit.button_a.is_pressed():
            buttonPressed = True
        if microbit.button_b.is_pressed():
            while microbit.button_b.is_pressed():
            buttonPressed = True
        return buttonPressed

    def createApple(self):
        badApple = True
        #try and fnd a location for the apple
            x = microbit.random(5)
            y = microbit.random(5)
            badApple = self.checkCollision(x, y) = [x, y]
        microbit.display.set_pixel(x, y, self.APPLEBRIGHTNESS)

    def checkCollision(self, x, y):
        #is this outside the screen
        if x > 4 or x < 0 or y > 4 or y < 0:
            return True
            #or in the snakes tail
            for segment in self.tail:
                if segment[0] == x and segment[1] == y:
                    return True
                return False

    def addSegment(self, x, y):
        #create the new segment of the snake
        microbit.display.set_pixel(x, y, self.SNAKEBRIGHTNESS)
        self.tail.insert(0, [x, y])
        #do I need to clear a segment
        if len(self.tail) > self.length:
            lastSegment = self.tail[-1]
            microbit.display.set_pixel(lastSegment[0], lastSegment[1], 0)

    def move(self):
        #work out where the new segment of the snake will be
        newSegment = [self.tail[0][0], self.tail[0][1]]
        if self.direction == self.UP:
            newSegment[1] -= 1
        elif self.direction == self.DOWN:
            newSegment[1] += 1
        elif self.direction == self.LEFT:
            newSegment[0] -= 1
        elif self.direction == self.RIGHT:
            newSegment[0] += 1

        if self.checkCollision(newSegment[0], newSegment[1]):
            #game over
            snakehead = self.tail[0]
            for flashHead in range(0,5):
                microbit.display.set_pixel(snakehead[0], snakehead[1], self.SNAKEBRIGHTNESS)
                microbit.display.set_pixel(snakehead[0], snakehead[1], 0)
            return False
            self.addSegment(newSegment[0], newSegment[1])

            #has the snake eaten the apple?
            if newSegment[0] ==[0] and newSegment[1] ==[1]:
                self.length += 1
                self.score += 10

            return True

    def left(self):
        if self.direction == self.RIGHT:
            self.direction = self.UP
        elif self.direction == self.UP:
            self.direction = self.LEFT
        elif self.direction == self.LEFT:
            self.direction = self.DOWN
        elif self.direction == self.DOWN:
            self.direction = self.RIGHT

    def right(self):
        if self.direction == self.RIGHT:
            self.direction = self.DOWN
        elif self.direction == self.DOWN:
            self.direction = self.LEFT
        elif self.direction == self.LEFT:
            self.direction = self.UP
        elif self.direction == self.UP:
            self.direction = self.RIGHT

snake = SnakeBit()

Tuesday, 10 November 2015

Raspberry Pi PiAware Aircraft Radar

After creating the PiAware Flight Indicator LED I was keen to see what else I could do with the aircraft data my PiAware setup was retrieving for me.

I thought I would see if I could make an 'old fashioned' radar to show what aircraft were being picked up so I could have my own desk based radar.

I found an example of a radar written in pygame, which became the basis of my code (although I am pretty sure the original author wouldn't recognise it now) and created a radar class.

I plugged in the GPS coordinates of the aircraft using the PiAware flight data class I created to produce a pretty swanky, even if I say so myself, radar of all the aircraft I am picking up signals from.

Setup PiAware
If you want to have a go, first you need to setup a PiAware server to receive data - you don't need a lot of equipment and its really easy to do.

Download my project
The code is on github at
git clone
Run the program
The program expects a number of command line parameters, the mandatory being the latitude and longitude of your PiAware server, which will be the centre of the radar.
cd PiAwareRadar/piawareradar
python3 mylat mylon
You can set other parameters for the IP address of the PiAware server, if your radar is running on a different machine, whether you want it to run full screen and the layout of your screen (normal or touch).

    usage: [-h] [--piawareip PIAWAREIP] [--screen SCREEN] [--fullscreen] lat lon
    PiAware Flight Radar
    positional arguments:
      lat                   The latitude of the receiver
      lon                   The longitude of the receiver

    optional arguments:
      -h, --help            show this help message and exit
      --piawareip PIAWAREIP The ip address of the piaware server
      --screen SCREEN       The screen config to use [normal / touch]
      --fullscreen          Fullscreen radar
The plus and minus buttons in the top right allow you to zoom in and out, if you click on a dot, the data about that flight will be display in the bottom right hand corner.

Sunday, 4 October 2015

PiAware - Aircraft Overhead Indicator LED

I've been using the PiAware software to track aircraft flying near me and I liked the idea of turning an LED on when a plane was overhead (or at least near by!).

The first step was creating a way of reading data from PiAware using Python 3, so I created a module called

Once I had the data it was simply a case of looping through each of the aircraft signals found, calculating the distance between my gps co-ordinates and the gps position of the aircraft. If the distance was less than 10km I turned the led on!

I 'reused' the code to calculate the distance between 2 GPS co-ords from codecodex.

Setting up

You'll need PiAware installed on your Raspberry Pi, up and running and tracking aircraft.

You'll need an LED, appropriate resistor, breadboard and a couple of Male/Female jumper cables to connect it togther.

The LED is connected to ground and pin 17 with the resistor in between.

cd ~
git clone
Launch the flightlight program passing the latitude (lat) and longitude (lon) of your PiAware station (use to find your gps location) and the range that should be used to detect if an aircraft is overhead.
usage: [-h] lat lon range
e.g. using GPS coords of 52.4539, -1.7481 (Birmingham, UK Airport) with a range of 10km
cd ~/flightlight/flightlight
sudo python3 52.4539 -1.7481 10
import RPi.GPIO as GPIO
import argparse

from flightdata import FlightData
from haversine import points2distance
from time import sleep

#pin of the LED to light

class LED():
    def __init__(self, ledPin):
        self.ledPin = ledPin
        GPIO.setup(ledPin, GPIO.OUT)

    def on(self):
        GPIO.output(self.ledPin, True)

    def off(self):
        GPIO.output(self.ledPin, False)

#read command line options
parser = argparse.ArgumentParser(description="PiAware Flight Light")
parser.add_argument("lat", type=float, help="The latitude of the receiver")
parser.add_argument("lon", type=float, help="The longitude of the receiver")
parser.add_argument("range", type=int, help="The range in km for how close an aircraft should be to turn on the led")
args = parser.parse_args()

#get the flight data
myflights = FlightData()

#set GPIO mode


    #create LED
    led = LED(LEDPIN)

    #loop forever
    while True:
        plane_in_range = False

        #loop through the aircraft and see if one is in range
        for aircraft in myflights.aircraft:
            if aircraft.validposition == 1:
                startpos = ((, 0, 0), (args.lon, 0, 0))
                endpos = ((, 0, 0), (aircraft.lon, 0, 0))
                distance = points2distance(startpos, endpos)
                if distance <= args.range:
                    plane_in_range = True

        #turn the led on / off
        if plane_in_range:

        #refresh the data

    #tidy up GPIO

Sunday, 27 September 2015

Read PiAware Flight Data with Python

I have been using Piaware for a couple of weeks and I like the idea of being able to read the signals from aircraft just using simple equipment.

I wanted to use this information to do interesting 'stuff', I'm imagining home built radars and led's which flash, but before I could do anything cool I needed to find a way of getting to this data using Python.

Its possible to read data directly from the dump1090 program using tcp sockets, but the data is a raw stream and it seemed like too much work (I'm all for simplicity)!

The Piaware install also comes with a web front end so you can see the data you are receiving [http://localhost:8080], you can also get to the json data [http://localhost:8080/data.json] which is feeding this web page and this looked like a much easier way of getting the data out.

I create a small Python 3 class called FlightData [link to github] which reads the data from the web page and parses it into an object.

You can install it by cloning the flightdata github repository and copying the file to your project (if there is sufficient interest I'll make it into an 'installable' module):
git clone
cp ./flightdata/ ./myprojectpath
You can test it by running the program file:
Below is a sample program which shows how to use it:
from flightdata import FlightData
from time import sleep

myflights = FlightData()
while True:
    #loop through each aircraft found
    for aircraft in myflights.aircraft:
        #read the aircraft data

   #refresh the flight data

Tuesday, 22 September 2015

Minecraft Game Tutorial - LavaTrap - Pycon 2015

At Pycon UK 2015, I did a couple of workshop at its Education Track Kids day.

It was great fun and to make sure there was something fresh for the children to get their teeth into I came up with a new exercise called "LavaTrap" so I thought I would share it!

You can download the worksheet which is great printed as an A5 booklet on a single piece of A4 or you can follow the exercise below.

The Lava Trap

Using Python and Minecraft: Pi edition we can change the game to do amazing things.

You are going to create mini game - a Lava Pit will instantly appear and Steve will be put at the centre of it, soon through the block he is standing on will disappear so he will have to move, but hang on all the blocks keep disappearing!



The first task is to start your program and get “Welcome to the Lava Trap” to appear on the screen:
  1. Press ESC to go back to the Minecraft menu but leave the game playing.
  2. Open Python IDLE by clicking Menu > Programming > Python 3.
  3. Use File > New Window to create a new program and save it as ‘’.
  4. Type the following code into the program to import the modules you will need.
from mcpi.minecraft import Minecraft
from mcpi import block

from time import sleep

  1. Create a connection to Minecraft using the code.

mc = Minecraft.create()

  1. Post a message to the chat window.

mc.postToChat("Welcome to the Lava Trap")

  1. Run your program by clicking Run > Run Module.

You should see your message appear in the Minecraft chat window.


  • An errors will be displayed in the Python Shell in red.
  • If you get an error check your code carefully.
  • Capital letters are important Minecraft is different to minecraft.


Next you will use the api to create the pit where the game will be played - when your program runs it will instantly appear under Steve before the game starts.

First update your program so it creates a single block of lava under Steve, by adding the following code:
  1. Put a 3 second delay into your program so that you can see what going on.


  1. Find out where Steve is in the world.

pos = mc.player.getTilePos()

  1. Create a block of lava under Steve.

mc.setBlock(pos.x, pos.y - 1, pos.z,

  1. Run your program by clicking Run > Run Module or by pressing F5.

Your program will wait 3 seconds and then a block of Lava will appear under Steve - he’s going fall in and burn!


  • Walk somewhere different and run the program again - another Lava block will appear.
  • Try changing the code to use DIAMOND_BLOCK rather than LAVA and see what happens.
You need to create a lot more lava in order for the game to be a lot more fun - next you will program a large slab of STONE with LAVA on the top:
  1. Use setBlocks() to create an area of STONE 2 blocks below Steve for the LAVA to sit on.

mc.setBlocks(pos.x - 5, pos.y - 2, pos.z - 5,

            pos.x + 5, pos.y - 2, pos.z + 5,


  1. Then create the LAVA under Steve.

mc.setBlocks(pos.x - 5, pos.y - 1, pos.z - 5,

            pos.x + 5, pos.y - 1, pos.z + 5,


  1. Run your program to see the Lava ‘pit’.

Make a DIAMOND_BLOCK platform in the middle for Steve to stand on:
  1. Create the diamond block.

mc.setBlock(pos.x, pos.y - 1, pos.z,

  1. Run your program Steve will be stuck in the middle of the Lava pit.

Challenge 1 - Can you code yourself out of the Lava Pit?

At the moment unless Steve flies or lays blocks down he can’t get out without getting burned - update your program so he can get out.


  • Use more setBlocks() commands to make a bridge out of the Lava pit.
  • You can change Steve’s x,y,z position using mc.player.setTilePos(x, y, z).
  • If it’s too easy, make the Lava Pit really big - is it still easy?

Make a game

Update your program to make blocks under Steve disappear:
  1. Post messages to the chat screen to warn the player the game is about to start.

mc.postToChat("Get Ready")

mc.postToChat("Blocks under you will keep disappearing")



  1. Create a variable called gameover and set it to False - it will be set to True at the end of the game.

gameover = False

  1. Create a loop which will continue until the game is over.

while gameover == False:

  1. Get Steve’s position.

   playpos = mc.player.getTilePos()

  1. Turn the block under Steve to OBSIDIAN as a warning and wait for 2 seconds.

   mc.setBlock(playpos.x, playpos.y - 1, playpos.z,


  1. After the warning turn the block to AIR, if Steve is standing on it, he’s going to be in the Lava pit.

   mc.setBlock(playpos.x, playpos.y - 1, playpos.z,


  1. Run the program, the game will start and you will have to put blocks down in the Lava pit to escape because otherwise they are going to disappear and Steve will fall in.

Game over

The game is over if Steve falls into the Lava, you need to modify your program to check if he has fallen into the Lava and put a message on the screen:
  1. Use an if statement to see if Steve’s height (y) is not equal to where he started, if it is set the gameover variable to True.

   if playpos.y != pos.y:

       gameover = True

  1. Put a message on the screen to let the player know they have been caught in the lava trap.

       mc.postToChat("Game over.")

  1. Run your program and see how long you can stay out of the lava.

Challenge 2 - Make the game your own.

This game is just the start, can you finish it? Here are some challenges:
  1. Make the game harder?
  2. Make a better game arena, perhaps build a stadium or walls around it so Steve can get out.
  3. Add points to the game, each time Steve doesn’t fall in he gets a point.
  4. Change the game so it starts easy but gets harder the longer you play.
  5. Add a 2 player (or even multiplayer!) option.


  • If you make the sleeps shorter it’ll make the game quicker and harder.
  • Create a variable called points at the start of the game and add 1 to it each time your program goes around the loop.
  • There are lots of experienced Python developers all around you - perhaps you can teach them!

Find out more

If you have enjoyed this check out “Adventures in Minecraft” and learn how to program Minecraft using Python on your Raspberry Pi, Windows PC or Apple Mac and the Minecraft resources on the Raspberry Pi website

Sunday, 6 September 2015

Pygame Zero - Pong

I wanted to explore Pygame Zero so I gave myself a challenge of creating a version of Pong.

My first piece of learning from the experience just reconfirms something I already knew - games development is hard!  Pygame Zero takes some of the pain and is certainly a lot easier to get started with than Pygame, but there is still a lot of work to do for game like Pong.

The second thing I learnt is that I didn't know how Pong worked! This page which describes how the balls reacts when it hits a paddle is really useful.

You will find all the code on github

You control the paddles with Q A (player 1) and K M (player 2).

Its very much unfinished and is missing features like:
  • Time limit - the game continues forever
  • Scores - the score should be displayed on the screen
  • 1 player mode - artificial intelligent 2nd player
Does anyone fancy picking it up?

from math import sin, cos, radians
from time import sleep

#setup the constants
WIDTH = 500
HEIGHT = 300

def reset_game(angle):

    #setup ball properties
    ball.pos = WIDTH / 2, HEIGHT / 2
    ball.x_float = float(ball.x)
    ball.y_float = float(ball.y)
    ball.angle = angle
    ball.x_vel = BALLSPEED * cos(radians(ball.angle))
    ball.y_vel = BALLSPEED * sin(radians(ball.angle))

    #position the paddles
    pad1.pos = 10, HEIGHT / 2
    pad2.pos = WIDTH - 10, HEIGHT / 2

#create a rectangle of the playing area
screenRect = Rect(10,0,WIDTH - 10,HEIGHT)

#create ball
ball = Actor('ball')

#create paddles
pad1 = Actor('paddle')
pad2 = Actor('paddle')

#reset the game

#setup the goals
goals = [0, 0]

def draw():

def update():

    #move the paddles
    if keyboard.q: -= PADDLESPEED
    if keyboard.a: += PADDLESPEED
    if keyboard.k: -= PADDLESPEED
    if keyboard.m: += PADDLESPEED

    #move the ball
    ball_old_x = ball.x_float
    ball_old_y = ball.y_float
    ball.x_float = ball.x_float + ball.x_vel
    ball.y_float = ball.y_float + ball.y_vel
    ball.x = int(round(ball.x_float))
    ball.y = int(round(ball.y_float))

    #move the ball back to where it was?
    reset_ball = False

    #has the ball left the screen?  
    if not screenRect.contains(ball):
        #did it hit the top or bottom?
        if < 0 or ball.bottom > HEIGHT:
            ball.y_vel *= -1
            reset_ball = True
        #it must have hit the side
            if ball.left < 10:
                print("Player 2 goal")
                goals[1] += 1
                print("Score {} : {}".format(goals[0], goals[1]))

            elif ball.right > WIDTH - 10:
                print("player 1 goal")
                goals[1] += 1
                print("Score {} : {}".format(goals[0], goals[1]))
    #has the ball hit a paddle
    if pad1.colliderect(ball):
        #work out the bounce angle
        bounce_angle = ((ball.y - pad1.y) / (pad1.height / 2)) * MAXBOUNCEANGLE
        ball.angle = max(0 - MAXBOUNCEANGLE, min(MAXBOUNCEANGLE, bounce_angle))
        #work out the ball velocity
        ball.x_vel = BALLSPEED * cos(radians(ball.angle))
        ball.y_vel = BALLSPEED * sin(radians(ball.angle))

        reset_ball = True

    elif pad2.colliderect(ball):
        bounce_angle = 180 - (((ball.y - pad2.y) / (pad2.height / 2)) * MAXBOUNCEANGLE)
        ball.angle = max(180 - MAXBOUNCEANGLE, min(180 + MAXBOUNCEANGLE, bounce_angle))
        ball.x_vel = BALLSPEED * cos(radians(ball.angle))
        ball.y_vel = BALLSPEED * sin(radians(ball.angle))

        reset_ball = True

    if reset_ball:
        ball.x_float = ball_old_x
        ball.y_float = ball_old_y
        ball.x = int(round(ball.x_float))
        ball.y = int(round(ball.y_float))

Tuesday, 28 July 2015

Change Blogger's "Cookie Consent" bar

If like me you are a user of blogger you will have no doubt notice that Google have kindly added a cookie consent message to your blog.

You may have also seen the announcement when signing into the blogger

Leading you to here to find about more information, including details on how to change the cookie consent bar to be appropriate for your blog.

If you want to change the values in the pop-up bar you can do so by adding a <script> tag into your templates <head>.

Log into Blogger, select Template from the menu and choose "Edit HTML" under the template.

In between the <head> and </head> tags you need to add a script tag and set a variable called "cookieOptions" which contains a json data e.g.:

<script>cookieOptions = {"msg": "This website uses cookies to ensure you get the best experience", "link": "", "close": "Ok", "learn": "More" };</script>

Will change the bar to:

The tags all change particular elements of the bar:
  • msg = the message displayed in the box
  • link = the url which clicking "Learn More" will redirect too
  • learn = the text in the "Learn More" button
  • close = the text in the "Got it" button
Note - the official page says the "msg" tag is actually "message", this is incorrect, changing "message" wont affect it.

You don't have to change all the elements, if you just wanted to change the message you could use:

<script>cookieOptions = {"msg": "This website uses cookies to ensure you get the best experience"};</script>

and all the other elements would remain the same.

You can also disable the bar setting cookieChoices to a blank json document using:

<script>cookieChoices = {};</script>