Monday, September 14, 2015

Cross compiling for Raspberry Pi

So since my main project ( for the Gameshow Pinball Machine now includes a web server (mongoose) and a json library (rapid json) and threads and wiring pi, i was getting fed up with the super long compile times on the pi itself.  It was taking about 30 seconds to compile and run.  Being used to interpreted high level languages, i deemed this unacceptable and went about trying to find a faster way of getting my iterative development process running.  My main plan was this:

  • Do my development locally on my laptop (well inside a vm running ubuntu)
  • Press the go button which would
    • Cross compile in ubuntu for arm
    • scp the binary to my raspberry pi
    • start an interactive ssh shell on the pi running my freshly copied binary

There are a bunch of tutorials out there about cross compiling for the rpi.  I got these working, but since I was using the WiringPi library ( I was having some trouble compiling it in.  You generally need the .so file which has been compiled for the target architecture - in this case, arm.  I grabbed and chucked it in my project.  You also need the .h files for the project, but as these are just plain text, they'll work cross platform.  My source files are in /src and /include.  The wiring pi files are in wiring_pi.
After grabbing the cross compiler from the official raspberry pi git repo ( and following the guide here , my compile line ended up looking like this:

arm-linux-gnueabihf-g++ -Wall -std=c++0x -pthread -D _DEBUG -D _LINUX -D GAMESHOW_BUILD_RASPI -I/home/poho/git/gameshow/wiring_pi/include -L/home/poho/git/gameshow/wiring_pi/lib_arm  -Wl,--start-group /home/poho/git/gameshow/wiring_pi/lib_arm/ -Wl,--end-group -iquote ./include ./src/*.cpp ./src/*.c -o gameshow_arm

lib_arm contains (copied from my pi) and wiring_pi/include has all the wiring pi .h files.  Both the .so and .h files can be found on any system that has installed the wiring pi build tools.

From here it was a simple matter of scping the compiled file (gameshow_arm) to my pi and running the file using ssh -t.  I'd set up an rsa key pair so i wouldn't even need a password!

Saturday, August 22, 2015

Watchdog Timer

So after I fixed all my lamp matrix problems, I kind of ran into another, luckily I was prepared for this one.  See as I use a lamp matrix with 8 columns, any given lamp is only energized 1/8th of the time.  For this reason I decided to use 18v to power the lights, to keep them nice and bright.  This isn't too bad for the lights - I believe 'real' pinball machines do the same.  Problem is, if I stop the program, whatever lights were previously lit will stay lit.  This hammers the lights with a full 18v which isn't very good for a 12v globe and will likely burn it out before long.
I'm also expecting to have a similar issue with my coils.  If I stop the program or it crashes for whatever reason, a coil may stay stuck on.  For a flipper this isn't much of an issue, but for anything else this is a very bad thing, as they can burn out in a short amount of time.  This is why i need a watchdog timer.  There are a bunch of good resources about this around the place but basically its a circuit that keeps it's output high if it receives a pulse every so often.  If the pulses stop (i.e. the program stops or crashes), then the output goes low after a short time (milliseconds).  

There are a bunch of circuits around 555 chips that can are mainly used for rebooting an arduino if a program crashes.  I tried this but the output actually pulses when the program stops, which is fine if you're rebooting a thing, but not so much if you are using it to drive a relay for high voltages.  I found a great example of one from Ben Heck's spooky pinball which I adapted for my own needs.  You can check it out from here:  It's based on a 74HC123 chip and works a treat.  There's even a pot on it to adjust the time.  I hooked it up to one of my column drives on my lamp matrix and bammo - all good.

After some tidying up of my wiring my boards so far look like this:
The watchdog is the yello perfboard thing.  I'm using automotive relays to turn the high voltages on and off.

Monday, July 13, 2015

Lamp matrix v1.1

Lamp matrix issues have been solved!

As it happens I was failing to properly calculate my resistor values on my TIP107 transistors.  By failing to properly calculate I of course mean 'took a wild guess'.  I was using a 10k resistor between the base and ground.  Using 18v this only allows for a total of 0.0018 amps via the base.  The hfe of this transistor is 200, so the current was being limited at .36amps.  Far less than the 2ish amps needed to drive all the lights.  I think the transistors were heating up, due to trying to limit that much current which was causing their properties to change.  Replace those 10k's with a 1k (which allows me 3.6a through the transistor, and all is well with the world.

My dodgy rework job as i cbf getting my boards reprinted.  Notice the pre-burned trace (my fault) and the sticky uppy pin on that there uln2803.

So here's the thing.  I drive my lamps with 18v, instead of their rated 12.  This is because they are only on 1/8th of the time due to the matrix.  Problem is, if my program stops while the lamps are on, i'll get 18v pumping straight through my lamps which will likely lead to a premature death.  Similar to what I intend on doing with coils, my intention now is to have a power distribution board with a watchdog timer on it.  The watchdog timer will go to a couple of automotive relays which control the 18 and 24v drives (lamps and coils).  I'll hook into one of the column drives for the watchdog.  More on that in a later post!

Sunday, June 21, 2015

The Lamp Matrix v1

So I got my lamp matrix PCB design manufactured from Dirt Cheap Boards:
After some messing around with the programming, it actually seemed to work:

I couldn't really get the light bright enough when they were strobing as fast as they could.  But then I noticed some oddities.  My TIP107's were heating up a lot.  Still not exactly sure why.  Then this happened:

Also notice the slight modification I had to make to that ULN2803 chip - had to bend the com leg out.  Poor design on my part.   You may not have realised yet, but I don't actually know what i'm doing.  A lot of trial and error goes into this.

So trying to pump 5+ amps through a tiny little trace like that turns out not to be such a good idea.  I needed to re-engineer.  Since i didn't want to wait for new boards to be manufactured and didn't want to have to re-solder all those components.

This seems to work a lot better.  The puzzling thing is that my TIP107's still heat up significantly.  The current draw also steadily increases as they heat.  Still haven't worked that one out.  Since each globe is 0.25a and there are max 8 ever on at once, surely the max draw of this would only be 2a.  This is the case when permanently on, but when it strobes fast (say 74khz), the draw goes up.  I have a feeling i may not be using the tip107's properly, so I need to go back to the drawing board for that.  Still, progress has been made!

Saturday, June 8, 2013

On Western Digital hard drives, PUIS and Rocket Raid controllers

Disclaimer:  This procedure worked for me.  Use at your own risk.  It uses software not written by me and downloaded randomly off the internet.  If you break something, it isn't my fault.

So a while back I bought 4x1T WD green hard drives (WD10EACS) and a rocket raid 1740 to use with them.  I eventually ended up using them as JBOD (turns out it didnt support hardware raid 5) for a few years with no problems.  This was until I upgraded my server with a motherboard that supported enough sata drives and no longer needed the raid controller.

Turns out, if you ever set staggered spin-up on these drives as I did, it sets some internal flag on the drive to use a thing called PUIS or Power Up In Standby.  This means the drives don't actually start spinning until they receive a request for some data.  Problem is, these particular drives don't support it (or something) and some sort of hack is in place in the rocket raid controller to get around this.  Long story short, none of my drives now work on anything but the RR controller.

This problems is vaguely documented around the web, this
being the most prominent.  It details using various tools and things to get them working again.  After about a day of trial and error, I finally fixed my drives.  To save anyone else the days worth of effort, I've documented my solution here:

Firstly you need to go and find a tool called HDAT2 from  download it and create a boot disk for it.
Then a tool called MHDD is needed but you need to inject the bootable ISO with some script files from the above hddguru address.  Problem is, this is quite difficult and requires a floppy drive, or a virtual floppy drive which turns out is quite difficult to use on a 64 bit machine.  Virtualbox and 32bit windows XP to the rescue. After a fair bit of futzing around I finally ended up with a final ISO file that can be burned and booted - the hddguru post doesn't say exactly where one of the bin files needs to go so I had to guess around a bit before getting it right.  Get the bootable ISO from here:
If you want to make your own, then just remember that PUIS goies in the scripts dir and off.bin goes into the dir above that.

So boot up with HDAT2  (it will likely take a while to get past the bios and detecting your non spun up hard drives) and you should end up with a command prompt.  Type
the /w is the important part, this will spin up the drives for you and start the hdat application.  We don't actually need HDAT for anything other than spinning up the drives.  All going well HDAT should now see your drives:

Swap your bootable CD with one MHDD one you downloaded (bootable3.iso).  Reset your computer.  This is important. If you shut down or power off your computer the hdd's will stop spinning and you'll have to start again.  You need to reset.  It should actually be quite quick to get past the BIOS now because the drives will be instantly detected.  Wait for MHDD to start and you should end up with something like this:

Now it is just a matter of selecting which drive is causing you problems (in my case both, well 3 actually but one isn't displaying for some reason - perhaps I was being a bit optimistic trying to do all 3 at once).  Once you select the drive by typing its number and pressing enter, type
After you accept the disclaimer that pops up, it should all be working again.  DRIVES FIXED!

Now a bonus image of the rig I used to get this all working:

Bonus searching keywords stolen from Hddguru:
Drives not identified in BIOS
WD drives don't spin up after removal from Highpoint RAID 23xx 2300 2310
WD PUIS problem
WD PM2 problem
How to reset WD PUIS
How to fix staggered spin up problem with drives after highpoint Raid
Invisible drives after highpoint raid
Highpoint RAID makes drives unusable

Friday, May 17, 2013

The Centurion

Have you ever played the brutal drinking game called the Centurion?  It goes like this - have one shot of beer every minute for 100 minutes.  It may not sound like much, but if you think about it, a 30ml shot 100 times is 3 litres of beer in a little under two hours.

Anyway, I've played this a few times and the biggest problem is keeping track of time and who has drank what.  Usually you need a timekeeper who isn't playing to ensure that all drinks are taken and that we drink at the appropriate time.  Well, for an upcoming bucks weekend (mine), I decided to remedy this.

I build it into an old tool case I had lying around.  There are 8 double seven segment displays to keep track of players scores, all driven by 595 chips attached to transistor arrays.  I decided not to use a 7-seg driver chip because it would have been more of a pain to solder.  The 595 and ULN2803 transistor array can pretty much be mounted side-by-side.  Since I didn't etch my own board, this means less point-to-point soldering.

The whole project is driven by an Atmega8 chip and coded via my Linux server.  The main board uses a 195 to read the state of all of the push buttons.  I count overflow interrupts to know when 1 second is up, and have a pause button hidden under a missile switch - you wouldn't want to accidentally pause this game.  I also built in a programmer pin-header to program the atmega chip in situ.

A large double 7segment display is used for the main timer - it actually required 7.something volts to run properly, so that was a pain.  The original plan was to have another of these on the right to count drinks elapsed, but I ran out of time.

I picked up some automotive LED strips as well as a home alarm screamer to notify the players when it's time to drink.  A potentiometer regulates the volume of the screamer, as well as some gaffer tape - it was particularly loud to begin with.  Fun fact - screamers sound weird when you change the amount of current going into them.

The whole deal is powered by a 12v SLA rechargeable battery which sits inside the case.

Misc photos of the whole process with bonus video at the end:

The main-board

Back of the main-board

The timer display

Back of the timer display

One of the scoreboards under construction

One of the scoreboards under construction

Completed scoreboard

Back of a completed scoreboard

Components ready to be mounted

Underside of the base.

Inside of the case - almost complete!

I added some dry-erase stickers so we don't lose track of who is who.

Closed for travel.

Thursday, April 21, 2011

7 Segment Displays

As a part of my project to build a breathalyzer using the MQ-3, I needed a nice way of displaying how much drink you've had. I had some 7-segment displays in my box of stuff that I had bought previously. They are from futurlec. Datasheets can be found by googling 7DR8021BS.

2-digit 7-segment display (I accidentally blew the middle decimal point, which is why you cant see it - its blacked out with some texta).

These 7-segs use common outputs for each segment, and a separate input for each digit:

The segments are labelled as in the next image - I believe this is standard.

Since the outputs are common I had to switch between digit #0 and digit #1 really quickly while at the same time connecting the outputs to ground to make whatever digit I want display. I could have used a 4511 driver chip for this, but I still need some transistors to connect the output to ground. Also the 4511 only drives 7 segments (so no decimal point) so instead I decided to use a 595 shift register. Same amount of pins on my Arduino to drive it, but more outputs!

My initial design used a bunch of discrete transistors, but this got messy fast. Even though it worked, I wasn't satisfied. It also meant a HEAP of extra soldering if/when I put this on perfboard:

Original design - note the upside-down arduino to control it.

Too many transistors!

As I refined my design, I discovered that you can get a transistor array on an IC - the ULN2803a. This IC has a common ground, so it switches directly to ground - which is ideal for these displays.

When coding for a setup such as this, you just need to switch stuff super fast. The first thing I did was work out what number (in binary) represented each digit I wanted to display. Then you just turn off everything, shift the digit into the shift-register (to drive the transistors) and turn on one of your inputs. Then repeat. eg:

turn off both of your inputs (digit 0 and 1)
shift some data into the 595 chip to set-up the output transistors for digit 0
turn on input 0
sleep for a milli or something (not strictly necessary)

turn off both of your inputs (digit 0 and 1)
shift some data into the 595 chip to set-up the output transistors for digit 1
turn on input 1
sleep for a milli or something (not strictly necessary)

Theres obviously a bit more code around it than this, but you get the idea.