IOT &Tesla we created title BMS system for lithium ion batteries. */

include

include

include

// Pins const int OnSwitchPin = 2; // pin to read on switch status const int ChargerRelayPin = 3; // pin to control the charger relay const int Pin110V = 4; // pin to read if charger is plugged in const int OnSwitchRelayPin = 5; // pin to control the on switch (dc-dc pwr) const int AlarmPin = 6; // pin to read celllog alarm signal const int latchPin = 8; // pin to connect to latch pin on shift register const int dataPin = 11; // pin to connect to data pin on shift register const int clockPin = 12; // pin to connect to clock pin on shift register const int CurrentPin = 1; // analog pin to read the current sensor

// Variables volatile float CurrentRead = 0; // holds CurrentPin analog read volatile float AHused = 0; // holds amp hours used float BatteryAH = 0; // holds usable battery amp hours int AlarmPinStatus = 0; // holds AlarmPin status int OnSwitchPinStatus = 0; // holds the OnSwitchPin status int Pin110VStatus = 0; // holds the Pin110V status unsigned long DelayTimer = 0; // variable to hold disconnect time float SOC = 0; // holds state of charge

// User defined variables const int RatedBatteryAmpHours = 78; // rated amp hours of the batteries const float DOD = .7; // maximum depth of discharge allowed

void setup() { pinMode(AlarmPin, INPUT); pinMode(ChargerRelayPin, OUTPUT); pinMode(Pin110V, INPUT); pinMode(OnSwitchRelayPin, OUTPUT); pinMode(OnSwitchPin, INPUT); pinMode(CurrentPin, INPUT); digitalWrite(AlarmPin, HIGH); // set AlarmPin high digitalWrite(ChargerRelayPin, LOW); // turn charger relay off digitalWrite(OnSwitchRelayPin, LOW); // turn on switch off

BatteryAH = RatedBatteryAmpHours * DOD; // calculate usable Ah

// initialize Timer1 cli(); // disable global interrupts TCCR1A = 0; // set entire TCCR1A register to 0 TCCR1B = 0; // same for TCCR1B // set compare match register to desired timer count OCR1A = 16001; // turn on CTC mode TCCR1B |= (1 << WGM12); // Set CS10 TCCR1B |= (1 << CS10); // enable timer compare interrupt TIMSK1 |= (1 << OCIE1A); // enable global interrupts sei(); }

void loop() {

// SOC gauge code // calculate SOC SOC = (BatteryAH - AHused) / BatteryAH; // write SOC to led bargraph if (SOC > .875) { // 8 leds lit up digitalWrite(latchPin, LOW); shiftOut(dataPin, clockPin, MSBFIRST, 255); digitalWrite(latchPin, HIGH); } else if (SOC > .75) { // 7 leds lit up digitalWrite(latchPin, LOW); shiftOut(dataPin, clockPin, MSBFIRST, 127); digitalWrite(latchPin, HIGH); } else if (SOC > .625) { // 6 leds lit up digitalWrite(latchPin, LOW); shiftOut(dataPin, clockPin, MSBFIRST, 63); digitalWrite(latchPin, HIGH); } else if (SOC > .5) { // 5 leds lit up digitalWrite(latchPin, LOW); shiftOut(dataPin, clockPin, MSBFIRST, 31); digitalWrite(latchPin, HIGH); } else if (SOC > .375) { // 4 leds lit up digitalWrite(latchPin, LOW); shiftOut(dataPin, clockPin, MSBFIRST, 15); digitalWrite(latchPin, HIGH); } else if (SOC > .25) { // 3 leds lit up digitalWrite(latchPin, LOW); shiftOut(dataPin, clockPin, MSBFIRST, 7); digitalWrite(latchPin, HIGH); } else if (SOC > .125) { // 2 leds lit up digitalWrite(latchPin, LOW); shiftOut(dataPin, clockPin, MSBFIRST, 3); digitalWrite(latchPin, HIGH); } else if (SOC > 0) { // 1 leds lit up digitalWrite(latchPin, LOW); shiftOut(dataPin, clockPin, MSBFIRST, 1); digitalWrite(latchPin, HIGH); } else { // 0 leds lit up digitalWrite(latchPin, LOW); shiftOut(dataPin, clockPin, MSBFIRST, 0); digitalWrite(latchPin, HIGH); }

// Charger connect code // read pin110v status Pin110VStatus = digitalRead(Pin110V); // if 110V power is plugged in if (Pin110VStatus == HIGH) { digitalWrite(ChargerRelayPin, HIGH); // turn charger on }

// Charger disconnect code // read alarm pin status AlarmPinStatus = digitalRead(AlarmPin); // if alarm turns on set a timer to detect false alarms if (AlarmPinStatus == LOW && millis() - DelayTimer < 10) { DelayTimer = millis(); // set timer } // if alarm stays on if (AlarmPinStatus == LOW && millis() - DelayTimer > 2000) { digitalWrite(ChargerRelayPin, LOW); // turn charger off AHused = 0; // reset amp hours DelayTimer = 0; // reset delay timer }

// DC-DC connect code // read on switch status OnSwitchPinStatus = digitalRead(OnSwitchPin); // if dc-dc switch is on && battery has capacity left if (OnSwitchPinStatus = HIGH && AHused < BatteryAH) { digitalWrite(OnSwitchRelayPin, HIGH); // turn dc-dc converter on }

// DC-DC disconnect code // if amp hours used exceeds usable amp hour capacity if (AHused > BatteryAH) { digitalWrite(OnSwitchRelayPin, LOW); // turn dc-dc converter off }

// DC-DC power down code // if dc-dc converter switch is off enter sleep mode if (OnSwitchPinStatus = LOW) { // enter sleep mode sleepNow(); } }

// sleep mode code void sleepNow() { attachInterrupt(0,loop, RISING); // set interrupt to on switch set_sleep_mode(SLEEP_MODE_PWR_SAVE); sleep_enable(); digitalWrite(latchPin, LOW); // turn off SOC gauge shiftOut(dataPin, clockPin, MSBFIRST, 0); digitalWrite(latchPin, HIGH); sleep_mode(); // enter sleep mode sleep_disable(); // resume code after exiting sleep mode }

// interrupt to count amp hours used ISR(TIMER1_COMPA_vect) { CurrentRead = analogRead(CurrentPin); // Convert currentread to amps CurrentRead = (CurrentRead - 512) * .78125; // Convert to AH & add to total AHused = AHused + (CurrentRead * .001); }

Built With

Share this project:
×

Updates