// Pin Definitions
const int redLED = 7;
const int whiteLED = 8;
const int greenLED = 9;
const int blueLED = 10;
const int powerSwitch = 5;
const int blockedSwitch= 4;
const int starvedSwitch = 3;
const int stopPushButton = 6;
const int startButton = 2;
// State Definitions
const int STATE_PREPARED = 10;
const int STATE_PRODUCING = 20;
const int STATE_STOPPED = 30;
const int STATE_BLOCKED = 40;
const int STATE_STARVED = 50;
const int STATE_IDLE = 100;
// Timing Definitions (in milliseconds)
const unsigned long TMR1_DURATION = 10000; // 10 seconds
const unsigned long TMR2_DURATION = 5000; // 5 seconds
const unsigned long TMR3_DURATION = 10000; // 10 seconds
const unsigned long TMR4_DURATION = 5000; // 5 seconds
// Global Variables
int currentState = STATE_IDLE; // Initial state is IDLE
unsigned long timerStart = 0; // To track when the state started
// Variable declarations
bool stopPushed = false; // Indicates a momentary push button press
bool stopLatched = false; // Tracks the latched state of the button
bool lastButtonState = HIGH; // Previous state of the button (assumes pull-up)
void setup() {
// Initialize serial communication
Serial.begin(9600);
// Initialize pin modes
pinMode(redLED, OUTPUT);
pinMode(whiteLED, OUTPUT);
pinMode(greenLED, OUTPUT);
pinMode(blueLED, OUTPUT);
pinMode(powerSwitch, INPUT);
pinMode(blockedSwitch, INPUT);
pinMode(starvedSwitch, INPUT);
pinMode(startButton, INPUT);
pinMode(stopPushButton, INPUT); // Set button pin as input with pull-up
// Start in IDLE state
setIdleState();
}
void loop() {
// Check the state of the power switch
if (digitalRead(powerSwitch) == HIGH) {
if (currentState == STATE_IDLE) {
transitionToState(STATE_PREPARED); // From IDLE to PREPARED state
} else {
updateState(); // Handle other states
}
} else {
if (currentState != STATE_IDLE) {
setIdleState(); // If power is off, go to IDLE state
}
}
// Read the current state of the push button
bool currentButtonState = digitalRead(stopPushButton);
// Transition detection: LOW to HIGH
if (currentButtonState == HIGH && lastButtonState == LOW && !stopLatched) {
stopPushed = true; // Set stopPushed HIGH for one scan
stopLatched = true; // Latch the state
} else if (stopLatched && currentButtonState == HIGH) {
stopPushed = false; // Maintain stopPushed LOW while latched
} else if (stopLatched && currentButtonState == LOW) {
stopPushed = false; // Reset stopPushed
stopLatched = false; // Unlatch when button is released
}
// Update lastButtonState for the next loop iteration
lastButtonState = currentButtonState;
// Debug output (optional)
// Serial.print("stopPushed: ");
// Serial.print(stopPushed);
// Serial.print(" | stopLatched: ");
// Serial.println(stopLatched);
delay(10); // Small delay to debounce the button
}
void updateState() {
unsigned long currentTime = millis();
if (digitalRead(blockedSwitch) == HIGH){
transitionToState(STATE_STOPPED);
}
else {
switch (currentState) {
case STATE_PREPARED:
// Wait for the StartButton to be pressed to start production
if (digitalRead(startButton) == HIGH) {
Serial.println("Start button pressed. Starting production.");
transitionToState(STATE_PRODUCING);
}
break;
case STATE_PRODUCING:
// Stop production if the StartButton is released
if (digitalRead(startButton) == LOW) {
Serial.println("Start button released. Stopping production.");
transitionToState(STATE_STOPPED);
} else if (digitalRead(blockedSwitch) == HIGH) {
Serial.println("Blocked condition detected.");
transitionToState(STATE_BLOCKED);
} else if (digitalRead(starvedSwitch) == HIGH) {
Serial.println("Starved condition detected.");
transitionToState(STATE_STARVED);
}
break;
case STATE_STOPPED:
// Wait for the StartButton to be pressed again to resume production
if (digitalRead(startButton) == HIGH) {
Serial.println("Start button pressed. Resuming production.");
transitionToState(STATE_PRODUCING);
}
break;
case STATE_BLOCKED:
// Handle blocked condition and resume if unblocked
if (digitalRead(blockedSwitch) == LOW) {
Serial.println("Unblocked. Resuming production.");
transitionToState(STATE_PRODUCING);
}
break;
case STATE_STARVED:
// Handle starved condition and resume if resolved
if (digitalRead(starvedSwitch) == LOW) {
Serial.println("Unstarved. Resuming production.");
transitionToState(STATE_PRODUCING);
}
break;
}
}
}
void setIdleState() {
// Turn off all LEDs
digitalWrite(redLED, LOW);
digitalWrite(whiteLED, LOW);
digitalWrite(greenLED, LOW);
digitalWrite(blueLED, LOW);
// Set the state to IDLE
currentState = STATE_IDLE;
Serial.println("System is idle.");
}
void transitionToState(int newState) {
currentState = newState;
timerStart = millis(); // Reset the timer for the new state
Serial.print("Transitioning to state: ");
Serial.println(newState);
switch (newState) {
case STATE_PREPARED:
digitalWrite(redLED, LOW);
digitalWrite(whiteLED, HIGH); // Indicate system is prepared
digitalWrite(greenLED, LOW);
digitalWrite(blueLED, LOW);
break;
case STATE_PRODUCING:
digitalWrite(redLED, LOW);
digitalWrite(whiteLED, LOW);
digitalWrite(greenLED, HIGH); // Green LED for production
digitalWrite(blueLED, LOW);
break;
case STATE_STOPPED:
digitalWrite(redLED, HIGH); // Red LED for stopped state
digitalWrite(whiteLED, LOW);
digitalWrite(greenLED, LOW);
digitalWrite(blueLED, LOW);
break;
case STATE_BLOCKED:
digitalWrite(redLED, LOW);
digitalWrite(whiteLED, HIGH); // White + Blue LEDs for blocked
digitalWrite(greenLED, LOW);
digitalWrite(blueLED, HIGH);
break;
case STATE_STARVED:
digitalWrite(redLED, HIGH); // Red + Blue LEDs for starved
digitalWrite(whiteLED, LOW);
digitalWrite(greenLED, LOW);
digitalWrite(blueLED, HIGH);
break;
}
}