Hi everyone,

I'm relatively new to arduino, and exploring a possibility to fix a screw up I did when rebuilding my transmission on my hobby car.

I forgot to check my speedometer cable drive after a total transmission havoc, so that ain't working...

I figured I could exorcize myself with this project and the same time fix a problem.

So the ground idea is to make a motor spinn the speedometer cable, and use GPS for controlling the speed.

After some reading, it seems feasible to use a arduino UNO, a GPS ultimate shield, and a motor controll shield.

From my reading the code from motor shield runs the motor in (pwm) speed "steps" from 0 to 255.

So in theory, the ideal solution is to make a reference to maybe 100kmh on a handheld GPS while a friend is driving the car and keep at that speed on the highway, then adjust the offset in the code you have to whatever it is for making the needle hit and stay at 100kmh in the speedo cluster.

But my question is this, is it even possible?
Because I don't find any information on the GPS ultimate shield for speed, just location.

Happy for all help (and learning)

Yes, it's possible. Most GPS navigation systems can estimate your speed. It's just a matter of maths.

You might want to use a stepper motor to drive the speedo, so you can accurately control the motor speed.

But this all sounds like a very complex way to go about it. Can you remove the mechanical parts of the speedo and attach a 270° servo motor directly to the needle?

PS. exactly what kind of supernatural entity are you possessed by? An Arduino can't really help much with that problem.

Ok, do the GPS shield even deliver speed signal to the arduino UNO?

Maybe a stepper motor is better to use than a regular DC motor, due to counting "steps", understand the logic in that sentence, but can they handle constant rotation that it would require to drive the speedo cable?

Haha, not possessed at all, but seems like a fun project, that also can give me some learning :slight_smile:

try adafruit

They are the stepper motors used in current car dashboards.
An application


Tom... :slight_smile:

Thanks for the tip,
However, I doesn't apply to my application, as this would have to sit in the speedo cluster itself.

I am looking for a way to rotate the speedo cable in the engine bay, and keep gauges original :slight_smile:


I forgot to check my speedometer cable drive after a total transmission havoc, so that ain't working...

Usually you have a metal helical gear on the output shaft of the gearbox, and a nylon or other wearable material gear on the speedo cable.
The helical gear is just about indestructible when you consider what it drives, what did you stuff up?

Tom... :slight_smile:

Hi,Usually you have a metal helical gear on the output shaft of the gearbox, and a nylon or other wearable material gear on the speedo cable.
The helical gear is just about indestructible when you consider what it drives, what did you stuff up?

Tom... :slight_smile:

That's correct, however when my tranny said bye bye the differential and some other parts blew out of the casing...

I then rebuilt another one, strengthened and with a lsd differential, and a better clutch.
So now the problem is that the engine is twisting itself out of the mounts instead, but that's another story :slight_smile:
At this point the helical gear is eating my drives, because it's either not aligned properly or it's missing a tooth that I didn't recognize when building the new tranny...

So, instead of taking apart everything again, this could be a nice autumn/winter project, as the car is stored every winter :slight_smile:

Even if the GPS does not pass a speed estimate to the Arduino, the Arduino could calculate that for itself by comparing each position update with the previous position, and knowing the time between them. This would take a little while to get going and establish satellite lock and a stable estimate. So maybe you could also include an accelerometer to help give a better speed estimate in the short term.

But another, perhaps easier and better option, compared to GPS, accelerometers etc, would be to attach some sensor, perhaps a Hall sensor or optical sensor, to something on the output side of the transmission, like the drive shaft or similar. Something rotating at or proportional to road speed. The Arduino could read this and control the stepper motor speed attached to the speedo.

Why not fit an after market Cruise Control Speed Sensor to get your tail-shaft speed.


then google how to drive a mechanical speedo


So devices are available.

Tom.... :slight_smile:

GPS doesn't work in tunnels. In Australia at least, the speed cameras in the tunnels make about $1M per week in fines.

A hall sensor on any shaft is usually pretty easy. If you have ABS brakes there is one on every wheel. Buy one more sensor and mount it alongside the original. If you don't have ABS, those sensors will work on almost anything, like the bolts on the U-joints.

Actually we don't have speed traps in our tunnels, but I know other countries have that.
So I guess hall effect sensor would be the best way if I decided to visit neighboring countries :slight_smile:

But does it need to be a hall effect sensor (that only reacts to magnetic fields)

Or maybe I could use a inductive switch sensor? They detect metal in front of them.

But I see that if I where to go with hall effect sensor, the US5881 sensor seems to be the best/easiest one to use for this.

Am I on to something, or am I way out now? :slight_smile:

You're onto something. All of those options will work.

