Category Archives: Arduino

Rebuilding the Vacuum Fluorescent Display

Back in April 2016 I posted details on how a Vacuum Fluorescent Display (VFD) works and a method of driving it from an Arduino type microcontroller using transistors, while this worked well it made for a rather bulky clock. I have now rebuilt the display using proper VFD driver chips, added a rotary switch with LED’s, NeoPixel capability and used a WeMos D1 Mini microcontroller to give me internet access over WiFi so the time and date can be set using the Network Time Protocol (NTP).

VFD Clock

This rebuild is much more practical than previously, it is now about 3cm deep and comprises of two boards back to back with pin header plugs/sockets as the interconnects. I have been running the clock for over a year without any problems, apart from having to switch the thing off and back on when Daylight Savings Time changes in the spring and autumn, but that’s a software (lazy programmer) problem.

Power Supply

Three different voltages are needed to operate this clock, 16 Volts for the VFD display anodes, 5 Volts for the microcontroller and NeoPixels and 3.3 Volts for the VFD cathode and other hardware.

Power layout for the VFD clock

From the 12 volt source, I split the power to a XL6009 boost module to supply 16V to the driver IC’s, the 5V power module can supply up to 5A which is enough for around 2 meters of NeoPixels. The 3.3V supply is created using a BA033T fixed voltage regulator running from the 5V module, I have used this to power the VFD cathode, the rotary encoder and VFD driver IC’s as this is the microcontrollers operating voltage.

Back of the VFD Clock

Driving the Display

To drive the anodes on the VFD display I used three MAX6920 Tube Drivers, these have a four wire serial interface and can switch up to 76V on the display.

MAX6920 VFD Driver

The physical connections from the driver IC’s to the VFD anodes (grids and elements, see the previous article for definition) are those that are most convenient for the PCB layout without having to use links or through-hole connections as the order of the pins for outputting the display can be mapped later in software.

MAX6920 Anode Connections on the PCB

In this case, the first anode pin on the display is on the right, but the serial data starts with the first MAX6920 chip on the left. I will explain in more detail in the software section below.

The Cathode is run from the 3.3 Volt supply, it has a 3.3V Zenner diode across it to protect against meltdown in case of over-voltage, the cathode is made from of strands of thin tungsten wires and shows as a short when testing in beep mode on the multimeter.

Zenner Diode for the VFD Cathode

Rotary Switch

I have used the SparkFun RGB Illuminated Rotary Encoder, as well as the encoding it also includes three LED’s and a push button switch. As the WeMos only has limited number of pins available, I used an MCP23008 I2C I/O Expander. I have covered these encoders in a previous post and have used a similar method here.

Rotary Encoder on the I2C Bus

In this project it turned out I don’t have much use for the rotary switch, the same result can be achieved with a push button and two LED’s, it goes red when setting the time over WiFi, goes green when the time has finished setting but is off when running normally, the push button displays the date when pushed. I expect the encoder could be used for setting an alarm should I ever have need to add one.

Software

The complete source code I am currently running in the clock can be found on my github repository, it has been written for the Arduino platform and can be considered unfinished and a bit of a mess. In almost all cases this clock will be a custom build with all the scavenged VFD displays being different I’ll be concentrating on how the display is being driven. Note that the software uses Latch and the MAX6920 driver chip uses Load.

To start, here are the physical connections for my VFD display, the display connections are shown looking from the back with pin one on the right, on the anode there are eleven grids and twenty-one elements, each grid illuminates a block of chosen elements. There are three MAX6920 driver chips, the first is on the left data is passed along the serial data line DIN/DOUT to the right:

Connecting the MAX6920 drivers to the display

While I’m not going to worry too much about how the data is sent to the display as this is being handled by the ShiftOutX library it may be useful to have an understanding of the byte order sent to the driver chips.

Breaking out the logic analyser we can see what is going on, in this first image below we can see that between the two markers one and two there are eleven data peaks to match the number of grids on the display the data is processed as a padded eleven character string: ‘    212848 ‘ the first four contain nothing but the bit selecting grid to be used the next six are busy as they contain the time, and the last is blank. There also appear to be two blank clock cycles after these, this may be a programming error on my part.

Data being sent to the display

the string is iterated so that each grid gets its own character with a very short delay between each this causes the persistence of vision effect and the time appears on the display.

