Gokart Tachometer and Speedometer Dials

Hi all,

I spent the winter cobbling together a set of dials for a gokart i built some years back and thought i’d post my results for all to use.

I will say before i begin that i am not an electronics engineer by a long way. This is the most complicated project i’ve attempted and may seem a little rough around the edges. I also wanted to make the most of what i already had (i.e. the old dials).

The dials each have a modified Arduino to calculate the speed and RPM and drive the dial motors themselves. I used a set of old motorbike dials (not stepper motor type) which are driven with PWM with the help of a small transistor. The speed is calculated from a pulse from a Honeywell 3GT101DC/3GT102DC gear tooth sensor on the rear axle chain sprocket. The RPM is calculated from a pulse from the existing tachometer line from the engine TCI unit with the help of a little cleaning circuitry.

I also added a change-gear LED, an neural gear indicator LED and the ability to read/control/recalibrate the dials with the I2C bus. The I2C bus also has a Arduino Diecimila connected with a 16x2 LCD module and a few buttons. This is unfinished and serves only to fiddle with some other settings.

I particularly owe a lot of the theory to:

SecretsOfArduinoPWM Secrets of Arduino PWM by Ken Shirriff
Arduino 101 - Timers and Interrupts http://letsmakerobots.com/node/28278 by RobotFreak

I’ll try to explain how it works.

The tachometer uses a LOW VOLTAGE pulse from the engine TCI unit from a line that was intended to drive a tach. The dangers of a vehicles ignition system are well known and the voltages can easily brick your circuits and perhaps you! Most people recommend not connecting to a vehicles ignition system ever because they vary between manufacturer/model and there are DANGEROUSLY HIGH VOLTAGES INVOLVED!!! Warned!

This pulse is sent into a 200k variable resistor which is used as a adjustable voltage divider, the output of which is fed into a HEF40106B inverting schmitt trigger. This inverted output was connected to hardware interrupt 0 (arduino digital pin 2). The speedometer is connected directly from the 3GT101DC geartooth sensor to hardware interrupt pin 0.

The outputs were simply a 2N3904 transistor connected in a motor driver arrangement with a 1N4001 diode connected across the output to ground any back current and a large low capacitance capacitor connected across output to smooth the PWM noise out. I also added a 20r variable trim pot in series with the motor to add and remove resistance. This was so i could have control over the maximum point the needle reached at full power.

Any other components were to facilitate the use of LEDs, buttons/switches and the I2C bus.

The programs work very similarly buy running the 16bit timer1 at 250 000hz. When a pulse from either the engine, in the case of the tach, or the geartooth sensor, in the case of the speedometer, triggers interrupt 0, the timer is read and reset. Because the frequency of the timer is known, and it is known that for each pulse the engine has rotated once, or that the wheels have turned a known amount(translating in to distance traveled) the value read from the timer can be used to calculate the speed or RPM.

When timer1 fills to its maximum value another interrupt is called to zero the RPM or speed. This is for when the time between pulses is too long or when they stop all together.

Once the RPM or speed values are calculated it attempts to translate it into a PWM output level that corresponds with the needle pointing at the right place on the dial. This was the biggest headache on the project because the dials are far from linear, leading to the long if statements and varying values depending on whether the needle was moving up or down at the time.

I hope the sketches make sense…ill post them after this one…

I tried to make the Arduino do as little calculations as possible. Which is why there is such a ridiculous way of calibrating the speedometer for wheel size. I tried to use some conversions and logic to come up with the ‘speedDivider’ and it appears to be pretty close to correct. Any other suggestions would be welcome.

Also it i know it may seem pointless using 2 separate ATMega168s to do the job that one could comfortably do. The problem i had was of clashing interrupts causing the odd random reading to be massively incorrect. When both the speed sensor and spark pulse both happen at the same time one of the interupts would be missed and the counter would not be stopped,read and reset like it should. So in the end it was much simpler to just build two boards with a shared powersupply.

Any suggestions questions are welcome.

Thanks for reading.






speed_only_working_25_01.ino (13.8 KB)

rev_only_working_15_03.ino (16.9 KB)