BBC micro:bit – Lunar Lander Project (part 1)

With my godson’s eleventh birthday coming up, I was wondering what would be an interesting gift. A few months ago, J, his little brother N, and I had been talking about passwords. They’d been told at school that it helped to misspell words – so ‘werdz’, say, rather than ‘words’ – and to insert punctuation marks. But why are you being given this advice, I pressed them. This led to some discussion about how a person – or more likely a computer program – might try and guess a password. And this, in turn, led to us writing some code in Scratch, a programming language for kids, that would actually guess passwords. The boys enjoyed themselves hugely. And they were just awestruck by how many brute force guesses were required to crack passwords.

So for J’s birthday, I thought something with coding might be fun. But I also liked the idea of him having something of his own, something not virtual. And so I got to wondering if we could code a game on one of these new breed of tiny computers, such as the BBC micro:bit.

What I had in mind was the sort of game that I had coded up back in the early 1980s using machines such as the ZX80 (my big brother’s), Commodore Pet (at school), Acorn Atom (at John Cupitt‘s), Oric-1 (mine!), and BBC Micro (at JC’s again). This was when I was first learning about programming and you either used BASIC – which was often too slow or couldn’t let you control the screen with sufficient precision – or more likely machine code. Tricky, but rewarding when you finally got things to work.


So I started doing some research on-line. It turns out that you can buy tiny displays and it looked, in theory, as if I could connect one of these to the micro:bit and make it work. I reckoned that if I could hook up a 128 x 128 pixel display to the micro:bit that would be large enough to make a playable Lunar Lander game.

Before I committed to ordering any parts, I thought I’d do some sort of proof of concept. These days, when I program it is mostly for the iPhone using Apple’s Swift language. So I knocked up the vary bare bones of a Lunar Lander program as an iPhone app, scaling the display size to 128 x 128 pixels. And all seemed OK.

Is 128 x 128 pixels enough for a playable Lunar Lander game? Doing a “proof of concept” on the iPhone.

There remained some uncertainty though. I couldn’t find any definite instructions or a worked example of connecting a micro:bit to any of the displays I’d been looking at. There were things written about doing this for other tiny computers, such as the Raspberry Pi, but not so much for the micro:bit. So I couldn’t yet be sure whether I could actually get the micro:bit to “talk” to a display. But I was getting to the end of what I could realistically do with desk bound research. And so, I ordered two micro:bits and two Inventor’s Kits, one each for me and for J. I also ordered one display to test out. If I couldn’t make it work, then I’d have to come up with a plan B.

Microbits and Inventor’s Kits. One for J and one for me.

Before I wrapped up J’s micro:bit I wanted to try things out and get a sense of how it worked, so I could tell his mum a little bit about it and write a decent note for him in his birthday card. I encouraged J to try out the hardware and follow the instructions on his own. But I also know that what he loves more than anything is doing things with other people. For him, that’s at least three quarters of the fun. And, so it turned out, he chose to wait for my visit – scheduled for a couple of weeks’ time – before breaking the seals on his new toys.

The actual micro:bit really is micro. I was expecting it to be small from the size of the box, but even so I was surprised at how tiny it is.

Back at home, I was figuring out how the micro:bit worked. You write code on your computer, using a special web page. And even without connecting the micro:bit you can see the effects as the page has a “simulator” – an animated picture of the micro:bit that performs, more or less, in the same way as the real hardware. The main thing the micro:bit does is let your create patterns on a 5×5 grid of LEDs, to respond to two buttons and, if you connect some headphones or a small speaker, make noises and play tunes. The simulator lets your try out all these things. And then, if you connect the computer to the micro:bit you can transfer the program to the tiny computer.

There are a few different choices of programming language for the micro:bit. Because I wanted J to be able to do some of the coding himself, I went for the option called the JavaScript blocks editor. The JavaScript language is one I know something about. It’s the language that can be run inside a web browsers and is used to make web pages do all sorts of clever things. And the “blocks editor’ bit means that kids can drag chunks of code around rather than having to type things in word by word.

Great, I thought. What I can do is to develop some code in my web browser using JavaScript and I can simulate the pixel display there. That way, I can write and test code before my display arrives. I went ahead and did this, getting some basic code to paint a lunar lander on the screen and move it about. (If you are reading this on a Mac or a PC, you can see a bare bones JavaScript proof of concept version of the game running in your browser. And you can click through to JSFiddle to the see the code.)

I was greatly encouraged to have my proof of concept up and running, but there was still the question of whether I could successfully connect micro:bit and display.

