Arduino GPS Speedometer With a Ks0108 - 128x64 GLCD (display)

34,624

250

79

About: Passionate about computers and stuff :-)

I wanted to build a digital speedometer for my car. There was nothing wrong with the one already installed in my car, I just wanted to have a big LCD display that will be positioned in a more convenient position - right in front of me. And as I did not want to mess with my car's electronic parts in order to tap in and read the "speed" signal straight from the car's computer, I opted for the GPS version.

Components needed:

1. Arduino Uno (Nano or other Arduino boards might be fine as well)

2. GPS module, I got this one https://www.dfrobot.com/wiki/index.php?title=GPS_Module_With_Enclosure_(SKU:TEL0094) (if the link is not working when clicked, just copy and paste it into your browser's address bar)

3. Graphic LCD (http://www.aliexpress.com/item/20PIN-LCD12864-Grap...)

4. 10k trimpot for adjusting the contrast of the LCD

5. 4.7k potentiometer for adjusting the brightness of the LCD

6. 100 ohm resistor to limit the current for the LCD brightness

7. Wires, suction cup, self-adhesive velcro, kitchen aluminium foil (or similar), soldering iron, pliers, hot glue gun, etc.

Optionally:

8. USB cable for powering the Arduino board (and LCD) and separately the GPS module

9. 2 x USB (5V) car power adapters (at least 1A each)

10. Plastic enclosure (or you could build one)

11. and of course, a car with a battery to power the whole stuff

Step 1:

PLEASE NOTE:

I would advise that you build a prototype version first, and only when tested and working start the actual building of the enclosure.

In order to be able to upload sketches to the Arduino board, the GPS module will have to be disconnected, as it uses the same RX and TX pins to communicate with the Arduino board as the Arduino IDE. While the GPS module was left connected, attempts to upload sketches failed in my case.

PS. As YukselV suggested, you could use SoftwareSerial instead of the "simple" Serial, in case you want to test other features which means uploading the sketch multiple times - you won't have to disconnect the GPS module in this case. Thanks YukselV! (https://www.arduino.cc/en/Reference/SoftwareSerial)

Similarly, the LCD power will have to be disconnected while uploading sketches to the Arduino board. This is due to the RESET pin being connected to the LCD, which interferes with the Arduino IDE. I read that one could simply connect the RESET pin of the LCD to +5V on the Arduino (permanently), or simply temporarily disconnect the RESET wire while uploading the sketch to the Arduino board. I simply disconnected the power supply when required.

***********************************************************************************

First, because my LCD order would take a while to arrive, I started by testing the GPS module using a LED display.

*********** UPDATE 31.10.2016 ********************

I have attached the .INO sketch for using with a 4-Digit-7-Segment-LED-Display

*********** end of UPDATE 31.10.2016 ********************

When the LCD finally arrived, it took me a while finding out the correct wiring for the LCD. I found a tutorial in Italian (http://www.mauroalfieri.it/elettronica/lcd-grafico...) that shows the wiring (http://www.mauroalfieri.it/wp-content/uploads/2013...). That however was not working properly for me, so I had to change some stuff around:

- I had to change some wiring around the 10k trimpot (controlling the LCD contrast)

- I added another 4.7k potentiometer in series with a 100 ohm resistor, that will allow me to control the LCD brightness as well.

EDIT: Thanks to ibenkos for pointing out that the +5v engine in my original wiring image was connected to ground rail on the breadboard. It should of course be connected to the positive rail - updated picture uploaded.

Then I wanted for the speed to be displayed instantly after starting my car engine and moving off. However I didn't want to leave the whole stuff powered up all the time and risk for the car battery to go dead. Therefore I would power the Arduino board and the LCD only when I start the engine, while the GPS module would be powered all the time, even when the engine is off (so that it won't take "I don't care how many seconds to lock onto the positioning satellites for required data to be sent to Arduino for processing").

It's up to you however to locate the appropriate points where to get power from the fuse board.

Using one USB car power adapter I would get continuous 5V to power the GPS module, while the second USB car power adapter would give me 5V to power the Arduino and the LCD only when I start the car engine.

One more thing to note: I used fused wires to connect to both car power adapters, so that they will blow in case of a short circuit, and not some other car electronics.

Step 2:

Here I was testing the LCD wiring - note the resistors I was using instead of the trimpot, which I did not have at the time.

Step 3:

I cut a whole in the plastic enclosure (that I bought from a local shop) that will allow the LCD display to fit in, and then I hot-glued the LCD in place. I've cut a piece of plastic sheet and placed it on the back of the LCD then I added some aluminium foil on top. I also added aluminium foil all around the plastic enclosure, including the back cover, and connected everything to ground. The idea is: try to enclose the Arduino board inside an improvised Faraday cage (https://en.wikipedia.org/wiki/Faraday_cage) in order to prevent any interference from other electronic devices that could affect the functionality of the Arduino board. That's the idea, anyway :-) Is this really necessary? I don't know.

