/* * Hencoop with automatic lamp and door timer, TM1637 display and two buttons */ #include #include #include #include #include #include // Extended TM1637 library https://github.com/bremme/arduino-tm1637 long openDoorVar = 3780; // Interval for door opening long closeDoorVar = 3600; // Interval for door closing const byte PIN_CLK = 2; // Define CLK pin (for 4-Digit Display) const byte PIN_DIO = 3; // Define DIO pin (for 4-Digit Display) const byte redButton = 4; // RedButton: light on, open door const byte blackButton = 5; // BlackButton: light off, close door const byte pinLight = 6; // Light relay const byte pinDC = 7; // DC motor relay const byte pinRelay3 = 8; // Motor relay control const byte pinRelay4 = 9; // Motor relay control const byte led = 13; SevenSegmentExtended display(PIN_CLK, PIN_DIO); // long ledPulse = 1000; // Interval for LED blinking pulse 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; // Threads: Thread pressButtonThread = Thread(); // Create thread for button state checking // Thread ledThread = Thread(); // Create thread for LED pulse indication 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(led, OUTPUT); pinMode(redButton, INPUT); pinMode(blackButton, 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"); // LED blinking thread: // ledThread.onRun(ledBlink); // ledThread.setInterval(ledPulse); // Interval for LED blinking // 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 (ledThread.shouldRun()) // ledThread.run(); if (pressButtonThread.shouldRun()) pressButtonThread.run(); if (timeStatus() == timeSet) { // If RTC works - call the checkTime function checkTime(); } else { display.on(); display.print("SET TIME"); } /* } else { // Fast blinking indicates that time is int i; // not set or DS1307RTC is not plugged for (i = 1; i <= 500; i++) { digitalWrite(led, LOW); delay(50); digitalWrite(led, HIGH); delay(50); } } */ } void checkTime() { // Winter // 6:56 open door, 7:01 light on, 10:01 light off, // 16:01 light on, 19:01 light off, 19:05 close door if (month()==11 || month()==12 || month()==1 ) { if (hour() == 6 && minute() == 56) { openDoor(); delay(60000); } if (hour() == 7 && minute() == 1) { lightOn(); delay(60000); } if (hour() == 10 && minute() == 1) { lightOff(); delay(60000); } if (hour() == 16 && minute() == 1) { lightOn(); delay(60000); } if (hour() == 19 && minute() == 1) { lightOff(); delay(60000); } if (hour() == 19 && minute() == 5) { closeDoor(); delay(60000); } } // Spring // 6:30 door open, 17:01 light on, 20:01 light off, 20:05 door close if (month()==2 || month()==3 || month()==4 ) { if (hour() == 6 && minute() == 30) { openDoor(); delay(60000); } if (hour() == 17 && minute() == 1) { lightOn(); delay(60000); } if (hour() == 20 && minute() == 1) { lightOff(); delay(60000); } if (hour() == 20 && minute() == 5) { closeDoor(); delay(60000); } } // Summer // 5:30 open door, 22:05 close door if (month()==5 || month()==6 || month()==7 ) { if (hour() == 5 && minute() == 30) { openDoor(); delay(60000); } if (hour() == 22 && minute() == 5) { closeDoor(); delay(60000); } } // Autumn // 6:01 open door, 17:01 light on, 20:01 light off, 21:05 close door if (month()==8 || month()==9 || month()==10 ) { if (hour() == 6 && minute() == 1) { openDoor(); delay(60000); } if (hour() == 17 && minute() == 1) { lightOn(); delay(60000); } if (hour() == 20 && minute() == 1) { lightOff(); delay(60000); } if (hour() == 21 && minute() == 5) { closeDoor(); delay(60000); } } } /* // LED pulse blinking thread void ledBlink() { static bool ledStatus = false; // LED status bool ledStatus = !ledStatus; // Invert LED state digitalWrite(led, ledStatus); // Activate LED state } */ // 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) { // if (digitalRead(redButton) == HIGH) serStr("Red button pressed, time showed"); // if (digitalRead(blackButton) == HIGH) serStr("Black button pressed, time showed"); 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() { serStr("Door opening started..."); digitalWrite(pinDC, LOW); // DC on delay(1000); digitalWrite(pinRelay4, LOW); delay(openDoorVar); digitalWrite(pinRelay4, HIGH); delay(1000); digitalWrite(pinDC, HIGH); // DC off serStr("...door opening finished"); } void closeDoor() { serStr("Door closing started..."); digitalWrite(pinDC, LOW); // DC on delay(1000); digitalWrite(pinRelay3, LOW); delay(closeDoorVar); digitalWrite(pinRelay3, HIGH); delay(1000); digitalWrite(pinDC, HIGH); // DC off serStr("...door closing finished"); } // 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(); }