Almost a year ago Martin came to me and asked me, if would like to join him on a cool project. His idea was to put a LED POV into a real race car to display messages written by the motorsport fans. This page has all of the details of how we finally managed to make this happen. If you are more interested in a summary version, please take look at this blog post.
Every race event attracts a lot of fans. The idea was to integrate the fans into the race. Therefore the race cars carries fan messages around the track and prints them into the night.
The technique used for that is called POV (Persistence of vision). It is somehow related to Light Painting. For that you take a long exposure picture and move the LEDs through it.
If the LEDs are switched on and off in the right pattern, it prints a readable message on the picture.
I built the first version of the circuit on prototyping board. It consists of:
- Mega328 Header board (Arduino compatible)
- LS20031 GPS Receiver from Sparkfun
- Polymer Lithium Ion Battery – 2000mAh from Sparkfun
- 16 * 2N3940 transistors with 16 * 1k resistors
- 16 * Piranha 4-pin LEDs (blue) with 16 * 47R current limiting resistors
- a strong suction cup
- aluminum profile to carry the LEDs
The LEDs I used here are not really high current ones. They draw about 20 mA at 3.0-3.2V. Nevertheless they are very bright (about 1000-2000 mcd). You don’t want to look straight into them.
The transistors are used to drive the LEDs. That’s mostly because you can not drive all LEDs with the ATmega328 directly, even if every LED draws only 20 mA. The sum for Vcc of GND pins should not exceed 200 mA (see datasheet), which means that I could not enable more than 10 LEDs. To be sure, I used the transistors.
The GPS module is only connected by Rx because I don’t want to write to the module. I had to use a jumper to connect and disconnect the module while uploading a new sketch. That was a bit of a hassle while testing it, but it worked.
Martin built the aluminum profile to carry the LED strip. He used a very strong suction cup to mount the LED strip at the outside of the car. It was extremely firm.
Testing the first prototype
To check if the first prototype worked, we had to get access to an Audi R8 and a race track. Of course we could have tested it on any street but where’s the fun then? So we got the chance to get our hands on a real Audi R8. Actually Martin was driving, while I was taking the pictures. Have I mentioned the car has 386 kW (525 PS) ? I was sitting on the passenger seat for the short test run and I couldn’t help myself but smiling all the way the car was accelerating.
We put the prototype in a cardboard box and put it on the passenger seat and installed the LED strip outside of the car.
We added the current speed, taken from the GPS to the end of the message to actually see how fast the car was running. The first results were very promising as you see.
It turned out that long exposure pictures (0.6 to 1 second) worked perfectly but you can’t barely see the effect on a film camera (Canon EOS 7D). That was what we expected. The film cameras shutter is just too fast.
After this test and same nice shots we were pretty confident that the same setup should work in a real race car as well.
Now we needed a racing team and a fast car. As we showed up with our prototype in a cardboard box they said “yeah, nice idea, but not in that shape”. To match the requirements for the race car I had to build a second prototype with proper PCB and enclosing. So I had to sat down and build this thing again, this time with proper PCBs and enclosing.
Changes in this version:
- I added a lipoly charger from Sparkfun. I thought it would be handy to be able to charge the battery without having to unmount everything.
- The transistors had been replaced by ULN2803 darlington drivers
- A debug LED to signal GPS fix positions
- The circuit has an ON/OFF switch
- The LED strip was connected through a DSUB-25 connector.
The LED strip is pretty much straight forward, except that I needed a PCB of about 180 to 200 mm length. The problem is, that Eagle CAD in the smallest edition allows only boards of 100×80 mm. I tried other tools on OSX for about 2 hours but wasn’t that successful. So I switched back to Eagle and designed only half of the board with 8 LEDs on it. Then, if you take two and rotate one by 180 degrees, you could solder them together to form one larger piece. The DSUB-25 cable has 9 connections to each board (8 + VCC), so there are no other connections between the two PCBs. The solution is not pretty but it worked out and I was in a hurry.
LEDs are the same as before, current limiting resistors are SMT 1206 22R. The picture still show 47R resistors. That’s because I failed. I replaced the LED driver without checking the remaining voltage at the LEDs. Surprisingly the ULN2803 had a higher voltage drop as my transistor solution. That made the LEDs dimmer. So I had to replace all SMT resistors.
To write the text nicely I needed a font. Because we wanted to use this with an Audi, we used the Audi font. But how do you convert a TTF into something useable for a microcontroller? I used Gimp to create a bitmap with all needed characters and saved it as XPM file (2 colors, B/W). This XPM gets then converted by a tiny Python script into a header file.
The tool computes the width of every character as well, so you don’t have to use a mono spaced font.
The Arduino sketch to switch the LEDs on and off is also not that complicated. I setup timer 2 to fire an interrupt (TIMER2_COMPA_vect). Every time the timer fires, it fetches the according line of the current character and dumps it out on all 16 pins. When the last character is reached, it starts over from the beginning of the message.
A bit tricky was to have the message not stretched or compressed at different speeds. To be able to draw the characters correctly, I used the GPS. The GPS is read constantly in the main loop. Every $GPVTG sentence is parsed to determine the current speed. With that value I can now set the OCR2A register to make the timer interrupt trigger slower or faster, which makes the LEDs light up for a longer or a shorter time.
While rewriting some portions of the code, sometimes the whole sketch went nuts. It took me a while until I figured out, what went wrong. I put a lot of debug messages in the LED output routines. That consumed quite a lot of time. That time was missing in the main loop where the GPS parsing happend. Sometimes there was an overflow on the serial connection. That affected my parsing and because I failed to use strlcpy instead of strcpy, everything goes mad.
Testing the second prototype
Everything was prepared for another test. This time with the real car, an Audi R8 LMS. We visited the Driving Center near Berlin to meet with the technicians of Audi Race Experience.
We installed the box behind the driver and the LED strip at the rear window. GPS signal reception wasn’t a problem so one of the drivers warmed up to drive some laps while we and a photographer prepared the cameras to shoot some test shots.
I like this picture a lot. The LED message came through quite ok. As a bonus, the photographer used a flash which freezed the car.
That’s the same setup as above, but without the flash. If you look closely at the message, you see it getting brighter and dimmer over the whole path. That was probably because of the ripples in the rear window. They must have caused refraction of the light.
Only two weeks later we were at the 24h race at the Green Hell, Nürburgring. If you don’t know the Nürburgring, it is a very famous and challenging race track, especially if the Nordschleife (20.3 km) is included. The 24 hour enduring race at the Nürburgring is a highlight in every year with a lot of fans camping and partying around the track.
A small App was developed and deployed on Audi’s Facebook page to acquire fan messages. These messages were taken and programmed into our two modules.
Next we installed the module and the LED strip in both race cars. To avoid the light refraction of the test before, we tried to install the LED strip closer to the window.
The software was modified to support multiple messages. The module picks a new message every minute. Time was taken of the GPS unit. To not annoy the race crew and to fit the regulations, I added the option to enable the LEDs only, if the car goes faster than 50 km/h.
So, everything was setup. We switched both modules on and the cars went out on the track.
Can you imagine how I felt? I was super nervous. Would everything work? Had I thought of everything? Would the box stay in place or jump around in the car after a couple of laps? Did I made a any changes to the code that could make the whole system fail? I had already double and tripple checked everything before but you never know. If something would go wrong, you can’t simply say: “We have a problem with our LED thing, could you please come into the pit, we would like to re-program our module”. The race crew had to run two race cars for 24 hours!
We had just a single attempt!
It took some hours until sunset and until it was dark enough for the LEDs to become visible. I setup my camera at the gallery. Then the first shot that captured a message.
“YEAH!” Fortunately the cars were extremely loud so no one heard me yelling. It worked! Here are some more pictures, taken also by other photographers around the track.
This was a fantastic experience. I enjoyed it very much.
Thanks to Martin for letting me join this great project. You did an awesome job, organizing and managing this event! Thanks also to kempertrautman, Audi Race Experience Team and TKL Team for hosting us and making this possible. You guys rock!
Last but not least, thanks to my girlfriend for in-between “emergency” test driving.