The code below is is supposed to act as a state machine. All it does is light up the LED corresponding to the appropriate state. When the user clicks the overRide button, the progression of the state changes, so the state will jump to another state indicated by the if statement instead of the natural progression. The program should be continuously listening for the keypad input. Such that if "*" is pressed three times consecutively or "E", the program will terminate. If those buttons are not pressed continuously, at least the program will change the state accordingly based on the if statements in each case of the switch statement.
I am having issues trying to figure out how to use millis(). I tried using delay() but it is not giving me the results that I want. The program does go into override mode, but it doesn't do it until it has entered the next state. Further more only 13/16 buttons will work in getting the program into override mode. I was trying to see if there was a way that I could press a button from the keypad during one of the states and have the button set overRide = true; so that overRide can be implemented during state it was clicked.
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
/**********************/
/* code for kepad
/**********************/
#include <Keypad.h>
#define KEYPAD_ROW0 22
#define KEYPAD_ROW1 23
#define KEYPAD_ROW2 24
#define KEYPAD_ROW3 25
#define KEYPAD_COL0 26
#define KEYPAD_COL1 27
#define KEYPAD_COL2 28
#define KEYPAD_COL3 29
const byte keypad_rows = 4; //four rows
const byte keypad_cols = 4; //three columns
char keypad_keys[keypad_rows][keypad_cols] = {
{'1','2','3','A'},
{'4','5','6','B'},
{'7','8','9','C'},
{'*','0','#','D'}
};
byte keypad_rowPins[keypad_rows] = {KEYPAD_ROW0, KEYPAD_ROW1, KEYPAD_ROW2, KEYPAD_ROW3}; //connect to the row pinouts of the keypad
byte keypad_colPins[keypad_cols] = {KEYPAD_COL0, KEYPAD_COL1, KEYPAD_COL2, KEYPAD_COL3}; //connect to the column pinouts of the keypad
Keypad customKeypad = Keypad( makeKeymap(keypad_keys), keypad_rowPins, keypad_colPins, keypad_rows, keypad_cols );
/****************************/
/* code for LCD display
/***************************/
#include <LiquidCrystal.h>
LiquidCrystal
lcd(4, 6, 10, 11, 12, 13);
//needed for temporarily holding text to be sent to LCD
char lcd_text_string[40];
int lcd_current_row;
int lcd_current_col;
// code for buzzer
const int BUZZER = 49;
// code for LEDs
const int GREEN = 32;
const int YELLOW = 34;
const int RED = 36;
const int BLUE = 38;
//current state
int current_state = 1;
//next state
int next_state = 0;
//OVERIDE KEY
bool overRide = false;
// hold keypad inputs
char userChar;
char keypad_input[3] = {0,0,0};
//counts the number of times character appears
int count = 0;
//Termination count
int terminate = 0;
void setup() {
// put your setup code here, to run once:
Serial.begin(115200);
// set up for buzzer
pinMode(BUZZER, OUTPUT);
//setup for LEDS
pinMode(GREEN, OUTPUT);
pinMode(YELLOW, OUTPUT);
pinMode(RED, OUTPUT);
pinMode(BLUE, OUTPUT);
}
void loop() {
char customKey = customKeypad.getKey();
if(customKey) // checks if key is pressed during a state
{
userChar = customKey;
lcd.print(userChar);
setOverRide();
}
else
{
overRide = false;
}
stateMachine();
}
//This function contains all the states
void stateMachine(){
switch(current_state)
{
case 1:
lcd.print("now in STATE: 1");
digitalWrite(GREEN, LOW);
digitalWrite(YELLOW, LOW);
digitalWrite(RED, HIGH);
digitalWrite(BLUE, LOW);
delay(3000);
lcd.clear();
if( overRide == false)
{
next_state = 2;
}
else if( overRide == true)
{
lcd.print("OVERRIDE MODE");
next_state = 9;
}
current_state = next_state;
break;
case 2:
lcd.print("now in STATE: 2");
digitalWrite(GREEN, HIGH);
digitalWrite(YELLOW, LOW);
digitalWrite(RED, LOW);
digitalWrite(BLUE, LOW);
if( overRide == false)
{
delay(7000);
lcd.clear();
next_state = 3;
}
else if( overRide == true)
{
delay(2000);
lcd.clear();
lcd.print("OVERRIDE MODE");
next_state = 7;
}
current_state = next_state;
break;
case 3:
lcd.print("now in STATE 3");
digitalWrite(GREEN, LOW);
digitalWrite(YELLOW, HIGH);
digitalWrite(RED, LOW);
digitalWrite(BLUE, LOW);
delay(2000);
lcd.clear();
if( overRide == false)
{
next_state = 4;
}
else if( overRide == true)
{
lcd.print("OVERRIDE MODE");
delay(2000);
next_state = 9;
}
current_state = next_state;
break;
case 4:
lcd.print("now in STATE 4");
digitalWrite(GREEN, LOW);
digitalWrite(YELLOW, LOW);
digitalWrite(RED, HIGH);
digitalWrite(BLUE, LOW);
delay(3000);
lcd.clear();
if( overRide == false)
{
next_state = 5;
}
else if( overRide == true)
{
lcd.print("OVERRIDE MODE");
delay(2000);
next_state = 9;
}
current_state = next_state;
break;
case 5:
lcd.print("now in STATE 5");
digitalWrite(GREEN, LOW);
digitalWrite(YELLOW, LOW);
digitalWrite(RED, HIGH);
digitalWrite(BLUE, LOW);
if( overRide == false)
{
delay(7000);
lcd.clear();
next_state = 6;
}
else if( overRide == true)
{
delay(2000);
lcd.clear();
lcd.print("OVERRIDE MODE");
delay(2000);
next_state = 9;
}
current_state = next_state;
break;
case 6:
lcd.print("now in STATE 6");
digitalWrite(GREEN, LOW);
digitalWrite(YELLOW, LOW);
digitalWrite(RED, HIGH);
digitalWrite(BLUE, LOW);
delay(2000);
lcd.clear();
if( overRide == false)
{
next_state = 1;
}
else if( overRide == true)
{
delay(2000);
lcd.print("OVERRIDE MODE");
delay(2000);
next_state = 9;
}
current_state = next_state;
break;
case 7:
lcd.print("now in STATE 7");
digitalWrite(GREEN, LOW);
digitalWrite(YELLOW, HIGH);
digitalWrite(RED, LOW);
digitalWrite(BLUE, LOW);
delay(2000);
lcd.clear();
next_state = 9;
current_state = next_state;
break;
case 8:
lcd.print("now in STATE 8");
digitalWrite(GREEN, LOW);
digitalWrite(YELLOW, LOW);
digitalWrite(RED, HIGH);
digitalWrite(BLUE, LOW);
delay(2000);
lcd.clear();
next_state = 9;
current_state = next_state;
break;
case 9:
lcd.print("now in STATE 9");
digitalWrite(GREEN, LOW);
digitalWrite(YELLOW, LOW);
digitalWrite(RED, HIGH);
digitalWrite(BLUE, HIGH);
overRide = false;
next_state = 1;
current_state = next_state;
for(int i = 0; i < 5; i++)
{
tone(BUZZER, 1000);
delay(1000);
noTone(BUZZER);
delay(1000);
}
lcd.clear();
break;
}
}
bool setOverRide() // returns the value of the boolean oveRide
{
lcd.print("OVERIDE FUNC");
Serial.println(userChar);
delay(1000);
lcd.clear();
overRide = true;
keypad_input[count]= userChar;
count++;
if( count == 3 )
{
if(keypad_input[0] == keypad_input[1] && keypad_input[1] == keypad_input[2])
{
terminate = true;
}
else
{
count = 0;
}
}
return overRide;
}