like one either, but a couple of weeks ago I was driving my fiancee’s
car and noticed that people were just flying by me on the freeway.
The speedometer said I was driving a little over the speed limit. By
chance I passed one of those speed trap trailers that the police put
on the side of the road. To my surprise there was a 10 mph
differential between the speed indicated on the trap and the speed
indicated on my speedometer! I instantly wondered how often my
fiancee was honked at. So I did what any good enginerd/boyfriend
would do; I built her a new one! In this tutorial I’ll show you how I
used 4 different SparkFun products to build a pretty cool GPS powered
digital speedometer.

I started with the Package Tracker
(because I had a spare one on my desk), but you can use any GPS
device you around that has a UART available. The code in this tutorial
was written for the LPC2148 ARM7, which is on the Package Tracker,
but it would be pretty simple to modify it to work on any platform.
Along with the Package Tracker I needed a GPS module; I chose the
EM408 because I'm familiar with it. I also needed a microSD card so
that I could use the USB ARM Bootloader to load my code onto the
board.

There are four different products we
have to connect to get this thing ready for programming: the Package
Tracker, the Graphic LCD, the Serial Graphic Backpack, and the 5V
Step-Up board. As should be obvious, the GPS module plugs directly
into the Package Tracker and the microSD card also just gets inserted
into the microSD socket on the board. Getting the LCD Backpack onto
the LCD is as easy as soldering a female header onto one of the
boards, and a male header onto the other, and plugging them in.

After reading the LCD datasheet I found
that I had to power the LCD with 5 volts. Unfortunately the Package
Tracker is a 3.3V system, and is powered by a 3.7V LiPo battery.
Luckily SparkFun has a 5V DC-DC converter breakout board! Now
we just have to figure out how to get power from the Package Tracker
to the 5V step-up, and how to get the 5 volts from the step-up board
to the LCD. The Package Tracker has a nice 6 pin header on one side
that has VCC and GND. Maybe I can get power from this? Better check
the schematic first though. Turns out we can’t use this VCC for the
5V step up board; the VCC on the header is from the 3.3V regulator on
the Package Tracker. While 3.3V is enough for the step-up board we
can only source 150 mA from this regulator. Considering the regulator
has to power the LPC2148 plus all of the peripheral components on the
Package Tracker I don’t want to risk adding another pretty big load
to it by asking it to power the LCD and the Serial Backpack.

Since we can't use the VCC on the
header we'll just have to take power directly from the battery to the
5V step-up board. I put the step-up board on a breadboard so that it
was easier to work with, but you could probably figure out a way to
get this working without it. Once we've got power to the breakout
board, we'll just connect the 5V output to the Serial Backpack and
we're good to go!

Writing the Code

The code for this project can be split

up into two general parts: getting the speed data from the GPS module, and sending the data to the LCD. The first thing we have
to do, though, is draw the speedometer. The speedometer is really
just a circle with a bunch of numbers placed inside of it. Pete did a
great job on the Serial Graphic Backpack firmware and included a
circle command, as well as text commands. All I had to do was figure
out how big I wanted the circle to be and where to place it, along
with where I wanted to place all of the text. Once I knew these
things I just had to send the serial commands to the LCD Backpack.
The serial commands for the LCD Backpack can be found here in the Serial Graphic Backpack datasheet.

To be honest I found the size and
location of the circle and numbers by using trial and error (...a lot
of error, let me tell you that!). You can see all of the numbers in
the drawSpeedometerOutline function of the Speedometer.c file and the Speedometer.h file, but I can quickly tell you that I used a circle
with a radius of 34 pixels centered at the X,Y coordinates 34,26.
Does it seem weird to you that the center of the circle is at a
height of 26 pixels, but the radius of the circle is 34? It should
seem as if the circle would run off the bottom of the LCD. And it
does! But this was precisely the look I was going for.

Now that I have the outline of my
speedometer I just need a ?needle? to indicate the current speed.
I thought the easiest way to do this would be to use the LINE command
on the serial backpack, however I would still need to know the
coordinates for the line that corresponded to each tick on the
speedometer. Unfortunately this called for a little bit of
trigonometry! I suppose I could have stuck with my trial and error
method, but I wanted to finish sometime this century; so I busted out
the calculator (well, actually I busted out Excel but you get the
picture). Take a look at this figure and the equations to see how I
was able to get the line coordinates.

