///////////////////// // Inclusions // ///////////////////// #include ///////////////////// // Definitions // ///////////////////// // Define the pin number for CytronDriver and Motor for Gate (MotorA) int freq = 5000; //PWM initialisation int ledChannel = 0; int resolution = 8; const byte dirPin = 18; // DIR is connected to pin 18. //Define limit switches //const byte LimitSwitch1 = 12; //physical buttons mapped to esp32 pins //const byte LimitSwitch2 = 26; //Physical buttons mapped to esp32 pins // toggles LED when interrupt pin changes state int pinLimitSwitch1 = 12; int pinLimitSwitch2 = 26; volatile int state = HIGH; portMUX_TYPE synch = portMUX_INITIALIZER_UNLOCKED; const byte LED1 = 14; const byte LED2 = 25; const byte StateA_Idle = 0; const byte StateA_OpenRoof = 1; const byte StateA_CloseRoof = 2; const byte StateA_OpenRoofComplete = 3; const byte StateA_CloseRoofComplete = 4; byte currentStateA; long currentTime, lastTime; int count = 0; char messages[50]; char messages2[50]; void IRAM_ATTR switches() { portENTER_CRITICAL(&synch); state = !state; portEXIT_CRITICAL(&synch); } void setup() { ledcSetup(ledChannel, freq, resolution); ledcAttachPin(19, ledChannel); //Attach PWM pin to GPIO 19 pinMode(dirPin, OUTPUT); pinMode(LED1, OUTPUT); //GPIO 34 pinMode(LED2, OUTPUT); //GPIO 35 digitalWrite(LED1, LOW); digitalWrite(LED2, LOW); //pinMode(LimitSwitch1, INPUT_PULLUP); //pinMode(LimitSwitch2, INPUT_PULLUP); pinMode(pinLimitSwitch1, OUTPUT); pinMode(pinLimitSwitch2, OUTPUT); attachInterrupt(0, switches, CHANGE); Serial.begin(115200); currentStateA = 0xFF; // Force a change to enter the idle state } void loop() { // Check if we need to change state byte nextState = currentStateA; switch (currentStateA) { case StateA_Idle: { // If we received a valid command, start the operation if(Serial.available() > 0) { switch (Serial.read()) { case 'a': Serial.println("OpenRoof"); nextState = StateA_OpenRoof; break; case 'b': Serial.println("EmergencyStop or Idle"); nextState = StateA_Idle; break; case 'c': Serial.print("CloseRoof"); nextState = StateA_CloseRoof; break; case '\r': // Ignore the carriage return character. break; case '\n': // Ignore the line feed character. break; default: Serial.println("Invalid Input"); // Here we notify that there was a bad comman break; } } } break; case StateA_OpenRoof: if (digitalRead(pinLimitSwitch1) == LOW) // == HIGH is not necessary nextState = StateA_OpenRoofComplete; break; case StateA_CloseRoof: if (digitalRead(pinLimitSwitch2) == LOW) // == HIGH is not necessary nextState = StateA_CloseRoofComplete; break; default: nextState = StateA_Idle; break; } // If there was a change, switch state and trigger enter condition if (nextState != currentStateA) { currentStateA = nextState; // Move in the new state switch (currentStateA) { // Entering the new state case StateA_Idle: // Stop motor A ledcWrite(ledChannel, 0); // we stopped here. digitalWrite(dirPin, LOW); digitalWrite(LED1, LOW); digitalWrite(LED2, LOW); //Serial.println("Roof Is Stationary"); break; case StateA_OpenRoof: // Start motor A ledcWrite(ledChannel, 128); digitalWrite(dirPin, LOW); digitalWrite(LED1, HIGH); //Serial.println("Roof Is Now Opening"); break; case StateA_CloseRoof: // Start motor A ledcWrite(ledChannel, 128); digitalWrite(dirPin, HIGH); digitalWrite(LED2, HIGH); //Serial.println("Roof Is Now Closing"); break; case StateA_OpenRoofComplete: // Start motor A ledcWrite(ledChannel, 0); digitalWrite(dirPin, LOW); //Serial.println("Roof Is Now Opened"); break; case StateA_CloseRoofComplete: // Start motor A ledcWrite(ledChannel, 0); digitalWrite(dirPin, HIGH); //Serial.println("Roof Is Now Closed"); break; } } }