In the next screen capture I have zoomed into more detail, it is showing the fifth grid and is displaying the number two. You can see that there are thirty-two clock cycles sent to the drivers while LOAD is high, this causes the driver chips to direct the data to the outputs. I am not entirely sure why the clock is being run while LOAD is low, I think it may be clearing the buffer before sending the required information.

Data being sent to a grid

You can see that 32 bits are sent to the display, but there are 36 pins available on the three MAX6920 drivers, you can also see that the outputs are arranged out of order. How do the drivers know which lines to switch for the display?

First off, an explanation of how the data is constructed then sent to the display. For this example I am sending the number five to the third grid, the data is constructed through the manipulation of a character array in three stages:

1. blank char array: 00000000000000000000000000000000
2. set the third grid: 00000000000000000000000000000100
3. set the number: 00111000011000011100000000000100

Because of the way the bits are ordered when sent to the drivers I have a lookup array VFDlookup to make life easier, in this case grid 3 can be found at position 29 in the VFDdata character array. I start with a blank character array of 32 bits VFDblank and copy this to VFDdata, I then use VFDlookup to find the position of the bit to set: VFDlookup[3] = 29. For the elements the encoding for each character is set in VFDdigits the code for number 5 is 1110000110000111 the code was worked out by experimentation, seeing which element lit up after I had completed the hardware, I have ignored the extra symbols used for the DVD player so I only need to set pins 15-30. Once complete the character array is converted to a unsigned long integer and sent LSBFIRST – Least Significant Bit First via ShiftOut_32.

While that explains the elements encoding to display the correct digit, the grid selection however is a different kettle of fish. I built this clock over a year ago and have forgotten how it works. Grids 1 and 2 are connected to the output pins 1 and 0 on the third driver, pins 2-5 are then skipped, and the rest are connected to the grids, with three more being taken from chip 2. I can’t work out how it knows to skip those pins, or that grid 2 is connected to pin 1. But it is an awesome clock though.

Links and Sources

The Fridge Door is Open

My fridge door tends to rebound when closed staying open a smidgen and letting all the cold out. Rather than just checking that the door is properly shut, I thought it about time to have a microcontroller make a noise when the door has been left open too long.

This circuit uses an Arduino compatible Teensy LC for all the work, it has a phototransistor to sense the state of the fridge door light, a couple of LED’s one to indicate the power and another that comes on when the door is open. There is also Piezo buzzer to make an annoying noise after forty five seconds of door open time. The unit runs of a 3.7v rechargeable Lithium-ion battery and I have added a recharging circuit that takes power via the Teensy’s 5v USB port.

Circuitry

Note: These diagrams show 3.7v as the supply voltage. The Teensy LC can only tolerate a maximum 3.3V on the data pins, so these circuits are driven from the 3V output on the Teensy. They will all work without modification on the 5v Arduino Uno.

I have used a phototransistor to detect the fridge door light, there are two variants of this circuit light activated or dark activated, the 100k resistor can be replaced with a 100k variable if you need to adjust the sensitivity, the 330k resistor provides a weak pull-down on the output. The phototransistor is being used in switch mode to provide a logical output (rather than active mode which provides an output relative to the amount of light), so the output is connected to a digital input on the Arduino. The BC547 transistor is half of the darlington pair to provide extra gain on the output.

Dark Activated Switch
Light Activated Switch

I chose the light activated switch, either will do but will provide different logical outputs to your controller. The circuit is enclosed in a small box inside the fridge and connected by ribbon cable to the controller, the ribbon cable is flat and does not upset the magnetic ‘seal’ on the fridge door.

Component Connections

To make some noise I used a piezo buzzer from an old computer, this is driven through a transistor as the Teensy does not provide enough current to drive it directly.

Piezo buzzer

There is also a push button to provide a reset function if the buzzer is sounding while the door is open.

Push Button

I have also added two LED’s, one to show power and anther that illuminates when the door is opened.

Power and door LED’s

The final circuit if for recharging the battery, it connects to the 5V connection on the Teensy LC so charges the battery when the USB connection is in use. This has been copied from the MCP3831T datasheet.

Battery Charger

Software

This uses an interrupt to listen for the light sensor, when the state changes, the door open pin is read to determine if the door is open or not. If it is then a timer is started, this gives you forty five seconds to complete your task before the alarm sounds. With the door closed the timer is stopped and set back to zero. If the sounder goes off while you are rummaging in the fridge the reset button can be pressed, this restarts the timer from zero again.

 

Links and Sources

A Box for my Pixles

This all started with wanting to modify a cheap camping light by replacing the LED’s with some colourful NeoPixels. I made a Printed Circuit Board to match the existing PCB disc that held the LED’s, as well as a board for an ATtiny85 microcontroller which incorporated a microphone and vibrating motor of the type used in a old mobile phone. The battery and charging circuit came from a cheap (Poundland) USB powerbank but it turned out that the battery from the powerbank didn’t fit in the camping light how I liked (in a measure twice, cut once sort of thing). Instead I made this:

Hacking the Yongnuo Wireless Controller

I wrote this back in May 2017 but it was never finished, I got distracted by other things and I needed the wireless controller for photography. I wrote all this and it would be a shame to delete it, so I am posting it now on the chance there may be of something of interest within.

I use this Yongnuo Wireless Controller in photography to control a number of flash units away from the camera body. It comes in two parts, a transmitter that connects to the hotshoe on the camera and receivers with a hotshoe that connect to the flash, a single transmitter can control any number of flash receivers within the claimed 300 meter range. The transmitter with a couple of receivers can be gotten of eBay for around £35.

Yongnuo Wireless Controller FSK 2.4GHz
RF-600TX transmitter
RF-602RX receiver

[image of transmitter and receivers]

I am looking to:

  • See how the flash is connected
  • Investigate how the transmitter works – reverse engineer as much as I can
  • See if I can control the transmitter directly with an Arduino
  • See if other devices using the same radio chip can also be controlled
  • Not destroy the transmitter while examining it

Opening it up

[images of the transmitter insides]

On the board inside you will find:

  • A power on/off switch
  • Bi-colour Red/Green LED
  • A dual-press button with two switches for operating the flash manually
  • A four way code selector (4 way DIL switch)
  • An anonymous (no markings) microcontroller – µC
  • A7105 2.4GHz FSK/GFSK ISM band wireless transceiver

On the underside, my board is marked with the following version and date:

Version: 1.21
Date: 14/04/23  – 23 April 2014

Looking at the datasheet for the A7105 it can work as both a transmitter and receiver and uses an SPI interface for user control, it appears to be popular with the radio controlled RC aeronautical drone community. The receiver looks to be very similar by way of components, using the same radio chip and anonymous microcontroller. I have not examined it in any detail and take care if disassembling as there are three hotshoe connections that need to be desoldered.

Receiver Insides
RF-602RX receiver

Flash Connection

On the Canon camera the hotshoe has six connections but we only need to examine three of these. Looking down on the camera with the lens facing away from you, the main plate where the flash slides in is ground, the large central dot is the flash trigger just below this on the left is the camera ready connection. I assume the rest are for the E-TTL functions and I have not looked at these.

Canon Hotshoe Connections
Canon Hotshoe Connections

Checking the hotshoe with a multimeter, the flash trigger appears to have a high resistance that decreases when the flash is fired, I suppose this is a legacy of when cameras were more mechanical. The Camera Ready connection goes High – around 5 Volts,  to tell the flash to wake up, that you have pressed the shutter halfway, the lens has focused and you are about to take a photo.

To find the duration of the flash signal on the cameras hotshoe I connected an almost flat AA battery between ground and flash to give me 1.2 volts to measure against on the oscilloscope (checking a canon flash itself, the voltage across the flash pin and ground is 4.47 volts). I found that the flash signal is sent by the camera for 352ms, which is quite long considering that a typical shutter speed of 1/125 second for flash photography works out at 8ms, although the amount of time a flash fires for is set on the flash and not by this signal.

Capturing the flash event
Capturing the flash event

Microcontroller Connections

I spent a while tracing out most of the transmitter circuit, I have ignored most of the supporting radio circuitry and the crystal timer as I am wanting to investigate the data side. The parts are also rather small and troublesome to investigate with standard multimeter probes.

RF600TX - Partial Schematic
RF600TX – Partial Schematic

The microcontroller looks to use internal pullup resistors for the input switches, the camera ready signal from the hotshoe switches a transistor to pull pin 16 low on the controller.

