EV Battery — ESP32 simulation

An interactive ESP32 circuit simulation you can run free in your browser on Velxio, by crganesh537.

Components

Sketch code

#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <OneWire.h>
#include <DallasTemperature.h>

#define VOLTAGE 34
#define CURRENT 35
#define TEMP 4

#define RELAY 23
#define BUZZER 19
#define GREEN 25
#define RED 26

#define START 33
#define STOP 32

LiquidCrystal_I2C lcd(0x27, 16, 2);
OneWire oneWire(TEMP);
DallasTemperature sensor(&oneWire);

bool charging = true; // Auto-starts charging immediately on boot
bool buzzerState = false;

float voltage, current, temp, soc;

int lastStartState = HIGH;
int lastStopState = HIGH;

float readVoltage() {
  return 10.0 + (analogRead(VOLTAGE) / 4095.0) * 6.0;
}

float readCurrent() {
  return (analogRead(CURRENT) / 4095.0) * 20.0;
}

float readTemp() {
  sensor.requestTemperatures();
  float t = sensor.getTempCByIndex(0);

  if (t == DEVICE_DISCONNECTED_C || t < -50 || t > 125)
    return 25.0;

  return t;
}

void setup() {
  Serial.begin(115200);

  pinMode(START, INPUT_PULLUP);
  pinMode(STOP, INPUT_PULLUP);

  pinMode(RELAY, OUTPUT);
  pinMode(BUZZER, OUTPUT);
  pinMode(GREEN, OUTPUT);
  pinMode(RED, OUTPUT);

  sensor.begin();
  Wire.begin(21, 22);

  lcd.init();
  lcd.backlight();

  lcd.setCursor(0, 0);
  lcd.print("EV Battery");

  lcd.setCursor(0, 1);
  lcd.print("BMS + Edge AI");

  delay(2000);
  lcd.clear();

  digitalWrite(RELAY, HIGH);
  digitalWrite(GREEN, HIGH);
  digitalWrite(RED, LOW);

  Serial.println("AIoT EV BATTERY BMS");
  Serial.println("Edge AI Fault Detection");
  Serial.println("System Ready - Auto Charging");
}

void loop() {
  voltage = readVoltage();
  current = readCurrent();
  temp = readTemp();

  soc = (voltage - 10.0) / 6.0 * 100.0;
  soc = constrain(soc, 0, 100);

  String fault = "NORMAL";

  if (temp > 45)
    fault = "OVERTEMP";
  else if (current > 15)
    fault = "OVERCURRENT";
  else if (voltage > 14.8)
    fault = "OVERVOLTAGE";

  int startState = digitalRead(START);
  int stopState = digitalRead(STOP);

  if (startState == LOW && lastStartState == HIGH) {
    charging = true;
    delay(50); 
  }
  lastStartState = startState;

  if (stopState == LOW && lastStopState == HIGH) {
    charging = false;
    delay(50); 
  }
  lastStopState = stopState;

  if (fault != "NORMAL") {
    charging = false;

    digitalWrite(RELAY, LOW);
    digitalWrite(GREEN, LOW);
    digitalWrite(RED, HIGH);

    if (!buzzerState) {
      tone(BUZZER, 2000);
      buzzerState = true;
    }

    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("AI FAULT:");

    lcd.setCursor(0, 1);
    lcd.print(fault);

  } else {
    if (buzzerState) {
      noTone(BUZZER);
      buzzerState = false;
    }

    digitalWrite(RED, LOW);

    if (soc >= 95) {
      charging = false;
    }

    digitalWrite(RELAY, charging);
    digitalWrite(GREEN, charging);

    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("V:");
    lcd.print(voltage, 1);
    lcd.print(" I:");
    lcd.print(current, 1);

    lcd.setCursor(0, 1);
    lcd.print("S:");
    lcd.print(soc, 0);
    lcd.print("% T:");
    lcd