Select Page

Difficulty Level = 9 [What’s this?]

This was a fun project I built using a perf-board Arduino with GPS receiver, some LEDs, some long wire, some clever code, and a car!

I have this friend that has a speeding problem. So I built this device for my friend so he’ll know when he’s speeding. How will he know? Because when the small perf-board Arduino device with a GPS module detects that his vehicle’s speed is over the speed limit, it turns on a police lights display that is mounted on the inside of his car’s rear windshield. When he sees those flashing police lights in the rear-view mirror, he’ll know he needs to slow down!

Police in the rear view mirror!

OK, it’s me, but you already figured that out. If you weren’t smart, you wouldn’t be here. Here’s a rundown of this project’s features:

  • A simple perf-board Arduino circuit with an EM-406a GPS Receiver connected to the microcontroller
  • A pair of CAT-5 cables running from the circuit to the back of my Honda Civic
  • A small perf-board with red and blue LEDs and two white LEDs representing the headlights of a police car. This small board is mounted on the inside of the rear windshield using suction cups.
  • The software running on the microcontroller is programmed to know the speed limit in different locations near where I live and drive. I did this by specifying “speed zones” which are polygons and a speed limit. The polygons are defined as a list of latitude/longitude vertices.
  • Whenever the GPS module reports the current position and speed (every second) the code determines which bounding polygon or “speed zone” the car is located in. If the GPS receiver reports that the current speed is greater than the speed zone’s limit, the police lights are activated. If below the speed limit, the lights will be turned off.

The Hardware

Look at this nice clean circuit…

OMG don’t look at the bottom!


This is the schematic. This is just a perf-board version of an Arduino with a few extra things. Ten of the digital outputs are connected to a header for the cable to connect to. The GPS receiver is connected to power and ground, and tied to the TX and RX pins on the ATMEGA328 microcontroller. There is a test switch connected to Arduino pin 9 (ATMEGA328 pin 15). Lastly, there’s a 5 pin header for interfacing with a USB to serial board so I can program the chip. The 5 pins are 5V, GND, TX, RX, and the DTR signal for resetting the ATMEGA328 processor when the chip is programmed.

Here’s the circuit board connected to the messy CAT-5 wiring harness. There’s about 6 feet of wire running to the LED circuit board.

The simple GPS Arduino conntected to a battery and the wires that run to the police lights.

The test button can be used to verify that everything is connected.

Blinky police lights that mount on the rear windshield of my car.

Here’s how the LED circuit board looks mounted in the rear windshield. I put a small square of black paper above the circuit board to reduce reflection on the glass.

LED circuit board mounted on inside of rear windshield

This is what it looks like when the police lights are activated. First a video shot to the rear of the car, then what it looks like in the rear view mirror. It was difficult to capture this on video, and it really doesn’t do it justice. I can tell you that when driving around at night, the illusion is fantastic. It really does look like there is a police car behind you!

The Code

Download the full Arduino code here.

The software running on the Arduino ATMEGA328 chip utilizes the wonderfully robust NewSoftSerial library for communicating with the EM-406a GPS module and the very convenient TinyGPS library for parsing the NMEA sentences from the EM-406a. Both of these awesome libraries are provided by Mikal Hart.

The TinyGPS library makes it easy to obtain the speed over ground in miles per hour. The method for determining whether my car is speeding or not depends not only on knowing how fast I’m going and where I am, but also knowing what the speed limit is where I am. For this, I have to hard-code in the information about various speed zones in the area I’m driving. This isn’t as tedious as it sounds. The idea is to define polygons on a map that represent different speed zones. Here’s a map I sketched in order to plan my code. I just did a screen capture in Google Maps and then drew on it with a simple drawing program. Click through for a larger version:

Click for larger map

Map showing polygons definition for my neighborhood - click through for larger map

Then I used a simple tool provided at Google Maps called the “tile detector”. By clicking on the tile detector map you can easily determine the latitude and longitude of any point. Then I defined polygons in the setupSpeedZones(). Each zone has a speed limit and a list of vertices that define the polygon.

  // Rockford Road                                                                                          
  speedZones[0] = &SpeedZone(45);
  speedZones[0]->setVertices(6, (Vertex[6]){
      Vertex(45.027162772967756, -93.48137855529785),
      Vertex(45.02946790848425, -93.4742546081543),
      Vertex(45.02955889877115, -93.46193790435791),
      Vertex(45.02861865883124, -93.46172332763672),
      Vertex(45.02861865883124, -93.47412586212158),
      Vertex(45.02649547957147, -93.48133563995361)});


  // Schmidt Lake Rd                                                                                        
  speedZones[1] = &SpeedZone(45);
  speedZones[1]->setVertices(10, (Vertex[10]){
      Vertex(45.044176126280206, -93.48219394683838),
      Vertex(45.04390322470628, -93.47322463989258),
      Vertex(45.043387740403595, -93.46974849700928),
      Vertex(45.0440548368525, -93.46498489379883),
      Vertex(45.0440548368525, -93.46185207366943),
      Vertex(45.04332709488612, -93.46185207366943),
      Vertex(45.0433574176529, -93.46580028533936),
      Vertex(45.04272063617576, -93.46983432769775),
      Vertex(45.043266449304376, -93.47434043884277),
      Vertex(45.04332709488612, -93.48215103149414)});

      ...

The function getSpeedLimit() checks to see if the current GPS position is within each speed zone starting with the first one. Note that I defined a “catch all” speed zone with a limit of 25mph around the whole area. It’s ok if polygons overlap as long as you understand that the first match found will be the one that is used for the speed limit. This means you have to order your speed zone definitions with care. My catch all speed zone is defined last for this reason.

The algorithm for determining if a point is within a polygon is actually quite simple (I was surprised). I adapted my code from the algorithm provided here. I’m grateful that I found such a simple implementation to use.

The rest of the code should be pretty self-explanatory. If the car is speeding, turn on the police lights. If not, turn them off. Download the full Arduino code here.

Conclusions

This project worked amazingly well. The GPS receiver can take a long time (maybe 3 minutes) to get a fix when it is powered on, but once it gets a fix, it is very accurate. The only shortcoming is that the EM-406a receiver only outputs NMEA sentences once per second, so there’s a bit of lag, but for the most part this device would correctly react to speed limit changes almost immediately after crossing a speed zone polygon border.

The speed over ground reported by the EM-406a is pretty accurate but seemed to be about 2mph lower than what my speedometer in my car reports. So if I was in a 45mph speed zone, the police lights would not come on until I got up to about 47mph. If this difference is consistent, I could easily compensate for it in the software.

Overall, this was a really fun project with great results!