Introduction: Breakin' the Law - Undercover Cop Car

About: Hack Sioux Falls Project!

We are Drake and Trayton

Our goal was to build a cop car that has Bluetooth operated lights and sirens.

We started by working on code for our lights and sirens and then working on finding and modifying a car.

We came up with Breakin' the Law because we are building/driving an undercover cop car and we aren't cops (that is what an undercover cop would say right?) ;-)

Step 1: Parts

For our project, we used a radio-controlled car that we already had and:

Step 2: Powering the Car

We had a lot of issues with the code. We found some examples online that we tried and ultimately had Will write us a code.

We also wanted to use battery packs instead of AA batteries but the packs caused interference with our remote controlled car. So we ended up sticking with AA batteries. We installed Mi-mh batteries but they were only 1.2V so we soldered in a two battery pack to bring the voltage up to 9.6V

This made the car a bit faster which is more fun :)

Step 3: Our Code

Using the example sketch for the Bluetooth module, we added in code for the LED lights and buzzer to make it sound like a siren. It worked pretty well in the end.

#include <SoftwareSerial.h>
SoftwareSerial BT(10, 11); 
// creates a "virtual" serial port/UART
// connect BT module TX to D10
// connect BT module RX to D11
// connect BT Vcc to 5V, GND to GND
#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
#include <avr/power.h>
#endif
#define PIN 5
#define PIN2 6

Adafruit_NeoPixel strip = Adafruit_NeoPixel(8, PIN , NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel strip2 = Adafruit_NeoPixel(8, PIN2 , NEO_GRB + NEO_KHZ800);

void setup()  
{
  // set digital pin to control as an output
  pinMode(13, OUTPUT);
  pinMode(9, OUTPUT);
  
  noTone(9);  // set the data rate for the SoftwareSerial port
  BT.begin(9600);
  // Send test message to other device
  BT.println("Hello from Arduino");
  strip.begin();
  strip2.begin();
  clearLights();
  strip.show();
  strip2.show();
}
char a; // stores incoming character from other device
boolean isTonePlaying = false;
boolean isLightsPlaying = false;
int iTone = 1000;
boolean iToneUp = true;
boolean lightIsBlueRed = true;
unsigned long previousMillis_tone = 0;
unsigned long previousMillis_light = 0;

void loop() 
{
  if (BT.available())
  // if text arrived in from BT serial...
  {
    a=(BT.read());
    if (a=='1')
    {
      digitalWrite(13, HIGH);
      BT.println("Lights & Siren On");
      isTonePlaying = true;
      isLightsPlaying = true;
    }
    if (a=='2')
    {
      digitalWrite(13, LOW);
      BT.println("Lights & Siren Off");
      isLightsPlaying = false;
      isTonePlaying = false;
      clearLights();
      noTone(9);
      iTone = 1000;
    }
    if (a=='?')
    {
      BT.println("Send '1' to turn lights & siren on");
      BT.println("Send '2' to turn lights & siren off");
    }   
  }

  if (isTonePlaying) {
    // The "2" here is the milliseconds between each tone step. Bigger will be slower
    if (millis() - previousMillis_tone >= 2) {
      previousMillis_tone = millis();
      if (iToneUp) {
        iTone++;
        if (iTone > 2000) {
          iToneUp = false;
        }
      } else {
        iTone--;
        if (iTone < 1000) {
          iToneUp = true;
        }
      }
      tone(9,iTone);
    }
  }
  
  if (isLightsPlaying) {
    // The "400" here is the millisecond time between each cycle of Red-Blue/Blue-Red
    if (millis() - previousMillis_light >= 400) {
      previousMillis_light = millis();
      if (lightIsBlueRed) {
        strip.setPixelColor(0, strip.Color(255,0,0));
        strip.setPixelColor(1, strip.Color(255,0,0));
        strip.setPixelColor(2, strip.Color(255,0,0));
        strip.setPixelColor(3, strip.Color(255,0,0));
        strip.setPixelColor(4, strip.Color(0,0,255));
        strip.setPixelColor(5, strip.Color(0,0,255));
        strip.setPixelColor(6, strip.Color(0,0,255));
        strip.setPixelColor(7, strip.Color(0,0,255));
        strip.show();
        strip2.setPixelColor(0, strip.Color(0,0,255));
        strip2.setPixelColor(1, strip.Color(0,0,255));
        strip2.setPixelColor(2, strip.Color(0,0,255));
        strip2.setPixelColor(3, strip.Color(0,0,255));
        strip2.setPixelColor(4, strip.Color(255,0,0));
        strip2.setPixelColor(5, strip.Color(255,0,0));
        strip2.setPixelColor(6, strip.Color(255,0,0));
        strip2.setPixelColor(7, strip.Color(255,0,0));
        strip2.show();
        lightIsBlueRed = false;
      } else {
        strip.setPixelColor(0, strip.Color(0,0,255));
        strip.setPixelColor(1, strip.Color(0,0,255));
        strip.setPixelColor(2, strip.Color(0,0,255));
        strip.setPixelColor(3, strip.Color(0,0,255));
        strip.setPixelColor(4, strip.Color(255,0,0));
        strip.setPixelColor(5, strip.Color(255,0,0));
        strip.setPixelColor(6, strip.Color(255,0,0));
        strip.setPixelColor(7, strip.Color(255,0,0));
        strip.show();
        strip2.setPixelColor(0, strip.Color(255,0,0));
        strip2.setPixelColor(1, strip.Color(255,0,0));
        strip2.setPixelColor(2, strip.Color(255,0,0));
        strip2.setPixelColor(3, strip.Color(255,0,0));
        strip2.setPixelColor(4, strip.Color(0,0,255));
        strip2.setPixelColor(5, strip.Color(0,0,255));
        strip2.setPixelColor(6, strip.Color(0,0,255));
        strip2.setPixelColor(7, strip.Color(0,0,255));
        strip2.show();
        lightIsBlueRed = true;
      }
    }
  }
}

void clearLights() {
  for (int i = 0; i < 8; i++) {
    strip.setPixelColor(i, 0);    //turn every pixel off
    strip2.setPixelColor(i, 0);    //turn every pixel off
  }
  strip.show();
  strip2.show();
}

Step 4: Our Final Project

We originally had the lights mounted on the top but we had a shorting issue and had to remove the lights. Putting the lights on the top made taking the car apart difficult so we ended up moving them to the front and rear bumper.

This also made the car more "undercover" as well.

This was a fun project and we learned a lot.

We are planning to work on another code to make the lights a directional amber like you'll see on emergency vehicles and we may do something of just a randomized pattern for a party car.