Working on a defective speedometer

A Toyota speedometer is kicking and screaming like a toddler while I try to fix it.

Similar projects worth following
This speedometer fits a 94 Toyota Pickup with the 22RE engine. While it keeps accurate distance traveled with the main odometer, the trip odometer is broken, and the speedometer reads way higher than it should.

My Toyota Pickup's speedometer has been reading incorrectly for quite some time. It shows a much higher speed than it should. As an example, next to construction projects on freeways there are radar-equipped LED signs which show speed readings of vehicles passing by. I will often see readings between 60-65 mph when I drive by, but my speedometer will read 105-110 mph. And I have driven this truck enough to know at the high end of 1st gear this truck is going about 15 mph, yet the speedometer is showing 25 mph.

I also damaged the trip odometer previously. It has a plastic shaft that comes out of the dash that you'd press to reset the trip odometer. On one particular day it required more force to press than normal, and like the fool I am, I pressed with more force to reset it. Except I heard and felt a crunch, and the odometer wouldn't reset to zero anymore. In fact the numbers on the trip odometer wouldn't spin anymore. Curiously the main odometer still tracked the mileage accurately, with occasional clicking of what I assume is gears jumping because a support piece is not allowing gears to mesh.

So like the curious lad I am, I took out the combination speedometer/odometer from this truck.

I'd sure like to keep this truck running past half a million miles.

People have documented this speedometer well enough. There are two versions of this speedometer, either mechanically or electronically driven. My truck is late enough to use the electronic version. There are 4 screws which hold the gauge in place, and also provide electrical connections. Three of these connections are important. The gauge needs 12V, GND, and a signal that comes from a sensor on the transmission.

The speed sensor is mounted at the rear end of the transmission, and sends pulses as the driveshaft rotates. It doesn't matter which way the driveshaft rotates, the output of the sensor are pulses. I did not disassemble the speed sensor, but I assume there is a rotating magnet that causes a hall effect sensor to short the output to ground. All that needs to happen to interface with this is to use a pullup resistor and detect every falling edge or rising edge as a fixed distance traveled. Assuming the use of the stock differential and stock size tires, the sensor is geared in such a way that every 4000 pulses/falling edges as a mile traveled.

The following image is one person's findings, but I did spend some time driving a known distance several times and tracking pulses, and I am getting closer to 4000 pulses per mile rather than their claimed 4038 pulses per mile. Do note that I am using 205/70/R14 tires inflated to 35psi, which comes out to about 201.9cm circumference instead of their given 239cm.

If all that's needed is an odometer, we could simply keep track of pulses and divide that by 4000 to get mileage. If we store two sets of counted pulses where one is reset to 0 by pressing a button, we get a trip odometer too.
To get an indication of speed, we also need to keep a fairly accurate time base. Since there are 3600 seconds in an hour, we have a factor of 4000 "pulses per mile" over 3600 "seconds per hour". Shifting units around, we arrive at 4000/3600 "pulses per second per mph".

With this calculated factor, I created a circuit that output a series of pulses, a square wave generator with adjustable frequency. I used the classic 555 timer for this.

With the given 10k potentiometer, I could generate square waves from about 12Hz to 125Hz. When this frequency range is fed into the speedometer, we should be seeing the needle move between 11mph and 112mph.

I was hoping that this speedometer was okay, but when I gave it an input signal with frequency of 31.2Hz, the needle moved to roughly 45mph instead of a proper 28mph reading. This lines up with the previous observation of 60-65mph actual speed being displayed as 105-110mph.

So something is definitely wrong with this speedometer. So let's look at the speedometer in more detail. Here is the backside of it....

Read more »


This fits the speed sensor for the W55/W56 transmissions. I got away with using 20% infill. ChatGPT created, ROFLhoff refined

Standard Tesselated Geometry - 68.25 kB - 07/13/2023 at 03:49



ChatGPT created, ROFLhoff refined

ino - 9.98 kB - 07/13/2023 at 03:49



This fits the speed sensor for the W55/W56 transmissions. ChatGPT created, ROFLhoff refined