Looking at the circuit diagram we see an output to the antenna from pin 8 of the micro controller. This outputs two different square waves when the shutter button is pressed, one for camera ready and another for flash. I think these are being modulated on the transmitter output to produce a radio signal and simplify the transmitter design. Looking at the output from pin eight on the oscilloscope, the two states can be seen quite clearly:

Camera Ready signal
Camera Ready signal
Flash signal
Flash signal

These square wave outputs are always the same, I thought it may change when a different code was chosen through the DIL switches. The transmitter unit does not receive any radio data, and no acknowledgement is made by the flash units.

Using a Logic Analyser

Time to break out the Logic Analyser, this is a cunning device that allows you to see the data being exchanged between the microcontroller and transceiver, I don’t want to get too detailed but think this may help for the following sections.

The data system being used by the A7105 is SPI. The Serial Peripheral Interface bus uses four wires: Chip Select SCS, multiple chips can be on the same SPI bus, but they all have different SCS connections, the master controller chip uses SCS to tell the slave chip it wants to use for data exchange. Serial Clock SCK: This is used to provide time synchronisation for the data exchange with a fixed duration for the highs and lows. Data SDIO: This is the data being sent by the microcontroller and GIO1 is data from the transceiver sent in reply, normally for SPI this is 8 bits, to make a byte.

The naming conventions used here are from the A7105 datasheet, The SPI bus has standard names for data lines; SDIO is MOSI – Master Out/Slave In, GIO1 would be MISO – Master In/Slave Out and SCS is SS – Slave Select. In our case the microcontroller would be the master and the transceiver the slave.

SPI Single slave
SPI Single slave

The Logic Analyser displays data in a form that allows you to see the logic, here we can see two bytes of data:

SPI example
Example of SPI data

The microcontroller – µC sends data on the SDIO line and listens for replies on GIO1. When the µC sets Chip Select SCS low this tells the transceiver that the µC wants to talk to it. The µC sends a command byte followed by one or more bytes of data – a packet. During the SCS event, data is only transferred while the clock SCK is running.

SPI data, binary data from the highs and lows
SPI data, binary data from the highs and lows

We can see that the logic on the SDIO is read every-time the clock goes low, falling edge, a clock tick on the SCK line represents a bit of data, eight ticks make a byte. We now have our binary data: 00100101 for convenience this is converted into hexadecimal 0x25.

When examining an SPI bus check any available datasheets to see if the clock is set to tick on a falling or rising edge, the bit order is Most Significant Bit – MSB or Least Significant Bit – LSB, and the data length (normally eight).

Looking at the A7105 Transceiver

A7105 Block Diagram (a clearer version can be seen in the datasheet)
A7105 Block Diagram (a clearer version can be seen in the datasheet)

From the A7105 datasheet the SPI bus is set for the following:

  • To activate SPI, the SCS pin must be set low
  • data length: 8 bits
  • bit order: Most Significant Bit First (MSB)

I have made the following connections to the transmitter. Soldering test leads to the microcontroller (µC) is the most convenient place to do this.

Connections to the Logic Analyser
Connections to the Logic Analyser

This table shows the Input/Output pins on the transceiver and microcontroller, as well as the colour of wire used for the logic analyser.

A7105 Description In/Out µC Wire Colour
11 SCS 3 Wire Chip Select I 9 yellow
12 SCK 3 Wire Clock I 10 orange
14 SDIO Read / Write I/O 12 brown
16 GIO1 4 Wire SPI Data Output I/O 11 red
17 GIO2 4 Wire SPI Data Output I/O 13 white
GND Ground black
Trigger Out O 8 grey

How the A7105 organises data

The transceiver has two data modes, Strobe and Control. There are eight strobe commands to control the various modes the chip supports, these are four bits in length and always begin with a 1, where the transceiver is being operated in 8 bit mode the final four bits are ignored. The Control registers are eight bits in length and are used to configure and read settings from the transceiver, they are eight bits in length, the first bit is always 0 and the second is either 1 for write or 0 for read. The table below shows examples of a write, a read (or more accurately a request, the transceiver replies on GIO1) and a strobe command sent by the µC.

