Controlling the Zoom H2n Audio Recorder with Arduino

In Part One I covered the byte codes sent by the Zoom Remote Controller RC1 and decoded data sent over the wire to the remote from the Zoom H2n Recorder.

In this post I will be covering the use of an Arduino style micro-controller to decode the signals sent by the remote, then control the recorder. I have used a Tennsy 3.1 Arduino clone as this is a small controller with two additional hardware serial ports, works with 3.3volt logic, and a with the addition of a crystal and button battery a real-time clock.

Arduino control of the Zoom H2n

Setup and Connections

The connections on the remotes four pin 2.5mm jack, with pin one being the tip:

  1. Remote Receive – RX
  2. Remote Transmit – TX
  3. Ground
  4. 3.1V – Power

On the Teensy there are two hardware serial UARTs available in addition to that used by the USB port, UART2: Pin 9 (RX2), Pin 10 (TX2) and UART3: Pin 7 (RX3), Pin 8 (TX3). Serial data is sent at 2400 baud, 8 bits, no parity, 1 stop (8n1). The response data shown is for when the recorder is in XY Stereo mode (0x20, 0x21), different codes are returned when other recording modes are used, see the end of Part One for details.

Serial Monitor

This first chunk of code is for monitoring the outputs of the remote control and recorder. Connect Remote Receive – RX on the remote to RX2 – Pin 9 on the Teensy and Remote Transmit – TX to RX3 – Pin 7 and Ground to Ground on the Teensy. This program will output data received to the Arduino IDE’s serial monitor.

The output is in four columns; the UART seeing activity, current milliseconds and the received data in hexadecimal and decimal values.

Taking Control – But Not Listening

Sending the command to the recorder blindly is quite straight forward, just send the bytes to the Remote Transmit – TX pin on the recorder (Zoom RX). This can be seen in the following, when run it starts the recorder recording for ten seconds. Connect: Remote TX to TX2 on the Teensy, Remote RX to RX2 and Ground to Ground.

Taking Control – And Listening for a Reply

The next stage is to have the Teensy control the Zoom and listen for a response from the recorder. Again, as before connect: Remote TX to TX2 on the Teensy, Remote RX to RX2 and Ground to Ground. For the demonstration I have added three buttons to act as the controller.

Zoom Control with three buttons

The following code needs more development work, I ran out of time, but I think gives a good starting point for further investigation. I have placed the commands for the remote in a structure, each command; record, pause and mark has four components, the command to transmit to the Zoom, the expected responses when starting and stopping and a flag to store the status.

There is a problem when resuming from pause, because the Zoom sends codes to flash the LED on the remote this can pick up the wrong pair of bytes; such as 0x21 0x21 instead of the expected 0x20 0x21.

I expect to be revisiting this, adding a timer function plus external battery for long running. I’m not sure how useful listening for a response is, sending the record command toggle on its own seems fairly robust without the need to check.

Links and Sources

Hacking the Zoom H2n Remote Control

The Zoom H2n is a portable sound recorder looking like an old fashioned microphone it is a handheld device that provides an assortment of stereo and surround recording modes, it records onto an SD card in MP3 or WAV format with options for various bitrates and frequencies. The unit is powered internally by two AA batteries and can also be powered from the USB port. The recorder I am experimenting on has firmware version 2.00 installed.

A not at all contrived image of the Zoom H2n Portable Recorder

The Zoom Remote Controller RC2 is a wired four pin 2.5mm jack plug connection, this remote has three buttons: record, mark, and pause there is also an LED to show when the H2n is recording. It is purchased separately from the recorder and only appears to be available bundled in an accessory pack. It looks difficult to take apart without leaving some damage, and this may not be necessary for decoding.

Zoom Remote and breadboard for testing

In this post I am looking to see how the remote works and find what control method it employs so in Part Two I can use an Arduino style micro-controller to provide an external trigger such as for timed recordings.

Setup for Testing

For testing I have made a breakout lead, this is essentially an extension cable split in half with a couple of molex style connectors allowing me to plug it into a breadboard. With this I have found the cable has the following connections, with pin one being the tip of the 2.5mm jack plug:

  1. Remote Receive – RX
  2. Remote Transmit – TX
  3. Ground
  4. 3.1V – Power

When checking with a multimeter I found continuity from the negative of the left battery (on the Mic Gain side) to pin three, ground, of the jack, there is also a connection between the positive of the right-hand battery to pin one of the jack but on the multimeter in diode mode there looks to be a capacitor, the voltage rises until no apparent connection is indicated. With no activity on the recorder the RX and TX pins show ~2.7 volts.

Determining the RX and TX pins turned out to be straightforward. When you press the record button after a moment the recording LED lights up, on the oscilloscope I can see three different square wave patterns for the three different buttons on the TX pin and a single type of square wave on RX to light the LED. The following images show the signal for the record button then that sent in response to to light the LED.

Signal sent by the remote when Record pressed
Signal sent by the Zoom recorder to light the LED in the remote

Also when buttons are pressed on the recorder data is seen on the RX line. For a more detailed examination I will need to break out the logic analyser.

Signal Analysis

Following some research where the remote for a Zoom H4n was examined, I set both channels being used on the logic analyser to the following:

  • Protocol: UART
  • 2400 baud, 8 bits, no parity, 1 stop (8n1)
  • Bit Order: LSB first, inverted logic: No
