Fixing the dash status light panel on a Toyota Supra

A few weeks ago, I was diagnosing an issue on a 1993 JZA80 Toyota Supra. As I was researching, I came across a suggestion to check for a faulty engine control unit. According to service manuals and sources on the internet, the check engine light (or malfunction indicator light) is supposed to switch on when the key is switched to the ON position. If this supposedly did not happen (or only happened intermittently), it could mean a faulty ECU that needs to be replaced.

These symptoms matched exactly what I was experiencing so I made the hasty diagnosis that I had a faulty ECU. Unfortunately, I bought a replacement, installed it and it made no difference.

Eventually, by accident, I discovered that if I physically pushed hard enough on the status light panel, I could get the lights to show. I pulled the dash and found this:


Notice the cracked solder joints on the connector?

The fix was rather simple. I simply went over each joint with a soldering iron and added more solder, ensuring everything reflowed correctly. I didn’t bother removing the old solder first. If I did, the final result could have been better as you can see from the picture below.


Alas, it works. After the 5 minutes it took to re-solder the connector, I placed everything back and it worked perfectly again.


Unfortunately, it did mean I spent money unnecessarily on a replacement ECU and have to re-sell it again but I’m glad it alerted me to the faulty status light panel. Without the malfunction indicator lights illuminating when they should, it could mean serious damage to the car later if it is being driven and there is an engine problem.

MagSafe to USB charger

Recently, I came up with the idea of creating something that will let me charge my phone via a MagSafe charger.

The use case for this is a bit limited (since you could just plug the phone into the laptop to charge) but could be handy sometimes when you don’t want to set up a laptop just for charging (like at an airport). Overall, this means needing to pack one less charger. The MagSafe charger cable being quite long (much longer than most USB chargers) can also be a bonus.

The device works by first negotiating with the MagSafe charger to give it power. When full power is given (it outputs 14-20V depending on the model), a buck convertor is used to step down the voltage to 5V that can be used by USB. Finally, a microcontroller is used to control the LED on the connector. I wanted the charger to be able to source at least 1.5A to the USB device.

At this point, I’d also like to add that the article about MagSafe written by Ken Sheriff was immensely helpful in developing this.

The first challenge of using MagSafe is that it has some safety features built in that prevents short circuits from becoming dangerous. Ken’s article details exactly what needs to be done to negotiate power from the charger. In short, on the first connection, the charger outputs either 6V or 3V (depending on model) that’s current limited to about 100uA. During negotiation, a resistive load is applied to the input that drops the voltage down to about 1.7V for one second. After that, the charger delivers full power.

The problem is that the rest of the circuit must be switched off with minimal leakage current until power negotiation is finished. To solve this, I configured a N-channel MOSFET to only turn on the rest of the circuit after power negotiation.


R1 is the resistor that will be used in power negotiation. D1 is a zener diode that will drop roughly 6.3V. In other words, if the voltage is less than 6.3V, the gate of the MOSFET will be pulled low by R2.

During power negotiation, the maximum voltage that will be output will be 6V so the voltage potential at the gate will be 0V which will keep the MOSFET switched off. After power negotiation, the voltage potential at Vin will be at least 14V. D1 will drop 6.3V, leaving roughly 8V at the gate of the MOSFET, switching the rest of the circuit on.

After power negotiation, things become very straightforward. My first thought was to just throw on a linear regulator but I quickly realised this would dissipate tremendous amounts of heat at higher loads (at 20V input voltage, we’re dropping 15V – at 1A current draw, we’re dissipating 15W of heat. Yikes!).

The buck regulator is pretty standard. I chose an AP1509 chip for ease of implementation. It’s supposed to be able to deliver 2A on its own.

Next up was the microcontroller. The microcontroller is supposed to communicate with the chip on the MagSafe connector via 1wire to set the colour of the LED. I chose an ATtiny85 for this since they’re readily available, have a low pin count and very easy to program with the Arduino software. The microcontroller just taps off the 5V output from the buck converter and uses an internal oscillator for its clock. The part count is very little. It just uses some pull-up resistors for the reset line and 1wire pin.

