Il Motore della Previsione Solare: Un’Analisi Passo-Passo delle Formule dietro i Pannelli Fotovoltaici ☀️🔬


👋 Introduzione: Quando la Tecnologia Prevede il Futuro

Hai mai voluto sapere non solo quanta energia produce oggi il tuo impianto solare, ma quanto potrebbe produrre nel momento esatto? Questo è il potere dei “Template” avanzati che utilizziamo nei sistemi di casa intelligente. Questi Template sono veri e propri mini-calcolatori, scritti in un linguaggio chiamato Jinja2, capaci di trasformare semplici letture meteo (come l’intensità del sole o la temperatura) in una previsione molto dettagliata della potenza reale prodotta dal tuo impianto FV.

In questo articolo, smonteremo questa “ricetta digitale” per capire esattamente quali formule vengono usate e perché ogni piccolo numero conta. Prepariamoci a fare un viaggio didattico tra fisica e tecnologia!

🧱 La Struttura: Ingredienti e Obiettivo

Il template ha due compiti principali:

  1. Controllare la Salute: Verificare che tutti i dati di ingresso siano presenti e validi.
  2. Simulare la Produzione: Usando le leggi della fisica, calcolare quanta energia il pannello riceve e quanta ne riesce a trasformare.

Gli Ingredienti Necessari (I Dati Iniziali)

Il sistema parte da due letture chiave dai sensori esterni:

  • GrawGraw​: L’intensità della luce solare che arriva sull’area di misura (Irradiazione GlobaleIrradiazione Globale).
  • TrawTraw​: La temperatura dell’aria all’esterno.

📐 Analisi Passo-Passo: Le Formule Semplificate (Il Cuore del Template)

Il template non fa un singolo calcolo, ma una catena di trasformazioni. Vediamo i passaggi chiave e le formule che li guidano.

Fase 1: Preparazione della Luce

Prima di tutto, dobbiamo capire quanta luce è davvero utile per il pannello e come questa luce cade su di esso.

  • Aggiustamento dell’Altezza (GG): Il template prende l’intensità grezza (GrawGraw​) e la corregge leggermente con un fattore (sensor_height_factor = 0.98). Cosa significa? È una piccola correzione per tenere conto del fatto che il sensore non è perfettamente allineato o misurato alla stessa altezza dell’impianto reale. G=Graw×0.98G=Graw​×0.98
  • La Distribuzione della Luce (DiffuseDiffuse vs DirectDirect): Il sole non è sempre un fascio dritto e perfetto; a volte la luce viene “sparsa” dall’atmosfera.
    • Il template calcola una frazione diffusa basandosi su quanto forte sta brillando il cielo (clearnessclearness). Questa frazione ci dice quanta luce arriva da tutte le direzioni, non solo dal punto esatto del sole.
    • Successivamente, usa i dati di orientamento (tilt_deg=30tilt_deg=30∘) per capire quanto è efficace la superficie del pannello a catturare quella luce diretta e diffusa.

Fase 2: Calcolare l’Energia Reale sul Pannello (GPOAGPOA​)

Questo è il passaggio fondamentale! Stiamo chiedendo: “Quanta energia colpisce davvero la superficie orientata del pannello?”

Il template mescola le frazioni di luce diretta, diffusa e riflessa dal terreno (l’albedo) con i fattori geometrici legati all’angolo di inclinazione ($30^\circ$). La formula combina questi elementi per ottenere GPOAGPOA​:

GPOA=G×(Frazione Diretta×Fattore Diretto+Frazione Diffusa×Fattore Diffuso+Riflesso Terreno×Fattore Riflesso)GPOA​=G×(Frazione Diretta×Fattore Diretto+Frazione Diffusa×Fattore Diffuso+Riflesso Terreno×Fattore Riflesso)

In parole semplici: Stiamo dando al sistema una mappa precisa di come la luce cade sul pannello, tenendo conto sia dell’orientamento che del tipo di cielo.

Fase 3: La Potenza Iniziale (Dal Calore alla Forza)

Una volta che sappiamo quanta energia colpisce il pannello (GPOAGPOA​), dobbiamo trasformarla in Watt. Usiamo la potenza nominale massima (PSTC_totalPSTC_total​, ovvero quanto produce l’impianto in condizioni perfette di laboratorio) e la confrontiamo con l’irradiazione ricevuta:

