GPS Lap Timer; or Labotomised my Sat-Nav

Keep a log of a project build here. Be sure to include pictures and as much documentation as possible.

GPS Lap Timer; or Labotomised my Sat-Nav

Postby nes » July 4th, 2011, 10:56 am

Training for an endurance race, we needed a better way to keep track of lap times. Having a mate keep an eye on a watch and shout out the time each lap was just not cutting it. So we wanted something on the vehicle to do the job, but at zero cost to match our remaining race budget.

So, we want something that can track the speed, and display the time taken to return to the spot we start from. How does it know where the starting place is and where it is? Well GPS seemed an obvious choice.

Thus, we need GPS receiver, computer and display and a battery to power it all. And it needs to be not too heavy.

So, where to get a GPS receiver on a budget? Ebay! Bluetooth GPS receivers are pretty cheap and can apparently be hacked to be wired directly to a computer rather than wireless, but they are not cheap enough for no-budget racing. So this item was scored instead.
Image
It's a malfunctioning car sat-nav. Runs WinCE and cost a whopping £4.

Actually, this was a lucky find as it not only powered up once some charge was put in the battery, but the menu system was functional enough to determine that it was picking up the GPS signal. (The software was corrupt though, so it wouldn't let you plan a route.)

Cue cracking it open to see what was inside.
Image

Well, I didn't take a photo of the next bit, but suffice it to say it was pretty modular inside, with each of the major subsystems grouped together in a separate area of the main PCB. Using a 'scope, the neatly labelled test pads were probed until I noticed a serial bit stream. Could this be NMEA, a sort of standard for navigation systems? To find out we need a dumb terminal.

To make a simple dumb terminal you need a PC with a serial port, or failing that a PC with a USB to serial adapter. To connect it to the logic level signals present in the Sat Nav, the signal has to be inverted and amplified. This can be done with a transistor and a couple of resistors. (As we are only listening in to the data, we only need to connect the Rx pin in the serial port.)

Now fire up the terminal program on the PC and try different baud rates until some text appears. Standard NMEA sentences appear as strings beginning with the characters $GP... In this case the baud rate is 38400, but it can be pretty much anything depending on the specific model of GPS receiver. The standard is apparently 4800 baud, which no one seems to use.

$GPRMC is the most common sentence and if you are lucky (which we were), appears once every second. The series of comma separated numbers following the $GPRMC contain most of the useful information such as the time, your latitude and longitude and your speed in knots.

With this sat-nav, the test pad with the NMEA data was in close proximity to another pad which also had some serial data on it, but only briefly when the unit was switched on. The connection to the inverter-serial port was switched to this pad to see what what was there. On it, there appeared a few lines starting $PSRF103,.... From this, Google came up with Sirf Star III as the most likely chip set in the receiver.

Last thing to do is find a likely candidate for the power rail. Pretty simply you are looking for the biggest capacitor you can find in close proximity to the GPS radio. There was one SM capacitor on the back of the PCB underneath the radio obviously bigger than the others and it has 3.3V across it when the unit is switched on. A continuity check reveals one side is shorted to ground (the metal cans and the metal shroud around the antenna socket.

Now armed with all the relevant info it's time to start the butchery. The section of PCB with the radio was cut away with a cutting disk on a dremel type tool. It could have been done with a hacksaw, but the circular blade was a bit thinner so less likely to stray and cut through something important.

Image

This done, it was time to check the GPS receiver still worked.
User avatar
nes
 
Posts: 127
Joined: January 27th, 2011, 9:20 am

Re: GPS Lap Timer; or Labotomised my Sat-Nav

Postby nes » July 4th, 2011, 1:27 pm

Well, I didn't get a photo of the next bit, but yes it did still work.

Four wires were added to the back of the sectioned radio: ground, power, the NMEA output from the receiver and the Sirf Star commands in. It was hooked up to a bench power supply set at 3.3V and serial data started appearing at the output at 33k baud. Success! The GPS radio consumes a fairly static 40mA when working.

update: Pulled the radio to get some better photos.
Image
Here are the wires soldered on. Blue are the serial Rx and Tx, red is +3.3v soldered to the + (banded) side of the only obviously polarized capacitor there, black is ground soldered to the RF shielding ring. There is a socket for an external antenna on the side which I am not using.

Image
This was an expensive board. I think I can see about 7 power/ground planes where I cut, so probably about 12 layers overall. There are regularly spaced vias for RF suppression all over it, and every bit of exposed copper is gold flashed.

Just for fun the battery was hooked back up to the sectioned sat-nav and it was switched on. Incredibly it booted.
Image

The touch screen no longer works, but that is probably just because I sliced right through the lock button. The processor is an ARM920T and there is probably still enough there to do something useful: CPU, RAM, ROM, battery charger, touch screen SDIO and audio amplifier. I think I can see an unpopulated JTAG header so one day I might try and do something useful with it one day. (Or it's free to a good home for the cost of the postage. I am in the UK, PM me if you are interested. LCD is a dumb one which requires lots of wires unfortunately.)
Last edited by nes on July 6th, 2011, 4:37 am, edited 2 times in total.
User avatar
nes
 
Posts: 127
Joined: January 27th, 2011, 9:20 am

Re: GPS Lap Timer; or Labotomised my Sat-Nav

Postby nes » July 4th, 2011, 1:41 pm

Back to the lap-timer. I still needed a few bits.

For the display, I happened to have a 4 line HD44780 clone LCD which I saved from being thrown out somewhere I worked once. This is quite big and easily visible while moving about. I considered a phone LCD, but the small size ruled it out.

For the new computer I bought an AVR ATMega32U2 cheap, again off the 'bay. These are great devices - basically a regular AVR but with a USB port added and a boot loader built in. All you have to do is wire a couple of pins to a USB cable and add an 8MHz (or 16MHz) crystal. You don't need an expensive programmer or an ISP header. In the Debian/Ubuntu repositories you can find a utility called dfu-programmer which is all you need to get going with these devices. (For Windows devs, I think Atmel have a free tool you can download.)

Image
As this is a one-off with minimal external components, I didn't bother with a PCB. The chip is hot-glued to the back of the LCD and the pins hooked up with bits of thin transformer wire. To the right of the AVR is a 3.3V voltage regulator for the GPS receiver which is dead-bugged and buried under a couple of chip capacitors (salvaged from a dead hard disk). When in boot loader mode, the AVR is quite sensitive to noisy power rails, so the capacitors are necessary.

To get into the built in boot loader, port D.7 has to be tied low while in reset. I arranged this by hooking up the respective pin to a button. Procedure is hold the button down whilst resetting.

The AVR only has a few things connected (directly) to it. They are:
  • USB D+, D-, both via 22 ohm resistors
  • GPS Tx, Rx (via AVR's UART pins)
  • HD44780 LCD (4 data lines, two handshaking lines)
  • Two push buttons
  • 8MHz crystal
  • Small capacitor for the built-in USB regulator
  • Reset button
Last edited by nes on July 4th, 2011, 2:13 pm, edited 1 time in total.
User avatar
nes
 
Posts: 127
Joined: January 27th, 2011, 9:20 am

Re: GPS Lap Timer; or Labotomised my Sat-Nav

Postby nes » July 4th, 2011, 2:04 pm

Image

For the battery, I recycled an external battery pack designed for an early gen iPod nano. This has a fairly large capacity li-po cell, coupled to a thin PCB with a combined charger/step up regulator circuit. It supplies a regulated 5V, and is charged by connecting it to a 5V supply. As I already have USB for the AVR chip, I simply used the 5V from this for the charger. It gets charged whenever it is connected to a PC, and the battery is big enough to keep the GPS going for about 20 hours - way more than we actually need.

The battery powers the LCD directly and also feeds the voltage regulator which powers the GPS and AVR. A switch taken from an old PC power supply is fitted in the positive feed.

Image
All the parts are crammed into a plastic project box and stuck down with more hot glue. This looks messy but holds well and the bits can be repositioned easily by just warming up the glue to soften it.

Image
Here is the decased GPS antenna glued in place against the side facing the sky...

Image
... and the radio which was sectioned from the sat-nav alongside it. They are connected via the short length of grey coax which was originally threaded through a hinge.

Image
Reset button for the AVR pokes though a hold in the lid.

Image
The bezel for the display is sectioned from a second plastic project box and is deeply recessed to try and keep the sunlight off the shiny screen. I am still working on the firmware, but is is functional enough at the moment to be useful. Here it is displaying the speed and some debugging stuff from early on.

Image
Stuck a bit of rubber on the back to stop it shifting about and getting too scratched up. The USB socket top left came from an old printer. The charging led shines through a hole in the side.

Image
It has logged about 7 hours so far over fairly rough conditions and hasn't been shaken to bits yet. It might actually last out until the race (very soon now) and maybe even get used again.

Total build cost has been less that £10 and probably about 10 hours dev time, plus a couple of hours to type this up. ;)
User avatar
nes
 
Posts: 127
Joined: January 27th, 2011, 9:20 am

Re: GPS Lap Timer; or Labotomised my Sat-Nav

Postby nes » July 4th, 2011, 6:13 pm

The source code can be found in this repository.
User avatar
nes
 
Posts: 127
Joined: January 27th, 2011, 9:20 am

Re: GPS Lap Timer; or Labotomised my Sat-Nav

Postby MS3FGX » July 4th, 2011, 7:40 pm

To be honest that wiring makes me a little nervous, but I can't argue with the end result, it looks great. The whole thing comes together beautifully, love the look of the case.
MS3FGX
 
Posts: 356
Joined: January 25th, 2011, 10:47 pm

Re: GPS Lap Timer; or Labotomised my Sat-Nav

Postby nes » July 5th, 2011, 4:13 am

Thanks. I think if I had had more time I might have made a PCB for it using toner transfer. It's mostly surface mount, so it would have only taken an hour or so to do, but the circuit has sort of evolved as I have been reading the data sheet for the ATMega and developing the software. It started off looking quite neat, but got knottier as more wires were added.

Hot melt glue is great for keeping everything set in place. Nothing has fallen off so far once it was stuck down.

Anyhow, onto the software. One of the features is that you speed is displayed in double size digits so it's easy to see while you're bumping along. With HD44780 displays you only get one size of character, but there is space for up to 8 user-defined 5x8 shapes. As in this application, we are not likely to go any faster than 99km/h, we can use these 8 user-defined characters arranged in a block to display two double sized digits.

Here's how they look:
Image Image
Image Image
Image

The function for drawing the numbers and the ROM look-up table defining the shapes is in the source repository.

This is the program for doing the test in the pictures above:
Code: Select all
static const prog_char Msg [] = "Test BigNum ...";
static const prog_char Clr [] = "            ";
int main (void)
{
   char i, j;

   Init ();
   
   SendCommand (CursorAddress (0, 0));
   PrintString (Msg);
   
   while (1)
   {
      for (i = 0; i < 9; i++)
      {
         SendCommand (CursorAddress (2, 3));
         for (j = 0; j < i; j++)
            SendData ('0' + j);
            
         SendCommand (CursorAddress (j + 6, 3));
         for (j = i + 2; j < 10; j++)
            SendData ('0' + j);
      
         SendCommand (CursorAddress (2, 2));
         PrintString (Clr);
         
         BigNum ((i << 4) | (i + 1), CursorAddress (i + 2, 2));
         _delay_ms (1000);
      }
   }
   return 0;
}
User avatar
nes
 
Posts: 127
Joined: January 27th, 2011, 9:20 am

Re: GPS Lap Timer; or Labotomised my Sat-Nav

Postby nes » July 5th, 2011, 5:43 pm

Cool! Made the HAD front page. Thanks guys!

I had better add some stuff about the software running on the AVR chip.

What comes out from the GPS receiver is a series of NMEA sentences transmitted serially. In this case, these are bunched together and repeat once per second, and that behaviour is common for all GPS receivers.

Here are some common GPS sentences, taken from this page:
Code: Select all
$GPRMC,225446,A,4916.45,N,12311.12,W,000.5,054.7,191194,020.3,E*68
$GPGSV,3,1,11,03,03,111,00,04,15,270,00,06,01,010,00,13,06,292,00*74
$GPGGA,064746.000,4925.4895,N,00103.9255,E,1,05,2.1,-68.0,M,47.1,M,,0000*4F

As you can see they each begin with $GP (for GPS), followed by a three letter abbreviation and some comma separated values. Each is terminated with a '*' followed by a two hex digit checksum.

$GPRMC is the must ubiquitous. It tells you latitude, longitude, altitude and time and date in UTC. Pretty much any receiver will start outputting these sentences as soon as it is switched on, though some of the fields will be empty until it gets a lock onto enough satellites for a positional fix.

In the case of Sirf Star III, you can send the receiver commands to change the rate it sends the specific sentences, switch the off, or demand them immediately. For this application, it is best to cut down the amount of chatter on the serial port to stop the main program getting constantly interrupted by new characters arriving through the UART. $GPGGA sentences for example come several at a time and just give you some information about each of the satellites it can see, which is useless to us.

Here is the initialisation sequence I use to switch off the unnecessary stuff and switch on some more useful sentences:
Code: Select all
$PSRF103,00,00,01,01*25
$PSRF103,01,00,00,01*25
$PSRF103,02,00,00,01*26
$PSRF103,03,00,00,01*27
$PSRF103,04,00,00,01*20
$PSRF103,05,00,01,01*20

I turn off $GPRMC and $GPVTG and turn on $GPVTG and $GPGGA which gives us just speed and heading and a leaned form of time and position respectively.

One thing to note is that this GPS ignores anything you sent it until it has finished initialising. I take care of this by waiting after power up until the first character appears from the GPS, then start sending commands. This only needs to be done once until the next time the power is cycled.

Looking at the breakdown of the VTG and GGA sentences, each field is always a set number of commas away from the initial '$'. I simply count the commas to find the value I am interested in.

Though they have decimal points, none of the numeric values is actually decimal. Rather they use nautical units like degrees and decimal minutes (not degrees minutes and seconds though), or hours minutes and seconds for time.

To cope with this, I just wrote three separate routines for dealing with each of the fields I am interested in. Latitude and longitude follow the pattern "[D]DDMM.mmmm,X", i.e. two or three digits of degrees and two whole digits of minutes, followed by a decimal fraction (in the range 0.0 to 59.9999), followed in the next field with the direction from the meridian/equator. Time is encoded as HHMMSS.s, and heading is in plain degrees with a decimal fraction.

Check out the source to see how I did it.
User avatar
nes
 
Posts: 127
Joined: January 27th, 2011, 9:20 am

Re: GPS Lap Timer; or Labotomised my Sat-Nav

Postby nes » July 5th, 2011, 6:04 pm

Now onto the math...

The AVR is only an 8-bit processor (albeit with a generous register set). To keep down processing time and memory requirements I am doing as much as possible with single precision floating point math. (I understand the GNU AVR single precision math lib has been hand optimized for best performance.)

The most important thing to know is the distance between two latitude/longitude coordinates. I have not bothered at all with altitude, as we don't encounter any gradients steep enough to make any practical difference. After a bit of research with Google, I settled on the haversine formula for working out the shortest distance between two points. It's probably overkill, but it is apparently a good compromise between computation time and required precision of the operators. Here's a good description.

I use it to calculate the exact distance covered between reports from the GPS, and also the distance from the start/finish line of our race circuit.

I was a bit dubious how much havoc noise in the receiver would play with the accuracy of distance measurements and whether randomness would cause a cumulative error over time. I checked this out by writing a simple test program to add up the distances covered each second and display the running total. Then I took the box for a long trip in the car (to and from a remote office). The box indicated a total of 104.4km against 106km on my car's trip counter. As the return journey was an indicated 103.9km, I put the difference down to inaccuracy in the car's instrumentation. (And the error in GPS measured distances could easily be accounted for by a fuel stop.) So, I am pretty pleased with the performance of both the GPS and the haversine formula.

Just clocked up another half hour on the track. Software could use a little more work. :)

edit: We are training for this. Race is this Sunday.
User avatar
nes
 
Posts: 127
Joined: January 27th, 2011, 9:20 am

Re: GPS Lap Timer; or Labotomised my Sat-Nav

Postby Astusvis » July 6th, 2011, 8:56 am

Mind telling me what race it is? My school's tech department has built a car for an endurance race... 12th July?
Astusvis
 
Posts: 1
Joined: July 6th, 2011, 8:51 am

Next

Return to Project Logs

Who is online

Users browsing this forum: Bing [Bot] and 3 guests