Category Archives: Miscellaneous

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

    Tom’s not buying an iPad

    This is a very techie post – so feel free to move on if tech is not your thing.

    So Tom’s not buying an iPad on principle and he’s written a wee blog post attempting to explain why. Tom’s particularly bothered that the iPad doesn’t run Flash, a type of web content that’s widely used and been around for ages. Because the iPad (and iPhone) doesn’t use Flash, some websites don’t work on the iPad. But more than that, Tom’s bothered about Apple being anti-competitive, taking away choice from users as well as being unfair to developers and content producers. (Apple takes a 30% slice of everything sold through it iTunes store: apps, music and, most recently, magazine subscriptions.)

    Since Tom asked me what I thought about his post, I thought I’d write something down…

    So Tom’s not buying an iPad on principle. I’m trying to get my head around what the principle is and if I can make sense of it.

    My first shot is this: it is as if Tom was a petrol head and saying that, as a matter of principle, he won’t buy a car that can’t fill up with petrol. Of course, he doesn’t mind it working on electric too. It is just he wants the choice: fill her up or plug her in. But the makers of these new electric-only iCars – you know, the ones with the cool design and smug adverts – they are taking that choice away. Tom cries foul. Fuel should be cross-platform. If I go to the trouble of refining some oil, how dare a car maker stop people putting my fumes in their tank?

    Tom and others have pointed out how, unlike in the car case, technology makes it easy to be cross-platform. There is no technical reason not to run Flash on the iPad. And between improvements Adobe has been making and the increasing speed of Apple’s mobile devices, it might even run well.

    Does this mean it is just about the money, a desire from Apple to rake it, to extort developers and, now, content publishers, ruthlessly exploiting their stranglehold on the phone and tablet market?

    Well, it might be a bit. Apple is a business after all. But it’s not only about that. Tom is bang on when he says Apple is set against the “browser-based web becoming a platform for rich device-independent applications”. That makes Tom sad — and a little cross. My emotions are different. Whenever I hear ‘cross-platform’ or ‘device-independent” I associate to “lowest common denominator’ and ‘shocking user experience’. Of course, there are exceptions to this – Adobe do a pretty good job at supporting two platforms with a good user experience on both. But you know, less work by the developer, usually means a less positive experience for the user. With mobile and tablet devices that’s especially so.

    There is nothing like writing an iPhone app for reinforcing this point. Until you start to really sweat the details, you have no idea how many details there are to sweat. Having seen my app on the iPod touch, my pal Martyn asked if I had plans to produce a version to run on his Android phone. Tom’s argument might be that if I’d used a good cross-platform tool to develop it, I’d be able to tell Martyn, no problem, porting between platforms is small beer. My argument, having sweated all the user interface details I couldn’t port ‘my’ app (the one that is polished), even if I could port some version of it. But it is my app, the one with the polish, that I care about and want to share. The price of sharing it with Martyn turns out to be quite high. Sorry Martyn. But I’m sure there are lots of great Android apps out there, the makers of which have really given their heart to, the details of which are super-polished. (And if that is the case, if those developers want to move across to an Apple product, they’ll have to sweat those details again.)

    It’s worth nothing that Apple’s business model is hardly uglier than anyone else’s. I’m not saying it’s OK, but any reservations would need to be targeted at the capitalist system rather than individual players within it. Yes, they are a big and ambitious player. Yes, they want to change the landscape and not merely compete within it. Whenever a landscape is changing, competition is fierce and some businesses get hurt. (Read up on alternating vs direct current at the end of the 19th century and the Adobe-Apple spat seems positively mild.) But Apple’s moves will only work if the market follows them. If they weren’t selling bucket loads, the lack of Flash and the 30% cut would simply seem eccentric or idiot risk-taking. As it is, the evidence is unequivocal: both end users and developers will stand for this. End users because the products are great to use, despite some websites appearing to be broken. Developers and content producers because 70% of a decent sized chocolate cake is way, way better than 90+% of dried up muffin.

    So Tom is missing out on the fun of being an iPad user just now. I hope that when he jumps to a rival tablet some time down the line, that his tablet runs great software, software made with love and polished to within an inch of its life. And that’s a definite possibility. After all, manufacturers and developers for those rival tablets have some stiff competition.

    By the way, Tom is as far from a petrol head as it is possible to be and has an admirably low ecological footprint.