198 lines
6.7 KiB
C++
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();
|
|
}
|