Sunday, 25 May 2014

Improved Arduino Frequency Counter

I built a Simple Arduino Frequency Counter last year, and it's been quite a useful project. Over the time it's been in use, I've been tinkering with it to improve the display and accuracy. This started off with a simple display of the frequency in Hz. I modified the code slightly to add some commas to make it easier to read:
That's how it stayed for a while. I'm now building a signal generator, and I thought it would be good to include this on the front panel, so I tidied the layout further and added a display of the signal period (1 / frequency).
I had noticed it seemed to read a little low, so I revisited the code to improve performance. The original worked by setting up an internal counter to count pulses coming into one of the pins. It waited one second, then read the counter. The count was taken as the frequency, the display was updated and the counter reset. I've now gone for a different mechanism, an interrupt driven approach, similar to that in this forum post.

I've altered that slightly, and now what it does is enable an interrupt on change on a pin. When that is triggered, it stores the start time. It then changes the interrupt to go to a different routine, and when that is called, counts pulses and stores the time of the last pulse. It then waits one second again and calculates the frequency, based on the time between the first and last pulse, to improve accuracy. As per the follow up to that forum post, I've taken into account ignoring the initial isr call as this may happen if the pin is high when the interrupt is enabled. I've done this with a third isr, again trying to keep the code in there down. The new code can be downloaded here.
The circuit remains very simple, basically connect the input to pin 2 (interrupt 0), and connect an LCD display however is most convenient, and alter the setup call to the standard Liquid Crystal library as appropriate. On breadboard, I used the pins nearest the display.
When transferred to a circuit board, all that is required is the ATMega328P, 16MHz crystal and 22pF caps, some 100nF decoupling caps and a main 47uF cap. The 10K multiturn pot is LCD contrast, overkill for what is required, but it fits neatly with the layout.
Add connectors for power, signal and the LCD. I used two 6 pin connectors as the central 4 pins of the LCD are unused. Again, these are wired using the  nearest and most convenient pins. The R/W pin is optional as it is always pulled low, but again for convenience, I connected that to a pin on the boarded version. The 6 pin 'stackable' connectors are used for arduino shields, but are ideal here as the long pins can be bent to make contact with the ATmega328P, reducing the amount of wiring to very little, mainly point to point using component leads.
I programmed the ATmega328P using the Arudino IDE and 'upload with programmer' and my trusty USBTinyISP. Then just install the LCD module, a standard HDD44780 based 16X2 LCD (in this case white on blue for a change) and connect up an input.
There is no input protection here, as it is intended to be used where the input is coming from a TTL chip in the same piece of equipment, using the same power supply. If you plan to use this with an external input, some protection and buffering would be required. This is left as an exercise for the reader.

Saturday, 3 May 2014

ZX81 and ZX Spectrum USB Keyboard PCBs

I've made quiet a few USB keyboards over the years out of broken ZX81s and ZX Spectrums, and they continue to be popular. The design has evolved quite a bit since my first ZX81 version, hand wired on pad board with an ATMega328P and software written using the Arduino tools.
A while ago a designed a board for the larger USB keyboards, like the Commodore 64 USB Keyboard.
Whilst I have used that PCB on ZX Spectrum builds, it is a bit large, and has a number of unused I/O pins, being based on the 44pin ATMega32u4.
Since the ZX81, ZX Spectrum (and ZX Spectrum+) only have an 8x5 keyboard matrix, I've designed a new smaller board with the 32 pin ATMega8u2, which has enough I/O pins for those computers, with a few spare.
The connectors are laid out to fit in the ZX81, with a USB connector going out the expansion port.
The keyboard membrane tails plug directly into the board, mounted at a slight angle on the underside of the lid.
The ZX Spectrum membrane tails are spaced further out, to these are connected via sockets on ribbon cable.
One connector can be directly connected, but it is tight, and there is insufficient height for a full size USB socket.
The next plan would be do design a long thin version for the Spectrum to avoid the need for the flying leads.
All of these keyboards are available to buy with or without internal Raspberry Pi at my Etsy store.

Update: The long, thin Spectrum specific boards are now available.