Apparently, I've stepped away from programming for too long... My intent is to have a light relay and a horn relay controlled by a single push button. The horn will follow the state of the push button (sounding when button is depressed, silent otherwise) and the light will be on for a period of time (say 3 seconds) from the first time the button is depressed. The light will stay on no matter the state of the push button during that aforementioned period of time allowing me to sound the horn repeatedly while not affecting the status of the light. After 3 seconds, the light turns off and is ready to relight upon next depression of the push button which, again, will also sound the horn.
With the code below, I have a couple issues:
- When the Uno is powered up initially, the horn relay is energized immediately until the first cycling of the push button, then it follows as described above correctly.
- The light relay never energizes no matter the state of the push button.
I believe the problem is in my application of the millis timing but I'm unsure where my logic is flawed.
Hardware
UNO R3
AOKIN 2-Relay Module
Generic Amazon pushbutton
```cpp
const int buttonPin = 5; // the pin that the pushbutton is attached to
const int rlyHrn = 6; // the pin that the horn relay is attached to
const int rlyLgt = 7; // the pin that the light relay is attached to
// Variables will change:
int buttonState = 0; // current state of the button
int lastButtonState = 0; // previous state of the button
unsigned long previousMillis = 0;
unsigned long elapsedTime = 0;
void setup() {
// initialize the button pin as a input:
pinMode(buttonPin, INPUT);
// initialize the horn relay as an output:
pinMode(rlyHrn, OUTPUT);
// initialize the light relay as an output:
pinMode(rlyLgt, OUTPUT);
// initialize serial communication:
Serial.begin(9600);
}
void loop() {
buttonState = digitalRead(buttonPin); //read current state of button
if (buttonState != lastButtonState) { //compare current button state to last
horn(); //run horn subroutine
lights(); //run lighting subroutine
lastButtonState = buttonState; //set last button state to current status for future use
}
}
void horn() {
if (buttonState == LOW) {
// if the current state is LOW then the button went from on to off:
digitalWrite(rlyHrn, HIGH);
} else {
// if the current state is HIGH then the button went from off to onn:
digitalWrite(rlyHrn, LOW);
}
}
void lights() {
previousMillis = millis(); // set present time into prevous millis for future math
elapsedTime = millis() - previousMillis; //establish elapsed time from line above and the *now* current time
if (elapsedTime < 3000) { //if less than 3 seconds have elapsed since button has gone high, execute this logic
digitalWrite(rlyLgt, LOW); //turn lights on
} else {
digitalWrite(rlyLgt, HIGH); // if more than 3s have elapsed, turn lights off
}
}
