Since I first saw Mikal Harts Reverse Geocache Puzzle I knew I needed to build one. My best mate and his wife are avid GeoCachers (is that a word?) and I decided to make a special gift for his 30th birthday. Well, I missed that particular deadline, but never mind, better late than never eh buddy!?
Having seen lots of other people try their hand at it in their own unique interpretations I had a few ideas of my own in mind. At the top of the list I wanted my Geocache to be more flexible than most.
My hope is that this unit will be passed on by the recipient once they have solved it to another person (and on, and on!). Therefore all the information is stored in human readable form on a Micro SD card internally. Every aspect of its operation can be adjusted by removing the SD card, modifying an XML like settings file on a PC, then reinserting the card or via a USB CDC Serial Interface. The following features can be modified:
If the unit detects that a fresh SD card has been inserted, a settings file is created with a default configuration and helpful notes (and the box is unlocked!).
The other aspect that can be personalised for the player are the messages that are displayed to the user before they can attempt to open the box. I term these “Taunts”. These are also held in a human readable file and can be modified as needed or wanted. The box will always pick the first message on the first run of the box, so giving useful instructions or a personalised message, then subsequent runs will have a randomised message. Again, if the unit detects that this file is missing, it is recreated with a default configuration.
The really big advantage of using the SD card is space. There is tons of it! It is therefore easily possible for me to record every attempt at opening the box, placing the location, time and distance to target. This information is recorded in a KML formatted file. When the user has opened the box, they can put the SD card into their computer, load the KML file straight into Google Earth, and see how well (or badly) they did. Example KML file here.
This also eased my debugging, as I could create a detailed debug log on the SD. When you are out and about traveling trying to debug it’s not much fun to be lugging a logging laptop around!
The box also has a USB CDC serial interface. This allows most of the SD card settings to be adjusted on the fly, along with a number of debugging and configuration options. This is also the main way of opening the box in an emergency, such as; running out of attempts, the SD card becoming corrupt, or any other unforeseen event. By connecting to the unit with a Terminal Emulator, when on the “Splash Screen”, a password protected menu is displayed (user password is configurable, plus a hard-coded master password).
The operation to the user is very similar to the previous versions seen. The user is presented with a single button User Interface. This one button switches on the unit and allows the user to interact. The box will shut off by itself after 30 seconds of inactivity, or once the sequence has been completed. Holding down the button for 5 seconds will also turn off the unit.
Once switched on the user is presented with a splash screen, then after a button push to confirm the switch on was intended and not accidental, the unit will display one of the custom messages randomly along with the custom greeting name. The text is dynamically formatted (word / page wrapped) so the person writing the prompts does not have to worry about formatting. The user is then prompted to press the button one more time to start the attempt (with inviting, flashing red button of doom!).
The software then starts checking the GPS data for a valid fix. The GPS power is switched on at startup to help mitigate the lock time. However, the EM406 seems to be pretty good at getting a lock, even indoors. The GPS is given 10 minutes to find a lock before the box will time out and shut off (without using up an attempt). If a valid fix is received, we wait for 10 GPRMC messages (this lets the GPS settle to ensure it is a reasonably accurate fix, plus adds to the tension!), then the software checks the 10th message against the target co-ordinates. If the distance for the GPS co-ordinates are within the accuracy of the target co-ordinates, the next target is selected if there are any remaining, or the box is opened if this was the last set of co-ordinates. If the distance to target is greater than required, the number of attempts is decremented, the user is told how far away they are from the target (in KM) and the box remains locked. The KML file is then updated on the SD card to record the attempt.
The LTC4412 Low loss power path controller is used to isolate the battery from the load and incoming power when connected to USB. This device along with the MOSFETs act as an “ideal” diode, providing a diode OR for the incoming power sources. When the voltage at the SENSE input is higher than the voltage at VIN, the MOSFETs are switched off, disconnecting the battery. When the voltage at the SENSE input is lower, the MOSFETs are switched on, connecting the battery to the load. The chip provides hysteresis to prevent the switches from flipping around due to bounce or instability on load change. The two MOSFETs are back to back to prevent their body diodes from conducting in the “wrong” way, which would be undesirable.
A typical diode would give an approximately 0.7 volt drop to the incoming battery voltage, effectively wasting a portion of the available battery power, and causing our regulators to hit their dropout voltage 0.7v higher than without. By using the LTC4412, we are instead dropping less than 20mV.
This device also allows us a “soft” power control, letting the PIC control its own power input whilst on battery by use of the CTL line. Whilst on battery; when the Button is pushed, TR1 is switched on, which pulls CTL low, enabling the LCT4412 and allowing the battery to be connected. The PIC switches on, and its first instructions are to set PWRON high, which through TR2 pulls CTL low. The user can let go of the button and the system remains on until the PIC releases PWRON to shut itself off. Whilst connected to USB, the system turns on and remains on regardless.
D6 prevents backpowering the PC USB port and provides the other side of the diode OR. Power drain in the “off” state should be less than the self discharge of the battery.
The MAX1555 Single Cell lithium Ion charger provides controlled charging of the internal 2000mAH lithium Ion Cell. A CHG indicator allows the PIC to detect when charging is complete to indicate to the user.
The charger is configured to take +5V from the USB connector, but uses the DC input pin on the IC. This is technically wrong, as the device will now draw up to 280mA from the USB port, which is not really allowed until the device has negotiated (until enumerated, devices should only draw 100mA). In reality, I’m not aiming for USB certification and most (if not all) USB ports should be able to deliver this just fine without negotiation and the faster charge speed will be appreciated.
The LT1615 Micropower step up DC-DC converter is used to provide a +12V bias supply required for the OLED.
The LTC1875 step down regulator is used to provide the main +3.3v supply on the board. It has a low dropout voltage, and will continue running “full on” (100% duty cycle) at 3.3v and lower.
The PIC 18F87J50 was selected due to a number of desirable properties;
The disadvantage is that the device is a 100 pin TQFP which makes assembly a little more tricky.
This is a 128x64 Mono colour OLED display. The one I use has a SSD0323 controller but any display that physically fits and uses a SSD0323, SSD1303 or SSD1325 controller should be ok. The display is an OSRAM Pictivia Calgary compatible module.
Sparkfun MicroSD card holder.
This is a 2000mAH Sparkfun Lithium polymer battery. Realistically the battery is overkill for the application, but it’s what I had lying around my bench. A smaller battery may be desirable.
EM406A GPS connector. I had an EM406A GPS module in my spares bin so on it goes. The EM406 connector is available from Sparkfun (or any good local stockist). The EM406A is rated to run from 4.5V to 6.5V from its datasheet. However from experimentation, I found that it would run quite happily from as low as 3V. If there are any doubts, the EM408 is rated at 3.3V and could be substituted to run off the 3.3v Regulator.
I purchased a number of micro servos from ebay. These are Turnigy TG9e 9 gram micro servos. It is important that the servo selected is rated to run from a single Lithium Ion cell.
The schematic and PCB were drawn and laid out in Eagle PCB 5.11.0 light. This was a learning experience for me, as I usually use Orcad for schematic capture, and someone else lays out boards for me. After an initial learning curve with the interface, I think I got the hang of things.
The board was constrained to 5cm by 5cm in order to take advantage of the SeeedStudio Fusion PCB service which offers a 2 layer 5x5cm prototyping service of 10 boards for $10 plus shipping. The boards I received back were excellent, and delivered to the UK in 2 weeks from time of order. I highly recommend this service.
The PCB was hand assembled by me using a hot air rework station and decent temperature controlled soldering iron (plus a steady(ish) hand). Sparkfun components were ordered from Cool Components in the UK.
Eagle brd and sch files here. Complete gerber stackup here.
Be aware there is a small error on the servo silkscreen indicating pin 1. Also if I was doing a second batch, I would find some space to make the BUTTON and SERVO headers 90 degree ones so they intrude less into the payload space.
A further oversight was the lack of any battery level monitor, something like a MAX17043 which is a complete single cell fuel gauge, or at least a input voltage monitor. Realistically I imagine the 2000 mAH battery should be enough to run the system to puzzle completion, without any recharges!
The firmware for running the box was written in Swordfish Basic. I’m afraid to say the quality probably isn’t up to scratch for certain sections but everything was done in a bit of a hurry. I’ve used modules and code from a number of contributors including:
NMEA2 by Graham Mitchell - I butchered his module into the sample timer module in order to share the GPS serial and Timer functions on the same interrupt.
SD File System 4.1.4 by Steven Wright - Used for accessing the SD card and inspiration for the debug menu system.
Updated USB library by Jerry Messina - Used for USB CDC communications and SF HID Bootloader.
RandGen by Ahmed Lazreg (Octal) - Pseudo-random Number generator.
Most of the important bits of code are commented. Some bits could probably do with a bit more polish though! Download the source here.
Points to note:
The PIC18F87J50 has 4K of SRAM on board. However, the USB BDTs are unhelpfully stuck in the middle at the 2K boundary. Swordfish is currently unable to deal with split memory like this, and therefore reports a maximum RAM size of 1K. This means it can also only automatically manage that 1K. Between the USB buffers, SD buffers and the GPS string buffers we would not have any memory left for anything else! However Swordfish does allow us to manually allocate memory outside of the “maxram” boundaries so that unused SRAM is still actually use-able! I have manually allocated memory above 3K to the SD buffers, GPS buffers and a large buffer used for manipulating the XML strings (to speed up file writing operations). The lower 1K automatically managed memory is therefore left free for everything else (and is filled to 1000 bytes out of 1024!). If you make any changes to these files, you’ll need to be aware of the memory map in order to avoid stomping all over these manually allocated buffers.
I have used a really dirty method of driving the servo. Because I only really need two positions, hard clockwise and hard counterclockwise, I have used one of the soft timers to control the servo. Because of the slight imprecision of the soft timer, there is some jitter on the servo (Jitter = servo hunts around slightly). This wastes power and unnecessarily wears the servo. In order to avoid this I only send servo control pulses to the servo for about 2 seconds when it needs to move. By not sending the control pulse, the servo stays in its last commanded position. This could be resolved by using a dedicated timer interrupt, rather than using the soft timer.
Due to limitations of floating point maths on a 8 bit microprocessor, the distance calculations start to go awry when dealing with small distances (approx. < 1K). Therefore the target precision should be greater than 500 metres at all times, and you should be aware that distances < 1K are not completely accurate. This could be resolved by bumping all floating point variables to integer variables, performing the calculations in integer math only, then dropping back to floating point.
The Pre-Compiled HEX image provided here contains a modified version of the SF HID Bootloader by Jerry Messina. A PicKit 2/3 is used on the ICSP header to put the initial image in. Once in, the Bootloader can be invoked from the CDC Debug menu, which then allows the firmware to be updated over USB using the stock Microchip HID bootloader PC client.
I couldn’t find a suitable wooden box to fit everything into. I did however spot a very nice cheap metal cash box which I felt would fit my needs nicely.
I think it gives the whole project a more industrial look. Of course a big limitation of using a metal box is that the GPS has to be mounted externally. However, the handle recess on this one is exactly the right size and depth the mount the EM406 GPS, along with an OLED display. Through testing, I found that the metal box did not appear to impede GPS reception whatsoever (unless the box was upside-down. Obviously). Holes were drilled and filed to pass through the GPS cable, OLED cable, USB connector and to mount the button and PCB
I used a two-part epoxy to secure the GPS, OLED display and USB connector to the top lid. The PCB was secured using 8mm standoffs with nuts and screws.
A custom laser-cut smoked transparent acrylic panel covers the top recess, giving a clean look to the build (and to hide my dodgy metalworking skills), but is transparent enough to let the OLED display and GPS LED shine through.
I removed the existing key lock and fabricated a micro-servo locking mechanism from acrylic which would engage the existing locking tab. Unfortunately this left a hole in the box where the key lock originally passed through, but I simply covered it up with an external acrylic plate. Only once everything else was fully tested and secured, I epoxied the servo lock mechanism to the inside of the box in the correct location which matches the removed key mechanism.
The acrylic for the top, front and locking mechanism was laser cut by Ponoko (via RazorLab in the UK). This is a service I would highly recommend, the price was pretty good and I think the final results look great! Note: There may be some optimisations possible to get the price down slightly on the panels by reducing cutting time (squarer holes or corners, smaller or closer raster text, etc). The source SVG for Inkscape is here.
I had a particular look for the button in mind.
Big. Imposing. Red. Flashing. Button.
I found a suitable one whilst browsing in maplin which just screamed “DO NOT TOUCH ME!”, whilst flashing invitingly.
…. That would be telling wouldn’t it! ;)
Suffice to say, the contents will be placed inside a zip lock bag to help ensure the content cannot jam up the servo mechanism (small chance due to small items). I also will be placing a laminate card inside explaining about the SD Card contents, a short explanation on reprogramming the targets and of course a congratulatory note.
All information and materials presented here are provided as is. I take no responsibility for any financial or physical, loss or harm (or if you set fire to your cat) if you make use of any part of the information presented.