When the display arrived in the post, the first task was to do some soldering so I could plug it in the “breadboard” and, through that, wire it up to the micro:bit.

Working with hardware is different from working with software. There are fewer second chances and my soldering skills were pretty rusty. But I seemed to get on OK. The most anxious part of the soldering operation was that the ‘connector’ part that came with the display had more pins than there were holes in the display board. I needed to clip off a few of the pins. I’m glad I was cautious and did an experimental clip first, as it turned out it was very easy to overshoot with the clipping.

The next phase of the project was the most challenging. The display is designed to talk to a computer using something called a Serial Peripheral Interface Bus (SPI). I was learning about this for the first time and was not finding many examples on-line of making practical use of the SPI with the micro:bit. Not for the first time, I wondered if I had bitten off more than I could chew.

At root there needs to be some wires between the display and the computer, and signals get sent down these wires to tell the display what to do. At the level of the hardware, I needed to connect some power and then four wires for communication. By following the published data sheet for the display and the micro:bit documentation, I wired everything up. And, at this point, the display actually lit up. This wasn’t telling me anything much, because I wasn’t yet sending any messages to the display to tell it what to do. But it was at least an encouraging sign.

The next phase was to start sending messages – in the form of a series of numbers – to the display to get it to do what I wanted. The people who provided the display provided lots of useful documentation and also some sample code that lets people with computers that are not micro:bits talk to the display. So I had to look at the code and convert it into the JavaScript language that the micro:bit could understand.

Writing about it now, it sounds straightforward enough. And by the time I’d gone through their code line by line, I suppose it was. But it took time and patience. For example, I had to identify what code was essential and what I could set aside. I couldn’t run or test this code, so it was a matter of reading through and making sense of it step by step. To even start the display up at all, required sending a series of numbers. And if any one of them was wrong it was entirely possible nothing would work. And then to get coloured dots to appear meant sending more carefully crafted numbers. Some hours later, I had checked and re-checked the code I had written. It all looked OK, so it was time to transfer the code to micro:bit and see what happened.

And what happened was… precisely nothing at all. The same white screen – yes, I already know the power is working – stared back at me as I stared at it.

Carefully checked code running, all wires attached and no change on the screen. Oh dear.

There was a real moment – indeed an extended stretch – of doubt here. Because at this point I wasn’t sure how many moves I had to make. I’m used to working in software, but perhaps there was some hardware thing that I’d failed to understand. Perhaps my soldering had been shockingly poor. Perhaps, I wondered, I just won’t be able to fix this.

Still, it’s engineering, right. So it’s a matter of coming up with hypotheses as to why it’s not working and testing each one. I checked which wires I’d connected between the micro:bit and the display. Everything was checking out. I got back to the original software provided by display supplier and compared key sequences between it and my code. And then, I spotted something.

One bit of code controls the signal sent down a particular wire that, basically, asks the display to sit up and pay attention. Surely, the pay attention signal would be positive three volts and not zero volts? That is a one instead of a zero. Well, I must have thought this without really thinking, because that’s what the code I’d written assumed to be the case. But as the display supplier’s code made clear, the “sit up and pay attention” signal was a 0 and the “ignore everything, it’s not for you” signal was a 1.

The code change took less than half a minute. Transferring the software to the micro:bit took about the same time again. By this time, I’d also wired up a speaker so the setup made some sounds when the software had transferred. And now, as the beep sounded, so the display transformed into hundreds of random coloured dots. Not quite what I was expecting, but a clear sign that the signals I was sending were getting through. And, amongst the random coloured dots, in red, was the just discernible outline of a lunar lander. I pressed one of the buttons on micro:bit that I had programmed to move the lander a pixel to the right. And again. And, yes, the lander was moving, leaving a trail of blackness behind it. Time for a picture, I thought.

Game On! My code is working and I have something that looks like a lunar lander on screen.

The multi-coloured background is just what happens when the display starts up. I needed to ask it, explicitly, to clear the screen. But I already had code, adapted from the display supplier’s, to paint rectangles of an arbitrary size. Although, even that code didn’t quite work the first time.

An almost clear screen with the lander

At this point I was optimistic about making rapid progress. The plan was to take chunks of the code I’d written for my proof of concept in the web browser and use it on the micro:bit. After all, they both say they use JavaScript.

However, as it turns out, the JavaScript for the micro:bit is a severely stripped down version of the language that runs in a web browser. Just how stripped down became apparent slowly and painfully. So, for example, inside the web browser the JavaScript language understands decimal numbers. And my code relied on the use of decimals all over the place. For example, it relied on decimals in working out how to draw a straight line or how to apply gravity or the force of a rocket booster to the lander. This particular problem was one of the more straightforward ones that I encountered. Instead of relying on fractions, I was able to just multiply everything up and then, when it came to calculating the real pixel position, divide down and round up.

