Here is my entire code.
#include "DHT.h" //including DHT11/21 library
#include<Wire.h>
#include<LiquidCrystal_I2C.h> //Including library for LCD that is connected to an I2C device
#include <DS3231.h> //Including library for clock that is connected to I2C
LiquidCrystal_I2C lcd1 (0x27, 16, 2); //Defining the LCD's I2C address, and size
DS3231 rtc(SDA, SCL);
Time t;
const byte startbuttonPin = 8; //Button connected to GND
const byte stopbuttonPin = 9;
const byte LCDbuttonPin = 7;
const byte testbuttonPin = 6;
const byte LED = 12; // Pin connected to LED
const byte turningLED = 5;
const byte motor = 10; //Pin connected to motor through a relay
const byte DHTPIN = 11; // Pin that DHT11/21 is connected to
const int OnHour = 9; //Using DS3231 clock to tell time to on motor
const int OnMin = 57;
const int OffHour = 9; //Using DS3231 clock to tell time to off motor
const int OffMin = 58;
#define DHTTYPE DHT11 // DHT 11
//#define DHTTYPE DHT22 // DHT 22 (AM2302)
//#define DHTTYPE DHT21 // DHT 21 (AM2301)
DHT dht(DHTPIN, DHTTYPE); //Initializing DHT sensor for arduino
// an enumeration class for the different states of the state machine
enum class States { // Assigns names to a set of numbers starting at 0.
WaitForButtonPress,
ButtonChecks,
SwitchOnMotor,
}
currentState; // these constants are used for this variable named "currentState"
enum class LCDs {
original,
pressed,
changed,
}
currentstate;
enum class counts {
Shows,
Waits,
}
currentvalues;
enum class Days {
ButtonPress,
Check,
Interval,
ShowDays,
}
currentarea;
bool codestart = false; //used to only start motor code when button has been released
bool state = false;
// variables for timePeriods
const unsigned long firstmotorOffPeriod = 8000; //the initial 4 days that the motor is off (in milliseconds), make cost if variable never changes
const unsigned long motorOnPeriod = 1000; // how long should the motor be on (in milliseconds), make const if variable never changes
const unsigned long motorOffPeriod = 3000; // how long should the motor be Off (in milliseconds), make const if variable never changes
const unsigned long dhtDelay = 4000; //the intervals where the LCD updates the humidity/temperature values
const unsigned long DayDelay = 10000; //the delay to update the day value
const unsigned long DayCount = 10000; //the time for a day to pass
int CountRounds = 0; // used to count loops, to stop code after certain loops
int CountDays = 0; //used to count days passed, for the LCD
void setup() {
Serial.begin(9600); //rate in milliseconds that arduino sends info to serial monitor
rtc.begin(); //starting up Clock
lcd1.init(); //starting up LCD display
lcd1.backlight();
dht.begin(); //starting up DHT sensor
pinMode(startbuttonPin, INPUT_PULLUP); //Button pin is an input device, and will atomatically pull up its state
pinMode(stopbuttonPin, INPUT_PULLUP);
pinMode(LCDbuttonPin, INPUT_PULLUP);
pinMode(testbuttonPin, INPUT_PULLUP);
pinMode(LED, OUTPUT); // LED pin is an output
pinMode(turningLED, OUTPUT);
pinMode(motor, OUTPUT); // Motor pin is an output
currentState = States::WaitForButtonPress; //Setting the current state for the enum function
digitalWrite(LED, LOW); //LED's state is initially always LOW
digitalWrite(motor, LOW); //Motor's state is initially always LOW
}
// parts of the program that belong to one functional unit are coded in their
// own function where each function has a self-explaining name
// This makes it much easier to test code and keep an overview
// with the growing of the code
void loop() {
NumberofDays();
TempHumidLCD(); //the state machine called inside the loop to run the humidity/temp snsor to display values on the LCD
motordelay(); // the state machine called inside the loop to run the relay/motor
// DayLCD(); //the state machine called inside the loop to print the number of days and number of loops
}
void motordelay() {
t = rtc.getTime();
unsigned long currentMillis = millis();
static unsigned long previousMillis = 0; // timestamp when the current State was started
// this is the state-machine based on the switch-case-statement
// depending on the value of variable "currentState" only the commands
// below one "case" gets executed
switch (currentState) {
case States::WaitForButtonPress:
// a state that waits for an external input to occur
if (digitalRead(stopbuttonPin) == HIGH) {
if (digitalRead(startbuttonPin) == HIGH) {
digitalWrite(LED, HIGH);
previousMillis = currentMillis;
codestart = true;
}
}
else {
digitalWrite(LED, LOW);
digitalWrite(motor, LOW);
}
if (codestart) {
if (currentMillis - previousMillis >= firstmotorOffPeriod) {
codestart = false;
currentState = States::SwitchOnMotor;
}
}
break;
case States::ButtonChecks:
if (digitalRead(stopbuttonPin) == HIGH) {
currentState = States::SwitchOnMotor;
}
else {
CountRounds = 0;
currentState = States::WaitForButtonPress;
}
break;
case States::SwitchOnMotor:
Serial.println("reached");
if (t.hour == OnHour && t.min == OnMin) {
Serial.println("Turning");
digitalWrite(motor, HIGH);
}
else if (t.hour == OffHour && t.min == OffMin) {
digitalWrite(motor, LOW);
}
currentState = States::ButtonChecks;
CountRounds++;
Serial.println(CountRounds);
break;
}
}
void TempHumidLCD() {
float h = dht.readHumidity();
// Read temperature as Celsius
float t = dht.readTemperature();
// Read temperature as Fahrenheit
float f = dht.readTemperature(true);
unsigned long currentMillis = millis();
static unsigned long previous = 0;
switch (currentstate) {
case LCDs ::original:
//Serial.print("Humidity: ");
//Serial.print(h);
//Serial.print(" %\t");
//Serial.print("Temperature: ");
//Serial.print(t);
//Serial.println(" *C ");
lcd1.setCursor(0, 0);
lcd1.print("No. of turns:");
lcd1.print(" "); // two blank spaces assuming CountRounds is a max of two figures,
lcd1.setCursor(0, 0);
lcd1.print("No. of turns:");
lcd1.print(CountRounds);
lcd1.setCursor(0, 1);
lcd1.print("No. of days:");
lcd1.print(" ");
lcd1.setCursor(0, 1);
lcd1.print("No. of days:");
lcd1.print(CountDays);
previous = currentMillis;
currentstate = LCDs::pressed;
break;
case LCDs ::pressed:
if (digitalRead(LCDbuttonPin) == HIGH) {
lcd1.setCursor(0, 0);
lcd1.print("Temp: ");
lcd1.print(" ");
lcd1.setCursor(0, 0);
lcd1.print("Temp: ");
lcd1.print(t);
lcd1.print((char)223);
lcd1.print("C");
lcd1.setCursor(0, 1);
lcd1.print("Humidity: ");
lcd1.print(h);
lcd1.print("%");
currentstate = LCDs::changed;
}
if (digitalRead(LCDbuttonPin) == LOW) {
currentstate = LCDs::original;
}
break;
case LCDs ::changed:
if (currentMillis - previous >= dhtDelay) {
// Serial.println("waiting");
currentstate = LCDs::original;
}
}
}
void NumberofDays() {
unsigned long currentMillis = millis();
static unsigned long previousday = 0;
switch (currentarea) {
case Days:: ButtonPress:
CountDays = 0;
if (digitalRead(stopbuttonPin) == HIGH) {
if (digitalRead(startbuttonPin) == HIGH) {
currentarea = Days::ShowDays;
}
}
else {
CountDays = 0;
}
break;
case Days::ShowDays:
if (digitalRead(stopbuttonPin) == HIGH) {
//Serial.println("Counting");
CountDays++;
previousday = currentMillis;
currentarea = Days::Interval;
}
else {
currentarea = Days::ButtonPress;
}
break;
case Days::Interval:
if (digitalRead(stopbuttonPin) == HIGH) {
if (currentMillis - previousday >= DayCount) {
//Serial.println("Waiting for day to pass");
currentarea = Days::ShowDays;
}
}
else {
currentarea = Days::ButtonPress;
}
break;
}
}