We know one set of coordinates for the
needle will be the center of the circle; the length of the needle
is up to you. I chose my needle to be 20 pixels long because it
seemed like the needle could go all the way around the speedometer
without running over the numbers inside the circle. Knowing these two
things would allow me to find the second set of X,Y coordinates for
each MPH on the speedometer. The first thing I did was relate the
degrees of the circle to a speed. I want the speedometer to display
up to 100 mph (even though there's no way that car will EVER hit
that speed). So if I estimated that if I used the entire circle for
speed I would have 133 mph. With this number I found that (1 MPH) is
equal to (2.7 Degrees) on the circle. Now I can use basic
trigonometric functions to find all of my coordinates. To find the X
coordinate I use the equation:

X Length = sin(MPH * 2.7)
* 20

And to find the Y coordinate I use the
equation:

Y Length = cos(MPH * 2.7)
* 20

I would need to perform this equation
for each MPH unit on the speedometer to get all of the X,Y
coordinates; but a simple spreadsheet can perform this for me in a
flash. You can see the spreadsheet I used in this file. After running
the calculation I just copied all of the coordinates into an array in
my code.

Whew! That's definitely enough math for
one day. After running some tests with my new coordinates I had some
good news and some bad news. The good news is that the equations
worked and the speedometer needle seemed to be right on track. The
bad news was that the LINE command wasn't going to be fast enough to
use in the system. This wasn't too much of a hassle, I took the code
for the LCD backpack and added a new command called SPEED; it
basically just takes an input speed and draws a line.

So now we have a speedometer drawing,
and we can send a speed to it. All we have left is to get our speed!
We'll get our speed from the GPS module on the LPC2148. If you've
never used a GPS module before, don't be intimidated. It's very easy.
In fact the only thing we do in this application is specify which
NMEA message we want to receive, and then listen to the messages on
the UART. You can find more about NMEA messages in this document. I
chose to listen to the RMC message because it includes ground speed
in the output. How simple is that! Every time I receive an RMC
message from the GPS module, I just extract the speed from the
message. The ground speed is reported in meters per second, so I just
convert the units to miles per hour by multiplying the value by
1.151. It's not a perfect conversion but it will do.

Once I have the speed from the GPS
module, I just need to post it to the LCD by sending my SPEED
command. However, my GPS module only updates once every second. This
means that my speed value can jump around. I don't want the needle on
my speedometer jumping around! I want the needle to increment from
it's current position to it's new position one mile per hour at a
time. This is pretty easy to do by using two different variables for
speed: one of the variables keeps track of the GPS speed, and the
other variable acts like a ?chaser? that is always trying to
catch the GPS speed. So, the GPS speed might go from 0 to 5 MPH in
one reading; but the ?chaser? value has to increment it's speed
by going from 0 to 1, 1 to 2 and so on. Then instead of sending the
GPS speed straight to the LCD, we send the ?chaser? speed to the
LCD so we get a more realistic visual on the LCD.

Where To Go From Here

The digital speedometer works great, but what can you do to it to make it better? I’ve created a list of improvements that could be made to our project. I’d love to see what you come up with!

Adding a Compass (Difficulty: Beginner)-One of the RMC message fields from the GPS module is Heading. Use this value to add a compass to the speedometer

Add Temperature (Difficulty: Intermediate) - The package tracker also has an SCP1000 and an SHT15 on board. Each of these sensors also has a temperature sensor on it. Add in sensor communication and display the temperature on the speedometer.

Improve the Speed Accuracy Part 1 (Difficulty: Advanced)-Currently the speed for the speedometer is only updated at 1 Hz because that’s how often we receive updates from the GPS module. Use an accelerometer (on board the Package Tracker) to determine intermediate speeds by integrating the acceleration values.

Improve the Speed Accuracy Part 2 (Difficulty: Advanced)-The problem with using speed from the GPS module is that GPS actually provides the Speed Over Ground value, not the actual speed. So if you’re going up a steep incline or decline the vehicle speed won’t be accurately reflected in the ground speed. You can compensate for this in one of two ways:

Use static measurements from an accelerometer to determine the tilt of the vehicle, and modify the speed accordingly. The problem with this method is that the orientation of the speedometer must be fixed to get accurate results

Enable GGA messages in the GPS module. GGA messages include the current altitude of the device. Use the altitude differental between points to calculate the slope of the vehicle path and adjust the speed accordingly.

I hope you enjoyed this tutorial! If you have any problems, or see any mistakes be sure to let us know by leaving a comment!

Comments
16 comments

It seems that the LCD used in this project is only sold without the backpack, and the backpack is only sold pre-attached to the “huge” graphic LCD. Can we get them sold together or at least the backpack sold by itself? Pretty please?