For current sensing, I opted for the ACS713. It’s a little pricey and overkill for the project but it’s very easy to use and has a small part count (just one filter cap). It outputs 500mV on no load and has a sensitivity of about 150mV per amp.

Normally, you’d want to pipe the output of the ACS713 to an amplifier before connecting it to a microcontroller to get the full range of input. However, I wanted to minimise parts so I had to use a trick to interface it to the ATtiny. The trick is to set the reference voltage of the ADC on the ATtiny to the internal 1.1V reference. That will give more than enough range for the ATtiny to detect a load.

I configured the ATtiny to set the LED to green if the current draw falls below a certain threshold. I’m still trying to calibrate it correctly but generally, it’ll turn green when the load drops to less than 100mA. Otherwise, the LED is set to orange. I actually forgot to put a filter cap near the ADC input pin so I had to take multiple readings and average it to get the right value but it worked fine in the end.

In the interests of safety, I also opted to put a polyfuse in line with the charger input in case something shorted out in the rest of the circuit. The MagSafe charger is capable of delivering huge amounts of power (85W on mine) and can completely ruin your day if something shorts out and catches on fire.

To prevent a USB device from drawing too much current, I also added a RT9701 USB current limiting switch to prevent a device from drawing too much power.

Last but not least, I needed a reliable way of connecting the MagSafe connector to my circuit. As you might’ve guessed, it was impossible to find MagSafe jacks for use in hobby projects. I ended up ordering cheap OEM replacement MagSafe boards on Aliexpress and rewiring them.

Finally, I put everything together on a custom made PCB (black soldermask to match the Apple replacement part :3) and watched it work!

So, that’s my first revision of the board. Unfortunately, the thing generates a whole ton of heat when my phone starts to draw around 0.7 amps. I haven’t measured the efficiency of the buck convertor but I’m sure it can be improved.

A Final Fantasy X lightning strike dodging aimbot

Since I bought the Final Fantasy X HD remaster, I’ve been (re)playing through the game (75 hours now!). I’m currently playing through a lot of the side quests.

Now, some of you Final Fantasy players may remember the 200 lightning bolt challenge. If you don’t, let me explain briefly.

There is a mini-game in FFX where you can dodge lightning strikes. How it works is the player walks through an area where the screen flashes at random intervals signalling a lightning strike. If you don’t hit X quickly enough to dodge it, your character gets hit by a bolt of lightning. If you do hit it quickly enough, your player jumps out of the way before it can hit him.

One of the side quests involves being able to dodge 200 of these lightning bolts in a row without being hit in between, leaving the area or saving. It’s said to be one of the hardest and most frustrating side quests in the game.

Naturally, since I’m a lazy, dirty cheat and didn’t want to go through the trouble of practicing, I thought of other, more automated ways to do it with a microcontroller (I really had to complete this side quest).

I needed two things to build a successful aimbot:

  1. A way to tell when a lightning bolt was about to strike
  2. A way to respond to it

The area where the lightning strikes is generally pretty dark and a lightning bolt causes the screen to flash brightly. That’s a fairly big contrast in terms of brightness. I simply used a photo-resistor taped to the screen and covered it with a black cloth (to prevent light from the room from affecting the readings).

Wiring the photo-resistor was also pretty simple. I just wired it straight from the pin to ground and enabled the internal pull-up to create a voltage divider. From there, it was trivial to get readings by using analogRead.

Calibration was pretty easy too. I ran an Arduino program to continuously print readings to serial. I waited around in the area of the game, waited for a lightning flash then went back to look at the readings.

I expected to had to graph the readings but I was actually able to tell straightaway by inspection. Before lightning struck, I was getting readings from the photo-resistor that ranged from 680-720. During the flash, I was getting readings from around 150-210. In the code, I simply regarded lightning has struck as any reading below 250.