Potenza Iniziale=(GPOA1000.0)×PSTC_totalPotenza Iniziale=(1000.0GPOA​​)×PSTC_total​ (Il diviso per 1000 serve perché le nostre misurazioni sono spesso in W/m2W/m2, mentre la potenza nominale è espressa su tutta l’area del modulo).

Fase 4: La Correzione Finale (L’Effetto della Temperatura)

Questo è il tocco di finitura. Anche se tutto va bene, quando i pannelli si scaldano troppo, diventano meno efficienti. Il template simula questo calore e applica una “penalità” basata sul delta termico (ΔT=Temperatura Cella25CΔT=Temperatura Cella−25∘C).

La formula di correzione finale è questa: Potenza Corretta=Potenza Iniziale×(1+γpΔT)Potenza Corretta=Potenza Iniziale×(1+γp​⋅ΔT)

Spiegazione Semplice: Se il pannello si scalda molto (ΔTΔT alto), e γpγp​ è un numero negativo, la parentesi (1+...)(1+…) diventa minore di 1, riducendo artificialmente la potenza calcolata. Questo assicura che la nostra previsione sia realistica.

✅ Conclusione: Un Modello Potente ma Semplificato

Il template è estremamente potente perché automatizza un processo che, se lo facessi a mano, richiederebbe ore di calcoli trigonometrici e termici!

Cosa abbiamo imparato? Abbiamo visto che il valore finale in Watt non dipende solo da “quanto c’è sole”, ma da: come cade la luce sul mio pannello (GPOAGPOA​), e quanto è caldo quel pannello (Correzione Termica).

È un esempio brillante di come i dati, quando vengono incartati con una buona dose di logica scolastica e fisica, possano trasformarsi in strumenti di previsione super diretti per la nostra vita quotidiana.

template:
  - sensor:
      - name: "FV Potenza Teorica Reale"
        unique_id: fv_potenza_teorica_reale
        unit_of_measurement: "W"
        device_class: power
        state_class: measurement
        state: >
          {% set G_raw = states('sensor.gw1100a_solar_radiation') %}
          {% set T_raw = states('sensor.gw1100a_outdoor_temperature') %}
          {% if G_raw in ['unknown','unavailable','none'] or T_raw in ['unknown','unavailable','none'] %}
            unavailable
          {% else %}
            {% set modules_count = 4 %}
            {% set P_stc_module = 585.0 %}
            {% set area_module = 2.582 %}
            {% set eta = 0.2266 %}
            {% set noct = 45 %}
            {% set gamma_p = -0.003 %}
            {% set tilt_deg = 30 %}
            {% set albedo = 0.20 %}
            {% set sensor_height_factor = 0.98 %}
            {% set G = (G_raw | float(0)) * sensor_height_factor %}
            {% set T_amb = (T_raw | float(20)) %}
            {% set _ = states('sensor.time') %}
            {% set area_total = area_module * modules_count %}
            {% set clearness = G / 1000.0 %}
            {% set df_raw = 0.45 + (1 - clearness) * 0.35 %}
            {% set diffuse_frac = [df_raw, 0.9] | min %}
            {% set diffuse_frac = [diffuse_frac, 0.1] | max %}
            {% set direct_frac = 1.0 - diffuse_frac %}
            {% set tilt_rad = (tilt_deg * pi / 180.0) %}
            {% set direct_factor = [ (cos(tilt_rad)), 0.0 ] | max %}
            {% set diffuse_factor = (1.0 + cos(tilt_rad)) / 2.0 %}
            {% set ground_reflect_factor = (1.0 - cos(tilt_rad)) / 2.0 %}
            {% set G_poa = G * ( direct_frac * direct_factor + diffuse_frac * diffuse_factor + albedo * ground_reflect_factor ) %}
            {% set P_stc_total = P_stc_module * modules_count %}
            {% set P_from_irradiance = (G_poa / 1000.0) * P_stc_total %}
            {% set T_cell = T_amb + (G_poa / 800.0) * (noct - 20.0) %}
            {% set deltaT = T_cell - 25.0 %}
            {% set P_temp_corr = P_from_irradiance * (1.0 + gamma_p * deltaT) %}
            {{ [ (P_temp_corr) | round(0), 0 ] | max }}
          {% endif %}

.

📡 Monitor VE.Direct con ESP32 e OLED: il progetto definitivo per il tuo impianto solare ⚡

Realizzare un monitor solare professionale, elegante e completamente personalizzato non è mai stato così semplice. In questo articolo ti mostro come ho costruito un sistema completo basato su ESP32, display OLED e protocollo VE.Direct, capace di leggere in tempo reale tutti i dati del regolatore Victron e mostrarli sia su schermo che su una dashboard web moderna e responsive.

