// Laadtoestand (SoC) van de LiFePO4-batterij van de klimaatmodule schatten door lading te tellen (Arduino Mega 2560)
// Stroomsensor ACS712-20A op A4: 2,50 V bij 0 A, 0,100 V per ampere (positief = ontladen).
// Spanningsdeler 100 kOhm / 33 kOhm op A3 voor de batterijspanning (tot 20 V). Bord: Arduino Mega 2560.
const float CAPACITEIT_AH = 120.0;
const float NUL_V = 2.50;
const float V_PER_A = 0.100;
const float DELER = (100.0 + 33.0) / 33.0;
const unsigned long DT_MS = 1000;         // elke seconde

float soc = 100.0;                        // laadtoestand in procent (start: vol)
unsigned long vorige = 0;

float spanningOp(int pin) {
  long som = 0;
  for (int i = 0; i < 16; i++) {          // 16 metingen middelen tegen ruis
    som += analogRead(pin);
  }
  return som / 16.0 * 5.0 / 1023.0;
}

void setup() {
  Serial.begin(9600);
}

void loop() {
  if (millis() - vorige >= DT_MS) {
    vorige += DT_MS;
    float stroom = (spanningOp(A4) - NUL_V) / V_PER_A;         // A, positief bij ontladen
    float uBat = spanningOp(A3) * DELER;                       // V
    float dtUur = (DT_MS / 1000.0) / 3600.0;
    soc -= stroom * dtUur / CAPACITEIT_AH * 100.0;             // coulombtellen
    if (uBat >= 14.2 && stroom < 0.0 && stroom > -2.0) {       // bijna vol: opnieuw ijken op 100 %
      soc = 100.0;
    }
    soc = constrain(soc, 0.0, 100.0);
    Serial.print(uBat, 2);
    Serial.print(" V  ");
    Serial.print(stroom, 2);
    Serial.print(" A  SoC ");
    Serial.print(soc, 1);
    Serial.println(" %");
    if (soc < 20.0) {
      Serial.println("Batterij bijna op de ondergrens van 20 %: niet-dringende verbruikers uit");
    }
  }
}
