// Greenhouse heating system #include #include // ArduinoThread #include // DHT Sensor Library by Adafruit 1.2.3 (!!! 1.3 not working) #include // A basic DS1307 library that returns time as a time_t #include // Extended TM1637 library https://github.com/bremme/arduino-tm1637 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 button = 4; const byte relay = 5; // Relay PIN #define DHTPIN 6 // PIN DHT DHT dht(DHTPIN, DHT11); // DHT-22 - AM2302 init SevenSegmentExtended display(PIN_CLK, PIN_DIO); int minTemp = 11; // Minimum temperature for relay (on) int maxTemp = 14; // Maximum temperature for relay (off) long relayWorkingTime = 600000; // 10min - minimun working time int tempThreadMs = 10000; // checkTemp thread interval int buttonThreadMs = 200; // pressButton thread interval int buttonState = 0; // Button state int buttonView = 0; // Button viewing state int relayState = 0; // Relay state long previousRelayChanged = 0; // Last time relay state changed long buttonPressed = 0; // Button ms pressed counter long previousButtonMillis = 0; // Last time button pressing long buttonInterval = 10000; // Interval for highlighting 4-Digit Display after pressing button // Threads: Thread pressButtonThread = Thread(); // Create thread for button state checking Thread checkTempThread = Thread(); // Create thread for temperature 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 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"); dht.begin(); pinMode(button, INPUT); pinMode(relay, OUTPUT); digitalWrite(relay, LOW); // Button state cheking thread: checkTempThread.onRun(checkTemp); checkTempThread.setInterval(tempThreadMs); // Interval for checking temperature pressButtonThread.onRun(pressButton); pressButtonThread.setInterval(buttonThreadMs); // Interval for checking button pressing delay(5000); // 5 second delay before display off and setup complete display.off(); serStr("...setup finished"); } void loop() { // Threads init: if (pressButtonThread.shouldRun()) pressButtonThread.run(); if (checkTempThread.shouldRun()) checkTempThread.run(); // Check RTC. if (!(timeStatus() == timeSet)) { display.on(); display.print("SET TIME"); delay (10000); } } // Check temperature thread void checkTemp() { unsigned long currentMillis = millis(); if (((currentMillis - previousRelayChanged) > relayWorkingTime) || (previousRelayChanged == 0)) { float tempFloat; readDHTtemp(&tempFloat); int tempInt = (int)tempFloat; if ((tempInt < minTemp) && (relayState == 0)) { serStr("low temperature - heating on"); digitalWrite(relay, HIGH); previousRelayChanged = currentMillis; relayState = 1; } if ((tempInt > maxTemp) && (relayState == 1)) { serStr("high temperature - heating off"); digitalWrite(relay, LOW); previousRelayChanged = currentMillis; relayState = 0; } } } // Check button pressing thread void pressButton() { unsigned long currentMillis = millis(); if (currentMillis - previousButtonMillis > buttonInterval) { previousButtonMillis = currentMillis; display.off(); } if (digitalRead(button) == HIGH) buttonState = 1; else buttonState = 0; if (buttonState == 1) { buttonPressed=buttonPressed+200; if (buttonPressed > 5000) { if (relayState == 0) { serStr("long press button - 5 sec - heating on"); digitalWrite(relay, HIGH); relayState = 1; previousRelayChanged = currentMillis; buttonPressed = 0; } else { serStr("long press button - 5 sec - heating off"); digitalWrite(relay, LOW); previousRelayChanged = currentMillis; relayState = 0; buttonPressed = 0; } } previousButtonMillis = currentMillis; display.on(); if (buttonView == 0) { display.printTime(hour(), minute(), true); } else if (buttonView == 1) { float tempFloat; readDHTtemp(&tempFloat); int tempInt = (int)tempFloat; byte rawData[4]; if (tempInt == 0) { rawData[0] = B01000000; // dash rawData[1] = B01000000; // dash } else { rawData[0] = display.encode(tempInt / 10); rawData[1] = display.encode(tempInt % 10); } rawData[2] = B01100011; // degree rawData[3] = display.encode('A') ; display.printRaw(rawData); } else if (buttonView == 2) { float humFloat; readDHThum(&humFloat); int humInt = (int)humFloat; byte rawData[4]; rawData[0] = display.encode('h'); rawData[1] = display.encode('u'); if (humInt == 0) { rawData[2] = B01000000; // dash rawData[3] = B01000000; // dash } else { rawData[2] = display.encode(humInt / 10); rawData[3] = display.encode(humInt % 10); } display.printRaw(rawData); } if (buttonView < 2) buttonView += 1; else buttonView = 0; } else { buttonPressed = 0; } } // DHT Temperature void readDHTtemp(float *a) { float t = dht.readTemperature(); *a = t; } // DHT Humidity void readDHThum(float *a) { float h = dht.readHumidity(); *a = h; } // 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(); }