Decoding of the first part of the stop recording command

First I decoded the buttons on the remote with the trigger on the logic analyser set to falling edge on the Remote TX line. On TX there is a pause between the two pairs of command bytes which appears to be the length of time the button was pressed, around 350-500ms, there is also a pause between bytes in the RX response, the value of the response changes depending on which recording mode you are in, those shown below are when the recorder is in XY Stereo:

Record Start
TX: 0x81 0x0 ~ 0x80 0x0
RX: 0x20 1.85s 0x20 0x21 record LED on
Record Stop
TX: 0x81 0x0 ~ 0x80 0x0
RX: 0x21 0x21 0x20 1.9s 0x20 0x20 record LED off
Pause (while recording)
TX: 0x80 0x2 ~ 0x80 0x0
RX: 0x21 51ms 0x21 0x20 then this repeats
492ms 0x20 0x21 to flash the LED
492ms 0x21 0x20 until pause is pressed again
Resume from Pause
TX: 0x80 0x2 ~ 0x80 0x0
RX: 0x21 0x21 LED on
TX: 0x80 0x1 ~ 0x80 0x0
RX: 0x21 492ms 0x20 0x21 LED on

I was also able to capture the following activity sent to the remote when various buttons were pressed on the recorder itself with the recorder in XY Stereo mode. Other models of the recorders made by Zoom have more advanced remotes, such as the RC4 as featured in this hack of the H4n. I suspect they would work on this machine too. This time I set the logic analyser to trigger with a falling edge on Remote RX. I think the 0x20 code is used to indicate the display illumination has been turned off. I saw activity on all buttons except the Mic Gain knob.

Power On – Without remote attached
TX: Lots of random activity
RX: 0x10 400ms 0x80 0x81
1.2s 0x10 0x0 0x80 0x0
140ms 0x0 0x0 0x80 0x80 0x0
~2ms 0x0 0x80 0x0 0x0 0x80 0x0
Power On – With remote attached
TX: 0x0 five pulses 30ms apart
30ms 0x0 0xA1 0x80 0x0 0xA1
RX: following pulses on TX 0x80 0x81 0x80 0x10
1.2s 0x10 0x0
148ms 0x0 0x0
~4ms 0x0 0x0 0x0
Record Start
RX: 0x20 20ms 0x20 0x21 LED on
Record Stop
RX: 0x21 0x21 0x21 0x20 ~ 0x20
~283ms 0x20 0x20  LED off
Menu \ Home – Into Menu
RX: 0x20 0x20 0x0
Exit from Menu
RX: 0x20 45ms 0x20
Play Switch: Up/Down/Press
RX: 0x20 55ms 0x20
Clipping detect (tapping the microphone with a pen)
RX: 0x10 0x2 56ms 0x2
59ms 0x10
60ms 0x10
354ms 0x10
Volume: Up and Down
RX: 0x20
Recording Mode Change: 4 channel surround
RX: 0x10 0x10 0x30 14ms 0x30 0x30
122ms 0x34
60ms 0x30
60ms 0x30
Recording Mode Change: XY Stereo
RX: 0x30 0x30 0x20 216ms 0x20
Recording Mode Change: 2 channel surround
RX: 0x20 0x20 0x30 0x30 18ms 0x30
148ms 0x30
164ms 0x30 0x6
56ms 0x14 0x30
477ms 0x30
Recording Mode Change: MS Stereo
RX: 0x30 0x30 0x10 170ms 0x10
50ms 0x12

I think these response codes are to light up various LED’s on the more advanced Zoom RC4 remote, this suggests that other remotes would work in this recorder.

The following table shows the response codes given with different microphone configurations when record is clicked to start recording:

TX: 0x81 0x0 ~100ms delay 0x80 0x0
XY Stereo: 0x20 750ms delay 0x20 0x21
2 Channel Surround: 0x30 750ms delay 0x30 0x31
MS Stereo: 0x10 750ms delay 0x10 0x11
4 Channel Surround: 0x30 750ms delay 0x30 0x31

In Part Two I will be covering the use of a Arduino style micro-controller as an alternative remote control.

Links and Sources

Fixing the Arduino incoming network connections error on the mac

On the Apple Mac if you use the Teensy micro-controller with the Arduino IDE you may have come across a persistent firewall error message when starting the IDE, I have seen this error for quite a while over a range of system and software upgrades. I have applied this fix to:

  • OS X 10.10 Yosemite and above / macOS 10.12 Sierra
  • Arduino IDE 1.6.13 – all versions, at least 1.5 and above.
  • Teensydunio 1.33 – and older versions

The Arduino IDE is installed in the default applications folder, as is the Teensyduino. Some knowledge of using the terminal is required.


On your Apple Mac, you installed the Teensyduino software for the Teensy and now when you start the Arduino IDE this error message appears:

Do you want the application “” to accept incoming network connections?
Clicking Deny may limit the application’s behaviour. This setting can be changed in the Firewall pane of Security & Privacy preferences.

Incoming Network Connections Error


When the Arduino IDE is installed it includes a certificate to assure the system that everything is correct, the Teensyduino installation makes changes to the IDE configuration and this causes a mismatch and the signature in the certificate does not match the installation.

You can verify the failed certificate in the terminal with the spctl command:

Without the Teensyduino software installed, the certificate shows correctly:

Another check is to use codesign


To fix this, first we need to create a self-signed certificate. In finder Keychain Access can be found in Applications > Utilities > Keychain Access

