Topics

► Games

► Sound & Music

► Clocks

► GPS

► Tools

► Tutorials

By processor

► ATtiny85

► ATtiny84

► ATtiny841

► ATtiny2313

► ATtiny861

► ATmega328

► ATmega1284

About Me

About Me

Feeds

RSS feed

Tiny GPS Speedometer [Updated]

29th November 2014

This article describes a simple speedometer based on a low-cost GPS module interfaced to an ATtiny85. It's based on a simple GPS parsing routine designed to run on any AVR processor, such as the ATtiny85. The resulting code described here is around 2Kbytes and doesn't require any additional GPS or floating-point library; it's completely self-contained.

The Tiny GPS Speedometer is based on the Adafruit Ultimate GPS Breakout [1] available from Proto-PIC in the UK [2], but would probably work with any GPS module:

Speedometer.jpg

Tiny GPS Speedometer. We're going at 1.69 mph.

Serial interface

The first step was to implement serial communication on the ATtiny85. GPS modules communicate using serial, and are easiest to interface to a chip with a built-in hardware UART, such as the ATmega328 in the Ardunio Uno. The only breadboard-friendly ATtiny chip with a UART is the ATtiny 2313, but this is a 20-pin package with more capabilities than this project needs. I decided to use the minimal ATtiny85, which would require implementing a UART in software/hardware.

Because I didn't need to change the GPS module's settings I didn't need a serial transmit, so I implemented a simple 9600 baud receive-only UART using the ATtiny85's USI, as described in an earlier article: Simple ATtiny USI UART.

Decoding the GPS string

The information in the NMEA string from the GPS module is decodede by the routine ParseGPS(); a full description of this is given in a separate article: Minimal GPS Parser

The routine decodes the time, latitude, longitude, speed, track, and date, although only the speed is used in this application.

Circuit

For simplicity I used a serial 7-segment display module for the display [3], available in the UK from HobbyTronics [4]. The ATtiny85 communicates with the display using its SPI interface, and needs two I/O lines; the SS line can be tied to ground since there's only one SPI device.

Here's the circuit:

Speedometer.gif

Tiny GPS Speedometer circuit.

Compiling the program

I compiled the program using the Arduino-Tiny core extension to the Arduino IDE [5]. This doesn't include a setting for the ATtiny85 with an 8MHz crystal, so you need to add the following definition to the boards.txt file:

###########################################################################

attiny85at8x.name=ATtiny85 @ 8 MHz  (external crystal; BOD disabled)

attiny85at8x.upload.using=arduino:arduinoisp
attiny85at8x.upload.maximum_size=8192

# Ext. Crystal Osc. 8.0 MHz; Start-up time: 16K CK/14 CK + 65 ms; [CKSEL=1111 SUT=11]
# Brown-out detection disabled; [BODLEVEL=111]
# Preserve EEPROM memory through the Chip Erase cycle; [EESAVE=0]
# Serial program downloading (SPI) enabled; [SPIEN=0]

attiny85at8x.bootloader.low_fuses=0xFF
attiny85at8x.bootloader.high_fuses=0xD7
attiny85at8x.bootloader.extended_fuses=0xFF
attiny85at8x.bootloader.path=empty
attiny85at8x.bootloader.file=empty85at16.hex

attiny85at8x.build.mcu=attiny85
attiny85at8x.build.f_cpu=8000000L
attiny85at8x.build.core=tiny
 
###########################################################################

After restarting the Arduino IDE this will add an ATtiny85 @ 8MHz (external crystal; BOD disabled) option to the Board submenu.

Connect the ATtiny85 to the Tiny AVR Programmer Board; see ATtiny-Based Beginner's Kit. Select the ATtiny85 @ 8MHz (external crystal; BOD disabled) option on the Boards menu and choose Burn Bootloader to program the ATtiny85 fuses for an 8MHz crystal clock. Then upload the program to the ATtiny85.

Displaying the speed

The main routine loop() simply repeatedly reads the decoded GPS speed and displays it on the four-digit LCD display:

void loop (void) {
  long temp;
  cli(); temp = Knots; sei();
  // Continuously display the speed in mph
  Display(temp*38/33);
}

Because the GPS variables are updated under interrupt, you need to disable interrupts around any reference to them with cli() and sei() to avoid the risk of reading a half-updated value. The speed in knots is multiplied by 38/33, which gives a good approximation to 1.151, the number of mph in a knot. The routine Display() displays the speed on the display, autoranging between two decimal places for speeds up to 99 mph, and one decimal place for speeds over 99 mph.

Note that the display will show 0.00 until the GPS module gets a fix; this can sometimes take a few minutes.

For a future project I plan to use the latitude, longitude, and track to make a simple navigator.

Here's the whole Tiny GPS Speedometer program: Tiny GPS Speedometer Program.

Updates

7th December 2014: The latitude and longitude are measured in minutes*10000, not minutes*1000 as stated in the original version of this article. Also, the GPS variables should be declared volatile, as they are updated by the interrupt service routine.

21st February 2016: I have updated the program to incorporate the improvements added to the Simple ATtiny USI UART. I have also added information about compiling the program and uploading it to the ATtiny85.


  1. ^ Ultimate GPS Breakout on Adafruit.
  2. ^ Ultimate GPS Breakout on Proto-PIC.
  3. ^ 7-Segment Serial Display on Sparkfun.
  4. ^ 7-Segment Serial Display on HobbyTronics.
  5. ^ Arduino-Tiny core on Google Code.

blog comments powered by Disqus