/*
const int sensorClosedPin = 2; // Sensor detecting the closed position
const int sensorOpenPin = 3; // Sensor detecting the open position
const int buttonClosePin = 4; // Button for closing the door (unused in this update)
const int buttonOpenPin = 5; // Button for opening the door (unused in this update)
const int buttonStopPin = 6; // Button to stop the door (unused in this update)
const int blueLEDPin = 7; // Motor control pin (controls opening/closing)
const int yellowLEDPin = 8; // Yellow LED for movement indication
const int greenLEDPin = 9; // Green LED for door closed indication
const int redLEDPin = 10; // Red LED for door open indication
const int buzzerPin = 11; // Buzzer pin
const int buttonControlPin = 12;
const int relayOpenPin = 13; // Relay control pin for opening the door
const int relayClosePin = 14; // Relay control pin for closing the door
const int relayStopPin = 15; // Relay control pin to stop the door
DOOR_CLOSED state means:
sensorClosedPin = LOW
sensorOpenPin = Ignoring,
DOOR_OPEN state means:
sensorClosedPin = Ignoring
sensorOpenPin = LOW,
DOOR_MOVING state means:
sensorClosedPin = HIGH
sensorOpenPin = HIGH
# Wokwi Library List
# See https://docs.wokwi.com/guides/libraries
# Automatically added based on includes:
Adafruit GFX Library
Adafruit SSD1306
*/
#include <Arduino.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
const int sensorClosedPin = 2;
const int sensorOpenPin = 3;
const int buttonClosePin = 4;
const int buttonOpenPin = 5;
const int buttonStopPin = 6;
const int blueLEDPin = 7;
const int yellowLEDPin = 8;
const int greenLEDPin = 9;
const int redLEDPin = 10;
const int buzzerPin = 11;
const int buttonControlPin = 12;
const int relayOpenPin = 13;
const int relayClosePin = 14;
const int relayStopPin = 15;
const int relayTogglePin = 16;
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1); // -1 for no reset pin
enum DoorState {
DOOR_CLOSED,
DOOR_OPEN,
DOOR_MOVING,
STOP_EMERGENCY
};
DoorState currentState = DOOR_CLOSED;
unsigned long lastChangeTime = 0;
unsigned long doorStartTime = 0; // Track time for moving or opened state
bool doorStateReadingEnabled = true; // Flag to control door state reading
bool yellowLEDBlinking = false;
struct Relay {
int pin;
bool active;
unsigned long startTime;
};
Relay relays[] = {
{relayOpenPin, false, 0},
{relayClosePin, false, 0},
{relayStopPin, false, 0},
{relayTogglePin, false, 0}
};
void setup() {
Serial.begin(9600);
pinMode(sensorClosedPin, INPUT_PULLUP);
pinMode(sensorOpenPin, INPUT_PULLUP);
pinMode(buttonClosePin, INPUT_PULLUP);
pinMode(buttonOpenPin, INPUT_PULLUP);
pinMode(buttonStopPin, INPUT_PULLUP);
pinMode(blueLEDPin, OUTPUT);
pinMode(yellowLEDPin, OUTPUT);
pinMode(greenLEDPin, OUTPUT);
pinMode(redLEDPin, OUTPUT);
pinMode(buzzerPin, OUTPUT);
pinMode(buttonControlPin, INPUT_PULLUP);
for (Relay& relay : relays) {
pinMode(relay.pin, OUTPUT);
digitalWrite(relay.pin, LOW);
}
if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
Serial.println(F("SSD1306 allocation failed"));
while (true);
}
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE);
displayInitialState();
}
void loop() {
handleInputs();
if (doorStateReadingEnabled) {
updateState();
}
manageLEDs();
checkBuzzer();
manageRelays();
updateDisplay(); // Update the OLED display
}
void displayInitialState() {
Serial.print("Initial State: ");
Serial.print("Sensor Closed: ");
Serial.println(digitalRead(sensorClosedPin));
Serial.print("Sensor Open: ");
Serial.println(digitalRead(sensorOpenPin));
}
void handleInputs() {
if (!doorStateReadingEnabled) {
if (digitalRead(buttonClosePin) == LOW || digitalRead(buttonOpenPin) == LOW || digitalRead(buttonControlPin) == LOW) {
doorStateReadingEnabled = true;
Serial.println("Door state reading resumed");
}
return;
}
if (digitalRead(buttonClosePin) == LOW) {
activateRelay(relayClosePin);
}
if (digitalRead(buttonOpenPin) == LOW) {
activateRelay(relayOpenPin);
}
if (digitalRead(buttonStopPin) == LOW) {
activateRelay(relayStopPin);
currentState = STOP_EMERGENCY;
lastChangeTime = millis();
doorStateReadingEnabled = false;
Serial.println("STOP button pressed - door state reading disabled");
}
if (digitalRead(buttonControlPin) == LOW) {
activateRelay(relayTogglePin);
}
}
void updateState() {
int sensorClosed = digitalRead(sensorClosedPin);
int sensorOpen = digitalRead(sensorOpenPin);
if (currentState != STOP_EMERGENCY) {
if (sensorClosed == LOW) {
currentState = DOOR_CLOSED;
doorStartTime = 0;
} else if (sensorOpen == LOW) {
currentState = DOOR_OPEN;
if (doorStartTime == 0) doorStartTime = millis();
} else {
currentState = DOOR_MOVING;
if (doorStartTime == 0) doorStartTime = millis();
}
}
if (currentState == STOP_EMERGENCY && millis() - lastChangeTime >= 1000) {
digitalWrite(relayStopPin, LOW);
currentState = DOOR_CLOSED;
}
}
void manageLEDs() {
switch (currentState) {
case DOOR_CLOSED:
digitalWrite(greenLEDPin, HIGH);
digitalWrite(blueLEDPin, LOW);
digitalWrite(redLEDPin, LOW);
stopBlinkingYellowLED();
break;
case DOOR_OPEN:
digitalWrite(greenLEDPin, LOW);
digitalWrite(blueLEDPin, HIGH);
digitalWrite(redLEDPin, LOW);
stopBlinkingYellowLED();
break;
case DOOR_MOVING:
digitalWrite(greenLEDPin, LOW);
digitalWrite(blueLEDPin, LOW);
digitalWrite(redLEDPin, LOW);
manageYellowLED();
break;
case STOP_EMERGENCY:
digitalWrite(greenLEDPin, LOW);
digitalWrite(blueLEDPin, LOW);
digitalWrite(yellowLEDPin, LOW);
blinkRedLED();
break;
}
}
void manageYellowLED() {
static unsigned long lastChangeTime = 0;
if (!yellowLEDBlinking) {
yellowLEDBlinking = true;
lastChangeTime = millis();
}
if (millis() - lastChangeTime >= 200) {
digitalWrite(yellowLEDPin, !digitalRead(yellowLEDPin));
lastChangeTime = millis();
}
}
void stopBlinkingYellowLED() {
yellowLEDBlinking = false;
digitalWrite(yellowLEDPin, LOW);
}
void blinkRedLED() {
static unsigned long lastBlinkTime = 0;
static bool redState = false;
if (millis() - lastBlinkTime >= 500) {
redState = !redState;
digitalWrite(redLEDPin, redState);
lastBlinkTime = millis();
}
}
void activateRelay(int relayPin) {
for (Relay& relay : relays) {
if (relay.pin == relayPin) {
relay.active = true;
relay.startTime = millis();
digitalWrite(relay.pin, HIGH);
break;
}
}
}
void manageRelays() {
unsigned long currentTime = millis();
for (Relay& relay : relays) {
if (relay.active && currentTime - relay.startTime >= 1000) {
digitalWrite(relay.pin, LOW);
relay.active = false;
}
}
}
void checkBuzzer() {
static unsigned long lastBuzzerTime = 0;
static bool buzzerOn = false;
unsigned long elapsedTime = millis() - doorStartTime;
if (currentState == DOOR_MOVING || currentState == DOOR_OPEN) {
if (elapsedTime >= 20000) {
if (millis() - lastBuzzerTime >= 1000) {
if (buzzerOn) {
noTone(buzzerPin);
buzzerOn = false;
} else {
tone(buzzerPin, 440);
buzzerOn = true;
}
lastBuzzerTime = millis();
}
}
} else if (currentState == STOP_EMERGENCY) {
static unsigned long lastStopBuzzerTime = 0;
static int beepCount = 0;
if (beepCount < 4) {
if (millis() - lastStopBuzzerTime >= 1000) {
tone(buzzerPin, 440);
lastStopBuzzerTime = millis();
beepCount++;
}
} else {
noTone(buzzerPin);
beepCount = 0; // Reset beep count after 4 beeps
}
} else {
noTone(buzzerPin); // Turn off the buzzer in other states
}
}
void updateDisplay() {
display.clearDisplay();
display.setTextSize(2);
display.setCursor(8, 16);
switch (currentState) {
case DOOR_CLOSED:
display.print("CLOSED");
break;
case DOOR_OPEN:
display.print("OPENED");
break;
case DOOR_MOVING:
display.print("MOVING");
break;
case STOP_EMERGENCY:
display.print("STOPPED");
break;
}
if (currentState == DOOR_MOVING || currentState == DOOR_OPEN) {
unsigned long elapsedTime = millis() - doorStartTime;
display.setTextSize(1);
display.setCursor(8, 40);
display.print("Time: ");
display.print(elapsedTime / 1000);
display.print("s");
}
display.display();
}
/*
{
"version": 1,
"editor": "wokwi",
"parts": [
{ "type": "wokwi-arduino-nano", "id": "nano", "top": -24, "left": -86.9, "attrs": {} },
{
"type": "wokwi-led",
"id": "yellowLED",
"top": -90,
"left": -197.8,
"attrs": { "color": "yellow" }
},
{ "type": "wokwi-led", "id": "greenLED", "top": -195.6, "left": -197.8, "attrs": {} },
{
"type": "wokwi-led",
"id": "redLED",
"top": -138,
"left": -197.8,
"attrs": { "color": "limegreen" }
},
{ "type": "wokwi-button", "id": "controlButton", "top": 150, "left": 150, "attrs": {} },
{ "type": "wokwi-piezo", "id": "buzzer", "top": 50, "left": 450, "attrs": {} },
{
"type": "wokwi-pushbutton",
"id": "sensorClosed",
"top": -329.8,
"left": 124.8,
"attrs": {}
},
{
"type": "wokwi-pushbutton",
"id": "sensorOpen",
"top": -483.4,
"left": 124.8,
"attrs": { "color": "blue" }
},
{ "type": "wokwi-slide-switch", "id": "sw1", "top": -322, "left": -179.3, "attrs": {} },
{ "type": "wokwi-slide-switch", "id": "sw2", "top": -322, "left": -102.5, "attrs": {} },
{
"type": "wokwi-buzzer",
"id": "bz1",
"top": -276,
"left": -36.6,
"attrs": { "volume": "0.1" }
},
{
"type": "wokwi-pushbutton",
"id": "btn1",
"top": -176.2,
"left": 115.2,
"attrs": { "color": "yellow" }
},
{
"type": "wokwi-pushbutton",
"id": "btn2",
"top": -406.6,
"left": 124.8,
"attrs": { "color": "green" }
},
{ "type": "wokwi-relay-module", "id": "relay2", "top": 38.6, "left": 259.2, "attrs": {} },
{ "type": "wokwi-relay-module", "id": "relay3", "top": 144.2, "left": 259.2, "attrs": {} },
{ "type": "wokwi-relay-module", "id": "relay4", "top": 249.8, "left": 259.2, "attrs": {} },
{
"type": "wokwi-led",
"id": "led1",
"top": -253.2,
"left": -197.8,
"attrs": { "color": "blue" }
},
{ "type": "wokwi-relay-module", "id": "relay1", "top": -134.2, "left": 240, "attrs": {} },
{
"type": "board-ssd1306",
"id": "oled1",
"top": 108.74,
"left": -18.97,
"attrs": { "i2cAddress": "0x3c" }
}
],
"connections": [
[ "nano:12", "btn1:2.l", "green", [ "v0" ] ],
[ "nano:11", "bz1:2", "green", [ "v-144", "h57.6" ] ],
[ "bz1:1", "nano:GND.2", "black", [ "v86.4", "h48" ] ],
[ "nano:10", "greenLED:A", "violet", [ "v0" ] ],
[ "nano:8", "yellowLED:A", "gold", [ "v0" ] ],
[ "redLED:C", "greenLED:C", "black", [ "v0", "h-28.4", "v0", "h0", "v0", "h0", "v-57.6" ] ],
[ "yellowLED:C", "redLED:C", "black", [ "v0", "h-28.4", "v-57.6" ] ],
[ "greenLED:C", "bz1:1", "black", [ "v9.6", "h154", "v-9.6" ] ],
[ "nano:6", "sensorClosed:2.l", "purple", [ "v-57.6", "h96", "v-220.8" ] ],
[ "nano:5", "btn2:2.l", "green", [ "v-134.4", "h57.6", "v-220.8", "h19.2" ] ],
[
"nano:4",
"sensorOpen:2.l",
"blue",
[ "v-115.2", "h57.6", "v-134.4", "h0", "v-182.4", "h57.6" ]
],
[ "sw2:2", "nano:2", "cyan", [ "v192", "h115.3" ] ],
[ "sw1:2", "nano:3", "orange", [ "v115.2", "h182.5" ] ],
[ "sw1:3", "sw2:1", "red", [ "v0" ] ],
[ "nano:GND.2", "sw2:3", "black", [ "v0" ] ],
[ "nano:GND.2", "sw1:1", "black", [ "v-249.6", "h-211.2" ] ],
[ "nano:GND.2", "sensorClosed:1.r", "black", [ "v-48", "h172.8", "v-249.6" ] ],
[ "nano:GND.2", "btn1:1.r", "black", [ "v-86.4", "h163.2", "v-57.6" ] ],
[ "nano:GND.2", "btn2:1.r", "black", [ "v-48", "h172.8", "v-326.4" ] ],
[ "nano:GND.2", "sensorOpen:1.r", "black", [ "v-48", "h172.8", "v-403.2" ] ],
[ "nano:5V", "sw1:3", "red", [ "v19.2", "h-297.6", "v-336", "h105.4" ] ],
[ "nano:9", "redLED:A", "green", [ "v0" ] ],
[ "relay2:VCC", "relay3:VCC", "red", [ "h-28.8", "v105.6" ] ],
[ "relay3:VCC", "relay4:VCC", "red", [ "h-28.8", "v105.6" ] ],
[ "relay3:GND", "relay4:GND", "black", [ "h-48", "v105.2" ] ],
[ "relay3:GND", "relay2:GND", "black", [ "h-19.2", "v-106" ] ],
[ "nano:13", "relay2:IN", "green", [ "v0" ] ],
[ "nano:A0", "relay3:IN", "green", [ "v0" ] ],
[ "nano:A1", "relay4:IN", "green", [ "v0" ] ],
[ "nano:7", "led1:A", "green", [ "v-86.4", "h-19.2", "v-105.6" ] ],
[ "bz1:1", "led1:C", "black", [ "v-9.6", "h-172.8" ] ],
[ "nano:GND.1", "relay2:GND", "black", [ "v0" ] ],
[ "nano:A2", "relay1:IN", "green", [ "v67.2", "h240", "v-134.4" ] ],
[ "nano:GND.2", "relay1:GND", "black", [ "v0" ] ],
[ "nano:5V", "relay1:VCC", "red", [ "v9.6", "h153.6", "v-163.2" ] ],
[ "nano:5V", "relay2:VCC", "red", [ "v0" ] ],
[ "nano:A5", "oled1:SCL", "green", [ "v48", "h28.8" ] ],
[ "nano:A4", "oled1:SDA", "green", [ "v28.8", "h9.6" ] ],
[ "nano:5V", "oled1:VCC", "red", [ "v57.6", "h-9.6" ] ],
[ "nano:GND.1", "oled1:GND", "black", [ "v48", "h-38.4", "v9.6" ] ]
],
"dependencies": {}
}
*/