Keychain Access certificates

From the menu choose: Keychain Access > Certificate Assistant > Create a Certificate… and set the following:

  • Name: anything useful, without spaces. You will be using this name later to apply the certificate – I used ‘arduino’
  • Identity Type: Self Signed Root
  • Certificate Type: Code Signing
  • Check the box “Let me override defaults”, this is important
Certificate Creation

click continue, and continue again past the security warning, then over the next few pages:

  • Serial Number: 1 – The serial and certificate name combination must be unique
  • Validity Period: 3650 – this will give you ten years
  • Email, name, etc: anything you like, or leave blank
  • Key pair info: set to RSA, 2048 bits
  • On the next four screens, from “Key usage extension” to “Subject Alternate Name Extension” accept the defaults
  • Location: login keychain.

Once created and back in the list, choose your certificate and from the menu go to File > Get Info (Cmd-i). In the Trust section at the top change: When using this certificate to Always Trust.

Trusted Certificate

Now that the certificate has been created, you need to apply it to the application, in terminal use the codesign command, this takes a few moments:

You’ll be asked to verify this, click ‘always allow’. To verify that your certificate has worked, check with codesign, using spctl will not work as this is a self-signed certificate.

Now, when you start the IDE on first run it will give you the allow/deny message again, click Allow and on subsequent use it will open as expected.

Links and Sources

Exploring Interrupts on the Arduino

Interrupts are a handy way of having the micro-controller listen for triggers and respond to them, instead of polling, constantly checking, the controller listens while getting on with other things, this is analogous to when the door bell rings you interrupt what you are doing to answer the door rather than repeatedly going and checking the door every few minutes to see if anyone is there. The interrupt is handled by micro-controller hardware and reacts very quickly and efficiently to a detected event, different micro-controllers have different interrupt pins available, for example the one used in the original Uno only has two digital pins available but on more recent models such as the Genuino 101 or the Teensy 3.2 all digital pins can be used.

In your program when an interrupt is triggered the action performed by your function – the Interrupt Service Routine (ISR) should be kept simple so as not to keep the controller occupied and possibly miss other trigger events, interrupts are for listening and monitoring to tell your main program that something has happened. The micro-controller can react to four different types of trigger:

  • LOW – trigger whenever the pin is low
  • CHANGE – trigger whenever the pin changes value
  • RISING – trigger when the pin goes from low to high
  • FALLING – when the pin goes from high to low

Square Wave Edges
Square Wave Edges

On the oscilloscope screen above we can see these conditions on a square wave, the change trigger can be said to be all the corners. If your input is being pulled high and goes low when triggered (as shown), then choose Falling or Low, it is better to detect a falling or rising edge as using low can cause the interrupt to trigger multiple times for the duration of the low state.


To illustrate the use of interrupts I have written a program to find the rotation and wind speeds of a 30cm Desk Fan. To do this I added a hall effect switch and magnet to find the rotation speed of the blades and bought a cheap Anemometer to find the speed of air being pushed out by the fan.

Circuitry for the Hall Effect Switch, Anemometer and monitor LED's
Circuitry for the Hall Effect Switch, Anemometer and monitor LED’s

To monitor the speed of the fan I have used a A1120EUA-T Hall Effect Switch and 10K pull-up resistor and glued this to the body of the fan near the motor shaft and on the shaft itself glued a small magnet.

Glued to the fan is a Hall Effect Switch with pull-up resistor and magnet on fan shaft.
Glued to the fan is a Hall Effect Switch with pull-up resistor and magnet on fan shaft.

The Anemometer is not particularly robust and could be seriously damaged by a pigeon. Taking the cap off you will find a bearing to allow the top to rotate freely as well as a magnet, inside there is a small reed switch that closes every time the magnet passes over it. I have connected this to the Teensy in the same way as would a button switch with a pull-down resistor.

The cheap Anemometer
The cheap Anemometer
Reed Switch inside the Anemometer
Reed Switch inside the Anemometer

The the reed switch in the anemometer creates a bit of noise when it closes as you can see on the oscilloscope below, these are picked up as false positives by the micro-controller and will give you bad readings. Fortunately this can be fixed in software by having the interrupt handler ignore further events for a few milliseconds.

Reed switch noise, after the first rise when the switch closes, the contacts bounce about for a short while before settling.
Reed switch noise, after the first rise when the switch closes, the contacts bounce about for a short time before settling.

A thing I found useful when testing this was to have the multimeter set to its frequency counter (Hz) and check that roughly the same cycles per second were displayed on the meter and on the Arduino serial out.


The Arduino commands to look out for are attachInterrupt and digitalPinToInterrupt to convert the named digital pin as you see on the board/piece of card to the interrupt name used by the controller. There are a few rules to remember when using interrupts:

  • Keep it simple – the function – Interrupt Service Routine (ISR) called by your interrupt should be short and simple, any extra data processing should be done in the main program.
  • Delay() won’t work, and don’t use Serial.print()
  • Make variables shared with the main code volatile – this tells the complier that the variable can change at any time, so it must be reloaded every time its referenced.


Here is a chart of the information gathered, it might even be interesting for someone with an interest in aerodynamics, anemology or something. The fan is a three speed SFC-300BP 12″/30cm Air Circulator and the Anemometer was placed one meter away from the fan positioned to capture the strongest wind.

