Introduction: Kids Car Racetrack With Easy Wireless Timer Display
There are many projects out there for showing how to time cars going down various tracks...from Pinewood Derby to Hot Wheels. When my friend Dan decided to build a track and asked me if I could come up with a timer system, I found everything from professional systems to hobbyist ones, but they all had something that felt complicated. I wanted to come up with a system that was simple for others to make, inexpensive, flexible, and that would have an external display such as a television or tablet. From Dan's side, he didn't want to just build a track..he needed something that his kids could put away, which didn't take up a ton of room, and which could use anything from pinewood derby cars to custom lego cars. Together, in the end we came up with an addictively fun project which we'd like to share with the community, especially scout troops or others who would like their kids to build timers for their pinewood derby setups vs. purchasing a system.
In this instructable I will focus on the timer portion, though I'll note some of the design choices made for the track which made that portion special (such as being able to disassemble it) as well as how it affected the electronics decisions. I believe there are many tutorials out there for how to build the tracks themselves, so I want to focus on the timer.
This project has the following features:
- The Track design is modular, in that it can be disassembled or reassembled with ease, and by kids.
- Pinewood derby, Lego cars (which are amazingly fun!) as well as Hot Wheel cars all work
- There are no wires running from the track. No need for a laptop plugged into the Arduino or anything like that. It's powered off of a simple USB power brick, like you'd use to charge a cell phone on the go. This is a game changer when kids can run back and forth, and around the track, without any tripping hazards
- The time display can be shown on anything that can browse the web. We've had the display up on everything from a cell phone to a large screen smart TV (Which had an internet browser built in)
Ok, so in summary, how was this done? An ESP8266, break beam sensors, and a button. Which takes us to the next section...
(Update: Video added to show the project end to end! Second video coming soon of a verbal code walkthrough :))
Step 1: Parts List for the Timer
- Adafruit Break Beam sensors (https://www.adafruit.com/product/216) - These come in pairs...a sender and receiver. You'll want a pair per lane you're planning on using.
- Adafruit Feather Huzzah - (https://www.adafruit.com/product/2821) - If you're comfortable with an 8266 you can do this even cheaper, but the Feather Huzzah makes this drop dead simple to setup
- Tactile switch / button - Just about anything will do here. This is how you 'start' the race
- 22 gauge hook up wire (I recommend 2 strands/colors the length of the track you're building, plus about 4 feet for some extra wiring which is needed. We had a 10 foot track, and I bought 25 foot rolls of red, black, and green...I probably have half a roll each left.
- Glue gun or epoxy to hold the sensors in place
- Cell phone power bank - You should be able to get a small cheap one at a local store for under 10 dollars. If you prefer online, this one is way overkill but not a bad price: (http://a.co/i6D43m9). You just want a way to power the feather huzzah, and it really doesn't take much draw. Note: You can also use a JST connector battery such as a https://www.adafruit.com/product/2011...this would save you some space, but it's in exchange of battery life and price.
- A micro USB cable to USB (you use this for the Feather Huzzah programming and from the power bank)
Step 2: Theory, and How It Works
Before I dive into the wiring, I want to discuss how it works, so that when you're hooking up things, you'll know how they fit in (and if you have better ideas or need to adjust it, you'll know now before you've soldered stuff :) )
The ESP8266 is the 'brain' of this...it'll run the program and look for 2 separate input sources...the start gate, and the end sensors on each lane. When the start gate hits the button, it starts a global timer...as each end gate gets tripped, the current value of the timer gets saved off for that lane.
One thing that becomes apparent when playing with these...is that some cars do not every finish. Or sometimes someone may want to run one lane...and not have cars on the other. To handle both of these scenarios, there is a timeout that is set to longer than any race should take. That way, if the overall timer hits that timeout, we can mark any cars that didn't finish as DNF (did not finish) and be ready to go for the next race.
The ESP8266 serves up an HTML page which it substitutes in values from the timer/sensors as they come in. This is great because it allows a tinkerer to change the colors, display, text, and other options very quickly and easily. Because it's just HTML, you can make a very dynamic and graphical display if you'd like!
Next up we'll look at wiring...
Step 3: Wiring
Update (2/25/2019) - Removed the picture that had the resistor...not sure where that came from, but it's not par to of this project! Apologies for any confusion that caused. The wiring is Positive to positive/negative to negative, and signal to a GPIO pin on the Arduino for the 3 wire receiver. The Sender is 2 wires and just needs to go to power...I ran the grounds together with a wire nut and then added a jumper wire to the Arduino ground, and did the same for the positive side)
Good news...it's really straightforward to wire up these sensors...and we only need to wire up a single button!
Before wiring up the sensors, find the ones with only two wires. These are the 'senders' and only require power to activate. The others, with three wires, are receivers...they have two power wires and a sensor wire. See the image above for the overall idea on how these get wired in.
What you'll want to do is mount all of the senders (2 wires) under the track, facing upwards. Drill a small hole through the track, then from below, using a spade bit slightly wider than the sensor, drill out a space for the sensor to mount, with the led portion facing upwards through the hole. Hold it there with something temporary...double stick tape for instance.
From the top of the track, the portion that goes 'over' it, you'll want to drill holes facing downwards, and place the matching sensor facing downwards. This is the portion of the sensor with three wires.
For both the upwards facing, and downwards facing sensors...connect all of the Red and black wires together. These are your power wires, and you'll want them run into your Arduino for power. The third wires on the top should all run to separate Arduino pins...I recommend using pins 12, 13, and 14 on the Huzzah Feather.
Place a button on your starting gate such that when the gate opens, but button gets hit. This will depend on your starting gate setup...for us we had a dowel we turned, so we added a piece of wood into that dowel that would hit the sensor when the gate was down. The main thing is when the gates open...the button needs to get hit. Since the start of the track is on the other end from the sensors you just mounted, you'll want to run two wires from the start button, down the sides or under the track, to the bottom.
Protip: For Dan's track, it separated into three pieces for ease of storage. But this meant that the wiring had to separate as well. Using Molex connectors here will allow you to unplug the wires if your track needs to be taken apart for storage.
The picture shows a small mini breadboard...if you're not great with connecting wires, I recommend using one of these to get the circuits going and tested. Long term you'll want to either epoxy the wires in to keep them there, or solder/heatshrink the wires together.
Next lets look at code...
Step 4: The Code...
The codes attached here. All configurations were moved to the top so that it's easy to edit, but here I'll go over them:
<p>#define LANE1PIN 12<br>#define LANE2PIN 13 #define LANE3PIN 14 #define STARTBUTTONPIN 5 #define MAXRACETIMESECONDS 7000 //maximum time a race may take in seconds before timing out const byte DNS_PORT = 53; // Capture DNS requests on port 53 IPAddress apIP(10, 10, 10, 10); // Private network for server DNSServer dnsServer; // Create the DNS object ESP8266WebServer webServer(80); // HTTP server int mode = 0; // 0 Ready 1 Started 2 Ended 3 Error</p><p>int sensorState = 0, lastState=0, StartButtonState = 0; int NUMRACERS = 3;</p>
Update 4/12/2020 - If you've never programmed an Arduino...there are some steps you should know! Here I'll walk through all of the steps.
- You'll want to install the Arduino IDE. An IDE is where you can put in code (which looks like text) and it'll send that over a usb cable to the board to program it. You only have to do this when you program it, after that if you power the board it'll run the program you send to it. You can get that from here: https://www.arduino.cc/en/Main/Software
- Download and install the Arduino software
- During install it may ask to install a serial port or com port...please allow that, this is how it will talk to your arduino board.
- The ESP8266 is an arduino compatable board, but it requires some additional info for the Arduino IDE to talk to it. You'll want to go here and follow these steps: https://randomnerdtutorials.com/how-to-install-esp...
- Launch the Arduino IDE
- Go to file->Preferences
- In the 'additional board manager URLs, add: https://dl.espressif.com/dl/package_esp32_index.j... http://arduino.esp8266.com/stable/package_esp8266...
- Once that's added, close the dialog and go to toos->board manager
- Search for "ESP8266" and select it...it should show up if step 3 worked
- Click 'install'. You should see the board info come down and then get installed
- Now go to tools->Boards and look at the list..it should be a bit larger than before, and the Feather Huzzah should show up. Select it! You may have to select the COM port, but at this point you should be well on your way to being able to send code to the board and programming it
- Open the LaytonLanes.ino source file...when you do you should get a dialog stating it needs to be in it's own folder called 'Laytonlanes'. Say Ok, and Arduino will fix up where the file goes
- There are two other files..the DNSServer.h and DNSServer.cpp...those are library files and need to go into a certain folder to work with Arduino...lets get them sorted next...
- The folder from step 4 that gets created should be where the Laytonlanes.ino file was located. If so, please copy both Dnsserver.h and dnsserver.cpp INTO that folder. When you open that folder you should now see 3 files (laytonlanes.ino, dnsserver.h, and dnsserver.cpp). If so, then please open laytonlanes.ino, and try to compile and upload. if this succeeds, use a phone or a device on wifi and look for a new wifihotspot called 'laytonlanes'. If you see it connect to that wifi hotspot, open a browser, and hopefully you see a webpage!
In the code, the lane pins are the pins that the sensors are hooked up to. You can change this, but please be careful and understand the pins on the Huzzah that are special. For instance, pin 2 and pin 0 have special behaviors when pulled high. If you're not familiar with Arduinos, then please stay with the recommended ones, upload the code, and you should have a working setup 'out of the box'.
The Maxracetimeseconds is the timeout value in milliseconds (so 7000 is 7 seconds). Most races on our track took under 6 seconds (most were under 2 even!) so 7 seconds seemed like a good number. You may want to adjust that part.
The apIP(10,10,10,10) is the IP address of the display. This means if you navigate a browser to http://10.10.10.10 while connected to the tracks wifi, you'll get the display. I chose that IP because it was easy to use and remember, but you may want to choose another.
Next we have the wifi config:
<p>// Wifi Config<br> WiFi.mode(WIFI_AP); WiFi.softAPConfig(apIP, apIP, IPAddress(255, 255, 255, 0)); WiFi.softAP("Layton Lanes"); </p><p> The softAP is the access point name...this is what shows up when people try to connect to the lanes via Wifi. You'll want to name this something personalized for your race track! Next we'll look at the output, and how to truly personalize this...</p>
Step 5: The Website...
In the code you'll see the line:
String responseHTML = ""
This starts the HTML portion of the display, and you should edit this how you see fit. This will let you customize the colors used on the display, the text to change it to your name, and gives you an area for a small fun quote. That being said, you should feel free to go wild on this! You can add whatever text you want, names of racers or family members, or whatever you'd like! This was customized for Dan's favorite team, the Miami Dolphins.
Two tips here..
If you want to do something similar and match the colors to a favorite sports team, this site can give you the HTML color codes: https://teamcolorcodes.com/
If you want to add an image...well there's no file system, so you have to use an image source which is base64 encoded. This site will help you with that: https://www.base64-image.de/
I think that one of the most fun parts of this project, besides it being wireless, is that the display can be totally customized! The default layout is shown in the image above.
Note: The webpage has debug text at the bottom...this should allow you to quickly test the lanes (place a hand under each one to see the numbers change) and lets you know, as an operator, what is going on. You can also remove this if you'd like to clean up the output, but we've found it incredibly helpful sometimes.
Step 6: Usage!
Ok, finally, how the heck does this work, and how do we use it!?
- From a device which can connect to wireless, look for your access point (Layton Lanes if you didn't change the name)
- Connect to that access point, and then navigate to http://10.10.10.10
That's..it. You should see the three lanes with dashes to indicate the race hasn't started. When you hit the button, you should see the timers going as the page auto refreshes. When each lane gets 'tripped' by a car, the timer will stop and time will be recored. when all three are done (or it times out!) you'll see the final race results.
You can use a phone, a tablet, a smart TV, a computer...anything with a browser that can connect to wifi can connect to the race track! You can even do things like connect a cell phone to it, and then use the wireless display from the phone to a TV (Miracast or airplay). This works with iphones, ipads, android tablets, windows devices...heck even a raspberry pi could be used if you wanted!
1) The first thing I check is the sensors...make sure that they're pointing at each other correctly, and that they register a '1' in the debug spew on the screen you're displaying on. If so, put a hand in the beam and make sure they switch readings to a '0'.
2) If you're having problems connecting, try unplugging power and replugging it in to reset the 8266. I've had this happen once in 10 hours of use, and I THINK I fixed the issue, but it's so tough to reproduce it's hard to say
3) If you can't see the access point, please make sure the chip has power. If you changed pins...make sure you're not using 2 or 0, as these may hold the Arduino in an off state.
4) Post in the comments if you're still stuck and I'll help where I can.
Step 7: Future Ideas / Advanced Stuff
For those comfortable with Arduinos, here's some easy mods that could be done that I just haven't gotten to yet:
- Add in neopixels above the lanes...you could use blue/red/white like ribbons to indicate who came in first/second/third if you want to bypass the display portion
- Use a servo or other method to start the race automatically...our design depended on hand turning the start, but this easily could've been a servo. you'd use the web page to then start the race, which would make the entire system tablet activated
- You could get fancier with the website if you wished, adding animations possibly
- The speed timer I use is an average over the whole course, you could use a point to point measurement for speeds
- You could use break beam sensors at the start as well as the end...then do auto configuration of the UI based on how many racers are there
- The quickest time of the night would be a good thing to track and keep. I may add this soon myself, as we found ourselves racing for hours trying to beat the quickest time vs. caring about 1:1 type races.