Go Down

Topic: Doing a routine (yellow LED on) after pin goes HIGH, <SOLVED>  (Read 111 times) previous topic - next topic

LS3Jack

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);
}

}

sherzaad

something like this maybe:
Code: [Select]

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

LS3Jack

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

sherzaad

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.

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.

LS3Jack

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:

Code: [Select]
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

Go Up