Justin StoneDominik Reichel
Published

MEGR 3171: Match Box Car Race Track

From store bought to home builds, race your "Hot Wheels" and let the track determine who the winner is!

BeginnerFull instructions provided10 hours514
MEGR 3171: Match Box Car Race Track

Things used in this project

Hardware components

Argon
Particle Argon
×3
High Brightness LED, White
High Brightness LED, White
×3
Microswitch, Roller Lever
Microswitch, Roller Lever
×3
dupont wires
×1
Resistor 220 ohm
Resistor 220 ohm
×3
Hot wheels track pack
×1
Power Bank
×1
USB-A to Micro-USB Cable
USB-A to Micro-USB Cable
×3

Software apps and online services

Particle Build Web IDE
Particle Build Web IDE
Fritzing
ThingSpeak API
ThingSpeak API

Hand tools and fabrication machines

Soldering iron (generic)
Soldering iron (generic)
Solder Wire, Lead Free
Solder Wire, Lead Free

Story

Read more

Schematics

Stating line

Finish line

Finish line

Track set-up

Micro-switch just before pressed by car

Micro-switch pressed by car

Micro-Switch solder and set-up (end of track)

Argon 1

Race Times Taken from ThingSpeak

https://thingspeak.com/channels/920683/private_show

Wiring Diagram of the Entire Project

Wiring Diagram of a Single Argon Unit

Code

Starting Line Code

C/C++
//Initilize Track LEDs
int track1_LED = D2;
//Initilize Starting Sensor Switches
int start1 = D4;
//Initialize LCD Screen Stuff

//Race Outcome Booleans
bool raceStarted = false;
bool raceFinished = false;
bool car1Done = false;
bool car2Done = false;


void setup() 
{
    //Subscribe to the Outputs of Tracks 1 and 2
    Particle.subscribe("Track1", myHandler, MY_DEVICES);
    Particle.subscribe("Track2", myHandler, MY_DEVICES);
    //Set up the oin modes for the LEDs and the Starting Switches
    pinMode(track1_LED, OUTPUT);
    pinMode(start1, INPUT);
}

void loop() 
{
    //Wait for the button press to start the race
    while(raceStarted == false && raceFinished == false)
    {
        if(digitalRead(start1) == 0)
        {
            //Tell the Track Argons that the race has started
            Particle.publish("StartGate","Start", PRIVATE);
            raceStarted = true;
            //Light the track leds
            digitalWrite(track1_LED, HIGH);
        }
    }
    
    if(raceFinished)
    {
        digitalWrite(track1_LED, LOW);
    }
}

//Handles the Race Status
void myHandler(const char *event, const char *data)
{
    //If Car 1 won the race
    if(strcmp(data,"Car1") == 0)
    {
        raceFinished = true;
    }
    //If car 2 won the race
    if(strcmp(data, "Car2") == 0)
    {
        raceFinished = true;
    }
    //If a Tie
    if(strcmp(data, "Tie") == 0)
    {
        raceFinished = true;
    }
}

Track 1 Code

C/C++
//Initilize Track LED
int statusLED = D2;
//Initilize Finishin Line Bump Sensor
int finishLine = D4;
int carTime = 100000000;
int opponentTime = 100000000;
//Race Outcome Booleans
bool raceStarted = false;
bool raceFinished = false;
bool car1Done = false;
bool car2Done = false;

void setup()
{
    //Subscribe to the Outputs of Tracks 1 and 2
    Particle.subscribe("StartGate", myHandler, MY_DEVICES);
    Particle.subscribe("Track2", myHandler, MY_DEVICES);
    //Set up the oin modes for the LED and the Finish line bumper
    pinMode(statusLED, OUTPUT);
    pinMode(finishLine, INPUT);
}

void loop() 
{
    //While the car has not finished the race, wait for it to finish
    while(!car1Done)
    {
        //Check the time once the car passes the finish line
        if(digitalRead(finishLine) == 0)
        {
            //Get the time of the car by subtracting the time when the race started from the current time
            carTime = carTime - micros();
            //publish the time and car1's race status
            car1Done = true;
            digitalWrite(statusLED, HIGH);
            Particle.publish("Track1", String(carTime), PRIVATE);
            delay(1000);
        }
    }
    //Check the outcome of the race
    checkOutcome();
}