Un progetto che unisce elettronica, programmazione e design… e che porta il tuo impianto solare a un livello superiore.

💙 Firmato: TechConnectHub

🔥 Perché questo progetto è speciale

Questo monitor non è un semplice lettore di dati: è un vero e proprio cruscotto intelligente per il tuo impianto fotovoltaico.

Ecco cosa fa:

  • Legge in tempo reale i dati VE.Direct del regolatore Victron
  • Mostra i valori principali su un display OLED 128×64
  • Offre una dashboard web moderna, scura, elegante e aggiornata ogni secondo
  • Funziona con hostname dedicato: `http://victron-monitor.localMostra:
  • Potenza pannelli (W)
  • Tensione pannelli (V)
  • Tensione batteria (V)
  • Corrente (A)
  • Produzione totale (Wh)
  • Produzione giornaliera (Wh)
  • Stato MPPT (Bulk, Absorption, Float…)
  • Numero di serie del regolatore
  • Versione firmware
  • Include una pagina OLED dedicata con il logo TechConnectHub
  • Sincronizzazione perfetta senza perdere pacchetti VE.Direct

Un progetto pensato per essere affidabile, bello da vedere e semplice da installare.

🧩 Hardware necessario

  • ESP32 DevKit (qualsiasi versione con WiFi)
  • Display OLED 128×64 I2C
  • Cavo VE.Direct → UART (TX → GPIO 32)
  • Alimentazione 5V
  • Qualche cavetto Dupont

🛠️ Collegamenti elettrici

  • Victron TX → ESP32 GPIO 32
  • Victron GND → ESP32 GND
  • OLED SDA → ESP32 GPIO 21
  • OLED SCL → ESP32 GPIO 22
  • OLED VCC → 3.3V
  • OLED GND → GND

💻 Il firmware completo

#include <Arduino.h>
#include <U8g2lib.h>
#include <WiFi.h>
#include <WebServer.h>

// -------------------- DISPLAY --------------------
U8G2_SSD1306_128X64_NONAME_1_HW_I2C u8g2(U8G2_R0, U8X8_PIN_NONE);

// -------------------- VARIABILI GLOBALI --------------------
float battery_voltage = 0;
float battery_current = 0;
float pv_power = 0;
float pv_voltage = 0;
float yield_total = 0;
float yield_today_real = 0;
String mppt_state = "Off";

String serial_number = "";
String firmware_ver = "";

unsigned long lastUpdate = 0;
unsigned long lastPageSwitch = 0;
int lcd_page = 0;

// -------------------- VE.DIRECT BUFFER --------------------
String veLine = "";
bool packetReady = false;

float new_voltage = 0;
float new_current = 0;
float new_pv_power = 0;
float new_pv_voltage = 0;
float new_yield_total = 0;
float new_yield_today_real = 0;
String new_state = "Off";

String new_serial = "";
String new_fw = "";

// -------------------- WIFI CONFIG --------------------
const char* ssid     = "BB1";
const char* password = "strangeapartament";

// -------------------- WIFI WATCHDOG --------------------
unsigned long lastWiFiCheck = 0;

void wifiWatchdog() {
  bool wifiDead =
      WiFi.status() != WL_CONNECTED ||          // caso 1: disconnessione reale
      WiFi.localIP().toString() == "0.0.0.0" || // caso 2: perdita IP
      !WiFi.isConnected();                      // caso 3: ghost connected

  if (wifiDead) {
    WiFi.disconnect(true);
    delay(200);
    WiFi.begin(ssid, password);
  }
}

// -------------------- WEB SERVER --------------------
WebServer server(80);

// -------------------- HTML PAGE --------------------
const char* htmlPage = R"rawliteral(
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>VE.Direct Monitor</title>
<style>
  body { font-family: Arial; background:#0d1117; color:#e6edf3; padding:20px; }
  h1 { text-align:center; color:#58a6ff; margin-bottom:25px; }
  .section-title { font-size:22px; margin-top:25px; margin-bottom:10px; color:#f0883e; text-align:center; }
  .card { background:#161b22; padding:18px; border-radius:12px; margin-bottom:15px; border:1px solid #30363d; }
  .label { font-size:18px; color:#8b949e; }
  .value { font-size:26px; font-weight:bold; margin-top:5px; }
  .watt { color:#f0883e; }
  .volt { color:#3fb950; }
  .amp  { color:#d29922; }
  .wh   { color:#a371f7; }
  .state { color:#58a6ff; }
  .footer { text-align:center; margin-top:30px; font-size:18px; color:#58a6ff; font-weight:bold; }
</style>
</head>
<body>

<h1>VE.Direct Monitor</h1>

<div class="section-title">Dati in tempo reale</div>

<div class="card"><div class="label">Pannelli</div><div class="value watt" id="pv_power">-- W</div></div>
<div class="card"><div class="label">Tensione Pannelli</div><div class="value volt" id="pv_voltage">-- V</div></div>
<div class="card"><div class="label">Batteria</div><div class="value volt" id="battery_voltage">-- V</div></div>
<div class="card"><div class="label">Corrente</div><div class="value amp" id="battery_current">-- A</div></div>
<div class="card"><div class="label">Produzione Totale</div><div class="value wh" id="yield_total">-- Wh</div></div>
<div class="card"><div class="label">Produzione Giornaliera</div><div class="value wh" id="yield_today_real">-- Wh</div></div>
<div class="card"><div class="label">Stato MPPT</div><div class="value state" id="mppt_state">--</div></div>

<div class="section-title">Informazioni Regolatore</div>

<div class="card"><div class="label">Seriale</div><div class="value state" id="serial_number">--</div></div>
<div class="card"><div class="label">Firmware</div><div class="value state" id="firmware_ver">--</div></div>

<div class="footer">By TechConnectHub</div>

<script>
function update() {
  fetch('/api')
    .then(r => r.json())
    .then(d => {
      document.getElementById('pv_power').innerText        = d.pv_power + " W";
      document.getElementById('pv_voltage').innerText      = d.pv_voltage.toFixed(2) + " V";
      document.getElementById('battery_voltage').innerText = d.battery_voltage.toFixed(2) + " V";
      document.getElementById('battery_current').innerText = d.battery_current.toFixed(2) + " A";
      document.getElementById('yield_total').innerText     = d.yield_total + " Wh";
      document.getElementById('yield_today_real').innerText= d.yield_today_real + " Wh";
      document.getElementById('mppt_state').innerText      = d.mppt_state;
      document.getElementById('serial_number').innerText   = d.serial_number;
      document.getElementById('firmware_ver').innerText    = d.firmware_ver;
    });
}
setInterval(update, 1000);
update();
</script>

</body>
</html>
)rawliteral";

// -------------------- VE.DIRECT PARSER --------------------
String csToState(int cs) {
  switch (cs) {
    case 0: return "Off";
    case 2: return "Fault";
    case 3: return "Bulk";
    case 4: return "Absorption";
    case 5: return "Float";
    case 7: return "Equalize";
    default: return "Unknown";
  }
}

void parseVEDirectLine(const String &line) {
  int sep = line.indexOf('\t');
  if (sep < 0) return;

  String key = line.substring(0, sep);
  String val = line.substring(sep + 1);
  long iv = val.toInt();

  if (key == "V") new_voltage = iv / 1000.0f;
  else if (key == "I") new_current = iv / 1000.0f;
  else if (key == "PPV") new_pv_power = iv;
  else if (key == "VPV") new_pv_voltage = iv / 1000.0f;
  else if (key == "H19") new_yield_total = iv * 10.0f;
  else if (key == "H20") new_yield_today_real = iv * 10.0f;
  else if (key == "CS") new_state = csToState(iv);
  else if (key == "SER#") new_serial = val;
  else if (key == "FW") {
    float fw = iv / 100.0f;
    new_fw = String(fw, 2);
  }
  else if (key == "Checksum") packetReady = true;
}

void readVEDirect() {
  while (Serial2.available()) {
    char c = Serial2.read();
    if (c == '\n') { parseVEDirectLine(veLine); veLine = ""; }
    else if (c != '\r') veLine += c;
  }

  if (packetReady) {
    battery_voltage = new_voltage;
    battery_current = new_current;
    pv_power        = new_pv_power;
    pv_voltage      = new_pv_voltage;
    yield_total     = new_yield_total;
    yield_today_real= new_yield_today_real;
    mppt_state      = new_state;
    serial_number   = new_serial;
    firmware_ver    = new_fw;
    lastUpdate = millis();
    packetReady = false;
  }
}

// -------------------- SETUP --------------------
void setup() {
  Serial.begin(115200);
  Serial2.begin(19200, SERIAL_8N1, 32, 33);

  u8g2.begin();
  u8g2.enableUTF8Print();

  WiFi.mode(WIFI_STA);
  WiFi.setHostname("victron-monitor");
  WiFi.setAutoReconnect(true);
  WiFi.persistent(false);

  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) { delay(500); }

  server.on("/", []() { server.send(200, "text/html", htmlPage); });

  server.on("/api", []() {
    String json = "{";
    json += "\"pv_power\":" + String(pv_power) + ",";
    json += "\"pv_voltage\":" + String(pv_voltage) + ",";
    json += "\"battery_voltage\":" + String(battery_voltage) + ",";
    json += "\"battery_current\":" + String(battery_current) + ",";
    json += "\"yield_total\":" + String(yield_total) + ",";
    json += "\"yield_today_real\":" + String(yield_today_real) + ",";
    json += "\"serial_number\":\"" + serial_number + "\",";
    json += "\"firmware_ver\":\"" + firmware_ver + "\",";
    json += "\"mppt_state\":\"" + mppt_state + "\"";
    json += "}";
    server.send(200, "application/json", json);
  });

  server.begin();
}

// -------------------- LOOP --------------------
void loop() {
  server.handleClient();
  readVEDirect();

  // WATCHDOG WIFI DEFINITIVO
  if (millis() - lastWiFiCheck > 5000) {
    wifiWatchdog();
    lastWiFiCheck = millis();
  }

  if (millis() - lastPageSwitch > 4000) {
    lcd_page = (lcd_page + 1) % 10;
    lastPageSwitch = millis();
  }

  u8g2.firstPage();
  do {

    if (millis() - lastUpdate > 15000) {
      u8g2.setFont(u8g2_font_ncenB12_tr);
      u8g2.drawStr(0, 30, "No VE.Direct...");
    } else {

      switch (lcd_page) {

        case 0:
          u8g2.setFont(u8g2_font_ncenB14_tr);
          u8g2.drawStr(0, 16, "Pannelli");
          u8g2.setFont(u8g2_font_fub17_tr);
          u8g2.setCursor(0, 60);
          u8g2.print(pv_power); u8g2.print(" W");
          break;

        case 1:
          u8g2.setFont(u8g2_font_ncenB14_tr);
          u8g2.drawStr(0, 16, "V Pannelli");
          u8g2.setFont(u8g2_font_fub17_tr);
          u8g2.setCursor(0, 60);
          u8g2.print(pv_voltage, 2); u8g2.print(" V");
          break;

        case 2:
          u8g2.setFont(u8g2_font_ncenB14_tr);
          u8g2.drawStr(0, 16, "Batteria");
          u8g2.setFont(u8g2_font_fub17_tr);
          u8g2.setCursor(0, 60);
          u8g2.print(battery_voltage, 2); u8g2.print(" V");
          break;

        case 3:
          u8g2.setFont(u8g2_font_ncenB14_tr);
          u8g2.drawStr(0, 16, "Corrente");
          u8g2.setFont(u8g2_font_fub17_tr);
          u8g2.setCursor(0, 60);
          u8g2.print(battery_current, 2); u8g2.print(" A");
          break;

        case 4:
          u8g2.setFont(u8g2_font_ncenB14_tr);
          u8g2.drawStr(0, 16, "Totale");
          u8g2.setFont(u8g2_font_fub17_tr);
          u8g2.setCursor(0, 60);
          u8g2.print(yield_total); u8g2.print(" Wh");
          break;

        case 5:
          u8g2.setFont(u8g2_font_ncenB14_tr);
          u8g2.drawStr(0, 16, "Giorno");
          u8g2.setFont(u8g2_font_fub17_tr);
          u8g2.setCursor(0, 60);
          u8g2.print(yield_today_real); u8g2.print(" Wh");
          break;

        case 6:
          u8g2.setFont(u8g2_font_ncenB12_tr);
          u8g2.drawStr(0, 16, "SER#");
          u8g2.setFont(u8g2_font_7x14B_tr);
          u8g2.setCursor(0, 55);
          u8g2.print(serial_number);
          break;

        case 7:
          u8g2.setFont(u8g2_font_ncenB12_tr);
          u8g2.drawStr(0, 16, "FW");
          u8g2.setFont(u8g2_font_fub17_tr);
          u8g2.setCursor(0, 60);
          u8g2.print(firmware_ver);
          break;

        case 8:
          u8g2.setFont(u8g2_font_7x14B_tr);
          u8g2.drawStr(0, 40, "TechConnectHub");
          break;

        case 9:
          u8g2.setFont(u8g2_font_ncenB14_tr);
          u8g2.drawStr(0, 16, "Stato MPPT");
          u8g2.setFont(u8g2_font_fub17_tr);
          u8g2.setCursor(0, 60);
          u8g2.print(mppt_state);
          break;
      }
    }
  } while (u8g2.nextPage());
}
  • font migliorati
  • pagina web divisa in sezioni
  • scritta TechConnectHub su OLED e web
  • parsing VE.Direct completo
  • sincronizzazione perfetto

🌐 Dashboard web moderna e responsive

La dashboard web è stata progettata per essere:

  • leggibile anche da smartphone
  • elegante grazie al tema scuro
  • aggiornata ogni secondo
  • divisa in due sezioni:
  • Dati in tempo reale
  • Informazioni del regolatore

Il footer mostra con orgoglio:

By TechConnectHub

🖥️ Display OLED: semplice, chiaro, professionale

Il display OLED mostra i dati in rotazione ogni 4 secondi:

  • Potenza pannelli
  • Tensione pannelli
  • Tensione batteria
  • Corrente
  • Produzione totale
  • Produzione giornaliera
  • Numero di serie
  • Firmware
  • Logo TechConnectHub

I font sono stati calibrati per essere:

  • grandi dove serve (es. 1.68)
  • compatti dove necessario (SER#)
  • sempre leggibili

🚀 Conclusione

Questo progetto trasforma un semplice ESP32 in un monitor solare professionale, elegante e completamente personalizzato.

È perfetto per chi vuole:

  • monitorare il proprio impianto solare in tempo reale
  • avere una dashboard moderna e accessibile da qualsiasi dispositivo
  • integrare estetica e funzionalità
  • costruire un prodotto degno di essere venduto

Un progetto che unisce tecnica, design e passione.

Firmato con orgoglio:

💙 TechConnectHub

🔋 Guida Pratica al SOC di Batterie in Parallelo con BMS

Se usi batterie LiFePO4 con BMS dedicati, sapere come calcolare il SOC (State of Charge) è fondamentale per monitorare quanta energia hai a disposizione. In questa guida, vediamo come funziona il SOC, come si calcola in parallelo, e come si distribuisce la corrente sotto carico.

📌 Cos’è il SOC?

Il SOC indica quanta energia è presente in una batteria rispetto alla sua capacità massima. È come il livello del serbatoio di carburante:

  • 100% SOC = batteria completamente carica
  • 50% SOC = metà carica
  • 0% SOC = batteria scarica (da evitare!)

✅ Formula semplificata:

SOC (%) = energia disponibile ÷ capacità totale × 100

🧮 Esempio 1: Batterie con cariche diverse

Hai due batterie in parallelo:

  • Batteria A: 100Ah al 75% → 75Ah disponibili
  • Batteria B: 50Ah al 50% → 25Ah disponibili
  • Capacità totale: 100 + 50 = 150Ah
  • Energia disponibile: 75 + 25 = 100Ah

👉 SOC totale = 100 ÷ 150 × 100 = 66,7%

🔋 Esempio 2: Batterie completamente cariche

  • Batteria A: 100Ah al 100%
  • Batteria B: 50Ah al 100%
  • Energia disponibile: 150Ah
  • Capacità totale: 150Ah

👉 SOC totale = 150 ÷ 150 × 100 = 100%

⚡ Esempio 3: Carico da 45A

Quando applichi un carico, la corrente si distribuisce in proporzione alla capacità:

  • Capacità totale = 100Ah + 50Ah = 150Ah
  • Carico totale = 45A

✅ Formula semplificata:

Corrente per ogni batteria = (capacità batteria ÷ capacità totale) × corrente totale

👉 Batteria A: 100 ÷ 150 × 45 = 30A 👉 Batteria B: 50 ÷ 150 × 45 = 15A

⚡ Esempio 4: Carico da 80A

Con un carico maggiore, la distribuzione resta proporzionale:

  • Capacità totale = 150Ah
  • Carico totale = 80A

👉 Batteria A: 100 ÷ 150 × 80 = 53,3A 👉 Batteria B: 50 ÷ 150 × 80 = 26,7A

📊 Entrambe si scaricano del 53,3% della loro capacità.

✅ Conclusione: Consigli pratici

  • Usa BMS compatibili per monitorare SOC e bilanciare le celle.
  • Non scaricare mai sotto il 20% per preservare la vita utile.
  • Il SOC totale si calcola come media proporzionale, non come valore minimo.
  • Distribuisci i carichi in base alla capacità per evitare squilibri.