Thanks :slight_smile:

Stuff ordered, so now to the waiting game...

As some said further up, I think I'll go for the steppermotor version, rather then regular motor.

If someone have tried a steppermotor in a project, I'm open for some advices :slight_smile:

Did you read "Stepper Motor Basics"? That's one of Robin's great contributions to this forum. Give him a Karma point when you find it.

Get the right kind of driver, such as one of the Pololu ones. Get a sufficient power supply. Start slow and ramp up the speed.

No, but sure will look for it, thanks :slight_smile:

Haha, yes, I'll guess that would be the safest way to get started :stuck_out_tongue:

So since last time i have recieved some parts and stuff,
Project turned away from my original idea of turning the cable, to use a servomotor directly behind the dialplate of the original speedometer, and screens to replace the "Clockwork" that was there.
Startet thinkering abit, loaned some code that i found useful, and made some that i found useful.
However, its seems ive stopped to a halt right now, (maybe i just need some "off" time from the computer also)
But i cannot seem to make the screens refresh, they are stuck at zero, no matter of how many turns the hall effect measures.
And also, i think i did a mistake, seemingly im not storing total lenght travelled (odometer).

Maybe you guys could chime in and assist, as this is my first time ever with arduino :slight_smile:

The code is like this now:

#include <EEPROM.h>   //library for working with internal memory arduino
#include <Wire.h>
#include <SPI.h>
#include <Adafruit_SSD1306.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SPITFT.h>
#include <Adafruit_SPITFT_Macros.h>
#include <gfxfont.h>
#include <Servo.h>   //library for servo operation
Servo servo;  //declare called servo servo
unsigned int min_speed=0;  //minimum displayed speed, km / h
unsigned int max_speed=180; //maximum displayed speed, km / h

#include <Adafruit_SSD1306.h>
#define OLED_RESET 4
Adafruit_SSD1306 display1(OLED_RESET);
Adafruit_SSD1306 display2(OLED_RESET);

#define NUMFLAKES 10
#define XPOS 0
#define YPOS 1
#define DELTAY 2

int OdometerButton = 8;
unsigned long lastturn, time_press; //time storage variables
float SPEED; //variable speed storage in the form of decimal fractions
float DIST; //distance variable in the form of decimal fractions
float TotalDist; //total distance travelled for vehicle
float w_length=2.21; //wheel circumference in meters
boolean flag; //a flag for storage (which is shown on the display, speed or distance)
boolean state, button; //checkboxes for the button click handler

void setup() {
  Serial.begin(9600);  //open port 
  attachInterrupt(0,sens,RISING); //connect an interrupt at pin 2 with increasing signal
  pinMode(3, OUTPUT);   //3 as an output pin
  digitalWrite(3, HIGH);  //apply 5 volts to pin 3
  pinMode(8, INPUT);   //here is the button
  servo.attach(4);  //servo on the 4 port
  display1.begin(SSD1306_SWITCHCAPVCC, 0x3D); 
  display2.begin(SSD1306_SWITCHCAPVCC, 0x3C);

  // Clear the buffer.

  // display2
  display2.print("KM:"); display2.print (DIST);

  // Clear the buffer.

  // display1
  display1.print("KM:"); display1.print (TotalDist);

  DIST=(float)EEPROM.read(0)/10.0; //remember the distance traveled at the start of the system (division by 10 is needed to save tenths of the distance, see the entry)

void sens() {
  if (millis()-lastturn > 80) {  //protection against accidental measurements (based on the fact that the car will not go faster than 180 km / h)
    SPEED=w_length/((float)(millis()-lastturn)/1000)*3.6;  //calculation of speed, km / h
    lastturn=millis();  //remember the time of the last turn
    DIST=DIST+w_length/1000;  //add the length of the wheel to the distance at each revolution of one

void loop() {
  int pos=map(SPEED, min_speed, max_speed, 180, 0); //translate the value from the minimum to the maximum in the rotation angle of the servos (from 0 to 180)
  servo.write(pos);  //turn the servo

  if ((millis()-lastturn)>2000){ //if there is no signal for more than 2 seconds
    SPEED=0;  //we believe that SPEED 0
     EEPROM.write(0,(float)DIST*10.0); //write DIST to internal memory. I did it so, because the internal memory does not like frequent rewriting. Also * 10 to save a tenth of

    if (digitalRead(8)==1) {    // If the button is pressed
   DIST=0;    //zero the distance


Before you got the displays working , did you have some working code that inputted the pulses and converted them to speed and distance?

Have you got code that works for one display and can update it?
Have you got code that works for both displays together and can update it?

Does the servo part of your code work?

Thanks.. Tom.. :slight_smile: