/* * Hencoop with automatic lamp and door timer, TM1637 display, two buttons and magnetically operated sealed switch */ #include #include #include #include #include // Extended TM1637 library https://github.com/bremme/arduino-tm1637 long maxOpenDoorVar = 8667; // Interval for maximum door opening time long closeDoorVar = 3667; // Interval for door closing const byte redButton = 4; // RedButton: light on, open door const byte blackButton = 5; // BlackButton: light off, close door const byte pinLight = 6; // Light power relay const byte pinDC = 7; // DC motor power relay const byte pinRelay3 = 8; // Motor relay control const byte pinRelay4 = 9; // Motor relay control const byte PIN_CLK = 10; // Define CLK pin (for 4-Digit Display) const byte PIN_DIO = 11; // Define DIO pin (for 4-Digit Display) const byte doorSwitch = 12; // Door's magnetically operated sealed switch long buttonCheck = 200; // Interval for checking button state byte buttonCommand = 0; // Variable for buttons value: 0 - nothing, 1 - light on, 2 - light off byte displayWork = 0; // Variable for display status: 0 - nothing, 1 - work long previousButtonMillis = 0; // Button previous press counter long buttonPressed = 0; // Button ms pressed counter long buttonLongPress = 5000; // Interval for long press button action long buttonShortPress = 600; // Interval for short press button action unsigned long lastButtonPressed; SevenSegmentExtended display(PIN_CLK, PIN_DIO); // Threads: Thread pressButtonThread = Thread(); // Create thread for button state checking void setup() { Serial.begin(9600); // Initializes the Serial connection @ 9600 baud for debug serStr("starting setup..."); display.begin(); // Initializes the display display.setBacklight(100); // Set the brightness to 100 % display.print("INIT"); // Display INIT on the display pinMode(pinRelay3, OUTPUT); pinMode(pinRelay4, OUTPUT); pinMode(pinDC, OUTPUT); pinMode(pinLight, OUTPUT); pinMode(redButton, INPUT); pinMode(blackButton, INPUT); pinMode(doorSwitch, INPUT); digitalWrite(pinRelay3, HIGH); digitalWrite(pinRelay4, HIGH); digitalWrite(pinDC, HIGH); digitalWrite(pinLight, HIGH); while (!Serial); // Wait until Arduino Serial Monitor opens setSyncProvider(RTC.get); // The function to get the time from the RTC if(timeStatus()!= timeSet) Serial.println("Unable to sync with the RTC"); else Serial.println("RTC has set the system time"); // Button state cheking thread: pressButtonThread.onRun(pressButton); pressButtonThread.setInterval(buttonCheck); // Interval for checking button pressing delay (1000); display.off(); serStr("...setup finished"); } void loop() { // Threads init: if (pressButtonThread.shouldRun()) pressButtonThread.run(); if (timeStatus() == timeSet) { // If RTC works - call the checkTime function checkTime(); } else { display.on(); display.print("SET TIME"); } } // Check button pressing thread void pressButton() { unsigned long currentMillis = millis(); if (((currentMillis - previousButtonMillis) > 20000) && (displayWork == 1)) { display.off(); displayWork = 0; } if (digitalRead(redButton) == HIGH || digitalRead(blackButton) == HIGH) { display.on(); displayWork = 1; display.printTime(hour(), minute(), true); buttonPressed = buttonPressed + 200; if (buttonPressed > buttonShortPress) { if (digitalRead(redButton) == HIGH) buttonCommand = 1; if (digitalRead(blackButton) == HIGH) buttonCommand = 2; } if (buttonPressed > buttonLongPress) { buttonPressed = 0; buttonCommand = 0; if (digitalRead(redButton) == HIGH) serStr("Red button long press"); if (digitalRead(redButton) == HIGH) openDoor(); if (digitalRead(blackButton) == HIGH) serStr("Black button long press"); if (digitalRead(blackButton) == HIGH) closeDoor(); } previousButtonMillis = currentMillis; } else { buttonPressed = 0; } if (digitalRead(redButton) == LOW && digitalRead(blackButton) == LOW) { if (buttonCommand == 1) serStr("Red button short press"); if (buttonCommand == 1) lightOn(); if (buttonCommand == 2) serStr("Black button short press"); if (buttonCommand == 2) lightOff(); } } void lightOn() { buttonCommand = 0; digitalWrite(pinLight, LOW); serStr("Light on"); } void lightOff() { buttonCommand = 0; digitalWrite(pinLight, HIGH); serStr("Light off"); } void openDoor() { unsigned long openStart = millis(); if (digitalRead(doorSwitch) == LOW) { serStr("Door opening started..."); digitalWrite(pinRelay3, HIGH); digitalWrite(pinRelay4, HIGH); delay(1000); digitalWrite(pinDC, LOW); // DC on delay(3000); digitalWrite(pinRelay4, LOW); while (digitalRead(doorSwitch) == LOW) { if ((millis() - openStart) > maxOpenDoorVar) { break; } delay(55); } digitalWrite(pinRelay4, HIGH); delay(2000); digitalWrite(pinDC, HIGH); // DC off delay(1000); digitalWrite(pinRelay3, HIGH); digitalWrite(pinRelay4, HIGH); serStr("...door opening finished"); } else { serStr("Can't open door, magnet shows that door is open"); display.on(); display.print("can't - door is open"); display.off(); } } void closeDoor() { if (digitalRead(doorSwitch) == HIGH) { serStr("Door closing started..."); digitalWrite(pinRelay3, HIGH); digitalWrite(pinRelay4, HIGH); delay(1000); digitalWrite(pinDC, LOW); // DC on delay(3000); digitalWrite(pinRelay3, LOW); delay(closeDoorVar); digitalWrite(pinRelay3, HIGH); delay(2000); digitalWrite(pinDC, HIGH); // DC off delay(1000); digitalWrite(pinRelay3, HIGH); digitalWrite(pinRelay4, HIGH); serStr("...door closing finished"); } else { serStr("Can't close door, magnet shows that door is closed"); display.on(); display.print("can't - door is closed"); display.off(); } } // Send string to serial monitor with millis() counter and date/time void serStr(const char* serString) { long currentTime = millis(); String space = " "; String stringToPrint = currentTime + space + serString; Serial.println(stringToPrint); // RTC mark Serial.print("RTC time = "); Serial.print(hour()); Serial.write(':'); Serial.print(minute()); Serial.write(':'); Serial.print(second()); Serial.print(", date (D/M/Y) = "); Serial.print(day()); Serial.write('/'); Serial.print(month()); Serial.write('/'); Serial.print(year()); Serial.println(); } void checkTime() { // January 08:06 08:50 16:27 17:11 if (month() == 1) { if (hour() == 8 && minute() == 15) { openDoor(); delay(60000); } if (hour() == 15 && minute() == 55) { lightOn(); delay(60000); } if (hour() == 17 && minute() == 35) { lightOff(); delay(60000); } if (hour() == 17 && minute() == 50) { closeDoor(); delay(60000); } } // February 07:18 07:56 17:31 18:10 if (month() == 2) { if (hour() == 7 && minute() == 20) { openDoor(); delay(60000); } if (hour() == 16 && minute() == 55) { lightOn(); delay(60000); } if (hour() == 18 && minute() == 30) { lightOff(); delay(60000); } if (hour() == 18 && minute() == 45) { closeDoor(); delay(60000); } } // March 06:11 06:47 18:30 19:07 if (month() == 3) { if (hour() == 6 && minute() == 15) { openDoor(); delay(60000); } if (hour() == 17 && minute() == 55) { lightOn(); delay(60000); } if (hour() == 19 && minute() == 30) { lightOff(); delay(60000); } if (hour() == 19 && minute() == 45) { closeDoor(); delay(60000); } } // April 04:48 05:27 19:33 20:13 if (month() == 4) { if (hour() == 4 && minute() == 55) { openDoor(); delay(60000); } if (hour() == 20 && minute() == 50) { closeDoor(); delay(60000); } } // May 03:31 04:20 20:32 21:21 if (month() == 5) { if (hour() == 3 && minute() == 50) { openDoor(); delay(60000); } if (hour() == 21 && minute() == 55) { closeDoor(); delay(60000); } } // June 02:43 03:44 21:15 22:16 if (month() == 6) { if (hour() == 3 && minute() == 15) { openDoor(); delay(60000); } if (hour() == 22 && minute() == 50) { closeDoor(); delay(60000); } } // July 03:08 04:04 21:05 22:00 if (month() == 7) { if (hour() == 3 && minute() == 30) { openDoor(); delay(60000); } if (hour() == 22 && minute() == 35) { closeDoor(); delay(60000); } } // August 04:15 04:58 20:08 20:51 if (month() == 8) { if (hour() == 4 && minute() == 15) { openDoor(); delay(60000); } if (hour() == 21 && minute() == 30) { closeDoor(); delay(60000); } } // September 05:21 05:58 18:50 19:27 if (month() == 9) { if (hour() == 5 && minute() == 25) { openDoor(); delay(60000); } if (hour() == 18 && minute() == 20) { lightOn(); delay(60000); } if (hour() == 19 && minute() == 50) { lightOff(); delay(60000); } if (hour() == 20 && minute() == 5) { closeDoor(); delay(60000); } } // October 06:20 06:57 17:32 18:09 if (month() == 10) { if (hour() == 6 && minute() == 25) { openDoor(); delay(60000); } if (hour() == 16 && minute() == 55) { lightOn(); delay(60000); } if (hour() == 18 && minute() == 30) { lightOff(); delay(60000); } if (hour() == 18 && minute() == 45) { closeDoor(); delay(60000); } } // November 07:20 08:02 16:24 17:06 if (month() == 11) { if (hour() == 7 && minute() == 30) { openDoor(); delay(60000); } if (hour() == 15 && minute() == 55) { lightOn(); delay(60000); } if (hour() == 17 && minute() == 30) { lightOff(); delay(60000); } if (hour() == 17 && minute() == 45) { closeDoor(); delay(60000); } } // December 08:05 08:51 15:56 16:42 if (month() == 12) { if (hour() == 8 && minute() == 20) { openDoor(); delay(60000); } if (hour() == 15 && minute() == 25) { lightOn(); delay(60000); } if (hour() == 17 && minute() == 5) { lightOff(); delay(60000); } if (hour() == 17 && minute() == 25) { closeDoor(); delay(60000); } } }