//Shift register default command line 0000 0000-LSB, LSB is Q0
//command for all leds on and latch and buzzer = 1100 1111= Q7 is latch, Q6 is buzzer, Q0-Q3 is led
#include <Arduino.h>
//#include <EEPROM.h>
#include <SoftwareSerial.h>
//#include <OneWire.h>
//#include <DallasTemperature.h>
//Note to self, state should equal charging only when current sensing indicates charging, revivsit charge function and make the update
#define ONE_WIRE_BUS_0 6
#define ONE_WIRE_BUS_1 7 //Digital pin declarartion for temperature sensor one
#define ONE_WIRE_BUS_2 8 //Digital pin declarartion for temperature sensor two
/*#define green_1 9 //first green to lilt for 100%
#define green_2 7 //second green to lilt for 75%
#define green_3 6 //third green to lilt for 50%
#define redPin 5 //Red LED of RGB for 10-25% batteryPercentage display
#define greenPin 8 //Green LED of RGB for 10-25% batteryPercentage display
#define bluePin 10 */ //Blue LED of RGB for 10-25% batteryPercentage display
// Move the buzzer to the shift reg output
#define iSense A2
#define Schg A0
#define AC A1
#define cell1 A5 //define battery cell1 as analog pin A0
#define cell2 A4 //define battery cell2 as analog pin A1
#define cell3 A3 //define battery cell3 as analog pin A2
//move the lil LED t the shift register, should be sonstantly on if batter isnt full at first instsllation
//#define latch 2
#define fan 2
#define chargePin 3
#define inv 4 //move the switch pin to the shift reg.
//#define buzzer 5
#define lilLed 5
#define latchPin 9
#define von 10 //Im connecting the switch to 5v, so digitalRead is plausible
#define changeOver 13 //move change over to shift reg
#define clockPin 12
#define dataPin 11
/*#define led1 9
#define led2 10
#define led3 11
#define led4 12*/ //all 4 leds are moved to shift reg
//state definitions
#define fullyCharged 2
#define notFull 4
#define charging 6
#define Tmax 40 //Max temperature
#define vonMaxRef 55.0
int count = 0;
//OneWire oneWire_in(ONE_WIRE_BUS_1); // OneWire libray call for temperature one
//OneWire oneWire_out(ONE_WIRE_BUS_2); //OneWire libray call for temperature two
//OneWire oneWire_mid(ONE_WIRE_BUS_0);
//DallasTemperature sensor_inhouse(&oneWire_in); //Dallas libray call for temperature one
// sensor_outhouse(&oneWire_out); //Dallas libray call for temperature two
//DallasTemperature sensor_midhouse(&oneWire_mid);
//SoftwareSerial serial(7, A1); // software rx,tx
//SoftwareSerial Percentage(8, 9);
String b_data = ""; //Array that holds all values thatgetprinted on serial monitor
float battCapacity = 1800, fullChargeVoltage = 12.4, lowChargeVoltage = 10.3;
float charge = 0.0, current = 0.0;
float batteryVoltage, batteryPercentage, voltage;
float cell_voltage[3] = {};
byte cells[3] = {cell1, cell2, cell3};
unsigned long currentStamp = 0, lastMillis = 0, lastStamp = 0, DumpTime = 0, cTime = 30000, wTime = 1000, diff, lastDumpTime = 0, lastDumpTime1 = 0, startTime = 0, currentTime = millis();
const long interval = 1000;
byte state, counts = 0;
bool chging = false, on = true;
struct BMS //creating a BMS class
{
void initializeBMS() //method for initializing the BMS
{
Serial.begin(9600);
// serial.begin(9600);
// sensor_inhouse.begin(); //temperature sense storage
//sensor_outhouse.begin(); //temperature sense storage
//sensor_midhouse.begin();
/* pinMode(green_1, 1); //Declaring our first green LED as OUTPUT pin
pinMode(green_2, 1); //Declaring our second green LED as OUTPUT pin
pinMode(green_3, 1); //Declaring our third green LED as OUTPUT pin
pinMode(redPin, 1); //Declaring redLED as output one
pinMode(greenPin, 1); //Declaring greenLED as output two
pinMode(bluePin, 1);*/ //Declaring blueLED as output three
pinMode(von, 0); //Note to self, pulldown this pin //Declaring buzzer pin as output
pinMode(Schg, 0);
pinMode(AC, 0);
pinMode(lilLed, 1);
pinMode(iSense, 0);
pinMode(changeOver, 1);
pinMode(inv, 1);
pinMode(chargePin, 1);
pinMode(latchPin, 1);
pinMode(clockPin, 1);
pinMode(dataPin, 1);
//Note to self, no ac sensing for when ac is plugged, hopefully the diode works
pinMode(fan, 1);
for (byte i = 0; i < 3; ++i)
{
pinMode(cells[i], 0);
}
digitalWrite(latchPin, 0);
shiftOut(dataPin, clockPin, MSBFIRST, 0b10000000); //latch the system
digitalWrite(latchPin, 1);
float temp = (analogRead(cells[2]) * 55.0) / 1024.0;
Serial.print("Starting Voltage: ");
Serial.println(temp);
if (temp > lowChargeVoltage && temp < fullChargeVoltage)
{
state = notFull;
while (temp > lowChargeVoltage && temp < fullChargeVoltage)
{
Charge();
temp = batteryVoltage;
Serial.println(temp);
digitalWrite(lilLed, 1);
}
digitalWrite(lilLed, 0);
charge = battCapacity;
state = fullyCharged;
}
else if (temp <= lowChargeVoltage)
{
charge = 0;
state = notFull;
}
else {
charge = battCapacity;
state = fullyCharged;
Serial.println(state);
}
// readCellVoltages();
}
/*We have some conditions:
1) Power switch is off, there is no charging
2) Power switch is switched on, there is no charging
3) Charging starts :
- AC is plugged
-Solar is plugged
-Charging and power switch is on
*/
void readCellVoltages(void) //method for reading cell voltages
{
for (byte i = 0; i < 3; ++i)
{
float voltage = analogRead(cells[i]);
voltage = (voltage * 55.0) / 1023.0;
cell_voltage[i] = voltage;
}
cell_voltage[1] -= cell_voltage[0];
cell_voltage[2] -= (cell_voltage[1] + cell_voltage[0]);
batteryVoltage = cell_voltage[2];
}
void Charge(void)
{
//readCellVoltages();
float batteryVoltage = (analogRead(cells[2]) * 55.0) / 1024.0;
Serial.print("Starting Voltage: ");
Serial.println(batteryVoltage);
currentStamp = millis();
if (state == notFull && (currentStamp - lastStamp >= wTime))
{
readCellVoltages();
if (batteryVoltage >= fullChargeVoltage)
{
batteryPercentage = 100;
state = fullyCharged;
}
else {
digitalWrite(chargePin, 0);
state = charging;
}
lastStamp = currentStamp;
}
else if (state == charging && (currentStamp - lastStamp >= cTime))
{
digitalWrite(chargePin, 1);
readCellVoltages();
if (batteryVoltage >= fullChargeVoltage)
{
batteryPercentage = 100;
state = fullyCharged;
}
else {
digitalWrite(chargePin, 0);
state = notFull;
}
lastStamp = currentStamp;
}
else if (state == fullyCharged)
{
Serial.println(state);
readCellVoltages();
if (batteryVoltage < fullChargeVoltage)
{
state = notFull;
}
else {
digitalWrite(chargePin, 1);
state = fullyCharged;
Serial.println(state);
}
}
}
float measureCurrent(byte pin)
{
float voltage = analogRead(pin);
voltage = (voltage * 5.0) / 1024.0;
voltage -= 2.5; //Note to self, make the 0<current<current drawn by circuit alone when theres no discharge
float current = voltage / 0.0133;
return current * 1000; //convert to milliamperes
}
void countQ(void)
{
diff = millis() - lastMillis;
if ( diff >= 1000)
{
current = measureCurrent(iSense);
if (current > 0)
{
chging = false;
charge = charge - (current * (diff / 3600000.0));
}
if (charge < 0)
{
charge = 0;
chging = false;
}
else if (current < 0 )
{
charge = charge + (-1.0 * current * (diff / 3600000.0));
chging = true;
}
lastMillis = millis();
}
}
void seriallizeData(void)
{
if (millis() - lastDumpTime1 >= 1000)
{
b_data = "[";
b_data += batteryVoltage;
b_data += " ";
b_data += batteryPercentage;
b_data += ",";
b_data += charge;
b_data += ","; //My Serializing Art ;)
b_data += current / 1000;
b_data += ",";
b_data += cell_voltage[0];
b_data += ",";
b_data += cell_voltage[1];
b_data += ",";
b_data += cell_voltage[2];
b_data += ",";
b_data += chging;
// b_data += ",";
// b_data += sensor_inhouse.getTempCByIndex(0);
// b_data += ",";
// b_data += sensor_outhouse.getTempCByIndex(0);
// b_data += ",";
// b_data += sensor_midhouse.getTempCByIndex(0);
b_data += "]";
b_data += ";";
Serial.println(b_data);
lastDumpTime1 = millis();
}
}
void computePercentage(void)
{
batteryPercentage = (charge / battCapacity) * 100;
if (batteryPercentage > 100)
{
batteryPercentage = 100;
}
}
/*void tempSense(void)
{
sensor_inhouse.requestTemperatures();
sensor_outhouse.requestTemperatures();
sensor_midhouse.requestTemperatures();
}
*/
float measureVoltage(int pin, float Max)
{
float voltage = analogRead(pin);
voltage = (voltage * Max) / 1023.0;
return voltage + 0.16;
}
void Shutdown()
{
if (batteryVoltage <= lowChargeVoltage) {
digitalWrite(latchPin, 0);
shiftOut(dataPin, clockPin, MSBFIRST, 0b00000000);
digitalWrite(latchPin, 1);
}
// while (sensor_inhouse.getTempCByIndex(0) >= Tmax || sensor_outhouse.getTempCByIndex(0) >= Tmax || sensor_midhouse.getTempCByIndex(0) >= Tmax) {
// digitalWrite(inv, 0);
// tempSense();
// digitalWrite(latchPin, 0);
// shiftOut(dataPin, clockPin, MSBFIRST, 0b11000000);
// digitalWrite(latchPin, 1);
// }
}
/*We have some conditions:
1) Power switch is off, there is no charging
2) Power switch is switched on, there is no charging
3) Charging starts :
- AC is plugged
-Solar is plugged
-Charging and power switch is on
*/
void doRoutine(void)
{
countQ();
computePercentage();
Charge();
// tempSense();
seriallizeData();
//Shutdown();
voltage = analogRead(Schg);
voltage = (voltage * 55) / 1024.0;
voltage += 0.16;
}
};
BMS bms; //creating a BMS object
/*void requestEvent() {
Wire.print(b_data);
delay(1000);
}*/
void receiveEvent(int howMany) {
}
void setup() {
bms.initializeBMS(); //initializing the BMS
// Wire.begin(102);
//Wire.onRequest(requestEvent);
//Wire.onReceive(receiveEvent);
}
void loop() {
while ( voltage < 11.0 && measureVoltageAC() < 100.0) { //Not charging
bms.doRoutine();
digitalWrite(changeOver, 0);
if (digitalRead(von) == 1) {
registerCommands(0);
}
else {
digitalWrite (inv, 0);
count = 0;
digitalWrite(latchPin, 0);
shiftOut(dataPin, clockPin, MSBFIRST, 0b10000000);// power switch not pressed
digitalWrite(latchPin, 1);
}
}
while ( voltage > 1.0 || measureVoltageAC() > 100.0) {
bms.doRoutine();
if (digitalRead(von) == 1) {
digitalWrite (inv, 1);
}
if (digitalRead(von) == 0) {
digitalWrite (inv, 0);
}
if (measureVoltageAC() > 100.0) {
digitalWrite(changeOver, 1);
registerCommands(1);
}
else {
digitalWrite(changeOver, 0);
registerCommands(1);
}
}
}
float measureVoltageAC(void)
{
float val = 0;
float maxpk = 0, RMS = 0;
unsigned long Time = millis(), sampleTime = 1000;
while (millis() - Time <= sampleTime)
{
for (int i = 0; i < 300; ++i)
{
val += analogRead(AC);
val /= 2;
}
if (val <= 0)
{
maxpk = 0;
}
else
{
if (val > maxpk)
{
maxpk = val;
}
}
}
maxpk = (maxpk * 505.0) / 1024.0;
//maxpk = (maxpk * 605.0) / 1024.0;
RMS = maxpk * 0.707;
return RMS;
}
void registerCommands(byte mode) {
if (mode == 0) {
// while (count != 4) {
// bms.doRoutine();
if (millis() - DumpTime >= 150 && count == 0) {
digitalWrite(latchPin, 0);
shiftOut(dataPin, clockPin, MSBFIRST, 0b10000001);
digitalWrite(latchPin, 1);
count = 1;
DumpTime = millis();
}
else if (millis() - DumpTime >= 150 && count == 1) {
digitalWrite(latchPin, 0);
shiftOut(dataPin, clockPin, MSBFIRST, 0b10000011);
digitalWrite(latchPin, 1);
count = 2;
DumpTime = millis();
}
else if (millis() - DumpTime >= 150 && count == 2) {
digitalWrite(latchPin, 0);
shiftOut(dataPin, clockPin, MSBFIRST, 0b10000111);
digitalWrite(latchPin, 1);
count = 3;
DumpTime = millis();
}
else if (millis() - DumpTime >= 150 && count == 3) {
digitalWrite(latchPin, 0);
shiftOut(dataPin, clockPin, MSBFIRST, 0b10001111);
digitalWrite(latchPin, 1);
count = 4;
}
// bms.doRoutine();
// }
if (count == 4){
digitalWrite (inv, 1);
if (batteryPercentage <= 75 && batteryPercentage > 50) {
digitalWrite(latchPin, 0);
shiftOut(dataPin, clockPin, MSBFIRST, 0b10000111); //leds are on
digitalWrite(latchPin, 1);
}
else if (batteryPercentage <= 50 && batteryPercentage > 25) {
digitalWrite(latchPin, 0);
shiftOut(dataPin, clockPin, MSBFIRST, 0b10000011); //leds are on
digitalWrite(latchPin, 1);
}
else if (batteryPercentage <= 25 && batteryPercentage > 10) {
digitalWrite(latchPin, 0);
shiftOut(dataPin, clockPin, MSBFIRST, 0b10000001); //leds are on
digitalWrite(latchPin, 1);
}
else if (batteryPercentage <= 10) {
digitalWrite(latchPin, 0);
shiftOut(dataPin, clockPin, MSBFIRST, 0b10000000); //leds and inv are on
digitalWrite(latchPin, 1);
}
else {
analogWrite(fan, 0);
digitalWrite(latchPin, 0);
shiftOut(dataPin, clockPin, MSBFIRST, 0b10001111); //leds and inv are on
digitalWrite(latchPin, 1);
}
}
}
else if (mode == 1) {
Serial.println(mode);
if (batteryPercentage <= 99 && batteryPercentage > 50) {
analogWrite(fan, 255);
digitalWrite(latchPin, 0);
shiftOut(dataPin, clockPin, MSBFIRST, 0b10000111); //leds and inv are on
digitalWrite(latchPin, 1);
bms.doRoutine();
delay(300);
digitalWrite(latchPin, 0);
shiftOut(dataPin, clockPin, MSBFIRST, 0b10001111); //leds and inv are on
digitalWrite(latchPin, 1);
}
else if (batteryPercentage <= 50 && batteryPercentage > 25) {
analogWrite(fan, 255);
digitalWrite(latchPin, 0);
shiftOut(dataPin, clockPin, MSBFIRST, 0b10000011); //leds and inv are on
digitalWrite(latchPin, 1);
bms.doRoutine();
delay(300);
digitalWrite(latchPin, 0);
shiftOut(dataPin, clockPin, MSBFIRST, 0b10000111); //leds and inv are on
digitalWrite(latchPin, 1);
}
else if (batteryPercentage <= 25 && batteryPercentage > 10) {
analogWrite(fan, 255);
digitalWrite(latchPin, 0);
shiftOut(dataPin, clockPin, MSBFIRST, 0b10000001); //leds and inv are on
digitalWrite(latchPin, 1);
bms.doRoutine();
delay(300);
digitalWrite(latchPin, 0);
shiftOut(dataPin, clockPin, MSBFIRST, 0b10000011); //leds and inv are on
digitalWrite(latchPin, 1);
}
else if (batteryPercentage <= 10) {
analogWrite(fan, 255);
digitalWrite(latchPin, 0);
shiftOut(dataPin, clockPin, MSBFIRST, 0b10000000); //leds and inv are on
digitalWrite(latchPin, 1);
bms.doRoutine();
delay(300);
digitalWrite(latchPin, 0);
shiftOut(dataPin, clockPin, MSBFIRST, 0b10000001); //leds and inv are on
digitalWrite(latchPin, 1);
}
else if (batteryPercentage == 100){
analogWrite(fan, 0);
digitalWrite(latchPin, 0);
shiftOut(dataPin, clockPin, MSBFIRST, 0b10001111); //leds and inv are on
digitalWrite(latchPin, 1);
}
if (batteryPercentage > 95 && batteryPercentage < 99.2)
{
counts++;
if (counts >= 10)
{
analogWrite(fan, 0);
counts = 10;
}
else {
analogWrite(fan, 255);
}
}
else {
counts = 0;
}
}
}