This is an Arduino project I created a few years ago. The idea was to build a stop light so my mom knew when to stop pulling into the garage. I made three versions of it. Version one was just a prototype, nothing fancy. All of the versions did have a switch as a master on/off.
Version two had three relays (one for each color: red, green, blue). There were 6 rows of RGB LEDs, with 5 LEDs per row; totaling 30 LEDs. If I remember correctly, these were common cathode LEDs, but it's been a while. I wish I had cataloged what parts I used better so I wouldn't have to redo the math all over again.
Click the button below for pictures, videos & code:
Version 2 picture front:

Version 2 back:
After finishing the soldering for more than ¾ of the LEDs in v2, I did some testing and realized how blindingly bright the LEDs were, and how there was absolutely no way so many were necessary to achieve a bright, saturated color. So, I made version three. It has exactly the same LEDs, relays, and resistors. The only difference is there's only three rows of RGB LEDs, with 5 LEDs per row; totaling 15 LEDs. The result was much more in line with what I wanted.
Version 3 front:

Version 3 back:

Then it came time to package it all together. I tried bending Lexan plastic to make a custom case. I read online about how to put it in an oven & it would be like putty. At the time, I was living in a condo & wasn't willing to risk burning the place down. I tried heating it with a butane torch, and I couldn't get it to the right consistency. It either burned or wasn't hot enough to bend. I tried finding pre-fabricated cases online, but none seemed to be the right size.
Since I've always been more interested in software than hardware, I moved onto other Arduino projects.
I've provided the Arduino code below. You're welcome to use it for your projects.
Arduino Code:
/*
Button
Turns on and off a light emitting diode(LED) connected to digital
pin 13, when pressing a pushbutton attached to pin 2.
The circuit:
* LED attached from pin 13 to ground
* pushbutton attached to pin 2 from +5V
* 10K resistor attached to pin 2 from ground
*/
// constants won't change. They're used here to set pin numbers:
//const int buttonPin = 2; // the number of the pushbutton pin
const int redPin = 10; // the number of the LED pin
const int greenPin = 11; // the number of the LED pin
const int bluePin = 12; // the number of the LED pin
const int proxPin = 3; // the number of the proximity pin
int timePulledIn = 0; // the amount of time we've been pulled in
// variables will change:
//int buttonState = 0; // variable for reading the pushbutton status
void setup() {
Serial.begin(9600);
// initialize the LED pin as an output:
pinMode(redPin, OUTPUT);
pinMode(greenPin, OUTPUT);
pinMode(bluePin, OUTPUT);
// initialize the pushbutton pin as an input:
// pinMode(buttonPin, INPUT);
}
void loop(){
// Serial.println("loop");
// establish variables for duration of the ping,
// and the distance result in inches and centimeters:
long duration, inches, cm;
// read the state of the pushbutton value:
// buttonState = digitalRead(buttonPin);
// check if the pushbutton is pressed.
// if it is, the buttonState is HIGH:
// if (buttonState == HIGH) {
// The PING))) is triggered by a HIGH pulse of 2 or more microseconds.
// Give a short LOW pulse beforehand to ensure a clean HIGH pulse:
pinMode(proxPin, OUTPUT);
digitalWrite(proxPin, LOW);
delayMicroseconds(2);
digitalWrite(proxPin, HIGH);
delayMicroseconds(5);
digitalWrite(proxPin, LOW);
// The same pin is used to read the signal from the PING))): a HIGH
// pulse whose duration is the time (in microseconds) from the sending
// of the ping to the reception of its echo off of an object.
pinMode(proxPin, INPUT);
duration = pulseIn(proxPin, HIGH);
// convert the time into a distance
inches = microsecondsToInches(duration);
cm = microsecondsToCentimeters(duration);
Serial.print(inches);
Serial.print("in, ");
Serial.print(cm);
Serial.print("cm");
Serial.println();
if ( (cm > 60) && (cm < 100) ) {
digitalWrite(redPin, LOW);
digitalWrite(greenPin, LOW);
digitalWrite(bluePin, HIGH);
delay(1000);
} else if ( (cm > 40) && (cm < 60) ) {
digitalWrite(redPin, LOW);
digitalWrite(greenPin, HIGH);
digitalWrite(bluePin, LOW);
delay(1000);
} else if (cm < 40) {
Serial.println("proximity is less than 20");
// turn red LED on:
digitalWrite(redPin, HIGH);
digitalWrite(greenPin, LOW);
digitalWrite(bluePin, LOW);
// delay(10000); //sleep 10 sec
do {
timePulledIn++;
Serial.print("timePulledIn=");
Serial.println(timePulledIn);
if (timePulledIn > 20) { //if we've been pulled in for more than 60 seconds
digitalWrite(redPin, LOW);
digitalWrite(greenPin, LOW);
digitalWrite(bluePin, LOW);
}
delay(1000);
if (timePulledIn == 25) {
timePulledIn=0;
goto bailout;
}
} while ( cm < 20 );
} else {
digitalWrite(redPin, LOW);
digitalWrite(greenPin, LOW);
digitalWrite(bluePin, LOW);
}
/* } else {
digitalWrite(redPin, LOW);
digitalWrite(greenPin, LOW);
digitalWrite(bluePin, LOW);
} */
bailout:;
}
long microsecondsToInches(long microseconds)
{
// According to Parallax's datasheet for the PING))), there are
// 73.746 microseconds per inch (i.e. sound travels at 1130 feet per
// second). This gives the distance travelled by the ping, outbound
// and return, so we divide by 2 to get the distance of the obstacle.
// See: http://www.parallax.com/dl/docs/prod/acc/28015-PING-v1.3.pdf
return microseconds / 74 / 2;
}
long microsecondsToCentimeters(long microseconds)
{
// The speed of sound is 340 m/s or 29 microseconds per centimeter.
// The ping travels out and back, so to find the distance of the
// object we take half of the distance travelled.
return microseconds / 29 / 2;
}
Version 1 Video Link: https://youtu.be/cdBbpF71Wrg
Version 1 Video: