I am trying to turn a Green LED off with a pin LOW signal and turn a red LED on. I can do that. When the pin signal goes back to HIGH I want the red LED to turn off and a yellow LED to turn on for 5 sec, then turn off and the green LED to turn on until the pin signal goes LOW again. Thank you for your help. --Jack
int buttonPin = 6;
int ledPinR = 1;
int ledPinY = 2;
int ledPinG = 3;
int buttonState = HIGH;
void setup() {
pinMode(ledPinR, OUTPUT);
pinMode(ledPinY, OUTPUT);
pinMode(ledPinG, OUTPUT);
pinMode(buttonPin, INPUT);
}
void loop() {
buttonState = digitalRead(buttonPin);
if (buttonState == HIGH) {
digitalWrite(ledPinY, HIGH);
digitalWrite(ledPinG, LOW);
digitalWrite(ledPinR, HIGH);
}
else {
digitalWrite(ledPinY, HIGH);
digitalWrite(ledPinG, HIGH);
digitalWrite(ledPinR, LOW);
}
//when pin gose high want ledPinY
//to go LOW for 5 sec, then back
//to green until pin 6 goes low again
{
digitalWrite(ledPinY, LOW);
digitalWrite(ledPinG, HIGH);
digitalWrite(ledPinR, HIGH);
delay(5000);
}
}
something like this maybe:
uint8_t buttonPin = 6;
uint8_t ledPinR = 1;
uint8_t ledPinY = 2;
uint8_t ledPinG = 3;
uint8_t FSM_State = 0;
uint8_t buttonState;
unsigned long oldtime;
unsigned long ms_timing_default = 1000;
unsigned long ms_period = ms_timing_default;
void setup() {
pinMode(ledPinR, OUTPUT);
pinMode(ledPinY, OUTPUT);
pinMode(ledPinG, OUTPUT);
pinMode(buttonPin, INPUT);
//initialise board and variables
digitalWrite(ledPinY, LOW);
digitalWrite(ledPinG, LOW);
digitalWrite(ledPinR, HIGH);
oldtime = millis();
}
void loop() {
buttonState = digitalRead(buttonPin);
if (buttonState == HIGH) {
if (oldtime - millis() > ms_period) {
switch (FSM_State) {
case 0: // RED LED ON
oldtime = millis();
FSM_State = 1;
break;
case 1: // YELLOW LED ON approx 1s after buttonstate has been HIGH
oldtime = millis();
digitalWrite(ledPinY, HIGH);
digitalWrite(ledPinG, LOW);
digitalWrite(ledPinR, LOW);
ms_period *= 5; //increase timing to 5s (5*ms_timing_default)
FSM_State = 2;
break;
case 2: // 5s period over.GREEN LED ON. will remain in green until button is released
oldtime = millis();
digitalWrite(ledPinY, LOW);
digitalWrite(ledPinG, HIGH);
digitalWrite(ledPinR, LOW);
ms_period = ms_timing_default; //reset timing to default value
FSM_State = 2;
break;
}
}
}
else if (oldtime - millis() > ms_period) { //if buttonstate is LOW. RED LED ON approx. 1s to 5s after buttonstate has been LOW depending on the FSM state when button was released
oldtime = millis();
ms_period = ms_timing_default;
FSM_State = 0;
digitalWrite(ledPinY, LOW);
digitalWrite(ledPinG, LOW);
digitalWrite(ledPinR, HIGH);
}
}
further reading for you if interested to learn more about the method used here: Several Things at a Time
Hope that helps
Thank you for the reply sherzaad and now I am starting to understand more about FSM_State. The sketch is still not stepping through the cases the way I need them to.
The LEDs that I am working with are try-color with a common anode and that is why I am taking the cathode to pins 1, 2, or 3 LOW to turn them on. The sequence is as (CASE 1) long as pin 6 is HIGH the green LED is on. (CASE 2) When Pin 6 goes LOW the green LED goes off and the red LED is on. (CASE 3) When pin 6 goes back to HIGH the red LED goes off and the Yellow LED turns on for 5 seconds and then goes back to CASE 1. I thank everybody for your help, I am learning. --Jack
LS3Jack:
The LEDs that I am working with are try-color with a common anode and that is why I am taking the cathode to pins 1, 2, or 3 LOW to turn them on. The sequence is as (CASE 1) long as pin 6 is HIGH the green LED is on. (CASE 2) When Pin 6 goes LOW the green LED goes off and the red LED is on. (CASE 3) When pin 6 goes back to HIGH the red LED goes off and the Yellow LED turns on for 5 seconds and then goes back to CASE 1.
To me, that is what the sketch I shared should be doing.
LS3Jack:
The sketch is still not stepping through the cases the way I need them to.
Please explain what it is actually doing in your set up and explain again how that is different to your requirement.
I got it to work for me. I had to change the HIGHs to LOW a LOWs to HIGH due to the way the LEDs were wired. Then when it cycled through the CASEs the yellow would just flicker, it would not stay on for 5 sec. In CASE 1 removed "ms_period *= 5" and replaced it with a "delay(5000)". Here is the sketch:
uint8_t buttonPin = 6;
uint8_t ledPinR = 1;
uint8_t ledPinY = 2;
uint8_t ledPinG = 3;
uint8_t FSM_State = 0;
uint8_t buttonState;
unsigned long oldtime;
unsigned long ms_timing_default = 1000;
unsigned long ms_period = ms_timing_default;
void setup() {
pinMode(ledPinR, OUTPUT);
pinMode(ledPinY, OUTPUT);
pinMode(ledPinG, OUTPUT);
pinMode(buttonPin, INPUT_PULLUP);
//initialise board and variables
digitalWrite(ledPinY, HIGH);
digitalWrite(ledPinG, HIGH);
digitalWrite(ledPinR, HIGH);
oldtime = millis();
}
void loop() {
buttonState = digitalRead(buttonPin);
if (buttonState == HIGH) {
if (oldtime - millis() > ms_period) {
switch (FSM_State) {
case 0: // GREEN ON
oldtime = millis();
FSM_State = 1;
break;
case 1: // YELLOW LED ON when buttonstate state gose HIGH for X amount sec
oldtime = millis();
digitalWrite(ledPinY, LOW);
digitalWrite(ledPinG, HIGH);
digitalWrite(ledPinR, HIGH);
delay(5000); //increase timing to 5s (5*ms_timing_default)
FSM_State = 2;
break;
case 2: // GREEN LED ON. will remain in green until button is released
oldtime = millis();
digitalWrite(ledPinY, HIGH);
digitalWrite(ledPinG, LOW);
digitalWrite(ledPinR, HIGH);
ms_period = ms_timing_default; //reset timing to default value
FSM_State = 2;
break;
}
}
}
else if (oldtime - millis() > ms_period) { //if buttonstate is LOW. RED LED ON
oldtime = millis();
ms_period = ms_timing_default;
FSM_State = 0;
digitalWrite(ledPinY, HIGH);
digitalWrite(ledPinG, HIGH);
digitalWrite(ledPinR, LOW);
}
}
sherzaad I thank you for pointing me in the right direction and I learned about FSM_State. --Jack