greenhouseheating/greenhouseheating.ino

198 lines
6.7 KiB
C++

// Greenhouse heating system
#include <Arduino.h>
#include <Thread.h> // ArduinoThread
#include <DHT.h> // DHT Sensor Library by Adafruit 1.2.3 (!!! 1.3 not working)
#include <DS1307RTC.h> // A basic DS1307 library that returns time as a time_t
#include <SevenSegmentExtended.h> // 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();
}