Address Byte Data
Bit: 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0
Control: CMD R/W Address Data
Write Example: 0x2 0x1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1
Read Example: 0x42 0xff 0 1 0 0 0 0 1 0 1 1 1 1 1 1 1 1
Strobe: CMD Strobe ID not used not used
Example: 0xa0 1 0 1 0 0 0 0 0

Examining the A7105 data

Data is exchanged on the SPI during two events, after the transmitter has been switched on, and when you are pressing the camera shutter or the button on the unit.

Power On

Extract of the SPI power on data showing SCS event 48, see the spreadsheet for more details
Extract of the SPI power on data showing SCS event 48, see the spreadsheet for more details

When you first switch on the unit, the microcontroller initialises the transceiver with a few hundred bytes of data, I have created this spreadsheet from the SPI data, hex data across is the most useful sheet to view:

In summary the initialisation sequence consists of the following

  • The microcontroller sets the majority of control registers to default
  • Internal calibration is started and the microcontroller keeps checking until this is done
  • Final cleaning up
  • Place the A7105 into standby mode

Shutter Press

On the SPI the shutter press action has two distinct stages, the preamble and the transmission. The preamble takes the camera out of standby mode and sets the channel it is going to be transmitting on. The transmission broadcasts the camera ready and flash states.

The Preamble
At the beginning of the datacaptue I see a preamble packet sent over the SPI:

Logic Analyser Data - first five bytes of the Preamble Packet
Logic Analyser Data – first five bytes of the Preamble Packet

This preamble looks to only appear when the flash is first operated after the transmitter unit has been switched on, subsequent use goes straight to transmit. The fifth byte changes depending on the DIL switch setting on the underside of the unit, as you can see in the four examples given in the table below.

bytes
DIL switch strobe control data strobe
0000 0xB0 0xB0 0x05 0xB5 0xF0 0xD0
1000 0xB0 0xB0 0x05 0xB5 0xE1 0xD0
0100 0xB0 0xB0 0x05 0xB5 0xD2 0xD0
1111 0xB0 0xB0 0x05 0xB5 0x0F 0xD0

Taking the first example, we can break this down to see what each byte is doing

SCS Packet IN/OUT Command Payload binary
0 0xb0 STROBE PLL Mode 0b10110000
1 0xb0 STROBE PLL Mode 0b10110000
2 0x5 0xb5 0xf0 IN FIFO Data TX data 0b00000101 0b10110101 0b11110000
817µs gap
3 0xd0 STROBE TX Mode transmission begins 0b11010000

It is difficult to work out what is going on here, according to the datasheet you send a packet of data 0xb5 0xf0 to be transmitted to FIFO Data 0x5 and follow that with the strobe command TX mode 0xd0, but what is transmitted bears no relation to the FIFO packet.

We need to look further back in the initialisation sequence and the datasheet, the A7105 has three modes of transmission; easy, segment and extension. We need to undertake a little bit of detective work to find which this is. Chapter 16.4 of the datasheet shows us the two registers used in the initialisation sequence we need to examine:

Bit: 7 6 5 4 3 2 1 0
FIFO I 0x3 FEP7 FEP6 FEP5 FEP4 FEP3 FEP2 FEP1 FEP0
Setting value: 0x1 0 0 0 0 0 0 0 1
FIFO II 0x4 FPM1 FPM0 PSA5 PSA4 PSA3 PSA2 PSA1 PSA0
Setting value: 0x0 0 0 0 0 0 0 0 0

The datasheet does not say directly so we need to go through each modes description to see which is the best fit. Segment FIFO looks good: “In Segment FIFO, TX FIFO length is equal to (FEP [7:0] – PSA [5:0] + 1). FPM [1:0] should be zero”. So our settings: (FEP:0b1PSA:0b0) + 1 = 2. The number of bytes sent our FIFO Data packet is also 2.

Further reading of the description “This function is very useful for button applications. In such case, each button is used to transmit fixed code (data) every time. During initialisation, each fixed code is written into corresponding segment FIFO once and for all. Then, if button is triggered, MCU just assigns corresponding segment FIFO (PSA [5:0] and FEP [7:0]) and issues TX strobe command.”

The Transmission
Taking an initial look at the data gathered during a shutter press on the Trigger Out (pin 8 of the microcontroller) we can clearly see the transition from Camera Ready and Flash as we saw on the oscilloscope earlier.

Logic Analyser Data
Logic Analyser Data

