Robostix tachometer

This page describes one way that you could provide a tachometer function using the Robostix.

Source Code
The source code is available from the SVN repository. Files from the Common directory are also used.

Sensor
Pretty much any type of sensor device can be used. I chose to use a QRB1134 reflective optical encoder.



The above picture was created using TinyCAD. The TinyCAD file is available here. The TinyCAD library file for the QRB1134 sensor is here.

The program uses the input capture feature of Timer3 in order to obtain timestamps for pulses from the encoder. So the above sensor would plug into the INT7/ICP3 (labelled as INT7 on the Robostix).

Here's a photo of my assembled sensor, along with a motor being tested.



The single letters (O, G, W, B) in the schematic correspond to the wire colors. The QRB1134 comes with 24" of wire preattached.

Test pulses
In order to facilitate testing, Timer2 is setup to generate a known frequency pulse stream. Timer2 is configured to use CTC (Clear Timer on Compare Match) mode, which causes the generated frequency to be given using this formula: fOCn = fclk_IO / ( 2 x N x ( 1 + OCRn )) where N is the prescalar factor, and fclk_IO is the CPU frequency (16 MHz). N was chosen to be 1024. OCR2 is an 8-bit register and can have the values 0 thru 255, so this gives a range of frequencies of 7812.5 Hz (when OCR2 is 0) to 30.5176 Hz (when OCR2 is 255). The OCR2 signal is available on the pin labelled PWM1C (it shares functionality with OC1C).

Theory of operation
The SIG_OVERFLOW3 interrupt occurs whenever Timer3 overflows. This is used to increment a 16 bit counter, which effectively widens the timer to a 32 bit timer. The SIG_INPUT_CAPTURE3 interrupt occurs whenever an input capture occurs (i.e. rising edge detected). This causes the current timer value to be saved. The interrupt handler combines the 16 bit capture time with the 16 bit overflow counter to create a 32 bit timestamp, which is stored in a circular buffer. It also toggles the blue LED each time a capture interrupt fires.

The main loop runs 4 times per second. Each time it runs, it toggles the red LED. It averages the times from the last 4 samples in the circular buffer and calculates the RPM. The RPM is reported on UART0. If you use the test pulse, with a cycles/rev of 1 and OCR2 of 255 (the defaults) then you should see a reported RPM of 1831.

You can press the 'C' key to change the cycles/rev factor, in case your encoder has more than one stripe on it. This factor is persisted in EEPROM. You can press the 'O' key to change the OCR2 value for the test pulse. This is also persisted in EEPROM.

Fuses
The default fuse configuration has EEPROM being erased everytime a chip erase cycle occurs. Using AVR Studio, you can check the "Preserve EEPROM memory through the chip erase cycle" to prevent this erasure from happening. For those using uisp, you would change the -=wr_fuse_h=0xc9 to be -wr_fuse_h=0xc1 instead (if you're using the defaults).