Help finishing State Machine Code

It's been some time since I have worked on this project and needed to come back around to it. I thought best to provide a summary to help explain what it's for as well.

Purpose - Clinic Notification System for Nurses

Summary
Clinic management has asked for a "timer light" that will notify nurses to tell patients about their wait time or adjusted wait time.

Function
On/Start Button will turn on a timer and a green light, the green light is on for 15 minutes. Then at after the green light will shut off and a yellow light will turn on for 5 minutes. Then after this five minute interval the yellow light will turn off and a red light will turn on, blinking, until the button is pressed again.

  • Green means patient was last spoken too "recently".
  • Yellow means patient has been waiting for more than 15 minutes, maybe pop your head in?
  • Red means the patient has not had an interaction or update in longer than 20 minutes update patient ASAP.

Once the second button is pressed it stops the timer and turns off all lights until the On/Start button is pressed again to run through this again.

Arduino unit is currently built and functioning. It works well OUTSIDE of a State Machine but a State machine is really where I believe it should be after receiving so much help here previously (6-8 weeks ago).

Here is the code - see below.

Requested Help

  • How do I fix the timing?
  • What should the timing be?
static unsigned long time;
static unsigned int state;

const int  buttonOn = 4;
const int  buttonOff = 11;
const int ledPin = 2;
const int ledPinY = 12;
const int ledPinR = 9;

int buttonStateOn;
int buttonStateOff;
int stateStartMillis;
int stateChange;
int currentMillis;

int StateLength[] = {4000UL,8000UL};

void setup()
{
  pinMode(buttonOn, INPUT);
  pinMode(buttonOff, INPUT);
  pinMode(ledPin, OUTPUT);
  pinMode(ledPinY, OUTPUT);
  pinMode(ledPinR, OUTPUT);
  Serial.begin(9600);

  time = 0;
  state = 1;
}

void loop()
{
  switch (state)
    {
    case 0:
    time = millis();
    break;
    case 1:
      buttonStateOn = digitalRead(buttonOn);
      if (buttonStateOn == HIGH  && time + millis() <= StateLength[1] ) {
        digitalWrite(ledPin, HIGH);
        time = millis();
        if (time - millis() > StateLength[1]) { //check if time has passed
          time = millis();
          state = 2;
        }
      } else {
        buttonStateOff = digitalRead(buttonOff);
        if (buttonStateOff == HIGH) {
          digitalWrite(ledPin, LOW); 
          delay(50);
          digitalWrite(ledPinY, LOW); 
          delay(50);
          digitalWrite(ledPinR, LOW); 
          delay(50);
          state = 0;
          time = 0;
        }
      }
    break;
    case 2:
      if (buttonStateOff == LOW) {
        digitalWrite(ledPin, LOW);
        delay(50);
        digitalWrite(ledPinY, HIGH);
        time = millis();
          if (time - millis() > StateLength[0]) { //check if time has passed
            time = millis();
            state = 3;
          }
        } else {
            buttonStateOff = digitalRead(buttonOff);
            if (buttonStateOff == HIGH) {
              digitalWrite(ledPin, LOW); 
              delay(50);
              digitalWrite(ledPinY, LOW); 
              delay(50);
              digitalWrite(ledPinR, LOW); 
              delay(50);
              state = 0;
            }
        }
    break;
    case 3:
      if (buttonStateOff == LOW) {
        digitalWrite(ledPinY, LOW);
        delay(50);
        digitalWrite(ledPinR, HIGH);
        delay(50);
        digitalWrite(ledPinR, LOW);
        delay(50);
        digitalWrite(ledPinR, HIGH);
        time = millis();
        } else {
          buttonStateOff = digitalRead(buttonOff);
          if (buttonStateOff == HIGH) {
            digitalWrite(ledPin, LOW); 
            delay(50);
            digitalWrite(ledPinY, LOW); 
            delay(50);
            digitalWrite(ledPinR, LOW); 
            delay(50);
            state = 0;
          }
        }
      }
}

See this example:
https://forum.arduino.cc/index.php?topic=525240.0

Thank you! I am taking a look now.

Ok so if I, a novice at Arduino, am going to go this route I am going to have to re-write everything.

Perhaps that is someone who can guide me specifically on my code, provided in the original post, so I can possibly work with what I have unless what I have is completed incorrect?

I almost wonder if I should simply incorporate a "power switch", physically, into this unit which is the on / start or reset/off to ease this rather than a state machine?

Ok so if I, a novice at Arduino, am going to go this route I am going to have to re-write everything.

You have the algorithm already in your head :wink:

I almost wonder if I should simply incorporate a "power switch", physically, into this unit which is the on / start or reset/off to ease this rather than a state machine?

You're in control.

void loop( ) {
    switch( state ) {
        case 'O':   if( digitalRead( start_button ) == HIGH ) {
                        state = 'G';
                        Timer = millis( );
                        digitalWrite( green_led, 0 );               // green on
                    }
                    break;
        case 'G':   if( (millis( ) - Timer) > green_to ) {          // test for green timeout
                        state = 'Y';
                        Timer = millis( );
                        digitalWrite( green_led, 1 );               // green off
                        digitalWrite( yellow_led, 0 );              // yellow on
                    }
                    break;
        case 'Y':   if( (millis( ) - Timer) > yellow_to ) {         // test for yellow timeout
                        state = 'R';
                        Timer = millis( );
                        digitalWrite( yellow_led, 1 );              // yellow off
                        digitalWrite( red_led, 0 );                 // red on
                    }
                    break;
        case 'R':   if( (millis( ) - Timer) > red_blink_to ) {      // test for red blink timeout
                        digitalWrite( red_led, !(digitalRead( red_led ) );
                        Timer = millis( );
                    }
                    break;
        default:    break;
    }

    if( digitalRead( stop_button ) == HIGH ) {
        digitalWrite( red_led, 1 );             // red off
        digitalWrite( yellow_led, 1 );          // yellow off
        digitalWrite( green_led, 1 );           // green off
        state = 'O';                            // system off
    }
}

Does this work?
Looks like you can get away without button debounce.

Thank you! Giving this a try, it's been a few days and have some time this afternoon to work on this project again.

Updates to follow! Appreciate the help!