A few months ago element14 gave away 500 LPC800-minikits. I thought that that was a nice starting point for a learn-to-solder-goodie for my hackerspace, so I started a design with it. Along the way I found out how to program this very little microcontroller. The demo is now finsihed: when you shake the board, it will appear to ‘write in the sky’. This phenomenon is called ‘persistence of vision‘, where you still see some light after it has moved on; it’s like those pictures with very long shutter times where car lights become long ‘scribbles’ of light. Here, we control how the lights are turned on and off, and thus appear to be writing in the sky!
In the final design, you can easily solder this board with a few components (see below). When you shake the board, a default text is shown ‘in the air’! But of course, it’s more fun to get your own name on the board, so you can reprogram it! Using the same interface for downloading the firmware, you can use a standard terminal (hyperterminal, or seyon) to type in your name, and you’ve got a personalized goodie!
The microcontroller I’m using is the LPC810. To my knowledge it’s the only ARM microcontroller in DIP8 housing. This gives only 6 pins for input and output, but that’s sufficient for my application. Moreover, an 8-pin DIP is very easy to solder, so great for a learn-to-solder goodie!
The chip is also small in memory size; with 4 kilobyte of flash available I’m running through code size quickly! I also have a hunch that this is even more so since the instructions are ARM Thumb, which uses 16 bit (two bytes) per insruction. In previous designs I’ve either used 8-bit microcontrollers with an 8-bit instruction set, or ARM microcontrollers with ample flash space.
Switch matrix tool
One of the ‘selling points’ for the LPC800 family is the Switch Matrix, that determines which peripheral input / output is connected to which pin of the microcontrollers. It is true, the flexibility in routing of signals is something I haven’t seen before. The possibilities are many, and that’s where I had some difficulty in grasping what was happening. I read all the documentation, and had some difficulty in grasping all possibilities and limitations. After I had written code for the matrix myself, I found the ‘Switch Matrix Tool’ on LPCware.com. This is a graphical guide to configure both the switch matrix, and each individual IO pin. If you ever get started using this series of microcontrollers I wholeheartedly recommend this tool!
Programming the LPC800 requires a USB to (TTL)serial converter. If you have one lying around, you’re set! Just power up with the ‘ISP’ switch pressed, and you’ll enter the bootloader. From here you can use either FlashMagic (windows, but also runs on Linux with Wine) or lpc2isp (runs more reliably on linux, in my experience). I found this a very nice feature; no expensive hardware required, almost ‘plug and play’. The protocol for programming uses commands in ASCII (human readable text), so you can also debug your connection by using a serial terminal.
Normally I configure my toolchain myself, using code::blocks as IDE. In this case, I was lazy, and just installed CodeRed LPCXpresso. It’s eclipse based, so startup takes quite some time on my PC, but after starting it works quite smoothly. I quite like this IDE, you can quickly jump to implemenations or declarations of code from the right mouse button menu when clicking on a function name. Somehow that’s something I really, really, really need in an IDE. With the right libraries in place, I could easily browse through code, and check out examples.
Regarding the abstraction / naming in the libraries I’m not that positive. I’ve used a lot of Xmega controllers in the past, and the default libraries adhere very strictly to the naming in the datasheets. I found the libraries and mnemonics to be a bit of a potpourri of names; especially if you also look at code from openlpc, which uses other naming for same registers (LPCSyscon / LPCsysctl)
- I used the SPI interface, first used the example drivers, but then limited my code size by copying only the code I needed to my own files. This really brought down code size, as I only need to write one byte to the SPI interface each time I use it.
- I used one GPIO line for the tilt sensor nothing special here.
- I used the Multi Rate Timer. I like the simplicity of this timer; a simple 4-channel downcounter, and because it is a 32-bit counter you get a very large range of timings you can use. This is one of the very, very nice examples of why 32-bit can be useful in small chips! In the old days you had to choose to either clock a timer fast, and then you can only generate short delays, or clock it slowly for long delays, but fail to have high timing resolution in short delays. Running a timer at 12MHz with 32-bit resolution opens up a lot of possibilities! Each channel -in my application- counts down from a value, triggers an interrupt when ready, and then reloads. I’m using one channel for debouncing the tilt switch, and one channel to generate the timing for the PoV display.
- I use the UART ROM driver to get the text to display. This is a badly documented, but very nice feature. The LPC800 series have a driver for the UART on-board, which can be used for simple command line control (no fancy protocol shizzle, you’ll have to add that yourself). Not only does it save on programming effort, it also saves in code size! With 4kB flash, and a complete font table loaded into that, that’s a welcome saving!
- I used In-Application flash programming to store the sentence that has last been sent over the UART to the microcontroller. This gives the possibility to change the text after programming the code. I thought that would be really fun; you can solder your own PoV display, and then it can tell it what it should display (of course, someone has to have a TTL serial adapter, but if you’re programming the microcontroller on-site, that is needed anyway.)! The In-Application Programming protocol is documented in the user manual, but I did need some example code to get it going right. It doesn’t take much flash size by itself, but you can only program in multiples of 64 bytes. So if you’re using IAP, you have to reserve a block of 64 bytes in the flash to store your data in. The location of this block can be given in the linker settings.
Persistence of Vision / tilt switch
The display works, by quickly blinking a row of LEDs. Because the LPC810 only has 6 I/O pins, I’ve used an external LED driver IC. This not only has the benefit of expanding the IO’s, it also simplifies soldering in the end application. The LED driver only requires one resistor to set the LED current, whereas driving from microcontroller IO would take one resistor per LED (or per two LEDs in charlieplexing mode). Thus: less soldering work, and less opportunity for taking the wrong values!
Normally, persistence of vision works either by making a continuous sideways movement, and control the LEDs in a fixed update rate to spell out the text, or use an accelerometer to measure the displacement and use that for a ‘fixed font with’ (speed of changing the LEDs is determined by speed of movement). I took an approach halfway in between: I’m using a tilt-switch for the symbol-to-symbol timing!
A tilt switch is normally used to measure…. tilt! It consists of a metal cilinder with a metal rolling ball inside, that shorts the two pins on the outside when held upright. When you keep the cilinder horizontal, the ball will still make contact, but when turning a bit further the ball will roll to the far end of the cilinder, and the two pins on the outside are no longer connected. But.. you can also use this to measure acceleration. When you shake the sensor you can feel and hear the ball going from one side to the other, due to the inertia of the ball. This way the microcontroller knows when the display is accelerated to one side or the other. When you start moving forward, I start writing text on the display at a fixed rate (set by one of the channels of the multi-rate timer). After a character is written, the display is blanked, and the microcontroller will wait until the display is reversed, and then is moved forward again to display the next character. The text will appear to be standing in the same place, and the width of the font is proportional to how fast you’re moving the display! You can probably see this better in the video than I can convey in words…
The code for this project can be found online in a git repository. The connections are as follows:
- STP08DP05 LED driver. I used this chip from ST, but many others are available that share the same pinning / IO
- SW-520D Tilt switch
- 2k7 resistor for LED current ( = brightness) control
- 8 LEDs
- 3V3 regulator + caps
- Switch or paperclip (shorting two pins) to get the LPC810 to start up in bootloader mode
- Power supply; USB connector, or maybe USB connector + goldcap for ‘offline’ usage?