You know you didn’t have to cone op with a data table to use in the Arduino code right? Arduino is capable of doing really efficient on-board trigonometry using the math.h library. you did know this right? or at least found out after doing this project??!

I like this project, I’ve been thinking of doing something like this for a motorcycle because the original speedometer is getting a bit clunky.
But there’s one thing I would do different and that would be to use the factory speedometer, and output your speed to that.
This of course requires another project, but one which I have been looking into. If this car is like most, it will have an air-core movement driving the speedometer needle. To make it easier to figure out, I would cut all the wiring to this movement and wire-in an all new circuit using something like a CS4192 air-core driver chip (onsemi.com). This takes a serial input and calculates the correct polarity and voltage to send to the two coils in the meter movement.
What I have built so far is based on the CS8190, which uses an analog input to drive an air-core movement over 300 degrees. This is being used with an LC-1 air/fuel ratio controller. So I have a gauge that shows the A/F ratio using a nice 6 inch needle which used to be a tachometer from a Ford. It just happened to work out that a 5 volt signal put the needle almost exactly at the 270 degree position, so it ‘looks’ right. Then I printed a new gauge face on acid-free matte photo paper. I had to make a traditional light to show the gauge face at night because the factory approach illuminates the face from behind, but the needle is still lit-up the same way as originally.
What I want to do is use the digital output on the LS-1, to get better accuracy. So I’m trying to learn how to use digital signals. Not there yet…

This is great! I am going to use this code for my senior design. I do have some questions though.
Did you actually modify the serial LCD backpack firmware? I noticed that you said you made a SPEED command, because the LINE command is too slow. Does that mean I will run into problems if I use this LINE command? I don’t understand how it is too slow anyways….
Also, am I correct in saying that you put the LCD speedometer coordinates in the firmware code. Can I get by not messing with the firmware code at all and still making this speedometer?

I’ve tried the above method and used trigonometry and formula above, but my needle is all over the place.
I’ve even tried just giving it values manually, but the needle start somehwere and jumps here and tehre every time a new value is entered!
What am I doing wrong?

Hi,
Thanks for sharing your project.
I thought about using the car's
onboard computer to obtain speedometer
information but I think the GPS
would definitely make it independent
of any car electronics.
I think one can modify this project
to be an automotive noise maker for
electric and hybrid cars which are
currently so quiet you can easily get
run over by them.
David

Good idea Starvin. Unfortunately,I have a Buick that I bought new 20 years ago and parts are getting hard to find. I’m on my third VSS, which was bought salvaged, and it’s intermittent as is the display itself.
A GPS speedo would be a relatively quick fix and something interesting to design and build as well. Something I could scratch off of my list of things to worry about :-)

i love the out of the box thinking but would have suggested a signal from the Vehicle speed sensor (located on the transmission) I don’t know what the honda voltages are but my dodge is 5V. So then you could check it against the GPS sig figure out what the difference was then make corrections to the signal from the VSS (which was reading slow on the stock speedo)
I am a car nut and am learning a lot more about my complicated car every day. I hope to contribute what I know about cars in exchange for some EE learning!

Hi, my name is Artiom and I am an Electrical Engineering student at University of Central Florida. I came across this tutorial when I was looking for ideas in implementing a GPS module in our project for Senior Design. I found your tutorial to be very helpful and I would like to have your permission to implement parts of your code in my project.
Please contact me at artiom@techwarelabs.com.
Thank You,
Artiom

Hey there, I stumbled across this post and wanted to let you know that it was the speed sensor and/ or the lines to the ECU on the car that caused the speed problem…I own two EG civics and both had similar problems. The electronic speed sensors from later model EK model civics can be used to interface to different gauge clusters too. if you still have the car it might be worth hacking on it a little bit more.

Cory, I am wanting to build something like this but can measure the speed of short distance movements, in the range of a few feet that move 0.3 to 2.0 m/s. Is this possible do you know? If it is and you’d like to make a few extra $ I’d love the help.
Thanks!
Scott
505-554-2578
scott.richardson.personal@gmail.com

Great tutorial!
Another way to get a more accurate velocity measurement would be to put the GPS in to binary mode so you can get your X, Y, Z position in ECEF (earth centered earth fixed) format. Then d/dt (sqrt(X2 + Y2 + Z2)) gives you your actual speed in m/s. Even if you drive off a cliff!

SparkFun is an online retail store that sells the bits and pieces to
make your electronics projects possible. Whether it's a robot that can
cook your breakfast or a GPS cat tracking device, our products and
resources are designed to make the world of electronics more accessible.

In addition to products, SparkFun also offers
classes and online tutorials to help educate
individuals in the wonderful world of embedded electronics.