I double checked my findings by having the micro-controller blink an LED every time lightning struck. As far as I could observe, there weren’t any false positives or false negatives. We had a 100% success rate.

As an aside, keep in mind that the median human reaction time is somewhere around 215ms. I’m guessing the designers of the game would be aware of this fact so the time window for a successful dodge should be around that. That’s a good benchmark for working out an appropriate button press debounce time and the maximum amount of time your code should take to react.

Now that we know how to detect a lightning bolt, the question of responding to it remains.

I was originally going to try and tie a servo onto the PS3 controller to press the button but owing to the weird, rounded shape of the controller, I wasn’t able to secure the servo onto it. That led me to look up ways to emulate a PS3 controller on a micro-controller to directly feed input to the PS3.

Turns out, there was a great project written for the Teensy that emulates a PS3 controller.

I took the code, hacked in an analogRead function, deleted everything I didn’t need and fixed a few compilation errors I had. I had the firmware make the character run around in circles and send a “pressed X” event every time it detected a lightning strike.

A quick test showed that my quick, hacked up mess actually worked! The LEDs blinked at the right times and my character dodged the lightning strikes perfectly every time. The timing was impeccable!

As a final touch up, I wired a second Arduino (hey, I was lazy) to count the number of times the Teensy blinked its LED and display the count on an LCD screen. From there, I just left it until the counter showed 200.

Finally, if you decide to use this, I recommend placing your character in a weird secluded corner to prevent him edging too close to a lightning tower (where you’ll just waste time since lightning doesn’t hit there).

Source code on Github

Linux Release Tracker

I am a casual kernel developer so it’s helpful for me to get an idea of roughly when the next merge window will open.

Here is a handy tool I wrote to keep track of Linux releases, inspired by the Mac Buyers Guide. It has an estimate of when the next major Linux release along with some basic statistics. It pulls data from Torvald’s Github mirror for Linux and is updated twice daily.

Linux Release Tracker


Deriving radii for round corners

A lot of 3D work I do involves working with round corners. In this case, I was designing a case to be fitted onto an appliance with a round corner.

The item was essentially rectangular except with corners rounded. While I could figure out the dimensions of the item quite easily with a calliper, I couldn’t figure out the radius of the corners (which I need in order to tell openSCAD).

I tried using all sorts of geometry tricks to no avail until I finally figured it out by using a tape measure.

What I ended up doing to find the radius of the corner was to calculate the perimeter of the item if it were rectangular (2 x width + 2 x height) and subtract the actual perimeter of the device.

That leaves the perimeter of the ‘corner’ edges which there are 8 (two on each corner). Dividing the remaining perimeter by 8 yields the radius of the border.

Of course, you’ll want to be super careful on how you measure and make sure you’re getting an accurate measurement! Furthermore, this will only work for objects that have corners that have the same radius. Anyhow, it worked well for me so enjoy.

Consolidating VMWare hard disks

When you create a virtual hard drive for use with VMWare, it doesn’t actually pre-allocate all the space for it (unless you ask it to). For example, if you chose to dedicate 20GB to your virtual machine, it won’t immediately take up 20GB of your (real) hard drive space. What will happen is the file size of your virtual size grows as your virtual machine starts using hard disk space. In other words, your virtual hard disk will only take up as much space as how much data your virtual machine uses.

Unfortunately, sometimes you move a large file into your virtual machine and delete it some time later and VMWare doesn’t recognise that it can reclaim some of your real hard disk space back. For example, my Windows 7 virtual machine tells me I am only using 17GB of the virtual hard disk space while the file size of the actual image is 28GB.

This happened when I installed a large program on my virtual machine and decided to uninstall it later since the SSD on which my virtual machine was hosted on was starting to run low on storage.

There are 3 steps to fix this issue:

  1. Defragment your virtual hard drive in the guest OS (optional)
  2. Run a program to zero out free space in the guest OS
  3. Shut the virtual machine down and tell VMWare to reclaim space.

The first step is recommended if your guest OS or filesystem supports it since it can consolidate the filesystem itself leaving large amounts of contiguous space for VMWare to clean up.

The second step zeros out the free space on the hard disk. When an operating system deletes a file, it often only marks the blocks used by the file as free and doesn’t actually write zeros to it for performance reasons. VMWare, because it is unaware of how the guest filesystem works, can’t tell the difference between useful data and discarded data. When we zero out free space, we’re essentially telling  VMWare that ‘this space is blank, you can have it back’.

On Windows 7, I used a program called sdelete. I ran the program with the following parameters:

sdelete -z C:

I haven’t tested personally, but there should also be similar programs on Linux and other operating systems.

Lastly, we need to power the virtual machine down to let VMWare clean up and consolidate the virtual hard disk so we can have some space back. Once you power down and enter the virtual hard disk section of the virtual machine properties, VMWare should offer the option to clean up or reclaim disk space.

After running this procedure, I managed to reclaim just over 10GB of free space back from my virtual machine.

DIY smart watch


A few weeks ago, I was made aware of the Open Source Watch project while looking for some inspiration for projects to build. It looked really well done. But, there was room for improvement and I thought I would have a crack at building my own smart watch too.

For the most part, I only used the OS watch as a reference. While it would be fun to put an existing design together, I was after building my own from scratch.

Firstly, let’s have a look at the differences between my design and the OS Watch.

The ‘tangrs Watch OS Watch
Microcontroller Arduino Pro Mini
8MHz 3.3V
Modified to run at 8MHz 3.3V
Flash Memory 32K 64K/128K
SRAM 2K 4K/16K
Bluetooth Module nRF8001 BLE112
Bluetooth 4.0 Low Energy 4.0 Low Energy
Battery 400mAH 500mAH
Buttons 2 4



There are some other subtle differences too.

  • Mine used a metal link watchstrap
  • Mine didn’t have LEDs
  • Mine didn’t have a switch
  • Vibration motor was wired differently
  • Arguably a better, cleaner look ;)

We had very similar constraints in what the watch had to do:

  • Battery had to last a whole day (10 hours bare minimum)
  • Display had to remain on to display the watch face at all times
  • As thin and as good looking as possible
  • Containing open source or easily found parts

So with these constraints, I set out to design my smart watch.

N.B. due to limited computing resources on the watch, I actually delegate most of the controlling work to a mobile phone app. The smart watch just exposes a command interface over bluetooth.


I picked the Arduino Pro Mini for this project since it was small, cheap and had a built-in LDO voltage regulator for 3.3V operation.

I believe the OS Watch uses a step-up converter to get stable 3.3V operation on it.  However, the drop-out voltage for the voltage regulator on my particular board was ~150mV, allowing perfect operation on input voltages as low as 3.45V. Because of that, I didn’t bother to add a step-up converter. Even at voltages lower than 3.45V, the ATmega can function within spec for 8MHz so it wasn’t a big deal. In fact, I could have just hooked up the unregulated voltage to the Arduino directly but I didn’t here.

I did have to desolder the reset button on the board though. It added 2mm to the thickness of the board and had the risk of being pressed. Instead, I wired the reset pin to an external interface in case the device had to be reseted.

The one thing that the OS Watch got right that I didn’t was the amount of SRAM. The OS Watch has 4K/16K depending on the microcontroller you use which is a lot more than the 2K that comes on ATmega328s. With a large framebuffer and bluetooth driver, I easily went over the 2K limit. In fact, I’m writing a driver for the OLED screen that doesn’t use a framebuffer and writes directly to the module for a saving of 1K.


I chose the nRF8001 bluetooth module from Adafruit because it was one of the few bluetooth 4.0 low energy modules available. I bought a few cheap bluetooth 4.0 UART chips off eBay but I couldn’t get them to work (and documentation was terrible).

The nRF8001 also has an interrupt pin so we can put the watch to a deep sleep mode and wake up when there is data to be read. Waking up on UART activity is impossible on the more power saving sleep modes since the UART module is powered down. I even tried tying the UART to an interrupt pin like some people suggested but there was still considerable data loss.

Unfortunately, I underestimated how large the driver would be. The Adafruit UART driver for this module takes up 1.2K of my precious SRAM! It was impossible to fit both the graphics driver and the UART driver.


For the OLED display, I used a module compatible with the Adafruit ones. I used the I2C module to reduce the amount of wires.

One thing to be careful about is that these displays suffer from screen burn in! This is especially a problem since it means that you have to take precautions when displaying a watch face constantly.

I somewhat mitigated this by inverting the display every minute (i.e. switch from black on white to white on black). It does take more power but it’s better than seeing outlines of text. Also I added a timeout to switch the display back to a watch face if there is no interaction with the watch (in case the watch loses connection and the mobile app can’t tell it to switch to a watch face).

Also note that the power consumption of the display is proportional to the number of white pixels displayed. There is also a dim mode that cuts power consumption to about one half. I used a timeout to switch to dim mode.


Buttons were wired to the interrupt pins. I had to kind of multiplex the use of one of the interrupt pins since there were 3 peripherals for 2 interrupt pins. I just threw a resistor onto the interrupt line from the bluetooth module and hooked both onto the same pin. The idea is either one of the button or the bluetooth module can pull the line low. We process bluetooth first, then check if the pin is still low. If it is still low, we know the button has been pressed.

Power Management

The Arduino is programmed to deep sleep until something needs attention. It follows a event loop pattern.

The idea is the device goes to sleep at the end of an event loop and waits for an interrupt to occur. The interrupts go to empty interrupt handlers (with the exception of the watchdog) which only serves to wake the processor up. At this point, the event loop runs again and checks what has changed.

The watchdog is programmed to tick every second to increment the time. The watchdog is used instead of the more accurate timers because its interrupt can wake the processor from deep sleep. The lost accuracy can be made up by having the mobile app synchronise the time every half hour or so.

Lastly, total power draw cannot exceed continuously exceed 40mA or we won’t be able to run it for 10+ hours.


I used a vibration motor from an old mobile phone with an impedance of 55 Ohms. I wired a 10uF capacitor in parallel with the motor to smooth out most of the ripple caused by it. Then I chucked a transistor on with a 1K resistor on the emitter and wired it to a MCU pin. The motor will draw ~60mA peak.

I wired it straight to the battery since the motor needs a bit of oomph to get it to start.

I didn’t bother to throw in a flyback diode since there didn’t seem to be any large negative voltages when I measured it with an oscilloscope. Most of the occasional spikes disappeared if I put a small resistor in series with the motor. The diode would also take up too much physical space.


Although the software side of my watch isn’t completely finished, I can say that there is still a lot to improve in my watch. It certainly doesn’t have the polish of the OS Watch yet.

Some things that need improving include:

  • Add an off switch
  • Print case in black, higher quality ABS
  • Thinner display

I will cover my progress in follow up posts.

3D printing adventures

I recently shelled out around $900 and bought myself a Prusa i3 3D printer kit for rapid prototyping. Unfortunately, I spent quite some time getting the ‘calibration’ working.

The RepRap wiki was very helpful in helping to calibrate. However, I was quite lucky and the supplier where I got my kit from actually provided me with some pre-calculated numbers so I cut down on about one third of calibration needed.

After some tweaking with acceleration and steps/mm adjustments for the Z-axis, I finally got my test cubes to print properly.

However, after a while, I noticed a lot of my prints were falling apart. Eventually, the print quality just dropped to downright unacceptable.

IMG_20140723_121508 IMG_20140721_132558


Notice how the layers don’t seem to stick together? The infill didn’t seem to be ‘infilling’ either. The whole thing seemed like a delicate honeycomb. Most of the time, I was able to crush and rip it apart fairly easily.

Let’s take a look at what the printer is actually doing.



As you can see, the extruder isn’t providing enough material.

At this point, I suspected a few things. Firstly, it’s obvious that there’s not enough material or that material is being extruded unevenly.

Of course, the first thing I did was head to the Print Troubleshooting page of the RepRap wiki and to the Google-mobile. Both suggested that my prints are turning out badly due to material contamination but I ruled this out initially since the rolls of filament were close to brand new.

Next, I suspected the Z-axis steps/mm calibration may be out of whack. Could it be that the Z-axis is moving up faster in reality than slic3r is expecting it to? Maybe not enough material is being deposited due to this discrepancy.

Something told me at the back of my head that this was unlikely since for a day or two, I was getting pretty good prints before this started happening and I didn’t touch the calibration settings at all. Nevertheless, I did waste a few days attempting to ‘recalibrate’ the Z-axis to no avail.

Maybe it was just a PLA thing? I took out a roll of ABS and fed it to the machine and printed a test object. Hey, presto! Apart from some dragging and oozing, the test object turned out okay! Unfortunately, the second print showed the same symptoms as PLA so I ruled material out.

Now, I started suspecting the extruder. Perhaps the plastic isn’t being heated to the correct temperature making it hard to extrude (and hence, the rest of the printer moves too fast for the extruder to keep up). I wasted a day heating up PLA to different temperatures with very little difference.

At this point, I was pretty frustrated and took a break from it for a few days.

When I finally decided to give it another crack, I suspected the extruder again. Maybe the E-steps/mm calibration was out (again, unlikely since the first few prints worked). No matter how I measured, the calibration was spot on (the supplier had it calibrated pretty precisely).

This whole time, I was on Google searching and reading about similar problems – none which matched mine exactly.

Alright, at this point, I decided it was time to take the material contamination possibility seriously. The room where I’m printing in can get quite humid so I suspect the filament may have gone dud quicker than expected. Baked both rolls of filament in the oven at 60 degrees and monitored the oven temperature very closely to make sure I didn’t deform the PLA plastic. I left them to bake for about 4 hours.

When I tried another print with the baked filament, I had the same problem. With both materials. Dammit. I then, took another break and came back a couple days later to have a look again.

Anyway, I still suspected the extruder. I tried a test print while gently pushing the filament into the feeder. And, what do you know? The layers started giving me clean lines for the first time in about two weeks!

So finally, I figured for some reason, it wasn’t extruding enough material. I didn’t think I made any build mistakes.

Although the extruder design appeared to be a custom one, it was simple enough to work out how it worked and I couldn’t see any problems.

My next suspect was the hot end. Could it be clogged? I tried to clean it out by heating the PLA to 190 degrees, letting it cool to about 40 degrees, then heating it to about 80 degrees and sharply pulling the filament out. That was supposed to pull out any bits of gunk. I actually did this a couple of times before trying another test print.

Again, no cigar. Dammit.

It wasn’t until I was casually browsing the supplier’s documentation for the printer that I had an epiphany. I noticed that the cog for pushing the filament through always needed cleaning. What if it wasn’t meant to be like that?

A quick Google told me that if the cogs needed constant cleaning, there was something wrong.

I looked at the extruder design again.



Maybe the ball bearing wasn’t pushing the filament hard enough onto the cog? Maybe that’s why the filament wasn’t being pushed though.

I added an extra bolt before the spring so the bearing pushes harder against the filament and fired another test print.



Hey, success!

Now, it’s definitely not a perfect print, there’s still inconsistencies to be fixed and fine tuning to do but it was over 9000 times better than the craptastic prints I was getting before!

At the very least now, I have the option of printing out and trying other, more standard extruder designs now.

The Success Box

This box was made with a button to press after a major achievement to boost your morale. It plays a song of your choice (or a random song) from a USB drive plugged into the side of the box. Personally, I prefer the Final Fantasy victory fanfares. With a little tweaking, you could easily make it stream over wifi or bluetooth.

The Components


The components used in this project are readily available. You should be able to build this machine in well under $100.