fan anemometer
setting RPM Hz RPM Hz m/s
1. 1045 17 150 2.5 1.10
2. 1223 20 201 3.35 1.47
3. 1366 22.7 214 3.5 1.5

I took 60 readings for each fan speed then averaged them, in my program I used the following formula to work out the wind speed from the Anemometer in meters per second:

    \[ v = \frac{2\pi rN}{60}\]


v = velocity in meters per second
r = radius in meters – distance from the centre to the middle of the cup
N = Revolutions Per Minute (RPM)

Links & Sources

More than one MCP23017?

I have a had a few requests on how to add more than one MCP23017 port expander to the Arduino via the i2c bus, this chip is a very useful and easy to use component that adds up to 16 digital I/O ports to the Arduino. This demonstration uses two MCP23017’s with three LEDs for output, one RGB LED to loop through a selection of colours, a single colour that blinks on and off, and another RGB LED that is controlled by a four button keypad. I have written the program using the millis() timer rather than the delay() function to maintain the illusion of multi-tasking.

Two MCP23017s and a Teensy
Two MCP23017s and a Teensy

Addressing the MCP23017

The port expander has a three pins, A0, A1, and A2 for which an address can be set, each MCP23017 on your i2c bus must be set to have its own address, this is a three bit address and up to eight expanders can be used. Although I suspect things may noticeably slow down as you add more expansion. There is an SPI version available, the MCP23S07, that may be better for use with larger setups.

MCP23017 pinout

The address connections are shown the chart below, where zero is a connection to ground and one is a connection to 5V (or 3.3 volts). The MCP Address column refers to the address used by the Adafruit driver as you will see later.

hardwired address i2c
A2 A1 A0
000 GND GND GND 0x20 0
001 GND GND 5v 0x21 1
010 GND 5v GND 0x22 2
011 GND 5v 5v 0x23 3
100 5v GND GND 0x24 4
101 5v GND 5v 0x25 5
110 5v 5v GND 0x26 6
111 5v 5v 5v 0x27 7

In my circuit I have assigned the first expander address 0x20 and the second 0x21.

Powering the Expanders

The port expander has been designed to run on a supply of 2.5v to 5.5v, so using a 5v supply from the USB port should be OK for a modest number of LED’s, you will need to calculate what your power requirements will be, approx 20mA per LED, so in this demonstration: 7 LED’s x 20mA = 140mA, plus whatever the chip itself is using. Bear in mind that each GPIO pin on the expander can only handle a maximum of current 25mA, and that the maximum total power dissipated must not exceed 700mW (after which point it’ll let the magic smoke out).

A Teensy 3.2 has a 3.3V supply but this is rated at 250mA maximum, the Ardunio UNO looks to be around 450mA on the 5V and only 50mA on the 3.3V output. For running from a battery I would look to use a 6v supply and a buck converter such as this Pololu step-down regulator.

The Hardware

On the left we see the Arduino UNO with the two i2c wires coming from pins A4 – SDA and A5 – SCL, two 4.7K ohm resistors are used for pullup, the port expanders are daisy chained along this bus, using pins 12 – SCL and 13 – SDA. See how the addresses are set on pins 15, 16 and 17, and note the 1K ohm resistor on the reset pin (18), without this resistor the circuit will work for a while then stop. The GPIO pins are connected as appropriate and the button switches do not need pull-up resistors as the port expanders internal pull-ups are turned on in the software.

Connecting two MCP23017 port expanders
Connecting two MCP23017 port expanders (click to enlarge)

Also if you are using RGB LED’s you will want to adjust the values I have given here, different colours have different power requirements so different resistor values are required to get a properly balanced colour LED. The RGB LEDs I have used are common anode, 5v is applied to the common and the path to ground to through the expander, this inverts the logic so setting the pin HIGH turns the LED off, and LOW turns it on.

The Software

The Adafruit MCP23017 library assigns each GPIO pin a number as you can see in the following diagram:

MCP23017 pin assignments

On both expanders the RGB LEDs are on ports 8,9 and 10 (to save me writing separate code for each RGB LED), the blink LED on port 7 of the first expander, and the buttons occupy ports 4, 5, 6, and 7 of the second. The first three buttons are used to toggle the red, green and blue in the second RGB LED while the fourth turns them all off. The other two LEDs are just doing things to show that they can do stuff.


Captive Nut How-To

A quick captive nut how-to, for when you are making a wooden box that has a lid you need to remove on an irregular basis. Wood screws tend to maul the wood after a while and then the lid falls off, these captive nuts are easy to do and just work.

You will need:

  • Nut and bolt
  • two part expoy adhesive
  • drill bit as large as the nut and a drill
  • Vaseline or any other petroleum jelly
parts needed
parts needed

In this example I am using an M4 nut and bolt and an 8mm drill bit. You may need to cut your bolt to length.

1. Drill your hole
in this case about 1 cm, deep enough so when you insert the nut and bolt the expoy will cover the nut. Clean it up, removing wood shavings and other debris.

Hole Drilled
Hole Drilled

2. Grease Up
To prevent the expoy sicking to the bolt smear some Vaseline onto your bolt, only a small amount is required, but you should get it into the thread, make sure you keep the nut clean. Thread the nut back onto the bolt, leaving 4-5mm of bolt protruding, as shown:

grease your bolt
grease your bolt

3. Mix up the Expoy
Mix a blob about the size of a marrowfat pea, enough to fill half of the hole. Drizzle this into the hole.

drizzle the expoy
drizzle the expoy

4. Plunge the nut and bolt into the hole
Wiggle it about a bit to make sure the expoy is well distributed. Position the bolt how you would like and leave to set. If you see the bolt moving use some sticky tape to hold it in place.

plunged bolt
plunged bolt

5. Remove the bolt
After about 10 to 15 minutes, the expoy will have set (unless you got that weird stuff). Use a screwdriver for at least the first turn as there will be a little adhesion, but it’ll come out cleanly.

If you have any excess expoy protruding it’s still quite soft at this time so cut it way with a Stanley knife as I have done in the example. Once fully cured expoy makes a hard plastic that can be difficult to cut.

the nut is captured
the nut is captured

The amount to cut off your bolt is the length of your bolt less the thickness of your lid less a bit of wiggle room, I use a cutting disc on a Dremel, and file the cut edge smooth. You need to ensure its long enough to go through the nut once cut as the expoy has a thread that gives a misleading nutness (technical term!) that soon wears away.

I hope you enjoy your captive nuts, I am sure they will give you many years of service. The same principle can also be applied to making captive bolts, especially if you wanted to use Wing Nuts for easier access.

Using a Thumb Slide Joystick

Here are some notes on using the Sparkfun Thumb Slide Joystick on an Ardunio. This is a small two way X-Y variable resistor based controller that uses two analogue pins on the Arduino and works with both the 5 volt logic of the Uno as well as the 3.3 volts of the Teensy.

Thumb Sliding Joystick
Thumb Sliding Joystick

I found that this joystick works well for giving the eight positions found at the stick limits crosswise and diagonally but it doesn’t seem sensitive enough for reporting accurate positions.


On the underside of the joystick there are four solder pads, looking from above with the screw holes pointing towards you, the connections are:

  1. X-Axis
  2. +5 volts
  3. Y-Axis
  4. GND
Connections, looking from above and circuit diagram

Should you take one to bits, you will find two sliders with small metal contacts and a circuit board with carbon tracks acting as a variable resistor. The sliders move in a parallel configuration, and the joystick control has a spring to return it to centre when released.

Inside the Joystick showing the contacts
Inside the Joystick showing the contacts
Carbon tracks on the circuit board, solder pads top left

These can be tricky to put back together afterwards.

Underside of the joystick, with some wires soldered to the connections
Underside of the joystick, with some wires soldered to the connections

The pads on the base are spaced at 2mm but with some bending it is possible to attach standard 2.54mm (0.1inch) header pins, solder the inside two first before attaching the outers.

Thumb Joystick test setup with a Teensy
Thumb Joystick test setup with a Teensy,

When mounting in a case or panel you will need to drill a 18mm hole for the controller and the thumb pad is raised about 3mm above the surface of the body. I would secure the controller in place with a couple of blobs of hot glue  rather than use the small screw holes.


For my setup I am using the Teensy’s 3.3 volt output to power the joystick and the X-Axis connected to Analog pin 0, and Y-Axis to Analog pin 1,

This test program shows the position of the joystick through the serial port, it attempts to calibrate itself and set the values for the chosen direction, if this is not always successful when returning to the centre position try experimenting with the tolerance and maxRange values.


Hacking a Vacuum Fluorescent Display

I’ve had this Vacuum Fluorescent Display – VFD recovered from a broken DVD player in the bits box for quite a while. I shall turn it into a clock and have it display the date at the press of a button, it will also set its time using the internet and the Network Time Protocol over a WiFi connection, I’ll be using a Teensy 3.1 Ardunio compatible micro-controller as this is compact and with the addition of a crystal and button battery has a clock built in.

VFD Digital Clock

This project is a complete replacement of the logic and driver that came in the DVD player, I have also used general electronic components as these are what I have available: 74HC595 8-Bit Shift Registers, ULN2803A Darlington Arrays and PNP transistors, rather than dedicated VFD driver chips, such as the MAX6920AWP+, Philips NE594N or the TI SN75518N available from eBay. If I were undertaking this again I would use a dedicated driver.

How A Vacuum Fluorescent Display Works

The VFD is made up of three layers, starting at the back these are:

  • The Anodes – these are elements of your display that illuminate
  • The Grid – to control a block of Anode elements
  • The Cathode – also referred to as Filaments or the Heater
A VFD showing the white Anode elements with a row of three illuminated, next are the honeycomb lattice grids and the five Cathode filament wires on top.

“The filament is heated, which causes it to release electrons, a process called thermionic emission. Since electrons are negatively charged, if there is a nearby piece of metal with a electrical charge more positive then the electrons from the cathode, the electrons will be attracted to it, allowing a current to flow.

The grid is positioned between the Anode and Cathode. If the grid is driven more negative than the cathode, it repels the electron cloud, which prevents any current from flowing. Since the grid is not heated, it does not emit any electrons itself.

A VFD is basically triode, except the anode is coated with phosphor. Therefore, when the the anode is more positive then the cathode, the free electrons in the cathode’s electron cloud flow towards the anode, and in the process strike the phosphor, exciting it.” Connor Wolf on

The display brightness is set by the difference in voltage between the Cathode and Anode. The Cathode filament should be set to a low voltage, no more than 4 volts as it is made from thin tungsten wires which can melt very easily. The Anode uses a higher voltage around 12 to 15 volts.

Multiplexing is used to display the output. Each grid controls a fixed number of elements, the element connections are common to each grid. For a clock you will need to loop between the grids selecting the correct elements to display before moving onto the next, the persistence of vision effect maintains an illusion of a complete display.

Further information

Connecting and testing your Vacuum Fluorescent Display

You will need to find the connections that your VFD uses as well as the best voltages to supply. Unless you are really lucky its unlikely you will find a datasheet for your display, so a little reverse engineering is required.

A selection of test hooks are very useful at this stage. You will also need two power supplies, one low voltage for the Cathode filament, I use 3.3 volts supplied from the Teensy/Arduino. For the gates and Anodes a variable DC supply you can adjust from 10 to 20 volts preferably with the current limited to 1mA, in some cases displays from older equipment will need a higher voltage, 50V and above. The ground on both your power supplies will need be connected together.

The flat VFD’s you see in consumer electronics, such as the DVD player, all have a similar layout. The two pairs of outer pins connect to the Cathode and the pins between these divide into two blocks one side will be for the grids and the other for the Anode elements.

First, establish that the pins you suspect are for the filament are indeed so, with your multimeter in continuity (beep) mode you should see a connection when you probe across these pins. Connect your 3.3v supply to these pins, it doesn’t matter which way round.

VFD Element being illuminated, with 3.3V across the Cathode filaments (red and black connections). with the first grid on the white connection, and third from last element connected to the green.

The following connections should be made:

  • 3.3 volts across the Cathode filaments (the red and black, above).
  • Ground on the 3.3 volts is shared with the power supply.
  • Two probes connected to the positive on the power supply for connecting to one of the Grids and one for connecting to a Cathode (white and green).

Next, set your variable power supply to its lower setting and with your positive power supply probes  attach one probe to a Grid pin, and the other to an Anode element, on my display I started with a pin furthest left and another furthest right, see if anything lights up, at a low voltage this will be rather dim. If an element has lit up has then increase the voltage until the brightness is what you would expect. If nothing lights then first check you have connected a grid and an element not two grids or two elements by choosing different pins. Or if you are reasonably sure then carefully increase the voltage.

When you are driving the display as a clock, the multiplexing will make each element appear dimmer I increased the display voltage to 15 volts to fix that.

VFD Pin mappings for my display
VFD Pin mappings for my display

Now you can map out the grids and elements, on mine, there are eleven grids the first and last grids are for special characters and the rest contain digits. With a Grid connected, go through each element and make notes, each element will have the same connection on each grid, so all the digit elements and special characters/icons have the same pins.

VFD pin numbers for the digits
VFD pin number mapping for the digits

Driving the Display

While the Cathode filaments are permanently on at 3.3V the 12V grid and Anodes require some kind of high voltage level shifter to have the 5V logic output from the Ardunio (or 3.3V logic on the Teensy) switch the 12V required at the display. The method I have used for switching is a NPN, PNP complimentary (Sziklai pair) output.

Transistor Control
Transistor Control

The NPN transistor is the switch controlled by the Ardunio this in turn switches the PNP transistor, the NPN transistor is being used to isolate the Ardunio from the high voltage required for the display. As the current being drawn is very low we only need small signal transistors NPN: BC549 and for the PNP: BC556.

For the PNP transistor to switch off the Base voltage needs to be close to that of the Emitter, as the Ardunio’s 5V logic is nowhere near the 12V used a NPN stage is added so when the Base of the NPN is on this pulls the Base of the PNP low and allows current to flow to the display. There are three resistors, R1 100K limits the current to the base of the NPN transistor to protect the transistor and Adrduino, R2 10K is biasing the output, working as the bottom half of a voltage divider, and R3 10K is both the top half of the voltage divider and pulls the PNP Base high keeping it off when not required.

Transistors as switches, further reading:

To reduce the component count and size of the project I have replaced the NPN transistors and the resistors R1 and R2 with ULN2803A Darlington transistor array, however the PNP transistor remains as the display requires a sinking output to provide a grounded connection to the load through the cathode.

Two of the four drivers, with, from the top, the Registers, Darlington Arrays, and PNP transistors
Two of the four drivers, the other two are underneath. with the Registers, Darlington Arrays, and PNP transistors.

Connecting to the Arduino

The next stage is to connect the 32 pin display to the Arduino. Obviously the micro-controller does not have enough I/O for this, so instead I have used four easy to use 74HC595 8-Bit Shift Registers with only a data, clock and latch to set up, they can be used to extend the number of output pins on the Arduino.

74HC595 Serial Connections (click to enlarge)

I have used the ShiftOutX library for my clock, but it helps to look at the Ardunio’s ShiftOut tutorial to see how they work.


To power this Digital Clock I am using a mains to 12V DC brick from some old electronics equipment, I then use a Buck power supply to provide a 5 volt supply for the Teensy and electronics, and for the display a Boost supply to bump the 12V to 15V, search for XL6009 Module on ebay, check that it has the XL6009 rather than the older LM2577 and set the output voltage before connecting the display.

Digital Clock Power Supplies, 5 volts, small board on the right, 12V to 15V from the larger board on the left

The Driver Circuit

Here is a quarter of the driver circuitry, for the 32 pin display I made four of these. You can see that there is an extra transistor, as the Darlington Array has seven inputs/outputs and also note that on the 74HC595 8-Bit Shift Register the Ardunio data pin connects to DS (pin 14)  and the next register in series connects to to Q7S (pin 9) of the previous register.

