Ok, so for my very first ever programming project, I put together a Garage Parking Sensor. Here is a list of parts I am using:
Nano
HC-SR04 Utrasonic Sensor
WS2812B 2X2 LED Panel
a 9v+ 1A power supply (it reads nearly 11v with no load)
a light sensor (which has analog and digital output)
and here is my code:
// libraries to include
#include <RunningMedian.h> //RunningMedian library
#include <Adafruit_NeoPixel.h> //Adafruit NeoPixel library
// define number of samples to include in RunningMedian
RunningMedian samples = RunningMedian(10);
// Create 'leds' object to drive LEDs and define pins
#define PIN 6 //digital pin to control color output
#define NUMLEDS 4 //number of LEDs on panel
Adafruit_NeoPixel leds = Adafruit_NeoPixel(NUMLEDS, PIN, NEO_GRB + NEO_KHZ800);
// define pins for echo sensor
#define trig 11
#define echo 12
// define pin for light sensor
#define light A7
long count = 0;
float m = samples.getMedian();
unsigned long previousMillis=0;
void setup()
{
//Serial.begin(9600);
// setup pins for ultrasonic sensor
pinMode(trig, OUTPUT);
pinMode(echo, INPUT);
// setup pin for light sensor
pinMode(light, INPUT);
// start led panel
leds.begin();
leds.show();
}
void loop()
{
{
int lightState = analogRead(light);
//Serial.println(lightState);
if (lightState >= 700)
{
int i;
long duration, distance;
for(i = 0; i < 10; i++)
{
digitalWrite(trig, LOW);
delayMicroseconds(2);
digitalWrite(trig, HIGH);
delayMicroseconds(10);
digitalWrite(trig, LOW);
duration = pulseIn(echo, HIGH);
distance = (duration/2) / 29.1;
samples.add(distance);
float m = samples.getMedian();
if (i > 10)
{
continue;
}
ledOff();
if (m > 60 && m < 100)
{
ledGreen();
}
if (m <= 60 && m > 40)
{
ledYellow();
previousMillis = millis();
}
if (m <= 40 && m > 20)
{
ledRed();
if(millis() - previousMillis >= 30000)
{
ledOff();
delay(25);
ledWhite();
delay(300000);
ledOff();
return;
}
else
{
return;
}
previousMillis = millis();
}
if (m <= 20 && m > 10)
{
Flash();
if(millis() - previousMillis >= 30000)
{
ledOff();
delay(25);
ledWhite();
delay(300000);
ledOff();
return;
}
else
{
return;
}
}
break;
}
}
else
{
ledOff();
delay(5000);
}
}
}
void ledRed()
{
//set display to RED
leds.setPixelColor(0, leds.Color(255,15,0));
leds.setPixelColor(1, leds.Color(255,15,0));
leds.setPixelColor(2, leds.Color(255,15,0));
leds.setPixelColor(3, leds.Color(255,15,0));
leds.show();
}
void ledGreen()
{
//set display GREEN
leds.setPixelColor(0, leds.Color(0,255,0));
leds.setPixelColor(1, leds.Color(0,255,0));
leds.setPixelColor(2, leds.Color(0,255,0));
leds.setPixelColor(3, leds.Color(0,255,0));
leds.show();
}
void ledYellow()
{
// set display YELOW
leds.setPixelColor(0, leds.Color(254, 193, 0));
leds.setPixelColor(1, leds.Color(254, 193, 0));
leds.setPixelColor(2, leds.Color(254, 193, 0));
leds.setPixelColor(3, leds.Color(254, 193, 0));
leds.show();
}
void Flash()
{
// flash RED/BLUE display
leds.setPixelColor(0, leds.Color(255,0,0)); // set display RED
leds.setPixelColor(1, leds.Color(255,0,0));
leds.setPixelColor(2, leds.Color(255,0,0));
leds.setPixelColor(3, leds.Color(255,0,0));
leds.show();
delay(50);
leds.setPixelColor(0, leds.Color(0,0,255)); // set display BLUE
leds.setPixelColor(1, leds.Color(0,0,255));
leds.setPixelColor(2, leds.Color(0,0,255));
leds.setPixelColor(3, leds.Color(0,0,255));
leds.show();
delay(50);
}
void ledOff()
{
// set display OFF
leds.setPixelColor(0, leds.Color(0,0,0));
leds.setPixelColor(1, leds.Color(0,0,0));
leds.setPixelColor(2, leds.Color(0,0,0));
leds.setPixelColor(3, leds.Color(0,0,0));
leds.show();
}
void ledWhite()
{
// set display to WHITE
leds.setPixelColor(0, leds.Color(225,205,205));
leds.setPixelColor(1, leds.Color(225,205,205));
leds.setPixelColor(2, leds.Color(225,205,205));
leds.setPixelColor(3, leds.Color(225,205,205));
leds.show();
}
I haven't received the light sensor or measured the actual distances yet (so the numbers will have to be changed), but the way this should work is when pulling into the garage, the automatic headlights will turn on and shine on the light sensor (which is checked for every 5 seconds and then enables the rest of the code), followed by GREEN (GO), YELLOW (SLOWLY), RED (STOP), FLASHING BLUE/RED (just in case we haven't stopped at RED, this will definitely grab your attention!), followed by a WHITE output for 5 minutes (as a safety/nightlite sort of thing).
I used the RunningMedian library because just sitting on my desk without moving anything, the HC-SR04 output would randomly vary as much as 10cm in either direction. I know this requires a lot more processing, but overall gives a much more accurate distance.
My first question is, I am not sure where to actually call previousMillis = millis() The code works very well the way it is, but I just want to make sure it is correct. As best as I can figure out, to make it work the way I want is that 30 seconds after the RED led is first called (or 30 seconds after the FLASH is first called, just in case we've gone too far) that the light turns white. I figured if I call it at the end of YELLOW and RED sequences that it does what I want, but it just doesn't look right to me.
Secondly, when the LEDs are called to be lit, they flicker. Is there a way to make the code run smoother to prevent this? It MIGHT be a power issue, as I am powering the LED panel off the 5v on the Nano, which in turn is powered by the 9v 1A power supply, but the flickering was not noticeable when I ran the Neo_Pixel example code OR before I added the IF statement to check for lightState.
Any help and/or feedback would be greatly appreciated!