Building a reliable Arduino solar module requires more than just wiring an INA226 current sensor to an I2C bus and pushing data to an MQTT broker. The microcontroller is only as effective as the physical plant it monitors. If your battery bank is undersized, or your inverter cannot handle the surge current of your load, the Arduino will either log a brownout event or watch the system collapse before its load-shedding relays can react.
This guide breaks down the physical sizing math for a 400W continuous off-grid load, translating those power requirements into exact battery configurations, solar array sizing, and the specific voltage thresholds your Arduino code needs to enforce.
System Architecture: Source to Load Block Flow
Before writing a single line of C++, you must define the physical current path. A robust Arduino-monitored solar system follows this strict block sequence:
- Source (PV Array): Solar panels wired in series/parallel to achieve the correct Vmp (voltage at maximum power) for the charge controller.
- Control (MPPT Charge Controller): Steps down the high PV voltage to the battery bank's absorption/float voltage. The Arduino monitors this via RS485/UART or reads the battery-side shunt directly.
- Storage (Battery Bank): The energy buffer. The Arduino reads the bank's voltage and current via a precision shunt (e.g., 100A/75mV) to calculate State of Charge (SoC).
- Conversion (Inverter): Converts DC to AC. The Arduino monitors the inverter's AC output side or relies on the DC-side current draw to calculate real-time wattage.
- Load: The target appliances. The Arduino controls a solid-state relay (SSR) or heavy-duty contactor on the load side to enforce Low Voltage Disconnect (LVD).
Battery Bank Sizing: Series vs. Parallel and the Math
Let’s size a bank for a specific scenario: a 400W continuous AC load (like a high-efficiency fridge and some LED lighting) that runs for 5 hours between peak sun cycles. The load has an 800W surge when the compressor kicks on.
The Sizing Math and Efficiency Factors
First, calculate the raw energy requirement: 400W × 5 hours = 2,000Wh.
Next, account for inverter inefficiency. A quality pure sine wave inverter operates at roughly 90% efficiency under this load.
2,000Wh / 0.90 = 2,222Wh required from the battery.
Now, apply the Depth of Discharge (DoD) limit. For Lithium Iron Phosphate (LiFePO4), we cap DoD at 80% to ensure a 10-year cycle life.
2,222Wh / 0.80 = 2,777Wh total required bank capacity.
If you were using legacy Lead-Acid batteries, you would also have to apply Peukert’s Law. Peukert's exponent ($k$) describes how a battery's effective capacity drops as the discharge rate increases. A lead-acid battery has a $k$ of roughly 1.3, meaning pulling 40A continuously from a 200Ah bank yields only about 130Ah of usable capacity. LiFePO4 has a $k$ of approximately 1.05, making its effective capacity nearly identical to its rated capacity at high discharge rates. If your Arduino code calculates SoC via Coulomb counting, you must hardcode the correct Peukert exponent for your specific chemistry.
| Configuration | Nominal Voltage | Capacity (Ah) | Total Energy (Wh) | Max Continuous Discharge (1C) | Recommended Main Cable (AWG) |
|---|---|---|---|---|---|
| 12V Parallel (2x 12V 150Ah) | 12.8V | 300Ah | 3,840Wh | 300A | 2/0 AWG |
| 24V Series (2x 12V 150Ah) | 25.6V | 150Ah | 3,840Wh | 150A | 4 AWG |
| 12V Parallel (3x 12V 100Ah) | 12.8V | 300Ah | 3,840Wh | 300A | 2/0 AWG |
| 48V Series (4x 12V 100Ah) | 51.2V | 100Ah | 5,120Wh | 100A | 8 AWG |
Series vs. Parallel Consequences
As shown in the table, wiring in series doubles the voltage while keeping the Amp-hour (Ah) capacity the same. Wiring in parallel doubles the Ah capacity while keeping the voltage the same. Total energy (Wh) remains identical, but the 24V or 48V series configurations are vastly superior because they cut the DC current in half (or quarter), allowing you to use much thinner, cheaper copper wire and reducing $I^2R$ heat losses.
Inverter Sizing and Solar Array Matching
With a 2,777Wh minimum battery requirement established, we must size the inverter and the solar array to replenish it.
Inverter and Charge Limits
Your load draws 400W continuously but surges to 800W. Inverters are rated by both continuous and surge capacity. A 1000W pure sine wave inverter is the absolute minimum here; it provides a 2000W surge headroom, ensuring the Arduino doesn't log a false "overcurrent" fault when the compressor starts.
For the charge controller, LiFePO4 batteries safely accept a standard charge rate of 0.5C and a maximum of 1C. For our 150Ah 24V bank, 0.5C equals 75A of charge current. Therefore, your MPPT charge controller must be rated for at least 80A at 24V.
Solar Array Sizing
To replenish 2,777Wh in a single day, we look at peak sun hours. Assuming an average of 4.5 peak sun hours (typical for the US Sunbelt, lower for the Pacific Northwest), the math dictates:
2,777Wh / 4.5 hours = 617W of solar panels.
Accounting for 20% real-world system losses (dust, wiring resistance, MPPT heat, high ambient temperatures derating the panels), you need a minimum array size of 770W. A standard configuration would be four 200W panels wired in a 2S2P (two series strings of two parallel panels) to hit an optimal Vmp of ~80V, which feeds perfectly into a 150V-max MPPT controller.
Arduino Monitoring Thresholds and Load Shedding
The physical hardware is only half the build. Your Arduino (or ESP32) must enforce strict voltage boundaries to protect the battery bank from over-discharge, which can permanently brick the BMS and lock you out of the cells.
Below is the decision-tree logic your microcontroller should execute on every I2C polling loop (typically 1Hz to 10Hz) when reading the INA226 or Victron SmartShunt data.
| State / Condition | Voltage Threshold | Approximate SoC | Arduino Action Required |
|---|---|---|---|
| High Voltage Disconnect (HVD) | 14.40V | 100% (Absorption) | Log "Full", disable solar dump loads, ensure BMS balancing. |
| Float Voltage | 13.60V | 100% (Resting) | Maintain normal operation, update Coulomb counter to 100%. |
| Low Load Shed (Warning) | 12.40V | ~20% | Trigger visual/audio alarm, disable non-essential DC loads via MOSFET. |
| Low Voltage Disconnect (LVD) | 12.00V | ~5% (Critical) | Open main load contactor immediately. Prevent inverter low-voltage fault. |
| BMS Cutoff Imminent | 11.20V | 0% (Danger) | System failure state. Microcontroller must run on isolated backup battery. |
Preventing the Brownout Trap
A common mistake when building an Arduino solar module is powering the microcontroller from the same battery bank it is protecting. If the bank drops to 11.2V and the BMS opens the main discharge FETs, the Arduino loses power exactly when you need it to log the fault and send an alert.
The Fix: Power the Arduino/ESP32 via a dedicated, isolated buck converter tied directly to the battery terminals (before the main BMS discharge FET, if your BMS architecture allows a dedicated low-current tap), or use a small, separate 18650 UPS HAT with an automatic switchover circuit. This ensures the MCU stays alive to transmit the "Bank Depleted" MQTT message to your home automation server before going into deep sleep.