Slowly, the game started to come together. There were plenty of wrong turnings, as there always are with programming, such as the landscape appearing at the top rather than the bottom of the screen.

Landscape in the sky. Classic computing error. The machine, of course, was doing exactly what I’d asked it to do.

The not so solid surface of the moon. Not so much a bug this time, just a case of not having got to the point where I’d added a test for the lander hitting the surface.

Next Steps

So I had most of a working game. I didn’t want to polish it up too much. Rather, I wanted to take the basic building blocks and ideas and get my godson to, first, put together his own hardware and, second, code up the game. Knowing that I had the really tricky code to talk to the display, to put pixels – and also little patterns of pixels, such as the lander – on screen, made it a viable plan. Although it still seemed pretty ambitious. I was only visiting for a weekend. But I very much hoped, J would both have fun and, at the end of the visit, have a viable – if basic – Lunar Lander game.

I’ll add a link to part 2 when it’s written… watch this space. If you want to try this project yourself check out Connecting a micro:bit and an AdaFruit 1.44 inch display.

Questions and Comments

Comments are not enabled on this site, but if there are interesting comments or useful tips submitted then I’ll append them to this or one of the other Lunar Landed related posts.



    Question or comment

    Paragraft – back in the app store

    Some Paragraft users contacted me about issues with the app on recent versions of iOS and on recent devices, such as the bigger iPads. They also told me that there had been warnings about the app needing to be updated to run in the future. While my time budget for active development of Paragraft is limited, I didn’t want loyal users to be let down. So I’ve done a round of updates to the app to fix current issues.

    The updates mean that the current incarnation Paragraft has a good bit of life in it yet. It plays nice with different screen sizes – although it’s not great at doing split-screen on the iPad. Most importantly, some nasty bugs that had arrived due to changes in iOS have been squashed.

    There is, in the “lab”, a version of Paragraft with outlining and iCloud sync. It’s not ready to roll just yet, but, maybe, when I have some time… I know I’d like to be using this app on a regular basis, so there’s some incentive to get it done. If you’d be interested, get in touch and when there’s a beta available for testing I can ping you the relevant link.

    Connecting a micro:bit and an AdaFruit 1.44 inch display

    This guide will show you how to interface a BBC micro:bit with the 1.44″ colour LCD display provided by AdaFruit and to implement a basic Lunar Lander game.

    I’ve not written a complete library to drive the display, but the code includes line drawing, rectangle filling, some very basic text support (roll your own fonts), and some very basic “sprite” support. There’s enough here, I think, to let you crack on and code up other simple games, using the graphics primitives provided. And you can drive the display through the JavaScript blocks interface, so if you’re coding with kids, they don’t need to flip into the raw JavaScript interface.

    The code provided here is in JavaScript (or TypeScript and, indeed, the pared down version of TypeScript used by the micro:bit). If you prefer Python, then the code should be fairly easy to port across. I partly chose the JavaScript approach so that if you’re coding with kids they can use the blocks interface.

    Hardware Steps

    Review the parts list below before working through the hardware steps.

    • Prepare the connector for the TFT display. The TFT display comes with a connector that lets you plug it into the breadboard. The connector has more pins than are needed so you need to clip off some of the pins. You can do this with some sharp scissors or with a pair of pincers. Be careful not to take off too many pins. I recommend leaving one extra pin on and then pulling that pin out of the plastic.
    • Solder the connector to the display board. Long pin facing down (the opposite side to the display) and short poking through to the top side (the display side).
    • Wire up. To understand what’s going on refer to the micro:bit pin out diagram and also the documentation provided by AdaFruit. These are the connections that you need to make:
      • Power: so the micro:bit can “power’ the display
        • micro:bit 0v goes to the Breadboard blue/- rail
        • micro:bit 3v goes to the Breadboard red/+ rail
      • SPI Interface – so the micro:bit can “talk” to the display
        • micro:bit P13 (SCK) goes to TFT display SCK. This is the clock signal for the serial interface.
        • micro:bit P15 (MOSI) goes to TFT display SO. This is the “master out” signal. It is sends the data to the display from the micro:bit.
        • micro:bit P16 to TFT display TCS. This is the TFT display “chip select” signal. When the micro:bit sets P16 to zero volts, it tells the display to listen. In software, we program P16 to be high (3v) by default and then pull it down to low (zero volts) when we are “speaking” to the display. (P16 is simply a free pin that I’ve chosen to do this job. The software below assumes you’re using P16.)
        • micro:bit P1 to TFT display D/C. This is the TFT display “data” or “command” signal. When the micro:bit sets P1 low (zero volts), it tells the TFT display we’re sending a command. When it’s set high (3v) it tells the display we’re sending data. (P1 is simply a free pin that I’ve chosen to do this job. The software below assumes you’re using P1.)
        • Breadboard blue/- rail to TFT display GND. This is the ground connection for the display, i.e. power.
        • Breadboard red/+ rail to the TFT display Vin. This is the +3 volts connection for the display, i.e. power.
        • Note: the display does have a hardware reset option, but I didn’t wire this up. The display can be reset through the SPI interface in software.
      • Piezo Buzzer
        • micro:bit P0 to one pin of the buzzer
        • Breadboard blue/- rail to the other pin of the buzzer
      • Extra Push Button Switch
        • micro:bit P12 to one pin of the push button. (P12 is simply a free pin that I’ve chosen to do this job. The software below assumes you’re using P12.)
        • Breadboard blue/- rail to the other pin of the push button

    Software Steps

    Overview of Driving the SPI Interface

    This is to explain how it all works. You might not be interested in this level of detail.

    • I couldn’t find any code for the micro:bit to drive the AdaFruit 1.44″ display. But AdaFruit does provide some code that I was able to adapt.
    • To talk to the display you need to send commands (which are documented in the ST7735R data sheet on the AdaFruit website). To send a command you need to set pin 1 to zero / zero volts (pin 1 is connected to the display’s command/data pin) and you need to set pin16 to one /  +3 volts (pin 16 is connected to the display’s chip select pin). This done you can use the micro:bit’s spiWrite command to send the command.
    • Most commands have some parameters. These are data. So you need to set pin 1 to one / +3 volts and then do one or more spiWrite commands to send the data.
    • With some commands you are recommended to pause after sending them before sending the next one. I took the pause guidance directly from the AdaFruit code.
    • Before you can send commands to set pixels you display you need to send a series of setup commands. I copied the setup sequence directly from the AdaFruit code. Their code has options for various different displays and the code I’ve provided is just for the 1.44″ display with the “green tab”. That’s the one Pimoroni supply.

    Overview of the Graphics Code

    • To get pixels on to the screen you first send the display a Set Address Window command. This specifies a starting x,y position and an ending x,y position. You follow this Set Address Window command by a series of byte pairs that represent the colour you want the pixel to be. In this setup, the pixels are delivered left to right.
    • The drawPixel function just draws a single pixel. I’ve not provided a lot of help for defining the colours. You can go back to the AdaFruit documentation for more help with that or look at the data sheet.
    • The drawRectangle function just a range for a block using Set Address Window. The clear screen function just draws a rectangle the size of the whole screen and sets it to black. You can vary the speed of the SPI interface. You’ll notice clearing the screen takes a moment or two at the default speed.
    • I’ve included some functions to draw sprites and to define sprites in a friendly way using strings of spaces and X’s. This could be souped up for multi-coloured sprites etc.
    • I’ve also included some functions to help draw the lunar landscape. The landscape is made out of segments that are defined by strings indication up / down / right-and-up / right-and-down / right.
    • There’s some line drawing code there, but it’s not used in the current version of the game. It hasn’t been thoroughly tested and may need to be tweaked.

    Overview of the Game Code

    • This is pretty standard stuff. There’s a loop that goes on forever.
    • Each time around the loop the game will either make a sound – which takes a brief moment – or will pause. This means things don’t go too fast.
    • Each time around the loop the vertical velocity of the lander is increased by a ‘gravity” factor.
    • Each time around the loop we check to see if the up / left / right booster button is being pressed. If it is, then we adjust the y or x velocity accordingly.
    • When the landscape is built, we record its height. That means we can check to see if the lander has hit the moon’s surface each time around the loop. We also check to see if it’s in the landing zone and if it’s going slowly enough.

    Installing the Code

    From within the blocks interface, you need to select the JavaScript tab.

    Then click on Explorer disclosure triangle (it’s on the left below the micro:bit simulator). And then click on the ‘+’ symbol to the right of the word ‘Explorer’.

    You’ll be asked ‘Add custom blocks?’ Click on the ‘Go Ahead’ button. You’ll now find when you open the Explorer disclosure triangle that there is a custom.ts file in the list of files.

    Copy the custom.ts file provided here and then paste it into your newly created custom.ts file. You will want to overwrite the default custom.ts file that is provided. Then do the same copying and paste for the main.ts file.

    The main.ts file (mostly) represents what you see in the blocks editor. But the micro:bit editor can get confused sometimes when you make changes in main.ts and the flip back to the blocks editor. Sometimes refreshing the browser window will fix things up.

    • main.ts code
    • custom.ts code – this includes a partial ‘naive’ font (designed by an 8 year old, so please don’t knock it). You can readily edit and expand the font in the code.

    The code is not super-tidy, but it is commented. If you’re using it and really stuck, send me a message and I’ll try to help. It’s possible, though how likely it’s hard to say, that I might tidy up the code to make something more like a standalone library. Or, of course, someone else might do that.

    Tips and Gotchas With JavaScript (TypeScript) on micro:bit

    • You can only use integers on the micro:bit. I’d done some test / proof of concept code in real JavaScript and then realised that none of this was going to work. To implement the Lunar Lander game you need to do sums on numbers that are fractions of a pixel. I adopted the approach of having some working coordinates that are pixel coordinates but multiplied up by 32. This allows for, say, velocity values, that are much smaller than one pixel.
    • The SPI writes seem not to work when called from OnStart. I initially had my display setup code called from OnStart. This didn’t work. My best guess is that the SPI interface doesn’t get set up right away. In any case, calling the display setup code later fixed the issues. So the code now sets a “startup” flag on startup and the Forever loop checks the status of this. It calls the startup code if the flag is set and then clears the flag.
    • Type inference is flaky. When you’re working in the blocks editor the system tries to figure out the type of variable based on first use. But it doesn’t seem to be very good at this and it can create issues flipping back and forth between the blocks editor and the JavaScript / TypeScript editor. For this reason, it helps to set up variables in the OnStart block with a default value. This ensure they are properly typed and prevents havoc. (This comment will seem just weird if you’ve not experienced the weirdness of the editor trying to fix things up and breaking your code.)
    • No built in command to combine arrays. It appears – unless I’ve got very confused – that you can’t add / combine two arrays with the micro:bit version of TypeScript. I had to write a custom function to do this.
    • You can specify crazy invalid types, through miscapitalisation, but only get bitten at runtime. TypeScript, unlike JavaScript, has static typing. You need to be explicit about what types you are using. This ought to be a good thing as it means that errors got flagged early and before something goes wrong at run time. Weirdly, though, you can make – and I did, more than once -new kind of mistakes that, in fact, only show up at runtime. The kind of mistake I made involved using the wrong capitalisation. So, for example, at one point, I’d wrttien “Boolean” instead of “boolean”. And, indeed, the editor had offered this up as an auto-completion. The behaviour that followed was just weird. So lesson for me is if it’s getting very weird, do a quick check for mis-typed types.

    Parts List

    • BBC micro:bit. I got mine from Maplin. They are widely available via mail order. At the time of writing, Maplin were charging £12.99
    • AdaFruit 1.44″ Color TFT LCD Display with MicroSD Card breakout – ST7735R. I got mine from Pimoroni. At the time of writing, they were charging £18.50 (which includes £2.50 for P&P).
    • Kitronik Inventor’s Kit. You can get this direct from Kitronik – and they send stuff out fast. I ordered mine from Maplin. At the time of writing they were charging £26.99. The key parts from the Inventors’s Kit used in this project, which can be sourced separately from Kitronik, are:
      • Edge-connector for the BBC micro:bit. This makes it easy (some might say possible) to connect the micro:bit to the display, piezo electric sounder, and extra button.
      • Breadboard and connecting cables. This lets you set up all the relevant wiring without doing any soldering. And, because there is no soldering, you can change you mind or reuse the breadboard and cables to make new projects later. Of course, if you’re going solder up a permanent project, using  Veroboard or a handmade PCB, this wouldn’t be required. And using the breadboard makes everything very quick and more fun.
      • Extra button switch. This isn’t needed for the display. But the example project, the Lunar Lander game, needs an extra switch and you get four in the kit.
      • Piezo Buzzer. This is like a tiny speaker and enables the micro:bit to make sounds. This isn’t needed for the display. But the example project, the Lunar Lander game, needs a buzzer.
    • USB Type-A to Micro-B USB Cable. This is used to connect the micro:bit to a computer so programs can be transferred. These are available all over. I got mind from Kitronik for £3.60. You might even have one already supplied with some other bit of equipment.

    Questions and Comments

    Comments are not enabled on this site, but if there are interesting comments or useful tips submitted then I’ll append them to this post.



      Question or comment