#include <Wire.h>
#include <Chrono.h>
Chrono chronoA;
Chrono chronoB;
Chrono chronoC;
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16, 2);
#include "ACS712.h"
const int CURRENT_SENSOR_PIN = A3;
const float MAX_CURRENT = 20.0; // Amps
#include <DHT.h>;
#define DHTPIN 5 // what pin we're connected to
#define DHTTYPE DHT22 // DHT 22 (AM2302)
DHT dht(DHTPIN, DHTTYPE);
//Initialize DHT sensor for normal 16mhz Arduino
int chk;
int buttonPin = 4;
int piezoPin= 6;
int ledPin1=7;
int ledPin2=8;
int ledPin3=9;
int relay1Pin =13;
int relay2Pin =12;
int relay3Pin =11;
int ledFlipflopPin=10;
int ledFlipflopState= LOW;
const long interval = 250;// interval at which to blink
const long interval2 = 900;// interval change text in LCD
const long interval3 = 15000;
int buttonPushCounter = 0; // counter for the number of button presses
bool buttonState = false; // current state of the button
bool lastbuttonState = false; // previous state of the button
unsigned long lcdOn=40000;
unsigned long previousTimeLedFlipflop=0;
unsigned long previousTimeNormal=0;
unsigned long previousTimesourceCutoffVolAlarm=0;
unsigned long previousTimebatOverVolAlarm=0;
unsigned long previousTimelcdOnOff=0;
float temp; //Stores temperature
float sourceCutoff = 48.80; //Source Cutoff voltage
float batCutoff = 10.80; //Battery Cutoff voltage
float sourceOvervoltage = 56.30; //Source Overvoltage
float batOvervoltage = 14.30;//Battery Overvoltage
float voltageHysteresis = 0.20;
int analogInput1 = A0; // voltage measurement pin
int value1 = 0;
float vout1 = 0.0;
float vSource = 0.0;
float R1a =100000;
float pot1 = 10000;
int analogInput2 = A1; // voltage measurement pin
int value2 = 0;
float vout2 = 0.0;
float vBat = 0.0;
float R2a =40000;
float pot2 = 10000;
byte count1 = 0;
byte count2 = 0;
byte count3=0;
byte count4=0;
byte count5=0;
bool firstScreen = false;
bool secondScreen = false;
bool thirdScreen = false;
bool fourthScreen= false;
bool fifthScreen= false;
bool sixthScreen=false;
bool seventhScreen=false;
bool eighthScreen=false;
bool ninthScreen=false;
bool lastpin1State=false;
bool pin1State=false;
bool lastpin2State=false;
bool pin2State=false;
bool lastpin3State=false;
bool pin3State=false;
long target1 = 20000; //20 sec
int mins1 = (target1 / 1000)/60;
int secs1 = round(target1 /1000)%60;
long target2 = 18000; //18 sec
int mins2 = (target2 / 1000)/60;
int secs2 = round(target2 /1000)%60;
long target3 = 15000; //15 sec
int mins3 = (target3 / 1000)/60;
int secs3 = round(target3 /1000)%60;
void setup() {
Serial.begin(9600);
pinMode(analogInput1,INPUT); // A0 is Source Voltage input
pinMode(analogInput2,INPUT); // A1 is Bat Voltage input
pinMode(CURRENT_SENSOR_PIN, INPUT);//A3 is current sensor input
pinMode(relay1Pin, OUTPUT);
pinMode(relay2Pin, OUTPUT);
pinMode(relay3Pin, OUTPUT);
pinMode(ledPin1, OUTPUT);
pinMode(ledPin2, OUTPUT);
pinMode(ledPin3, OUTPUT);
pinMode(ledFlipflopPin, OUTPUT);
pinMode(buttonPin, INPUT);
lcd.begin(16, 2);
lcd.setBacklight(1);
lcd.setCursor(0,0);
lcd.print("Batttery");
lcd.setCursor(0,1);
lcd.print("Protection v.1.5");
delay(3000);
}
void loop() {
//Serial.println(ledFlipflopState);
Serial.println(pin1State);
value1 = analogRead(analogInput1);
vout1 = (value1 * 5.0) / 1024;
vSource = vout1 / (pot1/(R1a+pot1));
value2 = analogRead(analogInput2);
vout2 = (value2 * 5.0) / 1024;
vBat = vout2 / (pot2/(R2a+pot2));
// Read the voltage from the ACS712 current sensor module
float voltage = analogRead(CURRENT_SENSOR_PIN);
// Convert the voltage to current
float current = (voltage / 1024.0) * MAX_CURRENT;
// Print the current to the serial monitor
//Serial.print("Current: ");
//Serial.println(current);
//delay(1000);
//Serial.println(buttonState);
temp= dht.readTemperature();
if (temp >= 55.0) {
digitalWrite(ledPin2,HIGH);
digitalWrite(relay2Pin, HIGH); //Stop charge the battery1
lcd.setBacklight(1);
Serial.println("High bat temp");
}
if (temp <= 54.0) {
if (vBat<=batOvervoltage) {
if (lastpin2State==false) {
digitalWrite(ledPin2,LOW);
digitalWrite(relay2Pin, LOW); //Charge the battery1
}
}
}
unsigned long currentTime = millis();
lcdOnOff();
buttonOnOff();
if (vSource<=sourceOvervoltage){
if (vSource>sourceCutoff){
if (vBat<batOvervoltage){
if (vBat>=batCutoff){
if (lastpin1State==false){
if (lastpin2State==false){
if (lastpin3State==false){
Normal();
}
}
}
}
}
}
}
if(vSource<sourceCutoff){
digitalWrite(ledPin1,HIGH); //Change the state
digitalWrite(relay1Pin,HIGH);//RL1 open
lcd.setBacklight(1);
Serial.println("vSource<sourceCutoff");
Serial.println("pin1State");
}
if (temp <= 54.0) {
if (vBat>=batOvervoltage) {
digitalWrite(ledPin2,HIGH);
digitalWrite(relay2Pin,HIGH);//RL2 open
lcd.setBacklight(1);
//Serial.println("batOvervoltage");
}
}
pin1State =digitalRead(relay1Pin);//Check pin state
if (lastpin1State==false){ //if it is changed
//Then the pinState went from false to true
if (pin1State == true){//if it is true
lastpin1State=true;
chronoA.restart(0); //Starts timer at 0
Serial.println("chronoA.start");
}
}
else if (chronoA.elapsed() < target1){
Serial.println("chronoA.running");
//If timer running, send to display data
long test1 = target1 - chronoA.elapsed();
int testSecs1 = round(test1 / 1000);
if (round(testSecs1/60) != mins1){
mins1 = round(testSecs1/60);
}
if (round(testSecs1%60)!= secs1) {
secs1 = round(testSecs1%60);
sourceCutoffVolAlarm();
displayLedFlipflop();
Serial.println("displayLedFlipflop");
//Serial.println(ledFlipflopState);
}
}
else if (chronoA.elapsed()>= target1 && vSource<=sourceCutoff) {
chronoA.restart(0); //Starts timer at 0
//If timer running, send to display here
long test1 = target1 - chronoA.elapsed();
int testSecs1 = round(test1 / 1000);
if (round(testSecs1/60) != mins1){
mins1 = round(testSecs1/60);
}
if (round(testSecs1%60)!= secs1) {
secs1 = round(testSecs1%60);
sourceCutoffVolAlarm();
displayLedFlipflop();
Serial.println("chronoA.restart");
}
}
else if (chronoA.elapsed() >= target1 && vSource>= sourceCutoff){
//if timer has stopped, reset here and trigger alarm
lastpin1State=false;
digitalWrite(ledPin1,LOW);
digitalWrite(relay1Pin, LOW);
stopA();
Serial.println("stopA");
Normal();
//digitalWrite(ledFlipflopPin,LOW);
//Serial.println("chronoA.elapsed >= target1");
}
pin2State =digitalRead(relay2Pin);//Check pin state
if (lastpin2State==false){//if it is changed
//Then the pinState went from false to true
if (pin2State == true){//if it is true
lastpin2State=true;
chronoB.restart(0); //Starts timer at 0
Serial.println("chronoB.start");
}
}
else if (chronoB.elapsed() < target2){
//If timer running, send to display
long test2 = target2 - chronoB.elapsed();
int testSecs2 = round(test2 / 1000);
if (round(testSecs2/60) != mins2){
mins2 = round(testSecs2/60);
}
if (round(testSecs2%60)!= secs2) {
secs2 = round(testSecs2%60);
batOverVolAlarm();
displayLedFlipflop();
Serial.println("LedFlipflop");
}
}
else if (chronoB.elapsed() >= target2 && vBat >= batOvervoltage){
chronoB.restart(0); //Starts timer at 0
//If timer running, send to display here
long test2 = target2 - chronoB.elapsed();
int testSecs2 = round(test2 / 1000);
if (round(testSecs2/60) != mins2){
mins2 = round(testSecs2/60);
}
if (round(testSecs2%60)!= secs2) {
secs2 = round(testSecs2%60);
}
batOverVolAlarm();
displayLedFlipflop();
Serial.println("chronoB.restart");
}
else if (chronoB.elapsed() >= target2 && vBat <= batOvervoltage){
//if timer has stopped, reset and trigger alarm
lastpin2State=false;
digitalWrite(ledPin2,LOW);
digitalWrite(relay2Pin, LOW);
stopB();
Serial.println("stopB.stoped");
Normal();
Serial.println("Normal running");
}
pin3State =digitalRead(relay3Pin);//Check pin state
if (lastpin3State==false){//if it is changed
//Then the pinState went from false to true
if (pin3State == true){//if it is true
lastpin3State=true;
chronoC.restart(0); //Starts timer at 0
digitalWrite(ledPin3, HIGH);
}
}
else if (chronoC.elapsed() < target3){
//If timer running, send to display
long test3 = target3 - chronoC.elapsed();
int testSecs3 = round(test3 / 1000);
if (round(testSecs3/60) != mins3){
mins3 = round(testSecs3/60);
}
if (round(testSecs3%60)!= secs3) {
secs3 = round(testSecs3%60);
displayLedFlipflop();
}
}
else if (chronoC.elapsed() >= target3 ){
//if timer has stopped, reset and trigger alarm
lastpin3State=false;
Serial.println("stopC");
digitalWrite(ledPin3,LOW);
digitalWrite(relay3Pin, LOW);
stopC();
Serial.println("stopC");
Normal();
Serial.println("chronoC.elapsed >= target3");
}
//count2++;
//Serial.println(count2);
}
void displayLedFlipflop(){
unsigned long currentTime = millis();
if (currentTime - previousTimeLedFlipflop >= 250) {
previousTimeLedFlipflop = currentTime;
// save the last time you blinked the LED
if (ledFlipflopState ==HIGH){
ledFlipflopState = LOW;
} else {
ledFlipflopState = HIGH;
// set the LED with the ledState of the variable:
}
digitalWrite(ledFlipflopPin, ledFlipflopState);
}
}
void Normal(){//RL1,RL2, RL3 are LOW
unsigned long currentTime = millis();
if (currentTime - previousTimeNormal >= 2000){
previousTimeNormal = currentTime;
count1++;
//Serial.println(count1);
//delay(1000);
if (count1 == 1){
firstScreen = true;
lcd.setCursor(0,0);
lcd.print("Battery ");
lcd.setCursor(11,0);
lcd.print("Temp ");
}
if (count1 == 2){
secondScreen = true;
lcd.setCursor(0,0);
lcd.print("Charging ");
lcd.setCursor(11,0);
lcd.print(temp);
lcd.setCursor(15,0);
lcd.print("C");
}
if (count1 == 3){
thirdScreen = true;
lcd.setCursor(0,1);
lcd.print("Vsource:");
lcd.setCursor(8,1);
lcd.print(vSource);
lcd.setCursor(12,1);
lcd.print("V ");
}
if (count1 == 4){
fourthScreen = true;
lcd.setCursor(0,1);
lcd.print("Vbattery:");
lcd.setCursor(9,1);
lcd.print(vBat,1);
lcd.setCursor(13,1);
lcd.print("V ");
count1 = 0;
}
}
//digitalWrite(ledFlipflopPin,LOW);
}
void sourceCutoffVolAlarm(){
unsigned long currentTime = millis();
if (currentTime - previousTimesourceCutoffVolAlarm >= interval) {
previousTimesourceCutoffVolAlarm = currentTime;
count5++;
//Serial.println(count2);
if (count5 == 1){
//ninthScreen = true;
lcd.setCursor(0,0);
lcd.print("Alarm RL1 ");
lcd.setCursor(0,1);
lcd.print("VSource: ");
lcd.setCursor(9,1);
lcd.print(vSource,1);
lcd.setCursor(13,1);
lcd.print("V ");
}
if (count5 == 2){
//ninthScreen = true;
lcd.setCursor(0,0);
lcd.print("SourceCutoff");
lcd.setCursor(0,1);
lcd.print("VSource: ");
lcd.setCursor(9,1);
lcd.print(vSource,1);
lcd.setCursor(13,1);
lcd.print("V ");
count5 = 0;
}
lcd.setCursor(12,0);
lcd.print(mins1);
lcd.setCursor(13,0);
lcd.print(":");
lcd.setCursor(14,0);
lcd.print(secs1);
if (secs1<=10){
//lcd.setCursor(15,0);
lcd.print(" ");
}
}
}
void batOverVolAlarm(){//RL2 is open, bat low voltage
unsigned long currentTime = millis();
if (currentTime - previousTimebatOverVolAlarm >= interval) {
previousTimebatOverVolAlarm = currentTime;
count2++;
//Serial.println(count2);
if (count2 == 1){
fifthScreen = true;
lcd.setCursor(0,0);
lcd.print("Alarm ");
}
if (count2 == 2){
fifthScreen = true;
lcd.setCursor(0,0);
lcd.print("RL2 ");
lcd.setCursor(0,1);
lcd.print("Vbattery:");
lcd.setCursor(9,1);
lcd.print(vBat,1);
lcd.setCursor(13,1);
lcd.print("V ");
count2 = 0;
}
}
lcd.setCursor(12,0);
lcd.print(mins2);
lcd.setCursor(13,0);
lcd.print(":");
lcd.setCursor(14,0);
lcd.print(secs2);
if (secs2<=10){
//lcd.setCursor(15,0);
lcd.print(" ");
}
}
void stopA (){
chronoA.stop();
}
void stopB (){
chronoA.stop();
}
void stopC (){
chronoC.stop();
}
void lcdOnOff(){
unsigned long currentTime = millis();
if (currentTime - previousTimelcdOnOff >=lcdOn){
lcd.setBacklight(0);
previousTimelcdOnOff=currentTime;
//digitalWrite(ledPin,LOW);
}
}
void buttonOnOff(){
buttonState = digitalRead(buttonPin);
// read the pushbutton input pin
if (buttonState != lastbuttonState){
// compare the buttonState to its previous state
if (buttonState == HIGH){
// if the current state is HIGH then the button went
//from off to on
lcd.setBacklight(1);
}
lastbuttonState = buttonState;
//save the current state as the last state,for next time through the loop
Serial.println(buttonState);
}
delay(50);
}