//Handles the Race Status
void myHandler(const char *event, const char *data)
{
    //Starts the timer once the race starts
    if(strcmp(data,"Start") == 0)
    {
        carTime = micros();
        raceStarted = true;
    }
    //Check what Track 2's Time is
    if(strcmp(event, "Track2") == 0)
    {
        car2Done = true;
        opponentTime = atoi(data);
    }
}

//Function to Determine the outcome of the race
void checkOutcome()
{
    if(car1Done && car2Done)
    {
        //If both cars have a registered time, then the race is over
        raceFinished = true;
        //compare the times of the two cars
        int outcome = carTime - opponentTime;
        //If the outcome is negative, then the car won
        if(outcome < 0)
        {
            Particle.publish("Track1", "Car1", PRIVATE);
            //Blink the LED in victory
            for(int i = 0; i < 15; i++)
            {
                digitalWrite(statusLED, LOW);
                delay(100);
                digitalWrite(statusLED, HIGH);
                delay(100);
            }
        }
        //If the outcome is 0 then the times are the same and the race is a tie
        else if(outcome == 0)
        {
            Particle.publish("Track1", "Tie", PRIVATE);
        }
        //If the outcome is positive the the car lost, turn off the light in shame
        else digitalWrite(statusLED, LOW);
    }
}

Track 2 Code

C/C++
//Initilize Track LED
int statusLED = D2;
//Initilize Finishin Line Bump Sensor
int finishLine = D4;
int carTime = 100000000;
int opponentTime = 100000000;
//Race Outcome Booleans
bool raceStarted = false;
bool raceFinished = false;
bool car1Done = false;
bool car2Done = false;

void setup()
{
    //Subscribe to the Outputs of Tracks 1 and 2
    Particle.subscribe("StartGate", myHandler, MY_DEVICES);
    Particle.subscribe("Track2", myHandler, MY_DEVICES);
    //Set up the oin modes for the LED and the Finish line bumper
    pinMode(statusLED, OUTPUT);
    pinMode(finishLine, INPUT);
}

void loop() 
{
    //While the car has not finished the race, wait for it to finish
    while(!car2Done)
    {
        //Check the time once the car passes the finish line
        if(digitalRead(finishLine) == 0)
        {
            //Get the time of the car by subtracting the time when the race started from the current time
            carTime = carTime - micros();
            //publish the time and car1's race status
            car2Done = true;
            digitalWrite(statusLED, HIGH);
            Particle.publish("Track2", String(carTime), PRIVATE);
            delay(1000);
        }
    }
    //Check the outcome of the race
    checkOutcome();
}

//Handles the Race Status
void myHandler(const char *event, const char *data)
{
    //Starts the timer once the race starts
    if(strcmp(data,"Start") == 0)
    {
        carTime = micros();
        raceStarted = true;
    }
    //Check what Track 2's Time is
    if(strcmp(event, "Track1") == 0)
    {
        car1Done = true;
        opponentTime = atoi(data);
    }
}

//Function to Determine the outcome of the race
void checkOutcome()
{
    if(car1Done && car2Done)
    {
        //If both cars have a registered time, then the race is over
        raceFinished = true;
        //compare the times of the two cars
        int outcome = carTime - opponentTime;
        //If the outcome is negative, then the car won
        if(outcome < 0)
        {
            Particle.publish("Track2", "Car2", PRIVATE);
            //Blink the LED in victory
            for(int i = 0; i < 15; i++)
            {
                digitalWrite(statusLED, LOW);
                delay(100);
                digitalWrite(statusLED, HIGH);
                delay(100);
            }
        }
        //If the outcome is positive the the car lost, turn off the light in shame
        else if (outcome > 0)
        {
            digitalWrite(statusLED, LOW);
        }
    }
}

Credits

Justin Stone

Justin Stone

1 project • 1 follower
Dominik Reichel

Dominik Reichel

1 project • 1 follower
Thanks to Dawson Pauley.

Comments