The main controller is a Raspberry Pi which is configured with the usbmount package. This will automatically mount USB drives under /media. I used a python script (run at boot time via /etc/rc.local – included at bottom of the post) that scans all the files ending in .mp3 in the /media directory and plays it when the GPIO goes high (i.e. an open circuit). I could have gotten an MP3 and DAC chip somewhere to output the audio and read music off an SD Card using a microcontroller but I couldn’t find a cheap solution.

The button was from a $10 emergency stop button I bought off eBay. Using an emergency stop button means I can stop the music any time by releasing the stop button. I took the button out of its enclosure and chucked it into my own. Be careful when you’re writing the software that the button is active high on the GPIO pull-up inputs (when the button is pressed, it is an open circuit – not a closed circuit unlike conventional buttons). I wired mine up to GPIO1 on the original Raspberry Pi B model since there’s a ground pin immediately to the left of it.

The PC speaker can be scavenged from any old computer and soldered to jumper wires to connect to an amplifier (or just a straight audio jack – see below).

Furthermore, I included an amplifier circuit to boost the audio. The is optional if you feel the power outputted by the Raspberry Pi is enough but it’s cheap enough to throw in even just as volume control.  However, the amplifier did make the speaker more susceptible to noise, possibly from fluctuations in the power supply or electromagnetic interference from the cables – it even picked up blips from my wifi dongle. I chose an LM386 circuit since it’s small, easy to use and inexpensive (~$5-$10). Don’t bother wiring up your own circuit, eBay and websites like DealExtreme sell premade LM386 modules that take 5V nicely. For the amplifier, I also had to solder an old pair of earphone wires to jumper pins for easy connection.

The Enclosure


I’ve included the design for the enclosure at the bottom of the post but be warned, the specs have changed slightly and I haven’t bothered to reflect the changes in the SCAD files.

Originally, I was going to 3D print the enclosure but felt it would look better made from wood. I was lucky enough to have a neighbour who had a CNC router in his garage and was nice enough to help me cut out the walls and build the enclosure (thanks Marco!).

The enclosure is designed to lock the Raspberry Pi in place via the SD card. Removing the SD Card lets the Raspberry Pi fall out nicely. Otherwise, it’s held in place by the USB connectors and SD Card. Nothing else was used to fix the board down.

The emergency stop button just needed screwing onto the top.

The speakers were fixed on with a plastic ring that came with the speaker. It was secured using nuts and bolts. I put a mesh on it too since it also came with the speaker.

The Software

The Raspberry Pi runs the default Raspbian Linux distro with a LOT of things cut out to reduce boot time. You may find minimal distros made for the Raspberry Pi that has a ~120MB footprint on the SD Card and fast boot times.

Next, I installed usbmount and pygame to automount USB drives as they are plugged in and for outputting sound in Python respectively.

Then, it’s just a matter of uploading the script that polls GPIO for changes and plays music at the right time. I have included the script I hacked up at the end of the post.

Don’t forget to add this script to your /etc/rc.local file along with code to export the GPIO interface and set it to input pull-up mode. You could use the horrible /dev/mem trick used in earlier tutorial Python code for the Raspberry Pi, but coming from a kernel developer background, I’d avoid messing directly with memory mapped I/O and just use the standard kernel interfaces for manipulating GPIO.

You may also want to configure your network interface to auto grab an address and install an SSH server so if you need to debug the box, you just have to plug in a wireless dongle instead of taking it all apart and hooking it up to a monitor.

Then, reboot your Pi and check everything works!

Files needed for this project

Idea for TI-Nspire serial adapter

The TI-Nspire has a serial interface in the dock connector at the bottom of the calculator. The easiest way to access this reliably is to simply solder a wire onto it but that’s obviously not an option for some people. A few people in the community have come up with some interesting designs for a home made adapter.

Here’s a simple and reliable adapter that I made out of tape, cardboard and some wires to replace my old, ugly, unreliable adapter.