However, make sure that you are not shorting any contacts on either the LCD or Arduino.

Step 4:

Because I needed two different 5V power supplies (one for Arduino and LCD, the other for the GPS module), and another wire that will connect to the potentiometer controlling the LCD brightness - four wires in total, if we account for the ground as well - I decided that I will use an USB cable, which is conveniently screened.

I took the USB connector off the Arduino board (I didn't have another one at that time, and having uploaded and tested the whole thing before), I cut another hole in the plastic enclosure, and there I had my required power connection. You could use an additional USB connector, if you think you might need to upload updated sketches to the Arduino board.

Or of course, you could use another type of an electrical connector altogether if you wish. The idea is to get those four wires inside the box connected to the appropriate power source - continuous 5V, engine on 5V, LCD brightness signal coming from the potentiometer, and ground.

Step 5:

I happened to have a suction cup from an old sat nav, which I wasn't using anymore. This will hold the whole box onto the windscreen of the car. The GPS module is attached using some self-adhesive velcro, with a small hole allowing the four wires (5v, ground, TX, RX) to go and connect inside the box.

Step 6:

And there it is, the final product located onto the dashboard, connected by the USB cable to the power supply and the potentiometer conveniently located beside the steering wheel (please note, I have a left hand driving car, the steering wheel is located therefore on the right hand side of the car)

And you can watch it working here:

Sorry for the video going in and out of focus - I was using a compact camera, with no option for a fixed focus.

Step 7:

Now for the code...

First, you need to download two libraries (in case you don't have them already in your Arduino's library folder):

1. OpenGLCD - https://code.google.com/p/glcd-arduino/downloads/l...

(more information can be found here: http://playground.arduino.cc/Code/GLCDks0108 and here https://bitbucket.org/bperrybap/openglcd/wiki/Home)

2. TinyGPS - http://arduiniana.org/libraries/tinygps/

Unzip and copy them in your Arduino's library folder (normally C:\Program Files (x86)\Arduino\libraries\). If the Arduino IDE is open, you have to close and re-open it, to allow for the new libraries to be loaded.

Step 8:

Then I found it very awkward to generate new fonts (as high as the screen height) that will be displayed onto my LCD. Therefore what I did was to create bitmaps (numbers 0 to 9 plus a blank) that will be displayed on my LCD.

After "installing" the openGLCD library, look for the file name called "glcdMakeBitmap.pde", normally located here

C:\Program Files (x86)\Arduino\libraries\openGLCD\bitmaps\utils\glcdMakeBitmap\

EDIT - April 12th, 2016!!!!

Added OpenGLCD library, which already has the .h (header) files. You need to copy and unzip where your Arduino IDE is located - normally C:\Program Files (x86)\Arduino\libraries\

EDIT - April 12th, 2016!!!! [ends]

To run this file you will need to download and install an additional piece of free software, called Processing, which is very similar to Arduino IDE.

EDIT - March 14th, 2016!!!!

Thanks ab710 for pointing out that using some newer Processing versions will give an error while trying to run the code. Please use the link below to download Processing 2.2.1 which in my case allows for properly running of the code.

https://github.com/processing/processing/releases?...

(https://github.com/processing/processing/releases?after=processing-0230-3.0a3)

Alternate download link: https://drive.google.com/open?id=1LzcEr3DhHO4HFnq9u4e2AE--H4-x7VLd

EDIT - March 14th, 2016!!!! [ends]

Open "glcdMakeBitmap.pde" in Processing and click Run, in the top-left corner.

The purpose of "glcdMakeBitmap.pde" application is to allow you to "feed" it with image files (gif, jpg, bmp, tga, png), and then some .h (header) files will automatically be created within the "bitmaps" folder of the openGLCD library. They will eventually be used to display your numbers (as images) onto the LCD.

I have attached an archive file named "numbers.zip" which you can download, unzip, and then drag each one of those .BMP files onto the running "glcdMakeBitmap.pde" in order to create the 11 header files (0 to 9, plus blank). But if you wish, you can design your own numbers, using different fonts, save them as BMP or other supported image file extension, and use them to create the header files which will be displayed onto the LCD.

PS. In case you're wondering why did I not upload the header (.h) files instead of the .BMP files, and save you the trouble of downloading and installing Processing, and running "glcdMakeBitmap.pde": It's not enough to simply copy the .h files into "bitmaps" folder, as the files named "allBitmaps.h" will be automatically updated as well (by the Processing application) to refer to the new files. Plus, in case you don't like my numbers, you now know how to create your own :-)

Step 9:

And finally the sketch, which is not very complicated, and should be self-explanatory.

I have also attached the .ino sketch for your convenience.

********************************************************************

#include //math library to use for round function

#include "TinyGPS.h" //GPS module library

#include // LCD library

TinyGPS gps; //create a gps object

float fLat, fLong; //floats for longitude and latitude; will be used to determine whether the GPS data is up to date or not

unsigned long fix_age; // returns +- latitude/longitude in degrees

int digit1, digit2, digit3; //integers to hold the three digits making up the speed

int iSpeed; //integer to hold the speed value from the GPS module

void setup()

{

Serial.begin(9600); //start the serial communication

// initialise the library, non inverted writes pixels onto a clear screen

GLCD.Init(NON_INVERTED);

}

void loop()

{

while (Serial.available())

{

//incoming serial data from GPS

int c = Serial.read();

if (gps.encode(c))

{

// process new gps info here, in case you want to display more details

}

}

gps.f_get_position(&fLat, &fLong, &fix_age); //get longitude and latitude, used to find if data is up to date

if (fix_age == TinyGPS::GPS_INVALID_AGE || fix_age > 2000)

{

//data was not updated for some time, assume that GPS connection is lost

iSpeed = 0;

}

else

{

//GPS connection is up to date, get the speed information, and round it to closest integer value

iSpeed = round(gps.f_speed_kmph()); // speed in km/h

}

//when not moving, the GPS module will still read some "speed" value, not necessarily zero

//in that case assume the car is not moving; only display values greater than 2

if (iSpeed == 1) iSpeed = 0;

displaySpeed(iSpeed); //call function to display the speed, digit by digit

}

void displaySpeed(int iSpeed)

{

//"simple" maths to extract each digit value

digit1 = iSpeed / 100;

iSpeed = iSpeed - (digit1 * 100);

digit2 = iSpeed / 10;

digit3 = iSpeed - (digit2 *10);

//display "blank" bitmap when necessary, instead of number zero

if (digit2 == 0 && digit1 == 0) digit2 = -1; //digit 2 is blank

if (digit1 == 0) digit1 = -1; //digit 1 is blank

//call function to display each digit, at their required position

drawDigit(digit1, 0);

drawDigit(digit2, 45);

drawDigit(digit3, 90);

}

void drawDigit(int digit, int pos)

{

switch (digit)

{

case 0:

GLCD.DrawBitmap(Number0, pos, 0);

break;

case 1:

GLCD.DrawBitmap(Number1, pos, 0);

break;

case 2:

GLCD.DrawBitmap(Number2, pos, 0);

break;

case 3:

GLCD.DrawBitmap(Number3, pos, 0);

break;

case 4:

GLCD.DrawBitmap(Number4, pos, 0);

break;

case 5:

GLCD.DrawBitmap(Number5, pos, 0);

break;

case 6:

GLCD.DrawBitmap(Number6, pos, 0);

break;

case 7:

GLCD.DrawBitmap(Number7, pos, 0);

break;

case 8:

GLCD.DrawBitmap(Number8, pos, 0);

break;

case 9:

GLCD.DrawBitmap(Number9, pos, 0);

break;

default:

GLCD.DrawBitmap(NumberBlank, pos, 0);

break;

}

}

Step 10:

If you have any comments, questions or ideas, please let me know. And I hope you'll enjoy (as much as I did) building your own Arduino based GPS speedometer.

3 People Made This Project!

Recommendations

  • Sweet Treats Challenge

    Sweet Treats Challenge
  • Paper Contest

    Paper Contest
  • Faux-Real Contest

    Faux-Real Contest

79 Discussions

0
None
Brown Ali

Tip 10 days ago

Hello all, found a solution to the issue I was having, involves using Software Serial and the updated TinyGPS ++ library. Ask and I'll email it to you (the code).

0
None
Brown Ali

Question 23 days ago

All my wiring is working fine, LCD comes on and displays zero ect...
However, even when I move, I only get 0. I have attempted to find different locations on account of a 'poor signal' however nothing changed. Is it something to do with the power for LCD and GPS both coming from the 5V pin of the Arduino board or not? Or is it to do with defining the RX/TX in the code?

3 answers
0
None
StudvioBrown Ali

Answer 23 days ago

Hi, normally powering both the LCD and the GPS module from the 5V pin on the Arduino shouldn't be a problem. However, did you check whether you are getting 5V on that pin, and that there is no drop in the voltage, depending on how you power your Arduino board? Why not try powering up the GPS directly from the 5V adapter and see if any luck. That of course supposing that the wiring is right, the GPS module is working, and that you are using the old software versions as explained in my original post above.
In my case the GPS is powered all the time, directly from the 5V power adapter, while the Arduino and the LCD only come on when I start my engine from an additional 5V power adapter.

0
None
Brown AliStudvio

Reply 23 days ago

Correction the PPS light is not flashing, could this be a signal issue?

0
None
Brown AliStudvio

Reply 23 days ago

I have ran the GPS with serial and TinyGPS++ and am getting correct accurate data. I am pretty sure the wiring is correct as LCD is working and GPS is rather simple. When I used Software serial I defined the RX and TX, do I need to do this? And would the power issue effect me not getting a value other than 0 on the LCD (GPS lights for power and PPS are flashing).

0
None
SébastienD7

7 months ago on Step 1

Hello,

where can I download your sketch for using with a 4-Digit-7-Segment-LED-Display ?

Thanks.

7 replies
0
None
SébastienD10Studvio

Reply 7 months ago

Hello, I didn't success, I only see "0" on my digit...

What's wrong on my diagram ?

RX -> TX TX -> RX

Gps 3.3V (on Arduino)

RX led is blinking, but not TX.

I even tried with 10kohms and 4.7 kohms resistors on RX/Ground (I saw on the web) but no success...

I use a Nano

Any idea ? Thanks.

0
None
StudvioSébastienD10

Reply 7 months ago

I did not try running this on a Nano, so I'm not sure whether it's some wrong physical connection, or the actual board that may be not compatible with it. Also, at the time I wrote this, I used the IDE version available back then. I won't be surprised if old code won't work with newer software versions. Does the code compile properly?

0
None
SébastienD10Studvio

Reply 4 months ago

Hello,

I finally success with it... GPS module was dead and I plug now on 5V (I probably was wrong with 3V connection). It works great now. I have questions:

-what is "delaytime" for ?

-what happens if I change the value ? (+ or -)

I use 3 digits display and I want to display speed with decimal point with 2 numbers (74.5 km/h for example), I don't need a digit for "100".

I think I have to change "Ispeed" but how to display decimal point between second and third digit ?

Thanks.

0
None
StudvioSébastienD10

Reply 4 months ago

Hi, I see no reference to "delaytime" in my code. Some other user (mak2orcullo_electronics) proposed some changes in order to add more functionalities (SmartDelay). Is that what you are talking about?

If you want to display decimal points, then you need to declare "iSpeed" as Float rather than Int, and delete the line where the value you get from the GPS module gets rounded (iSpeed = round(gps.f_speed_kmph());). Then in order to display that number with the decimal point, you need to design additional bitmap images to be displayed when needed. The code then needs to be changed as well, in order to display those new images. But I am afraid that you will have to write that code yourself, as it is not part of my project. Thank you.

0
None
SébastienD7Studvio

Reply 4 weeks ago

Hello,
any possibility changing GPS 1Hz to 10Hz ?
Regards.

0
None
SébastienD10SébastienD7

Reply 7 months ago

Yes it does.
I found mistakes with the code, "//" before an instruction, I erased them but it stills display 0.
I'll check later.
Regards.

0
None
AlistairB18

Question 2 months ago

I have just assembled the above in the schematic and the LCD is turning on, but nothing is being displayed, any ideas?

0
None
alibrown987

Question 4 months ago

Hi there, i am planning on creating this exact project, is there anyway i contact you for further questions, for example the LCD is no longer available, will this work? https://goo.gl/ndJsGg

2 answers
0
None
Studvioalibrown987

Answer 4 months ago

0
None
alibrown987Studvio

Reply 4 months ago

Thanks very much for your response, I will order that display! I have created the Bit Maps in processing, and they have created the files in the OpenGLCD folder. What else should I do before the parts arrive?

0
None
Vini_e

Question 6 months ago

Hello,

I want to collect the speed each second and save it so I can acess it later in the laptop and check the data. There's no need for a screen.

Some help/advices are needed.

Nice work by the way.

1 answer
0
None
StudvioVini_e

Reply 6 months ago

Hi, in that case you would need to add the option of saving the data, one option being an SD card. You would then need to remove the code for displaying the data, and add the code for saving it instead. The first part is simple enough, the second task is not part of this project, and something that does not interests me (at the moment), so you'll have to write it yourself. There are plenty of tutorials on this however (writing data to SD cards).

0
None
Optimat

8 months ago

Well explained Studvio. This will surelyhelp me out in my current LED project.