VFD Driver circuit (click to enlarge)


This demonstration uses the ShiftOutX library. It loops through each grid and each element within that grid, it does not use multiplexing.

This second demonstration counts from 0 to 9999, with the digits right aligned on the display, it uses multiplexing and the display will appear dimmer than before:

Sources and References

Upgrading the Python Oracle Client

This is a follow up to one of my previous postings: Python and the Oracle Client. The main databases here are being upgraded to Oracle 12 and I’ve taken the opportunity to update the client used by my Python scripts, also its good practice to install new clients when old versions go out of support.

Current Setup

The system I am upgrading here has the following configuration, but this should work with any RPM based distribution, such as CentOS and SUSE :

  • Red Hat Enterprise Linux Server release 6.6 (Santiago)
  • Python 2.6.6
  • python connector: cx_Oracle – 5.1.2
  • oracle-instantclient11.2-basic-
  • oracle-instantclient11.2-devel-

To find the versions of your currently installed software:
$ python
Python 2.6.6 (r266:84292, Nov 21 2013, 10:50:32)
[GCC 4.4.7 20120313 (Red Hat 4.4.7-4)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import cx_Oracle
>>> print cx_Oracle.version

and the Oracle client:
$ rpm -qa | grep oracle


If you have the old versions installed you will need to do some tidying up by removing the client and python connector, version 11 of the client despite being RPM packaged had some non-standard elements. Use rpm to delete the old version of instant client, remove devel first:
$ sudo su
# rpm -ev oracle-instantclient11.2-devel-
# rpm -ev oracle-instantclient11.2-basic-

you may also need to remove the library reference from a previous installation:
# rm /etc/
# ldconfig

to remove the Python oracle connector, there are two methods. Manually, by finding the previously installed package deleting the files and editing the package list:
# find / -name -print
# cd /usr/lib/python2.6/site-packages
# rm -rf cx_Oracle-5.1.2-py2.6-linux-x86_64.egg

now edit the easy-install.pth file
# nano /usr/lib/python2.6/site-packages/easy-install.pth
and remove the line:

Or do it the easy way, if you have pip installed:
# sudo pip uninstall cx_Oracle
easy_install does not have an uninstall option.


Download and install version 12 of the Instant Client and SDK (devel), these can be gotten from: For Linux choose the correct flavour for your installed operating system: x86 or x86-64 for 64bit operating systems, you will need to register on the site gain access the files.
# rpm -i oracle-instantclient12.1-basic-
# rpm -i oracle-instantclient12.1-devel-

Now to install the python connector:
# easy_install cx-Oracle
or, the recommended method:
# pip install cx-Oracle
Installation for the version 12 client is much more straight forward than that for version 11.


A quick test to ensure that the expected versions appear, and that you can connect to the database.
Python 2.6.6 (r266:84292, Nov 21 2013, 10:50:32)
[GCC 4.4.7 20120313 (Red Hat 4.4.7-4)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import cx_Oracle
>>> cx_Oracle.version
>>> ocDB = cx_Oracle.connect(oraConn)
>>> ocDB.version


Water Splash Photography

Two drops of water colliding, frozen in time using the power of high speed flash photography produce an infinite variety of shapes. While this can be done with a pipette, a camera, a single flash gun, practice and good hand/eye co-ordination. I have an Arduino Uno and I am going to use it. IMG_8887What is happening in this picture? Two carefully timed water droplets have been released from above and are plummeting towards a bowl of water. The first drop has hit the water and is rebounding, just as the up-spout reaches its zenith, the second drop collides with the top resulting in a mushroom shaped splat, with the event captured in the camera with a frame of 1/10,000th of a second. In this post I’ll be sharing my experiences in creating these water drop images, I’ll be looking at the photography equipment, electronics, and technique.
up meets down

Photography Equipment

Camera: This can be any DSLR or advanced compact, it must have Bulb mode, and be triggerable by an electronic wired connection, some have an IR remote but I found this to be difficult to setup. Set the ISO to be around 200.

Lens: I use a 100mm Macro, with focus set to manual and image stabilisation off. The aperture is set high, at least f22 to give a suitable depth of field and improve image sharpness.

Tripod: A good solid one with easy to adjust ball head.

Flash: I use up to five flash guns for my photos, two for back light, one to give an under-light through the glass bowl, another for front light and finally one handheld. Rechargeable batteries for the flashes are recommended, I use 2400mAh NiMh Duracells.

The flash guns need to be in manual mode at their lowest power setting, this is to give the shortest duration of flash for the sharpest results. As you increase the flashes power the duration of the light emitted gets longer, causing burred images. On my Canon flash I set it to 1/128 second and on the Nissin Di622 set the EV to -1.5.

6N2A5694  6N2A5698

For connecting the Arduino to the flashes I use a 2.4GHz wireless remote trigger, with four receivers and a modified hotshoe mount attached to the transmitter Look for the Yongnuo RF-602 Remote Flash trigger on ebay, (not to be confused with the remote shutter release).  Most modern TTL flash guns appear to be missing the wired remote trigger connection that you can just plug into.

The flashes also have a built in slave trigger, where it sees that one flash has gone off so it set itself off too. On the Canon flashes this appears to only work in ETTL mode and can’t be used for this, but the Nissins work well.


The frame is bits of wood held together with glue and stands about 75cm high this is to allow the water to accelerate and produce decent sized splashes. At the base is an extra large seed tray, the type without holes, to contain any spillages. This normally has a glass bowl full of water acting as the drip splash event zone. Halfway up the fame is mounted the laser and detector and at the top a reservoir of water and solenoid valve.

The reservoir is a one litre plastic storage tub from Poundland with a hole drilled in the base and a short length of 8mm PVC tubing hot glued into place. The tubing can be difficult to glue as its rather flexible, pushing down a short section of solid tube made from the outer of a disposable biro fixes that. This pipe is connected to the solenoid, observing the correct direction of flow marked on the valve.

The reservoir has a Mariotte Syphon fitted to the lid, this is to provide a constant and stable water pressure to the valve, the pipe from the lid ends about 2cm short of the reservoir base.


The Arduino and control electronics are all set to produce this photo taking sequence:Trigger Prototype

  1. press ‘play’ button on remote control
  2. lights out – dark room
  3. open shutter on camera
  4. solenoid releases two drops of water
  5. drips pass through laser detector – timer started
  6. drops arrive and do their thing
  7. flash guns triggered by timer – picture taken
  8. shutter closed on camera
  9. lights on

The electronic circuit can be broken down into these five blocks; lights, laser, IR receiver, solenoid control, flash control, camera control, each diagram shows the label name for the pin used rather than a pin number. The diagrams can be enlarged by clicking on them.

IR Receiver: The IR receiver allows use of an old TV remote control. My original design was to have a rotary dial and a small OLED display, but this simplified everything considerably. If you don’t have a spare remote one can be gotten from Poundland. I have the Arduino send any text output to a laptop on the USB port.


Laser: Warning: keep away from eyes, permanent damage can occur with exposure to any laser. The laser is used with a photo-transistor to detect drips of water as they plummet to their splash event. I used a small 3 Volt 5mW red laser with a built-in lens, I have added a resistor and diode in series to prevent over voltage as they’re a bit delicate. Although a modified laser pointer will do just as well. The TEPT4400 phototransistor is a type rated for visible light and has higher sensitivity to change than a photoresistor.

laser control
Laser Control

Lights: Warning: Mains Electricity Can Kill, this is to be avoided. If you are uncertain about this part then don’t do it. I rapidly found that working in darkness between shots just made life difficult, and finding the light switch became a hassle. To fix that I got a pre-made 5v Relay circuit and wired this up to a table lamp to provide some illumination. Using a standard wall socket and backbox connect live through the normally open side of the relay, and the neutral and earth to the socket.

 6N2A5700 6N2A5705

Remember to keep the electricity away from fingers (and any other body parts) and water.

Solenoid Control: I use a 12v solenoid, (search for “12v solenoid valve water arduino” on ebay, a couple of sellers have suitable models with connectors included). I use a mosfet transistor to switch the power, this has been detailed in one of my previous blog postings.

Solenoid Control

Flash and Camera Control: The electronics for the camera and flash are closely related. Both use the ILD74 optocoupler to electrically isolate the camera and flash equipment from the Arduino. Although the camera focus connection is not used here I have included it as it may be useful later on.

camera control
camera and flash

The Canon camera has two different types of wired connection on the shutter release depending on the model of camera, a standard three pin 2.5mm jack or a N-3 connector (search for “canon N3 connecting cable” on ebay). A list of connectors for other makes of cameras can be found here.

canon remote
Remote shutter connections for Canon

Sound: Although not used here, this setup works well with a piezo microphone for use with popping water balloons and the like, use a buzzer that is enclosed in a plastic housing with a hole on top and buzzes when DC power is applied. Connect the output to an analogue pin on the Arduino, your software can use a very similar method to that for the laser.

Sound Detect
water balloon pop
Balloon pop with sound detector

Setup and Use

Have plenty of dish cloths or towels to hand, this can get a bit moist. Keep an eye on your camera equipment making sure it doesn’t get wet.

For setting up a shot I use a steel ruler with a magnet stuck to it I set the water dripping to make sure it lands where I want on the magnet, the camera is then focused on the magnet, take away the ruler and you have your properly focused splash event.

Splash Hat on Magnet

Add colour with food dies, adding these to the reservoir seems to work best and keeping the water in the splashdown area clean. Guar Gum thickens the water and makes larger drops and bigger splashes, you only need to add a small amount, about a teaspoon per litre and you’ll need to sieve out any lumps before use. Fluorescein is quite entertaining when used with a UV lamp, adding a green glow to your splashes. Adding diluted water based paints to the reservoir can add a lot of colour, but has a tendency to block the solenoid.

Sparkly backdrops can be gotten from the craft section in stationers. An A4 sized (21cm x 30cm) sheet is normally enough. Try bouncing the flash off the backdrop.

It is all about experimentation, expect to take lots of photos, many of which will be poor. Make notes of timings when you get good results, when you get a good shot, very small changes in timings can produce fairly dramatic effects.


Here is an Arduino sketch, press Play on the remote to start a two drip sequence. adjust the amount of time in milliseconds between the laser detect and flash – flashWait with Volume +/-: +10,-10, Channel +/-: +5,-5, Fast Fwd/Rev: +2,-2, and the time betweenDrips with 4 (+1) and 7 (-1).

Links and Sources

My water drop photos on flickr:

Two Drops of Water