Hacking an Inspection Microscope

Sometimes I need to be able to take photographs of very small things, and the so-called macro mode on my point-and-shoot camera just won’t cut it. And it never hurts to have an inspection scope on hand for tiny soldering jobs, either, though I prefer a simple jeweler’s loupe in one eye for most tasks. So I sent just over $40 off to my close friend Alibaba, and a few weeks later was the proud owner of a halfway usable inspection scope that records stills or video to an SD card.

Unfortunately, it’s only halfway useable because of chintzy interface design and a wobbly mount. So I spent an afternoon, took the microscope apart, and got it under microcontroller control, complete with WiFi and a scripting language. Much better! Now I can make microscope time-lapses, but much more importantly I can take blur-free photos without touching the wiggly rig. It was a fun hack, so I thought I’d share. Read on!

Out of the Box

Nice image, but don’t touch!

The scope, as it arrives, is really fun. The image is just fine and most everything works as advertised. Looking at bugs and flowers was good for a few hours at least. However, all of the small details that make for a pleasant user experience are botched.

For instance, the clearance on the SD card is so tight that you can’t insert or remove it without something thin to press it in, or having very long fingernails. Some of the buttons are hard to reach behind the big focus knob. The menu system, to turn on or off the LED ring light for instance, is horrendous. These are minor quibbles, and for the price I’m totally willing to overlook them.

But the killer, for my purposes, is that the stand is so wobbly that the act of pressing the “OK” button to take a picture blurs whatever image was there. The video mode has a “motion detection” method — it’s always on because the camera wobbles so much that it always thinks the object has just moved. The culprit is the cheesy frame that ends in a thick silicone suction cup that wiggles around like a bowl of jelly. This is not how you design tripods.

There are two possible fixes for the vibration issue. The first is to build a better frame, and that’s something I’ll probably end up doing eventually, because the inspection scope is a useful piece of gear. The other solution is simply to trigger the exposure (and other) buttons without touching the wiggly little beast. Welcome to the Internet of Microscopes!

Hack, Hack, Hack

Opening up the case, the first thing I found was a row of five test points on the key panel, so I soldered some header wires to them to see what’s up. (That was easy!) They’re labelled GND, VCC, KEY, PWR, and VBAT, which doesn’t leave much to the imagination. Four out of the five are labelled correctly.

I’m an analog hacker at heart, and I usually start off with an oscilloscope when poking around unknown signals, but I decided to start off with a logic probe this time, because surely the single KEY line was encoding the five front-panel buttons in some sort of digital code. Imagine my surprise when each button press looked identical on the logic sniffer. Burned again. Back to the trusty oscilloscope.

Five buttons, five voltages

It turns out that the five buttons are tied to five different resistors that serve as the lower half of a voltage divider, and an ADC reads this voltage out to figure out which key was pressed. That explains the five voltage levels on the yellow scope trace.

This is a classic dirty trick and I’ve been waiting for the day when I absolutely had to minimize the number of wires connected to a panel. Who knew that I’d see something hackish like this in an actual product?

The power button is separate and pulls the PWR line (in green on the scope trace, on a 5 V vertical scale) to the VBAT line. A quick test with a 3.3 V power supply convinced me that I could turn the device on and off with a microcontroller’s GPIO. I was also pretty sure that I could connect up five GPIO pins to different resistors and “press” the corresponding button. So I pulled off the panel to measure the individual resistors.

In case you want to replicate this at home, the resistors are 0 Ω, 15 kΩ, 30 kΩ, 46.6 kΩ, and 70 kΩ respectively, and doing a little math on the measured voltages, the pullup resistor on the top of the voltage divider is probably nominally 100 kΩ. Alternatively, if you have a DAC you could just send voltages of 0 V, 400 mV, 750 mV, 975 mV, or 1325 mV to the KEY pin. I soldered up the closest resistors I had in my box, verified that they all worked and called the hardware done.

But what’s up with the VCC line? Something didn’t make sense, because the buttons pulled the voltage down despite being connected to VCC, and the KEY line was pulled high by default. Testing it out, of course VCC was a dead-short to GND and the pull-up resistor was on the KEY line. There was an unpopulated resistor on the keypad panel PCB as well, suggesting that in a previous revision the buttons pulled up, but the manufacturer optimized away a single resistor by using the microcontroller’s internal pullup. It’s either laziness or deliberate sabotage that they didn’t change the test-point silkscreen to match. (Imagine how much fun it would be to connect your test equipment up to “VCC” and GND!)

The Usual Suspects

The rest of the work was just me using my favorite tools for a quick job like this. You might want to use an Arduino or a single ESP8266, but I’ve been playing around with Mecrisp-Stellaris Forth on cheap STM32F103 boards lately, so that’s where I went. I was originally thinking of making a custom remote key panel, so the many GPIO pins would have meant that I wouldn’t have to resort to the ADC-and-resistors trick.

I was already using UART serial for programming and debugging, and decided that a separate key panel was a project in its own, so I cheesed out and put the microscope on the WiFi network. I flashed an ESP8266 with the esp-link WiFi-serial bridge firmware. Voila, remote control. Powering the microcontrollers off of the microscope’s VBAT line (through a switch) makes the whole thing entirely self-contained when I have to move it around the desk.

There were many details that required trial-and-error testing to get right. Different delays are required for button presses in camera mode and in the menu system, for instance. I didn’t optimize these, but made the delay long enough that it always works. The power on and off button only works if held down for longer than 1.5 seconds. It’s quirky. This was all pretty quick to get working with an interactive debugging system like the Forth environment, although I don’t think it would be all that much worse in a compile-and-flash loop like in C or Arduino either.

More guts, just for completeness

There are two cute things that I did in the firmware that are worth mentioning. The KEY line that’s used to detect button presses is only pulled up when the microscope’s power is on, so it can be read by the microcontroller to figure out if the microscope is currently on or off. When the microscope first turns on, it is in video mode, which allows the software to keep track internally of the mode it’s currently in.

Combined, this allows for a single “shoot” command that first verifies that the microscope is on, then switches into camera mode if it’s not already there, and then finally takes a photo. Similarly a “delete” command switches over to preview mode and deletes the last photo, confirming all of the “are you sure?” dialogs automatically. The code is here if you’re interested.

Making it Usable and Then Some

The out-of-the-box menu system is horrible. It requires something like fifteen keypresses to toggle the ring light on or off. Scripting this in the microcontroller makes it a lot more pleasant. Moreover, it’s now possible to set up repetitive exposures to make time-lapses, or film a two-minute video once every ten minutes, or automate essentially anything. I might add a distance sensor to make filming automatic when a PCB is present under the lens, or something silly. I really like the idea of tying these script functionalities to external buttons: a one-press light toggle or bracketed exposure button would be nice, as would a single-button delete.