scad - 2.12 kB - 07/13/2023 at 03:49


  • A digital replacement made by ChatGPT, no really!

    ROFLhoff07/13/2023 at 03:47 0 comments

    Well since I want to drive this truck while I search for another speedometer, I better make something to take its place. I can try making a digital replacement. As mentioned before I need capture pulses to make an odometer, and keep accurate time to make a speedometer. At least that's the high-level approach.

    I have an old Arduino Duemilanove that I used during my early hobbyist days. Its LDO can handle up to 20v, so it should be able to handle a bit of electrical crude. I have a spare OLED display, one of the 0.96" I2C variants. While the ATMEGA328 had better input range than other microcontrollers of the era, I will need to level shift the speed sensor pulses. A simple NPN BJT inverter with the collector on one of the input pins, and a 10k ohm resistor going from the base pin to the speed sensor signal should suffice. I'll just have to detect falling edges to update the two odometer variables.

    Now I can spend the time to made a sketch and it shouldn't take much time, but I am curious how well everybody's favorite AI tool ChatGPT can do with this task. Will it make an Arduino sketch with common functions, will it focus on programming on an atmega328, manually setting up the I2C interface or use libraries?

    I'm actually shocked at what it made. It used the common Arduino libraries, setup the I2C correctly, used the right OLED display library, it setup and used interrupts correctly. There was very little I had to adjust. I'm sure ChatGPT stole someone's working code, it was too good.

    I have the working code included as "speedometer_v1.ino" in the project files.

    Now it's one thing to just make a sketch and upload it to the Arduino, I did not want to cut the wiring harness going into my dash to get the speed sensor signal, only to have the device not work. I wanted to try this code out on something else. I actually have a second speed sensor that fits this truck. For some reason when you buy these sensors, they don't come with the actual gear that meshes with the transmission, you're supposed to keep the old one and stick it in the replacement. I wasn't going to drop the sensor on the truck so I can spin this sensor on my desk. It's a fairly deep shaft that a finger wouldn't fit in. The bottom has a weird shape to it, so I can't drop a screwdriver down and twist easily.

    Okay ChatGPT has been good for me so far, let's see if it can make something custom that I can use with OpenSCAD. I have a 3D printer and plenty of PLA to use. I gave it a general description of the bottom shape, depth of shaft, and to put a wide disc on top with a finger cutout so I can twirl this new part. And ChatGPT did not disappoint.

    Outside of correcting the units, it gave useable code. After converting the code to STL, and generating Gcode in Ultimaker Cura, 90 minutes later I had a working part!

    This was a satisfying picture to take!

    The white breadboard has a 555 timer for testing, but in this image it's just being used for the +12V/GND access. The OLED is on the yellow breadboard, and the extra button is there to reset the trip odometer. Currently on the OLED display is the speed on the first line, the second line is fixed text, the third line is displaying pulses (that large number is the current engine mileage * 4000 pulses/mile), and the last line is the trip odometer in pulses. The final code used miles, but I did not want to spin this sensor 400 times to increment the trip odometer a tenth of a mile.
    The DSO-138 oscilloscope is storing a period of pulses from me spinning the sensor for a few seconds. On the top left is says 11.415Hz, which comes out to 10.3 MPH. The OLED display is continuously updating the speed, so in the time that I'm taking the picture it's going to read 0 mph.

    I included some startup code that checks if I have the trip odometer reset button held while powering the Arduino, which puts it an adjustment mode. Using the Arduino's COM port, I can update the mileage.

    I'm very satisfied with the code so far,...

    Read more »

  • Whoops, I did it again! I tried fixing something and broke it further!

    ROFLhoff07/13/2023 at 02:02 0 comments

    So I have some rather bad news to give on this speedometer. It seems that I have broken a fine wire which connects to the PCB that comes out of the speedometer needle windings. It's not visible in this picture, but there are 4 wires that are wrapped around pin headers that were soldered to the PCB. One broke off I assume during the initial removal of the PCB. I did note that at one point, one of those pin headers slid around a significant amount when I used my solder sucker on it. It was the bottom right pin header.

    You can also see how that  2-part epoxy mended the parts together.

    So now the speedometer does not read correctly, in a different way now! The odometer seems fine though. I broke a little plastic tab when removing the metal can that sits over the speedometer needle windings. luckily it seems that the one remaining tab is good enough to hold it back on. I was able to reach down inside with some fine SMD tweezers and pull the broken wire into free space. Unfortunately I don't think my soldering iron can reach down and tin the wire. I will spend some time finding a replacement speedometer. Stay tuned for an update...

    P.S. - If the odometer/trip odometer on your gauge is the only thing with issues, I highly recommend that you do not attempt to remove the PCB. Even if you want to replace the electrolytic capacitors, there is plenty of room to replace those without removing the PCB.

View all 2 project logs

Enjoy this project?



ROFLhoff wrote 07/13/2023 at 18:05 point

Hope you see this comment, I can't seem to continue the reply chain.

You likely have a broken piece of plastic in the trip odo. It's a fairly tight workspace with the PCB installed, but I don't recommend you remove it unless you have to. Hopefully it's a clean break and not a floating piece to wiggle back into the mechanism.

The prompts I gave ChatGPT were simple. I had it do one thing at a time. In the initial prompt I told it to make an openSCAD model, at first it was a cylinder shape, then to cut a slot, cut a cylinder of smaller diameter than the shaft, add a large diameter cylinder on the other side, cut a small circle from the edge of the large cylinder. Other than messing up the units, it output valid code.

  Are you sure? yes | no

Dan Maloney wrote 07/12/2023 at 20:25 point

That looks almost identical to the speedo in out 1997 4Runner. Which also has a defective trip odometer. Watching with interest.

  Are you sure? yes | no

ROFLhoff wrote 07/12/2023 at 20:51 point

Hi Dan, does the entire unit not work or just one of odometers not work?

  Are you sure? yes | no

Dan Maloney wrote 07/13/2023 at 17:38 point

Just the trip odo -- the speedo and the regular odo work fine.

I'm really interested in how you got ChatGPT to design that part for you in OpenSCAD. What was that process like?

  Are you sure? yes | no

Similar Projects

Does this project spark your interest?

Become a member to follow this project and never miss any updates