GIO2 shows a mirror of the Trigger Out, but zooming in to the data and I see that it follows the Trigger signal. Looking in the initialisation spreadsheet at SCS event we see that the command 0xc 0x1 was sent for setting the function of the GIO2 pin. Looking at the datasheet this appears to be set as an ‘I am transmitting’ signal, WTR – Wait until TX or RX has finished. If I force GIO2 low by sorting it to ground then the flash does not fire when I press the shutter

Logic Analyser Data
Logic Analyser Data

In my data capture the Camera Ready signal was transmitted six times, and the Flash signal thirteen times, I am sure this is dependant on the length of time I had the shutter button pressed on the camera.

Apologies for the inconclusive ending, I ran out of time to pursue this further

Links and Sources

Using Phototransistors

With one of my electronics projects I am wanting to add a couple of phototransistors to make a crude movement sensor and to do this I first need to discover the best way of using them. A phototransistor is sensitive to the amount of light falling upon it, as this increases higher current is allowed through the device. This in turn can be used provide a variable voltage to an analogue input on your microcontroller.

For this posting I am using two different phototransistors, the SFH3710 is a surface mount device smaller than a red lentil and the TEPT4400 is through hole and looks like small white LED and is easier to prototype with, they are both NPN transistors made to respond to visible light at wavelengths around 570nm.

left TEPT4400, right the SFH3710 mounted in stripboard for prototyping

Connecting

A bias, or load, resistor is required to produce an output (VOUT). This can be above or below the phototransistor.
Common Emitter
The resistor RC acts to pull-up the voltage, as light increases the output voltage drops.

Common Emitter

Common Collector (Common follower)
In this case the resistor RE acts to pull-down the voltage, as light increases the output voltage increases.

Common Collector

Phototransistor Modes

The Fairchild Semiconductors application notes describe the two modes that phototransistors can be used in; switch and active. The mode is set by the value of the load resistor RL:

  • Switch Mode: VCC < RL x ICC
  • Active Mode: VCC > RL x ICC

Where :

  • VCC = Supply Voltage
  • RL = Load Resistor (Rc or Re)
  • ICC = Maximum anticipated current

In switch mode the transistor is either on or off, this ‘digital’ output is useful for object sensing or object detection, typically a resistor value greater than 5kΩ is adequate, the output in the ‘high’ state should equal the supply voltage, and for ‘low’ the output should be below 0.8V.

In active mode the output is variable, giving a value related to the amount of light. To use this a low value resistor is required to prevent VOUT exceeding the supply voltage, using Ohms Law you can find the maximum resistance, the value above which the transistor may respond in switched mode: Rmax = VCC / ICC, so: 5v / 4mA = 1.2kΩ. Connected up as Common Emitter, selecting a resistor value 30% below this to ensure a margin of error a 875Ω should give 4.5V at the output when completely dark, dropping to below one volt when saturated with light.

The drawback with active mode is that phototransistors have a non-linear response to light, as light increases beyond a certain level their output will suddenly jump and then flatten out, other factors, such as the ambient temperature and the type of light (daylight, fluorescent tubes, LED’s, etc) also affect the value of the output.

Practical Experiments

I want to test that the above is actually true, this circuit uses a white LED pointed at a TEPT4400 along a short piece of black straw to act as a stray light shield. The LED brightness is set using PWM on the Arduino. The phototransistor is setup for Common Emitter output, so the output voltage will drop as the light increases. For active mode RC was set to 220Ω and for switched mode this was 10kΩ.

Phototransistor Test Circuit

The code below uses PWM to fade the white LED up to full brightness, the reading taken from the analog port is a majority candidate reading, where from the ten readings made the one that occurs most often is used as the phototransistor output bounces around, I think this is caused by the PWM, the results are output on the serial port for use in a spreadsheet.

From the output, I was able to produce these graphs, remember that for the Common Emitter setup being used the voltage drops as the light increases, not quite getting the smooth response to light/time I was expecting.

With 10k resistor

With 220R resistor

I am not sure why I got these results, they were consistent and I suspect my test setup. Some more experimentation is needed, but for now I have run out of time.

Links and Sources

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
Mark
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.

Symptoms

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 “Arduino.app” 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

Cause

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

Fix

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.

Hardware

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.

Software

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.

Data

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}\]

where:

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