#include <Wire.h>
#include <Keypad.h>
#include <LiquidCrystal_I2C.h>
#include "DHT.h"
#include <elapsedMillis.h>
elapsedSeconds co2Sec;
unsigned int co2_Interval = 1;
elapsedSeconds fanSec;
unsigned int fan_Interval = 5;
#define DHTPIN 4
#define DHTTYPE DHT22
DHT dht(DHTPIN, DHTTYPE);
float t ;
LiquidCrystal_I2C lcd(0x27, 20, 4); // set the LCD address to 0x27 for a 16 chars and 2 line display
// LCD Connection:
// GND - GND
// VCC - 5V
// SDA - A4
// SCL - A5
const int ROW_NUM = 4; //four rows
const int COLUMN_NUM = 4; //four columns
char keys[ROW_NUM][COLUMN_NUM] = {
{ '1', '2', '3', 'A' },
{ '4', '5', '6', 'B' },
{ '7', '8', '9', 'C' },
{ '*', '0', '#', 'D' }
};
byte pin_rows[ROW_NUM] = { 9, 8, 7, 6 }; //connect to the row pinouts of the keypad
byte pin_column[COLUMN_NUM] = { 5, 4, 3, 2 }; //connect to the column pinouts of the keypad
// Keypad Arduino
// 1 2
// 2 3
// 3 4
// 4 5
// 5 6
// 6 7
// 7 8
// 8 9
Keypad keypad = Keypad(makeKeymap(keys), pin_rows, pin_column, ROW_NUM, COLUMN_NUM);
String input_value;
long input_int;
//Mosfet output wires
int output1 = 10; //24 volt out
int output2 = 11; //24 volt out
int output3 = 12; //negative - switching no more than 59v because its mosfet
int output4 = 13; //negative - switching no more than 59v because its mosfet
//Output previous time
unsigned long previousOutput1Time = 0;
unsigned long previousOutput2Time = 0;
unsigned long previousOutput3Time = 0;
unsigned long previousOutput4Time = 0;
//Output stay on time 1000ms(1s)
float outputOnTime1 = 1000;
float outputOnTime2 = 0;
//delay after 1 cycle
unsigned long delayInOut1Out2 = 4;
unsigned long delayAfterCycle = 0;
//Cycle previous time
unsigned long previousCycleTime = 0;
//Timing for auto mode on and off
unsigned long outElapsed = 0;
unsigned long outStartTime = 0;
unsigned long outPreviousTime = 0;
int state = 0;
int mode = 3;
unsigned long totalCycle = 4200;
int count = 0;
int solenoid = 0;
int outputRelays = 0;
unsigned long elapsed = 0;
unsigned long currentTime = 0;
unsigned long startTime = 0;
unsigned long lastelapsed = 0;
//////////////co2 sensor //////////////////////////
#define sensorIn 2 // Sensor PWM interface
unsigned long pwm_high_start_ticks = 0, pwm_high_end_ticks = 0;
double pwm_high_val = 0, pwm_low_val = 0;
volatile uint8_t flag = 0;
int CO2 = 0;
void interrupt_rising() {
pwm_high_start_ticks = micros(); // store the current micros() value
if (2 == flag) {
flag = 4;
pwm_low_val = pwm_high_start_ticks - pwm_high_end_ticks;
} else {
flag = 1;
}
attachInterrupt(digitalPinToInterrupt(sensorIn), interrupt_falling, FALLING);
}
void interrupt_falling() {
pwm_high_end_ticks = micros(); // store the current micros() value
if (1 == flag) {
flag = 2;
pwm_high_val = pwm_high_end_ticks - pwm_high_start_ticks;
}
attachInterrupt(digitalPinToInterrupt(sensorIn), interrupt_rising, RISING);
}
//////////////////////////////////////////////////////////////////////////
void setup() {
// put your setup code here, to run once:
dht.begin();
lcd.init();
lcd.clear();
lcd.backlight();
Serial.begin(9600);
pinMode(output1, OUTPUT);
digitalWrite(output1, LOW);
pinMode(output2, OUTPUT);
digitalWrite(output2, LOW);
pinMode(output3, OUTPUT);
digitalWrite(output3, LOW);
pinMode(output4, OUTPUT);
digitalWrite(output4, LOW);
startTime = millis();
outStartTime = millis();
pinMode(sensorIn, INPUT);
attachInterrupt(digitalPinToInterrupt(sensorIn), interrupt_rising, RISING);
}
void loop() {
// put your main code here, to run repeatedly:
if (mode == 0) {
//lcd.setCursor(18, 0); lcd.print("M"); lcd.print(mode);
lcd.setCursor(0, 0);
lcd.print("Cycle: ");
lcd.print(totalCycle);
lcd.setCursor(0, 3);
lcd.print("Run:A/B");
lcd.setCursor(0, 1);
lcd.print("Delay Inside: ");
lcd.print(delayInOut1Out2 - (outputOnTime1 + outputOnTime2) / 1000);
lcd.print("s");
lcd.setCursor(0, 2);
lcd.print("Out1&2: ");
lcd.print(outputOnTime1 / 1000);
lcd.print("s ");
lcd.print(outputOnTime2 / 1000);
lcd.print("s ");
//lcd.setCursor(0,3);lcd.print("Next Page:C");
lcd.setCursor(15, 3);
lcd.print("Set:D");
char key = keypad.getKey();
if (key) {
}
if (key == 'C') {
lcd.clear();
mode = 0;
startTime = millis();
elapsed = 0;
} else if (key == 'D') {
currentTime = millis();
elapsed = 0;
mode = 4;
lcd.clear();
} else if (key == 'B') {
lcd.clear();
mode = 2;
startTime = millis();
elapsed = 0;
lcd.clear();
} else if (key == 'A') {
lcd.clear();
mode = 1;
startTime = millis();
elapsed = 0;
outStartTime = millis();
outElapsed = 0;
}
//Auto mode pre start function
} else if (mode == 1) {
lcd.setCursor(0, 0);
lcd.print("Press 1 to start ");
//lcd.setCursor(0, 1); lcd.print("Press: 1 ");
lcd.setCursor(0, 2);
lcd.print("Output:1,2");
lcd.setCursor(0, 3);
lcd.print("Exit:C");
count = 0;
char key = keypad.getKey();
if (key) {
}
if (key == 'C') {
lcd.clear();
currentTime = millis();
elapsed = 0;
mode = 0;
} else if (key == '1') {
lcd.clear();
startTime = millis();
elapsed = 0;
outStartTime = millis();
outElapsed = 0;
mode = 3;
} else if (key == '2') {
lcd.clear();
output1 = output2;
output3 = output4;
startTime = millis();
elapsed = 0;
outStartTime = millis();
outElapsed = 0;
mode = 3;
} /*else if (key == '3') {
lcd.clear();
solenoid = output3;
startTime = millis();
elapsed = 0;
outStartTime = millis();
outElapsed = 0;
mode = 6;
}*/
} else if (mode == 2) { //Manual runing mode to drive output solenoids
elapsed = (millis() - startTime);
//lcd.setCursor(0, 3); lcd.print(elapsed / 1000);
lcd.setCursor(5, 0);
lcd.print("Manual Run"); //lcd.print(mode);
lcd.setCursor(0, 1);
lcd.print("Press:1234 > OUT1234");
lcd.setCursor(0, 2);
lcd.print("On delay Time:");
lcd.setCursor(14, 2);
lcd.print(outputOnTime1 / 1000);
lcd.print("s");
lcd.setCursor(14, 3);
lcd.print("Exit:C");
if (elapsed - previousOutput1Time >= outputOnTime1) {
digitalWrite(output1, LOW);
}
if (elapsed - previousOutput2Time >= outputOnTime2) {
digitalWrite(output2, LOW);
}
if (elapsed - previousOutput3Time >= outputOnTime1) {
digitalWrite(output3, LOW);
}
if (elapsed - previousOutput4Time >= outputOnTime1) {
digitalWrite(output4, LOW);
}
char key = keypad.getKey();
if (key) {
if (key == 'C') {
lcd.clear();
digitalWrite(output1, LOW);
digitalWrite(output2, LOW);
digitalWrite(output3, LOW);
currentTime = millis();
elapsed = 0;
mode = 0;
} else if (key == '1') {
digitalWrite(output1, HIGH);
previousOutput1Time = elapsed;
} else if (key == '2') {
digitalWrite(output2, HIGH);
previousOutput2Time = elapsed;
} else if (key == '3') {
digitalWrite(output3, HIGH);
previousOutput3Time = elapsed;
} else if (key == '4') {
digitalWrite(output4, HIGH);
previousOutput4Time = elapsed;
}
}
} else if (mode == 3) {
if (co2Sec >= co2_Interval ) { /////////////////////////////////////////co2///////////
if (flag == 4) {
flag = 1;
double pwm_high_val_ms = (pwm_high_val * 1000) / (pwm_low_val + pwm_high_val);
/*if (pwm_high_val_ms < 0.01) {
Serial.println("Fault");
} else if (pwm_high_val_ms < 80.00) {
Serial.println("preheating");
} else */
if (pwm_high_val_ms < 998.00) {
double concentration = (pwm_high_val_ms - 2) * 5;
CO2 = concentration;
float t = dht.readTemperature();
// Print pwm_high_val_ms
/*Serial.print("pwm_high_val_ms:");
Serial.print(pwm_high_val_ms);
Serial.println("ms");*/
//Print CO2 concentration
Serial.print(concentration);
Serial.print(",");
Serial.print(t);
Serial.print(",");
lcd.setCursor(0, 2);
lcd.print("CO2#");
lcd.print(concentration);
lcd.print("/T:");
lcd.print(t);
Serial.println();
co2Sec = 0;
///////////////////
} /*else {
Serial.println("Beyond the maximum range :398~4980ppm");
}*/
}
}
//////////////////////////////////////////////////}
elapsed = (millis() - startTime);
//lcd.setCursor(0, 2); lcd.print(count);
if (elapsed > ((totalCycle * delayInOut1Out2) * 1000)) {
/*startTime = millis();
elapsed = 0;*/
lcd.clear();
digitalWrite(output1, LOW);
digitalWrite(output2, LOW);
digitalWrite(output3, LOW);
currentTime = millis();
outStartTime = millis();
elapsed = 0;
outElapsed = 0;
mode = 1;
}
if (CO2>=2000) {
mode = 9;
}
if (elapsed>10000 ) {
mode = 10;
}
//
outElapsed = (millis() - outStartTime);
if (outElapsed > (delayInOut1Out2 + delayAfterCycle) * 1000) {
outStartTime = millis();
outElapsed = 0;
elapsed = 0;
}
if ((outElapsed > delayInOut1Out2 * 1000 - outputOnTime1) && (outElapsed < delayInOut1Out2 * 1000 /*- outputOnTime1*/)) {
static unsigned long lastStateChangeTime = 0;
static bool outputState = false;
unsigned long currentTime = millis();
if (digitalRead(output1) == LOW && (currentTime - lastStateChangeTime >= outputOnTime1)) {
//digitalWrite(output1, HIGH);
count++;
lastStateChangeTime = currentTime;
}
digitalWrite(output1, HIGH);
//lcd.setCursor(14, 0); lcd.print((elapsed / (delayInOut1Out2 * 1000))); lcd.print("of"); lcd.print(totalCycle);
//lcd.setCursor(14, 1); lcd.print((outElapsed / 1000)); lcd.print("of"); lcd.print(delayInOut1Out2); lcd.print("s");
lcd.setCursor(0, 0);
lcd.print("Cycles:"); /*lcd.print((elapsed / (delayInOut1Out2 * 1000)));*/
lcd.print(count);
lcd.print("/");
lcd.print(totalCycle);
lcd.setCursor(0, 1);
lcd.print("Timer: ");
lcd.print((outElapsed / 1000));
lcd.print("of");
lcd.print(delayInOut1Out2 + delayAfterCycle);
lcd.print("s");
lcd.setCursor(0, 3);
lcd.print("Exit:C Set:D");
} else {
digitalWrite(output1, LOW);
//lcd.setCursor(14, 0); lcd.print((elapsed / (delayInOut1Out2 * 1000))); lcd.print("of"); lcd.print(totalCycle);
//lcd.setCursor(14, 1); lcd.print((outElapsed / 1000)); lcd.print("of"); lcd.print(delayInOut1Out2); lcd.print("s");
lcd.setCursor(0, 0);
lcd.print("Cycles:"); /*lcd.print((elapsed / (delayInOut1Out2 * 1000)));*/
lcd.print(count);
lcd.print("/");
lcd.print(totalCycle);
lcd.setCursor(0, 1);
lcd.print("Timer: ");
lcd.print((outElapsed / 1000));
lcd.print("of");
lcd.print(delayInOut1Out2 + delayAfterCycle);
lcd.print("s");
lcd.setCursor(0, 3);
lcd.print("Exit:C Set:D");
}
//2 output
if ((outElapsed > 0) && (outElapsed < outputOnTime2)) {
digitalWrite(output3, HIGH);
//lcd.setCursor(14, 0); lcd.print((elapsed / (delayInOut1Out2 * 1000))); lcd.print("of"); lcd.print(totalCycle);
//lcd.setCursor(14, 1); lcd.print((outElapsed / 1000)); lcd.print("of"); lcd.print(delayInOut1Out2);
lcd.setCursor(0, 0);
lcd.print("Cycles:"); /*lcd.print((elapsed / (delayInOut1Out2 * 1000)));*/
lcd.print(count);
lcd.print("/");
lcd.print(totalCycle);
lcd.setCursor(0, 1);
lcd.print("Timer: ");
lcd.print((outElapsed / 1000));
lcd.print("of");
lcd.print(delayInOut1Out2 + delayAfterCycle);
lcd.print("s");
lcd.setCursor(0, 3);
lcd.print("Exit:C Set:D");
} else {
digitalWrite(output3, LOW);
//lcd.setCursor(14, 0); lcd.print((elapsed / (delayInOut1Out2 * 1000))); lcd.print("of"); lcd.print(totalCycle);
//lcd.setCursor(14, 1); lcd.print((outElapsed / 1000)); lcd.print("of"); lcd.print(delayInOut1Out2); lcd.print("s");
lcd.setCursor(0, 0);
lcd.print("Cycles:"); /*lcd.print((elapsed / (delayInOut1Out2 * 1000)));*/
lcd.print(count);
lcd.print("/");
lcd.print(totalCycle);
lcd.setCursor(0, 1);
lcd.print("Timer: ");
lcd.print((outElapsed / 1000));
lcd.print("of");
lcd.print(delayInOut1Out2 + delayAfterCycle);
lcd.print("s");
lcd.setCursor(0, 3);
lcd.print("Exit:C Set:D");
}
char key = keypad.getKey();
if (key) {
if (key == 'C') {
lcd.clear();
digitalWrite(output1, LOW);
digitalWrite(output2, LOW);
digitalWrite(output3, LOW);
currentTime = millis();
elapsed = 0;
outElapsed = 0;
mode = 0;
} else if (key == 'D') {
currentTime = millis();
elapsed = 0;
mode = 4;
lcd.clear();
}
}
} else if (mode == 4) { // Program Cycle Time
lcd.setCursor(0, 0);
lcd.print("Enter Cycle");
lcd.setCursor(0, 1);
lcd.print(totalCycle);
lcd.print(" ");
lcd.setCursor(0, 2);
lcd.print(input_value);
lcd.print(" ");
lcd.setCursor(0, 3);
lcd.print("*Clr # Entr D Next");
char key = keypad.getKey();
if (key) {
if (key == '*') {
input_value = ""; // clear input value
lcd.clear();
} else if ((key == '#') && (input_value.length() > 0)) {
input_int = input_value.toInt();
totalCycle = input_int;
} else if (key == 'D') {
mode = 5;
lcd.clear();
input_value = "";
} else if (key >= '0' && key <= '9') {
input_value += key; // append new character to input value string
}
}
} else if (mode == 5) { // Program Cycle Time
lcd.setCursor(0, 0);
lcd.print("Enter Cycle Delay");
lcd.setCursor(0, 1);
lcd.print(delayAfterCycle);
lcd.print(" s");
lcd.setCursor(0, 2);
lcd.print(input_value);
lcd.print(" s");
lcd.setCursor(0, 3);
lcd.print("*Clr # Entr D Next");
char key = keypad.getKey();
if (key) {
if (key == '*') {
input_value = ""; // clear input value
lcd.clear();
} else if ((key == '#') && (input_value.length() > 0)) {
input_int = input_value.toInt();
delayAfterCycle = input_int;
} else if (key == 'D') {
mode = 6;
lcd.clear();
input_value = "";
} else if (key >= '0' && key <= '9') {
input_value += key; // append new character to input value string
}
}
} else if (mode == 6) { // Program Cycle Time
lcd.setCursor(0, 0);
lcd.print("Enter OutputOnDelay1");
lcd.setCursor(0, 1);
lcd.print(outputOnTime1);
lcd.print(" ms");
lcd.setCursor(0, 2);
lcd.print(input_value);
lcd.print(" ms");
lcd.setCursor(0, 3);
lcd.print("*Clr # Entr D Next");
char key = keypad.getKey();
if (key) {
if (key == '*') {
input_value = ""; // clear input value
lcd.clear();
} else if ((key == '#') && (input_value.length() > 0)) {
input_int = input_value.toInt();
outputOnTime1 = input_int;
} else if (key == 'D') {
mode = 7;
lcd.clear();
input_value = "";
} else if (key >= '0' && key <= '9') {
input_value += key; // append new character to input value string
}
}
} else if (mode == 7) { // Program Cycle Time
lcd.setCursor(0, 0);
lcd.print("Enter OutputOnDelay2");
lcd.setCursor(0, 1);
lcd.print(outputOnTime2);
lcd.print(" ms");
lcd.setCursor(0, 2);
lcd.print(input_value);
lcd.print(" ms");
lcd.setCursor(0, 3);
lcd.print("*Clr # Entr D Next");
char key = keypad.getKey();
if (key) {
if (key == '*') {
input_value = ""; // clear input value
lcd.clear();
} else if ((key == '#') && (input_value.length() > 0)) {
input_int = input_value.toInt();
outputOnTime2 = input_int;
} else if (key == 'D') {
mode = 8;
lcd.clear();
input_value = "";
} else if (key >= '0' && key <= '9') {
input_value += key; // append new character to input value string
}
}
} else if (mode == 8) { // Program Cycle Time
lcd.setCursor(0, 0);
lcd.print("Enter Delay Ou1&Out2");
lcd.setCursor(0, 1);
lcd.print(delayInOut1Out2 - (outputOnTime1 + outputOnTime2) / 1000);
lcd.print(" s");
lcd.setCursor(0, 2);
lcd.print(input_value);
lcd.print(" s");
lcd.setCursor(0, 3);
lcd.print("*Clr # Entr D Next");
char key = keypad.getKey();
if (key) {
if (key == '*') {
input_value = ""; // clear input value
lcd.clear();
} else if ((key == '#') && (input_value.length() > 0)) {
input_int = input_value.toInt();
delayInOut1Out2 = input_int + ((outputOnTime1 + outputOnTime2) / 1000);
} else if (key == 'D') {
mode = 0;
lcd.clear();
input_value = "";
} else if (key >= '0' && key <= '9') {
input_value += key; // append new character to input value string
}
}
} else if (mode == 9) { //Manual runing mode to drive output solenoids
elapsed = (millis() - startTime);
//lcd.setCursor(0, 3); lcd.print(elapsed / 1000);
if (elapsed > 25000) {
mode = 3;
}
char key = keypad.getKey();
if (key) {
if (key == 'C') {
lcd.clear();
digitalWrite(output1, LOW);
digitalWrite(output2, LOW);
digitalWrite(output3, LOW);
currentTime = millis();
elapsed = 0;
mode = 0;
}
}
} else if (mode == 10) { //Temperature pause
elapsed = (millis() - startTime);
//lcd.setCursor(0, 3); lcd.print(elapsed / 1000);
float t = dht.readTemperature();
if(fanSec > fan_Interval){
digitalWrite(13, HIGH);
}
if (elapsed <= 20000) {
digitalWrite(13, LOW);
mode = 3;
}
char key = keypad.getKey();
if (key) {
if (key == 'C') {
lcd.clear();
digitalWrite(output1, LOW);
digitalWrite(output2, LOW);
digitalWrite(output3, LOW);
currentTime = millis();
elapsed = 0;
mode = 0;
}
}
}
}