//Protection Summer 2025 Version2.6
#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=12;
int ledPin2=8;
int ledPin3=9;
int ledPin4=13;
//int relay1Pin =13;
//int relay2Pin =12;
//int relay3Pin =11;
int ledFlipflopPin=10;
int ledFlipflopState= LOW;
const long interval = 500;// interval at which to blink
const long interval2 = 1000;// interval at which to blink
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=60000;
unsigned long previousTimeLedFlipflop=0;
unsigned long previousTimeNormal=0;
unsigned long previousTimesourceOverVolAlarm=0;
unsigned long previousTimesourceCutoffVolAlarm=0;
unsigned long previousTimelcdOnOff=0;
unsigned long previousPreAlarmTime=0;
unsigned long PreAlarmTime=15000;
const unsigned long minSwitchTime = 10000; // 10 seconds
float temp; //Stores temperature
float sourceCutoff = 20.00; //Source Cutoff voltage
float sourceOvervoltage1 = 40.00;//Source Overvoltage
float sourceOvervoltage2 = 47.00;//Source Overvoltage
float sourceOvervoltage3 = 54.50;//Source Overvoltage
float voltageHysteresis = 0.60;
int analogInput1 = A0; // voltage measurement pin
int value1 = 0;
float vout1 = 0.0;
float vSource = 0.0;
float R1a =100000;
float pot1 = 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 lastledpin1State=false;
bool lastledpin2State=false;
bool lastledpin3State=false;
bool ledpin1State=false;
bool ledpin2State=false;
bool ledpin3State=false;
bool cFlag1 = false;
bool pinCheck1 = false;
bool cFlag2 = false;
bool pinCheck2 = false;
bool cFlag3 = false;
bool pinCheck3 = false;
long target1 = 20000; //20 sec
int mins1 = (target1 / 1000)/60;
int secs1 = round(target1 /1000)%60;
long target2 = 15000; //15 sec
int mins2 = (target2 / 1000)/60;
int secs2 = round(target2 /1000)%60;
long target3 = 10000; //10 sec
int mins3 = (target3 / 1000)/60;
int secs3 = round(target3 /1000)%60;
void setup() {
Serial.begin(2400);
pinMode(piezoPin, OUTPUT); // Set buzzer - pin 6 as an output
pinMode(analogInput1,INPUT); // A0 is Source Voltage input
pinMode(CURRENT_SENSOR_PIN, INPUT);//A3 is current sensor input
//pinMode(relay1Pin, OUTPUT);
//pinMode(relay2Pin, OUTPUT);
pinMode(ledPin1, OUTPUT);
pinMode(ledPin2, OUTPUT);
pinMode(ledPin3, OUTPUT);
pinMode(ledPin4, OUTPUT);
pinMode(ledFlipflopPin, OUTPUT);
pinMode(buttonPin, INPUT);
//digitalWrite(ledPin4,HIGH);
lcd.init();
lcd.begin(16, 2);
lcd.setBacklight(1);
lcd.setCursor(0,0);
lcd.print("Batttery");
lcd.setCursor(0,1);
lcd.print("Protection v.2.6");
delay(3000);
}
void loop() {
//Serial.println("ledpin1state is " );
//Serial.println(ledpin1State);
value1 = analogRead(analogInput1);
vout1 = (value1 * 5.0) / 1024;
vSource = vout1 / (pot1/(R1a+pot1));
// 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);
//unsigned long currentTime = millis();
lcdOnOff();
buttonOnOff();
if (vSource>sourceCutoff){
if (ledpin1State==false){
Normal();
}
}
unsigned long currentTime = millis();
if (vSource>=sourceOvervoltage1){
lcd.setBacklight(1);
digitalWrite(ledPin1,HIGH); //Change the state
//digitalWrite(relay1Pin,HIGH);//RL1 open
}
if (vSource>=sourceOvervoltage2){
digitalWrite(ledPin2,HIGH); //Change the state
ledpin2State=true;
//digitalWrite(relay2Pin,HIGH);//RL1 open
}
if (vSource>=sourceOvervoltage3){
digitalWrite(ledPin3,HIGH); //Change the state
ledpin3State=true;
//digitalWrite(relay3Pin,HIGH);//RL1 open
}
if(vSource<sourceCutoff){
//digitalWrite(ledPin1,LOW);
//digitalWrite(ledPin2,LOW);
//digitalWrite(ledPin3,LOW);
//digitalWrite(ledPin4,LOW);
displayLedFlipflop();
lcd.setBacklight(1);
sourceCutoffVolAlarm();
//Serial.println("vSource<sourceCutoff");
//Serial.println("pin1State");
}
ledpin1State =digitalRead(ledPin1);//Check pin state
if (lastledpin1State==false){ //if it is changed
//Then the pinState went from false to true
if (ledpin1State == true){ //if it is true
lastledpin1State=true;
chronoA.restart(0); //Starts timer at 0
//Serial.println("First countdown");
}
}
if (chronoA.elapsed() < target1 && ledpin1State == true){
//Serial.println("First if - 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);
}
//chronoA.restart(0); //Starts timer at 0
sourceOverVolAlarm();
displayLedFlipflop();
buzzer();
//Serial.println("chronoA.elapsed()<target1");
//Serial.println(ledFlipflopState);
}
if (chronoA.elapsed() >= target1 && vSource<=sourceOvervoltage1 - voltageHysteresis){
//if timer has stopped, reset here and trigger alarms
ledpin1State=false;
digitalWrite(ledPin1, LOW);
stopA();
Normal();
//Serial.println("ledPin1, LOW");
}
if (chronoA.elapsed() < target1 && ledpin2State == true){
//Serial.println("Second if - 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);
}
//chronoA.restart(0); //Starts timer at 0
sourceOverVolAlarm();
displayLedFlipflop();
buzzer();
}
if (chronoA.elapsed() >= target1 && vSource<=sourceOvervoltage2 - voltageHysteresis){
//if timer has stopped, reset here and trigger alarms
ledpin2State=false;
digitalWrite(ledPin2, LOW);
sourceOverVolAlarm();
displayLedFlipflop();
chronoA.restart(0); //Starts timer at 0
//Serial.print("ledPin2, LOW");
//Serial.println("ledpin2State");
//Serial.println(ledpin2State);
}
if (chronoA.elapsed() < target1 && ledpin3State == true){
//Serial.println("Third if - 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);
}
//chronoA.restart(0); //Starts timer at 0
sourceOverVolAlarm();
displayLedFlipflop();
buzzer();
}
if (chronoA.elapsed() >= target1 && vSource<=sourceOvervoltage3 - voltageHysteresis){
//if timer has stopped, reset here and trigger alarms
ledpin3State=false;
digitalWrite(ledPin3, LOW);
sourceOverVolAlarm();
displayLedFlipflop();
chronoA.restart(0); //Starts timer at 0
//Serial.print("ledPin3, LOW");
//Serial.println("ledpin3State");
//Serial.println(ledpin3State);
}
if (chronoA.elapsed() >= target1 && vSource>=sourceOvervoltage3){
//if timer has stopped, reset here and trigger alarms
sourceOverVolAlarm();
displayLedFlipflop();
chronoA.restart(0); //Starts timer at 0
//Serial.print("Third count restart");
//Serial.println("ledpin3State");
//Serial.println(ledpin3State);
}
}
void displayLedFlipflop(){
unsigned long currentTime = millis();
if (currentTime - previousTimeLedFlipflop >= 500) {
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("Everything ");
lcd.setCursor(11,0);
lcd.print("Ok ");
}
if (count1 == 2){
thirdScreen = true;
lcd.setCursor(0,1);
lcd.print("Vsource:");
lcd.setCursor(8,1);
lcd.print(vSource);
lcd.setCursor(12,1);
lcd.print("V ");
count1 = 0;
}
}
}
void sourceOverVolAlarm(){
unsigned long currentTime = millis();
if (currentTime - previousTimesourceOverVolAlarm >= interval) {
previousTimesourceOverVolAlarm = currentTime;
count5++;
if (count5 == 1){
//ninthScreen = true;
lcd.setCursor(0,0);
lcd.print("Alarm OverV ");
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("SourceOverV ");
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 sourceCutoffVolAlarm(){
unsigned long currentTime = millis();
if (currentTime - previousTimesourceCutoffVolAlarm >= interval2) {
previousTimesourceCutoffVolAlarm = currentTime;
count5++;
//Serial.println(count2);
if (count5 == 1){
//ninthScreen = true;
lcd.setCursor(0,0);
lcd.print("Alarm LowV ");
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(" LowV ");
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 stopA (){
chronoA.stop();
}
void PreOverAlarmTime(){
unsigned long currentTime = millis();
if (currentTime - previousPreAlarmTime >= 10000){
lcd.setBacklight(1);
previousPreAlarmTime=currentTime;
Serial.println("Running PreAlarmTime");
}
}
void lcdOnOff(){
unsigned long currentTime = millis();
if (currentTime - previousTimelcdOnOff >=lcdOn){
lcd.setBacklight(0);
previousTimelcdOnOff=currentTime;
}
}
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);
}
void buzzer(){
tone(piezoPin, 1000); // Send 1KHz sound signal...
delay(1000); // ...for 1 sec
noTone(piezoPin); // Stop sound...
delay(1000); // ...for 1sec
}