Solar and Battery Management System using Arduino Nano
Index
Project Objective
This project aims to develop a solar and battery power management system using an Arduino Nano. The system prioritizes solar energy during daytime (in SUB mode) to power an inverter and charge a battery, while intelligently switching to utility power (WAPDA) when necessary. The primary objective is to ensure continuous power availability while protecting the battery from over-(dis)charge (quantity) and high (dis)charge (rate) conditions.
System Overview
- Primary Power Source: 4 x 300W (Voc = 24V, Isc = 15A) PV solar array via a PWM charge controller.
- Backup Power Source: 220V 50Hz utility grid (WAPDA).
- Storage: 12V 200Ah lead-acid tubular battery, which stays at ≈12.9V when fully charged, with no load and no charging.
- Load: 600W inverter powering light AC appliances (mainly fans & lights).
Operational Logic
- During daytime:
- Power is drawn from the PV array (according to solar on/off time settings and sunlight availability) to run the inverter and charge the battery.
- In the morning, load is switched from grid to solar at the configured sun time.
- In the evening, after sun time, load is kept on solar as long as the battery doesn't start discharging.
- If battery starts discharging due to any of the following reasons, load is switched to grid, even during daytime:
- Sunlight is not sufficient to produce the minimum required current (configured) e.g. due to morning / evening or clouds.
- Inverter load exceeds solar supply.
- After switching to grid, we keep trying to switch back to solar after some delays (configured).
- At night:
- If grid is available, use it instead of draining the battery.
- If grid is unavailable, use the battery to run the inverter as long as the battery state remains within safe operating limits (see Battery Protection Rules).
- If USB mode is selected (instead of SUB), grid is always given priority. This can be useful in winters when not much power is needed during daytime. So inverter runs only during power outages.
Also see the flowchart.
Battery Protection Rules
-
Over-discharge / high-discharge protection
- Inverter is turned off if battery voltage drops below
BVlow, even if there is no grid. A 2 minutes window is given if voltages remain above BVcrit.
- Discharging current is also limited to
BIhigh. A 10 seconds window is given if discharge rate is below BIcrit (e.g. for torque load, or to allow PWM controller to draw more power from PV array).
-
Over-charge / high-charge protection
- Start beeping if battery is overcharged i.e. charged above
BVfull or at a rate higher than BIhigh. We cannot control the PWM controller with Arduino. But we can cry.
Alarms
Raise alarm (start beeping) if any of the following is true:
- Battery is above
BVfull
- Battery is below
BVlow
- Battery is being charged at a rate higher than
BIhigh
- Battery is being discharged at a rate higher than
BIhigh
- During daytime, if sunlight is sufficient, and:
- Battery is being discharged (at any rate; we should be using solar)
- Inverter turned off (and switched to grid; we should be using solar)
- Exact reason of turning off the inverter is shown on the screen. See On-Screen Warnings below.
Before raising alarms, give a 5-30 seconds window for temporary spikes / dips in battery voltage / current.
On-Screen Warnings
Inverter turned off (and switched to grid) due to:
- E 1: Battery low – voltage below
BVlow
- E 2: Battery overloaded – high current (>
BIhigh) drained
- E 3: Load higher than the solar power (during daytime) – due to morning / evening, clouds etc.
- E 4: Load higher than the solar power (during daytime) – your fault.
Display + Settings
- Use MENU button to jump to the next screen and UP/DOWN buttons to change the configurable values.
- First 5 screens are informatory. On these screens, UP/DOWN buttons turn off the display.
- Display also turns off if no activity is detected for 5 minutes. Press any button or wave hand (to trigger the infrared proximity sensor) to turn the display back on.
- When display is on, waving hand before the IR sensor rotates the display between informatory screens. Waving hand on the last info-screen turns off the display.
- On SAVE screen (the last one), UP/DOWN buttons save the changed settings, if any. Then it jumps to the first screen. If it doesn't, there is a problem with the set values such as:
- Display jumps back to the first screen after 30 seconds of inactivity (except first 4 informatory screens).
- When you select SUB mode or opt to not check sun time, unused setting screens are jumped automatically.
Screens:
INFO | Battery voltage (left, Volts) and current (right, Ampere)
INFO | Battery voltage (left, Volts) and power being drawn from or fed to the battery (product of voltage and current) (right, Watt)
INFO | PV array voltage (left, Volts) and current (right, Ampere)
INFO | PV array voltage (left, Volts) and power (product of voltage and current) (right, Watt)
INFO | Clock (left, 24h format) and temperature (right, °C)
BVfull | Battery full charge voltage (Volts, range: 12.0-16.0, default: 14.4)
BVlow | Battery discharged voltage low threshold (Volts, range: 10.0-13.0, default: 12.0 (≈ 50% DoD))
BVcrit | Battery discharged voltage critical threshold (Volts, range: 9.0-12.0, default: 11.0)
BIcrit | Battery discharge current critical threshold (Ampere, range: 20-60, default: 50)
BIhigh | Battery discharge current high threshold (Ampere, range: 10-30, default: 20 (@ C10))
BIlow | Battery discharge current low threshold (Ampere, range: 1-15, default: 5)
- Prioritize solar or grid (Selection, options: SUB / USB, default: SUB)
- Delay before switching AC load to inverter after starting inverter (Seconds, range: 0-10, default: 5)
- Delay before switching AC load back to inverter after inverter turned off due to battery overloaded (high current drained) or voltage dropped, now no grid and battery is above
BVlow (Minutes, range: 1-10, default: 5)
SOLAR | Delay before switching AC load back to inverter (daytime) after inverter was turned off due to sunlight not sufficient, now let's retry (Minutes, range: 15-60, default: 15)
SOLAR | Delay before switching AC load back to inverter (daytime) after inverter was turned off for any other reason (Minutes, range: 1-10, default: 5)
- Window before switching AC load to grid if battery voltages are between
BVlow and BVcrit (Minutes, range: 1-10, default: 2)
- Window before switching AC load to grid if battery discharge current is between
BIcrit and BIhigh (Seconds, range: 5-60, default: 10)
SOLAR | Window before switching AC load to grid (daytime) if battery discharge current is between BIhigh and BIlow (Minutes, range: 1-10, default: 2)
SOLAR | Window before switching AC load to grid (daytime) if battery discharge current is below BIlow (Minutes, range: 1-15, default: 5)
SOLAR | Check sun time (Selection, options: 1 (true) / 0 (false), default: 1)
SOLAR | Clock time (24h format)
SOLAR | Solar on time (24h format, range: 05:00-10:00, default: 07:00)
SOLAR | Solar off time (24h format, range: 14:00-19:00, default: 17:00)
SOLAR | Solar minimum current required from PV array (Ampere, range: 1-30, default: 15)
- Display brightness (Level, range: 1-10, default: 1)
- Buzzer loudness (Level, range: 1-10, default: 1)
CALIB | Show the following battery/PV voltage/current calibration screens (Selection, options: 1 (true) / 0 (false), default: 0)
CALIB | Battery voltage offset (Volts, range: ±10, default: 0)
CALIB | Battery voltage factor (Multiplier, range: 0.5-2, default: 1)
CALIB | Battery current offset (Volts, range: ±10, default: 0)
CALIB | Battery current factor (Multiplier, range: 0.5-2, default: 1)
CALIB | Solar voltage offset (Volts, range: ±10, default: 0)
CALIB | Solar voltage factor (Multiplier, range: 0.5-2, default: 1)
CALIB | Solar current offset (Volts, range: ±10, default: 0)
CALIB | Solar current factor (Multiplier, range: 0.5-2, default: 1)
- Save
Flowchart
Actual checks and details are a bit complex but a simplified version is:
Hardware Components
- Arduino Nano [1] – main controller for sensor reading and decision-making.
- FL-2C Shunt Resistor 100A 75mV [4] [24] + 2 x HCPL-7840 [23] + ADS1115 [38] + B0505S [37] – used to measure PV voltage and current.
- Isolation is required because PWM charge controller does not have common GND across its input (PV array) and output (battery) sides.
- HCPL-7840 Isolation Amplifier
- Power supply: 4.5V-5.5V, current: ~11mA x 2
- Input voltage:
- Input is differential voltage i.e. 2 input pins.
- Common-mode range: (input pins must stay between) –2.0V …
VDD1 + 0.5 V ("Steady-State Input Voltage" [27])
- E.g. up to ~5.5V on 5V supply
- If pushed above or below the range (due to spikes), the internal clamp diodes are forward-biased and start dumping current. Use a series resistor like ~100kΩ to limit the current below ~10µA.
- Differential range:
- ±100mV with non-linearity ≤0.20%
- ±200mV with non-linearity ≤0.35%
- ±308mV absolute maximum
- Input bias current: 0.5µA-2µA (40 MΩ differential, 20 MΩ common mode impedance)
- Gain: 8V/V
- Output voltage:
- Common mode i.e. at 0V input, both outputs sit at 2.5V (with 5V supply). VOUT+ goes above 2.5V and VOUT- goes down by the same value. VOUT+ - VOUT- gives the amplified differential voltage.
- Absolute output voltage range is 0.5V-4.5V.
- Linear differential swing range is ±0.8V around mid-point i.e. 1.7V-3.3V (200mV input).
- Output current: 15 mA
- ADS1115 16-Bit 4-Channel ADC + PGA:
- Supply voltage: 2-5.5V
- Input quiescent/supply current: 2.5~200μA
- Input bias current: ~0.5µA (impedance in MΩ range, both in differential and common mode)
- Default I2C Address: 0x48
- Input Channels: 4 single-ended or 2 differential (programmable compare channels)
- Sampling Rate: 8-860 SPS (programmable)
- Voltage ranges: 6 settings from ±256mV to ±6.144V (programmable)
- PGA: up to 16x
- B0505S-1W DC-DC Isolated Power Converter:
- Input voltage: 4.5V-5.5V
- Supply current: ~5mA
- Output voltage: 5V
- Output current: 200mA
- Efficiency: ~85%
- Alternatives:
- Use a voltage/current sensor module like INA219 with digital I2C isolators like ADuM1250 / ISO1540 or a 6N137-based custom isolator.
- Instead of digital isolation, do analog isolation.
- Use HCPL-7840 with a precision rail-to-rail op-amp like MCP6002 / MCP602.
- Use a galvanically-isolated sensor, like ACS758 (for current only), which is a hall-effect based linear current sensor.
- LV 25-P is a similar one for voltage sensing.
- B0505S alternative: Power from PV-array using LM78L05 with UVLO (TL431 + 2N3906).
- A more complex way to detect sunlight sufficiency is by using a BH1750 Light Sensor Module [8].
- FL-2C Shunt Resistor 100A 75mV [4] [24] + 2 x HCPL-7840 [23] + ADS1115 [38] – used to measure battery voltage and current (charging and discharging).
- Same specs as in PV sensor details.
- Using isolation here to prevent propagation of HF noise coming from inverter and PWM charge controller. INA219 does high-side sensing. So difficult to deal with noise.
- H11AA1 Optocoupler [15] – detects grid presence.
- Has two anti-parallel IR LEDs, so it produces a conduction pulse on both half cycles of the mains. 50Hz mains → 2 pulses per 20ms → 100 pulses (100 rises and 100 falls) per second i.e. 100Hz.
- Input LED:
- Forward voltage drop: 1.2-1.5V
- Forward current (IF): 10mA (max 60mA)
- Practically seems to work at <1mA
- CTR: Minimum = 20% (at IF = 10mA, VCE = 10V)
- Output voltage:
- Limit (VCEO): 30V
- Drop (VCE(sat)): ≤0.4V
- Output current (IC): ≤1mA (safe limit)
- Alternatives:
- PC814
- Even a uni-directional optocoupler like PC817 should also work with pulse-width detection frequency limited to 50Hz.
- 220V AC to 5V DC Converter
- AC 220V Optocoupler Isolation Module
- ZMPT101B AC Single Phase Voltage Sensor Module [6]
- DS3231 Precision RTC Module [7] – remembers time so that to schedule solar on / off time in the morning and evening respectively.
- 5V Relay [10] (in NO mode) – used to switch AC load between grid and inverter output.
- 5V Relay [10] (in NC mode) – used to turn off inverter when not needed (to save battery) or during battery protection events. This relay is installed inside the inverter in series with the main power button.
- 8-Digit Display MAX7219 Module [11] – shows information and configurable values.
- 5-12V Active Buzzer [12] – for alarms.
- Max current: 40mA (at 12V)
- 3 x Push Buttons (momentary) [13]:
- Left (DOWN): Decrease a configurable value (setting).
- Center (MENU): Switch between screens and turn off the display.
- Right (UP): Increase a configurable value (setting).
- IR Proximity Sensor [22]:
- Wave hand to turn on the display, or rotate between informatory screens.
- 12V 1W Fan [42] – used for cooling
- 2 x MP1584 Buck Converter [40] – convert battery's 11~15V to 12V and 5V.
Minor Parts
For PV Current / Voltage Sensing:
- Resistors:
- 1 x 100kΩ
- 1 x 470Ω
- 4 x 33Ω
- Capacitors:
- 2 x 10nF 50V Ceramic
- 4 x 0.1µF 50V Ceramic
- 2 x 10µF 25V Electrolytic
- Inductor (DIP):
- Inductance: 100µH
- Current: ≥1.5A
- DCR: ~0.1Ω
- SRF: >10MHz
For Battery Current / Voltage Sensing:
- Resistors:
- 1 x 100kΩ
- 1 x 820Ω
- 4 x 33Ω
- Capacitors:
- 2 x 10nF 50V Ceramic
- 4 x 0.1µF 50V Ceramic
For H11AA1 Optocoupler:
- 2 x 220kΩ Resistor (with live and neutral) – 230V (RMS, 325V peak) AC input current limiting.
- Forward current (max):
- Power rating: 2 (60mW per resistor)
- 10kΩ Multi-turn Potentiometer – for pulse-width calibration.
- 0.1µF 50V Ceramic Capacitor – filter glitches.
For Buzzer:
- 2N3904 NPN BJT – controls voltage supply (5-12V) to the buzzer to adjust the loudness.
- Collector-emitter voltage: 40V
- Max collector current: 200mA
- Max base current: 20mA (200mA / 10)
- Max base-emitter voltage drop: 0.95V (fully saturated)
- Transition frequency: 300MHz | Rise/fall time: 35ns (switching speed matters for PWM)
- Linearity:
- Base voltage vs. collector current is exponential.
- For linearity, use 2N3904 in closed-loop with an op-amp like LM358 / CA3130.
- For even more accuracy, use a DAC like MCP4725 instead of filtered PWM.
- 470Ω Resistor – between the transistor (2N3904) base and Arduino pin to protect high current draw.
- For 100mA current draw from the transistor (5V - 0.7V / 10mA)
- 1kΩ seems to work.
- 1N4007 Diode – for flyback protection with the buzzer.
- 22µF 25V Electrolytic Capacitor
- Better insert an RC filter (b/w Arduino and transistor, or b/w transistor and buzzer) to flatten / smooth out the averaged output of PWM.
For Relay (AC):
- 2N3904 NPN BJT – drives the relay.
- 470Ω Resistor – between the transistor (2N3904) base and Arduino pin to protect high current draw.
- For 100mA current draw from the transistor (5V - 0.7V / 10mA)
- 1kΩ seems to work.
- 1N4007 Diode – for flyback protection at the relay coil.
- 3mm Green LED – invertor-on (mains-off) indicator.
- 330Ω Resistor – LED current limiter:
For Relay (Inverter):
- Same parts as for AC relay
- 47µF 16V Electrolytic Capacitor – for stabilizing voltage at the relay coil.
- Purpose is to act as a local energy reservoir, supplying extra current to avoid the voltage dip during the initial surge when the relay coil is energized. But size it wisely (or add a small resistor in series) to avoid high inrush current to the capacitor itself when the transistor turns on (though BJTs can tolerate short over-current spikes).
- 2 x 1N5822 Schottky Diode – for diode ORing. Power sources isolation is required because inverter relay is triggered from 2 sources in parallel: Arduino and a power adapter. Latter is used to bypass the protection system.
For Fan:
- 2N2222A NPN BJT – drives the fan.
- 330Ω Resistor – between the transistor (2N2222A) base and Arduino pin to protect high current draw.
- For 120mA current draw from the transistor (5V - 0.9V / 12mA)
- Fan current draw is ~50mA.
- 1N4007 Diode – for flyback protection.
For Battery Power Supply (LC Filter):
- 100µH Inductor (DIP)
- Capacitors:
- 0.1µF 50V Ceramic
- 10µF 50V Ceramic
- 100µF 25V Electrolytic (low-ESR polymer/aluminum)
- TL431 Regulator [32] – cuts-off whole circuit supply if battery drops below 7V.
- Reference:
- Voltage: 2.5V ±1%
- Bias current: 50-100µA (needs current limiter for <1mA)
- Output (cathode-anode):
- Current: 100mA
- Voltage: 2.5-37V
- Drop: 1.8-2.5V
- When active, cathode pulls down to 1.8-2.5V, not 0V
- Depends on the current (0.2Ω internal resistance)
- Output: 0.5~34V
- Max power loss: 700 mW (TO-92 package)
- Configurations:
- Series-regulator (like LM7805, variable-zener) topology:
- Add 2 resistors from REF → anode (R1) and cathode → REF (R2)
- Vout = 2.5 x (1 + R2 / R1)
- Low-side switch (cut-off / UVLO):
- Design a divider from power supply accordingly
- Cut-off is not very sharp due to linear region. Need to add hysteresis (positive feedback resistor).
- SI2301 P-MOS – provides feedback to TL431 (for hysteresis) and drives MP1584 buck converters.
- Resistors:
- 1 x 100kΩ
- 1 x 22kΩ
- 1 x 10kΩ
- 1 x 6.8kΩ
- 1 x 2.2kΩ
Others:
- 2 x 0.1µF 50V Ceramic Capacitor – for MP1584 buck converters output.
- 2 x 3-Pin T-Block Connector – for:
- AC mains connections. And output of relay to switch AC load between grid and inverter output. It controls a high-power 220V-driven changeover relay. Latter can also be triggered from AC mains to bypass the protection system.
- FL-2C Shunt Resistor terminals & PV+ supply
- 4 x 2-Pin T-Block Connector – for:
- FL-2C Shunt Resistor terminals (battery)
- Battery 12V supply
- Relay (inverter)
- Buzzer
- Barrier T-Block Screw Connector – for external connections.
- 2 x 1A Fuse + Fuse Holder – for whole circuit's protection.
- High-frequency electrical noise (HF EMI/RFI) from inverter and PWM controller may cause excessive RMS current in the fuse, even though DC measurement appears low (multimeter shows average DC). This high RMS may cause localized heating in fuse due to HF current ripple/pulses. To avoid this:
- Do LC or RC filtering.
- Use a slow-blow fuse.
- Run dedicated pairs of wires (positive and negative) from the battery to the Arduino circuit (do not share with inverter leads).
- Use a long wire for Arduino circuit power supply.
- DC Power Jack (male + female) – to make a detachable connection to relay (inverter).
- Veroboard Dotted (145mm x 65mm) – circuit designing.
- 2.54mm Pitch Male Header – soldered with the veroboard to connect the sensor modules.
- 2.54mm Pitch Female Header – soldered with the veroboard to connect the sensor modules.
- 2 x 2.54mm Pitch Jumper – buck converters output cut-off for voltage adjustment.
- Plastic Enclosure Box (160mm x 96mm x 50mm) – enclose the circuit.
- 4 x Plastic PCB Circuit Board Spacer – between veroboard and the box bottom.
- 2-Core Cable, 3-Core Cable – for 12V power supply, relay (inverter) and FL-2C Shunt Resistor connections, AC connections.
BoM
- 1 x Arduino Nano [1]
- 4 x HCPL-7840 Isolation Amplifier [23]
- 2 x ADS1115 16-Bit 4-Channel ADC + PGA [38]
- 2 x FL-2C Shunt Resistor 100A 75mV [4] [24]
- 1 x B0505S-1W DC-DC Isolated Power Converter [37]
- 1 x H11AA1 Optocoupler [15]
- 1 x DS3231 Precision RTC Module [7]
- 2 x 5V SPDT Relay [10]
- 1 x 8-Digit Display MAX7219 Module [11]
- 1 x 5-12V Active Buzzer [12]
- 3 x Push Buttons [13]
- 1 x IR Proximity (Obstacle Avoidance) Sensor [22]
- 1 x 12V 1W Fan [42]
- 2 x MP1584 Buck Converter [40]
- 1 x TL431 Regulator [32]
- 2 x 2.54mm Pitch Jumper [41]
- 2 x 3-Pin T-Block Connector
- 4 x 2-Pin T-Block Connector
- 1 x Barrier T-Block Screw Connector
- 2 x 1A Fuse + Fuse Holder
- 1 x DC Power Jack (male + female)
- 1 x Veroboard Dotted (145mm x 65mm)
- 1 x 2.54mm Pitch Male Header
- 1 x 2.54mm Pitch Female Header
- 1 x Plastic Enclosure Box (160mm x 96mm x 50mm)
- 4 x Plastic PCB Circuit Board Spacer
- 1 x 2-Core Cable
- 1 x 3-Core Cable
- 3 x 2N3904 NPN BJT
- 1 x 2N2222A NPN BJT
- 1 x SI2301 P-MOS
- 2 x 100µH Inductor (DIP)
- 4 x 1N4007 Diode
- 2 x 1N5822 Schottky Diode
- 1 x 3mm Green LED
- 1 x 10kΩ Multi-turn Potentiometer
- Resistors (0.25W):
- 8 x 33Ω
- 2 x 330Ω
- 1 x 470Ω
- 1 x 820Ω
- 3 x 1kΩ
- 1 x 2.2kΩ
- 1 x 6.8kΩ
- 1 x 10kΩ
- 1 x 22kΩ
- 3 x 100kΩ
- 2 x 220kΩ
- Ceramic Capacitors (50V):
- 4 x 10nF
- 12 x 0.1µF
- 1 x 10µF
- Electrolytic Capacitors:
- 2 x 10µF 25V
- 1 x 22µF 25V
- 1 x 47µF 16V
- 1 x 100µF 25V
Connections
1. FL-2C Shunt + HCPL-7840 + B0505S (PV Array)
- B0505S:
- Connections:
GND → GND rail
VIN → 5V rail
0V → GND_ISO rail → PV-
+VO → 5V_ISO rail
- Filters (for stabilizing):
VIN → 10µF electrolytic → GND
+VO → 10µF electrolytic → 0V
- Voltage Sensing:
- Voltage Divider:
- PV+ → 100µH inductor → 100kΩ → Junction (VD1) → 470Ω → GND_ISO rail
- HCPL-7840 (U1):
- Input:
VDD1 → 5V_ISO rail
GND1 → GND_ISO rail
VIN+ → 33Ω → Voltage divider junction (VD1)
VIN- → 33Ω → GND_ISO rail
- Output:
VDD2 → Arduino-side 5V rail
GND2 → Arduino-side GND rail
VOUT+ and VOUT- → ADS1115 analog input pins (ADS1_A0 and ADS1_A1)
- Filter:
VIN+ → 10nF ceramic → VIN-
- Works in combination with 33Ω in-series with
VIN+ and VIN-.
VDD1 → 0.1µF ceramic → GND1
VDD2 → 0.1µF ceramic → GND2
- Calibration:
- Divider output at 25V PV input:
- HCPL-7840 output:
- Current Sensing:
- Shunt Resistor:
- Place in series with the charge controller negative input:
- Due to common-mode range limit of HCPL-7840, we cannot sense high-side.
- HCPL-7840 (U2):
VIN+ is connected to shunt controller-side (SHT), VIN- to PV-side (PV- / GND_ISO). Use same resistors.
VOUT+ and VOUT- is connected to other pair of ADS1115 analog input pins (ADS1_A2 and ADS1_A3)
- Remaining details are same as that of voltage sensor.
- Calibration:
- Shunt output at 60A PV input:
- HCPL-7840 output:
- ADS1115 ADC:
VDD → 5V rail
GND → GND rail
SCL → Arduino Nano A5 (SCL)
SDA → Arduino Nano A4 (SDA)
A0 → U1 VOUT+ (ADS1_A0)
A1 → U1 VOUT- (ADS1_A1)
A2 → U2 VOUT+ (ADS1_A2)
A3 → U2 VOUT- (ADS1_A3)
2. FL-2C Shunt + HCPL-7840 (Battery)
- Voltage Sensing:
- Voltage Divider:
- Battery supply 12V+ (BSP1) → 100kΩ → Junction (VD2) → 820Ω → GND rail
- HCPL-7840 (U3):
- Power both sides of HCPL-7840 from Arduino 5V rail and GND rail.
- Calibration:
- Divider output at 16V PV input:
- HCPL-7840 output:
- Current Sensing:
- Shunt Resistor:
- Place in series with the battery negative terminal:
- BAT- → Shunt → GND rail
- Shunt should account for Arduino circuit current when drawn from the battery.
- HCPL-7840 (U4):
VIN+ is connected to shunt battery-side (BAT-), VIN- to load-side (GND). Use same resistors.
- We get positive readings when battery is charging.
- ADS1115 ADC:
- Connections:
A0 → U3 VOUT+ (ADS2_A0)
A1 → U3 VOUT- (ADS2_A1)
A2 → U4 VOUT+ (ADS2_A2)
A3 → U4 VOUT- (ADS2_A3)
- To change the I2C address from default (0x48) to 0x49, solder the
ADDR pin to VDD.
- Remaining details are same as that of PV sensor.
- Replace ADS1_A[N] connections with ADS2_A[N], and junction VD1 with VD2.
3. H11AA1 Optocoupler – AC Detection
- AC Side:
- 10kΩ Potentiometer:
- Terminal 1 → 220kΩ → Live (220V_L)
- Terminal 2 → 220kΩ → Neutral (MAIN_N)
- Connections:
- Pin 1 → Pot terminal
- Pin 2 → Pot wiper
- DC Side:
- Connections:
- Pin 4 (emitter) → GND rail
- Pin 5 (collector) → Arduino Nano D2 (digital input with internal pull-up enabled)
- Pin 6 (base) → Unconnected (transistor is driven by the LEDs)
- Filter: Pin 4 → 0.1µF ceramic → Pin 5
4. DS3231 RTC Module
VCC → 5V rail
GND → GND rail
SDA → Arduino Nano A4 (SDA)
SCL → Arduino Nano A5 (SCL)
5. Relay (AC Changeover)
- 2N3904 Driver:
- Base → 1kΩ resistor → Arduino Nano D4
- Emitter → GND rail
- Collector → Relay & LED (AC_RC-)
- Relay:
- Coil+ → 5V rail
- Coil- → 2N3904 Collector (AC_RC-)
- AC Load:
COM → 220V_L
NO → Changeover coil (Live) (AC_REL)
- Changeover coil (Neutral) → 220V Neutral
- Protection:
- Relay coil+ → [Cathode] 1N4007 [Anode] → Relay coil- (reverse polarity)
- LED:
- Anode → 330Ω → 5V rail
- Cathode → 2N3904 Collector (AC_RC-)
6. Relay (Inverter)
- Same transistor and protection connections as AC relay, except that use Arduino Nano D5 for control signal.
- Filter:
- Relay coil+ → 47µF electrolytic → Relay coil-
- Power ORing:
- Relay coil+ → [Anode] 1N5822 [Cathode] → Arduino circuit 5V rail
- Relay coil+ → [Anode] 1N5822 [Cathode] → External 5V+ adapter
- Relay
COM and NC → Inverter on/off switch
- Relay coil- → External 5V- adapter
7. MAX7219 8-Digit Display
VCC → 5V rail
GND → GND rail
DIN → Arduino Nano D12 (MISO/CIPO)
CS → Arduino Nano D11 (MOSI/COPI)
CLK → Arduino Nano D10 (SS/CS)
8. 5–12V Active Buzzer
- Driver Circuit:
- 2N3904 Base → 1kΩ resistor → Arduino Nano D6 (PWM frequency: ~976 Hz)
- 2N3904 Emitter → GND rail
- 2N3904 Collector → Buzzer-
- Buzzer+ → 12V rail
- Protection:
- Buzzer+ → [Cathode] 1N4007 [Anode] → Buzzer- (reverse polarity)
- Filter:
- Buzzer+ → 22µF electrolytic → Buzzer-
9. Push Buttons (x3)
- Each Button:
- One terminal → GND rail
- Other terminal → Arduino Nano D7, D8, D9 (digital inputs with internal pull-up enabled).
10. IR Proximity Sensor
VCC → 5V rail
GND → GND rail
OUT → Arduino Nano D3
11. Fan
- Driver Circuit:
- 2N2222A Base → 330Ω resistor → Arduino Nano D14
- 2N2222A Emitter → GND rail
- 2N2222A Collector → Fan-
- Fan+ → 12V rail
- Protection:
- Fan+ → [Cathode] 1N4007 [Anode] → Fan- (reverse polarity)
12. MP1584 Buck Converter (12V)
- Input:
IN+ → Battery supply 12V+ (BSP2)
IN- → GND rail
- Output:
OUT+ → Jumper → 12V rail → Arduino Nano VIN
OUT- → GND rail
- Filter:
OUT+ → 0.1µF ceramic → OUT-
13. MP1584 Buck Converter (5V)
- Input and filter same as 12V converter.
- Output:
OUT+ → Jumper → 5V rail → All 5V modules and other circuit components
OUT- → GND rail
14. Power Supply
- 12V Battery:
- 12V Supply Types:
- Raw battery supply (BAT+)
- Filtered battery supply (BSP1)
- Regulated battery supply (BSP2)
- Maintained 12V supply (12V rail)
- Connections:
- BAT+ →
- Fuse + inductor to produce filtered supply (BSP1)
- Load (inverter and solar charge controller). -ve side of the load is connected to GND rail (battery -ve side through shunt).
- BSP1 →
- TL431 + SI2301 to produce regulated supply (BSP2)
- Battery voltage sensing divider
- BSP2 →
- MP1584 to produce 12V rail
- Arduino 5V pin is very sensitive for input. Connecting with PC is unsafe. So we feed it through
VIN (requires 6V+).
- MP1584 to produce 5V rail
- For accurate ADC readings, make sure that the output voltages match the Nano's on-board AMS1117 regulator output.
- Ground (BAT-) feeds the shunt to produce GND rail.
- Fuse + HF Noise Filter:
- BAT+ → Fuse → 100µH inductor → BSP1
- Filters (between BSP1 and GND rail):
- 100µF electrolytic
- 10µF ceramic
- 0.1µF ceramic
- UVLO:
- Voltage Divider:
- BSP1 → 22kΩ → Junction (TL_REF) → 10kΩ → GND rail
- Drops 8V to ~2.5V for TL431 reference.
- Current:
- TL431:
REF →
- Divider junction (TL_REF)
- SI2301 feedback
- Anode → GND rail
- Cathode →
- 6.8kΩ → BSP1 (for minimum 1mV load)
- SI2301 signal
- SI2301:
- Source → BSP1
- Gate → 2.2kΩ → TL431 cathode (≥2mA current)
- Drain →
- BSP2
- 100kΩ → TL431
REF (feedback)
- Hysteresis: ~1V:
- Turn-on:
- Turn-off:
- 220V AC:
- Connections:
- MAIN_L (Live) → Fuse → 220V_L
- Feeds:
- H11AA1 Optocoupler – AC sensor
- Relay (for changeover coil)
Schematics
Solid boxes show external components. Dotted boxes show units.
Arduino Circuit:
Solar and AC (Grid + Inverter) Circuit:
This circuit works independent of Arduino control. But Arduino control depends on this circuit.
- Problem: Inverter is part of a UPS i.e. inverter + charger. But we usually charge the battery only on solar power. And UPS starts charging the battery if utility grid is present.
- Solution: Use an 220V AC changeover relay to move the mains ↔ inverter switching out of the inverter. Relay is active when on mains, connecting house supply to the mains. When inactive, it connects the supply to the inverter output.
- Problem: Since the UPS no more gets the grid supply, it's always running (with its fan) taking ~20W from battery. We need to manually switch it on and off.
- Solution: Put a 5V relay inside the inverter, in- series with the manual switch. Relay is powered using an adapter which is powered by the mains grid. So as long as utility grid is present, relay is active and keeps the inverter turned off.
- Problem: Switching to the mains from the inverter is quick. But switching to inverter takes 2-3 seconds because inverter needs time to start.
- Relay actuate time should not be more than a hundred milliseconds. Even better alternative: use an Automatic Transfer Switch instead of a relay.
- Solution: None so far. Probably there is a way (electronically) inside the inverter circuit to:
- Put the inverter on standby instead of completely turning off.
- Disable the battery charging while still feeding grid supply.
Switches:
- SW1:
- OFF: On inverter
- ON:
- Grid not available: On inverter
- Grid available:
- On grid
- SW2:
- ON: Inverter off
- OFF:
- Inverter on
- SW3:
- ON: UPS (charger) gets grid supply
PCB
Isolated Current / Voltage Sensor Module:
2 x HCPL-7840 + filters / protectors. Details for PV and for battery.
Pin config for PV / battery:
- SHT / BAT-
- GND_ISO / GND
- 5V_ISO / 5V
- ADS1_A3 / ADS2_A3
- ADS1_A2 / ADS2_A2
- GND_ISO / GND
- VD1 / VD2
- ADS1_A1 / ADS2_A1
- ADS1_A0 / ADS2_A0
- 5V
- GND
Or (swapping input / outputs of identical halves):
- VD1 / VD2
- Same
- Same
- ADS1_A1 / ADS2_A1
- ADS1_A0 / ADS2_A0
- Same
- SHT / BAT-
- ADS1_A3 / ADS2_A3
- ADS1_A2 / ADS2_A2
- Same
- Same
Front:
- Relay
- Connector
- Fuse
- LED
- 330Ω
- 220kΩ
- 10kΩ Potentiometer
- 220kΩ
- H11AA1
- 0.1µF
- MAX7219
- Jumper
- 0.1µF
- MP2307
- Arduino Nano
- Push Button
- Push Button
- Push Button
- Connector
- Connector
- Connector
- Connector
- 2N3904
- 2N3904
- 1kΩ
- 1kΩ
- IV Module (Battery)
- IV Module (PV)
- 100kΩ
- 820Ω
- ADS1115
- ADS1115
- IR Proximity Sensor
- 100µH
- 100µH
- Fuse
- 0.1µF
- 100µF
- 0.01µF
- 100kΩ
- 470Ω
- 2.2kΩ
- 6.8kΩ
- 10kΩ
- 22kΩ
- 100kΩ
- TL431
- 10µF
- 10µF
- B0505S
- MP1584
- Jumper
- 0.1µF
- 2N2222A
- 330Ω
- Connector
- DS3231
- 22µF
- 1kΩ
- 2N3904
- Connector
- AC_REL
- MAIN_N
- MAIN_L
- GND - Relay (Inverter)
- 5V - Relay (Inverter)
- BAT- - Shunt (Battery) Battery-Side
- GND - Shunt (Battery) Load-Side
- GND - Shunt (Battery) Load-Side
- BAT+
- PV- - Shunt (PV) PV-Side
- SHT - Shunt (PV) Load-Side
- PV+
- 12V - Buzzer
- GND - Buzzer
Back:
- SI2301
- 1N4007
- 1N4007
- 1N4007
- PV- source
- SHT source
- PV+ source
- PV+
- BSP1
- GND
- TL_REF
- TL_REF
- BSP2
- GND
- 5V_ISO source
- GND_ISO source / PV-
- 5V
- GND
- 5V source
- D14
- GND
- 12V
- GND
- 5V
- SDA
- SCL
- GND
- D6
- 12V
- BAT+
- GND source (BAT- via shunt)
- GND
- BAT-
- SHT
- GND_ISO
- 5V_ISO
- ADS1_A3
- ADS1_A2
- GND_ISO
- VD1
- ADS1_A1
- ADS1_A0
- 5V
- GND
- BAT-
- GND
- 5V
- ADS2_A3
- ADS2_A2
- GND
- VD2
- ADS2_A1
- ADS2_A0
- 5V
- GND
- GND_ISO
- BSP1
- GND
- 5V
- GND
- SCL
- SDA
- ADS1_A0 source
- ADS1_A1 source
- ADS1_A2 source
- ADS1_A3 source
- 5V
- GND
- SCL
- SDA
- 5V
- ADS2_A0 source
- ADS2_A1 source
- ADS2_A2 source
- ADS2_A3 source
- D3
- GND
- 5V
- 5V
- GND
- D5
- D4
- AC_RC-
- AC_RC-
- 5V
- AC_RC-
- 5V
- AC_REL
- AC_REL
- MAIN_N
- MAIN_L
- 220V_L
- 220V_L
- GND
- D2
- 12V source
- GND
- BSP2
- D2 source
- D3 source
- D4 source
- D5 source
- D6 source
- D7 source
- D8 source
- D9 source
- D10 source
- D11 source
- D12 source
- SCL source
- SDA source
- D14 source
- D10
- D11
- D12
- GND
- 5V
- D7
- D8
- D9
- GND
- GND
- GND
Joints:
- GND: 23 (10, 14, 18, 21, 23, 27, 31, 32, 44, 46, 50, 55, 58, 60, 68, 77, 80, 94, 97, 116, 121, 122, 123)
- 5V: 14 (17, 19, 24, 43, 47, 54, 59, 67, 71, 78, 79, 85, 87, 117)
- 12V: 3 (22, 29, 96)
- BAT-: 2 (33, 45)
- BSP1: 2 (9, 57)
- BSP2: 2 (13, 98)
- GND_ISO / PV-: 5 (5, 16, 35, 39, 56)
- 5V_ISO: 2 (15, 36)
- PV+: 2 (7, 8)
- SHT: 2 (6, 34)
- 220V_L: 2 (92, 93)
- AC_REL: 2 (88, 89)
- AC_RC-: 3 (83, 84, 86)
- D2: 2 (95, 99)
- D3: 2 (76, 100)
- D4: 2 (82, 101)
- D5: 2 (81, 102)
- D6: 2 (28, 103)
- D7: 2 (104, 118)
- D8: 2 (105, 119)
- D9: 2 (106, 120)
- D10: 2 (107, 113)
- D11: 2 (108, 114)
- D12: 2 (109, 115)
- D14: 2 (20, 112)
- SCL: 4 (26, 61, 69, 110)
- SDA: 4 (25, 62, 70, 111)
- ADS1_A0: 2 (42, 63)
- ADS1_A1: 2 (41, 64)
- ADS1_A2: 2 (38, 65)
- ADS1_A3: 2 (37, 66)
- ADS2_A0: 2 (53, 72)
- ADS2_A1: 2 (52, 73)
- ADS2_A2: 2 (49, 74)
- ADS2_A3: 2 (48, 75)
Load Calculation
| Components |
Current (mA) |
Pin |
Mode |
Pin Source (+) / Sink (-)Current (mA) |
H11AA1 Optocoupler – AC sensor (pulled-up @ ~20kΩ) |
|
D2 |
Input |
-0.25 |
| IR proximity sensor module |
10-20 |
D3 |
Input |
~0 |
2N3904 - drives a 5V relay (AC) |
60 |
D4 |
Output |
6 |
2N3904 - drives a 5V relay (inverter) |
60 |
D5 |
Output |
6 |
| 2N3904 - drives a 12V buzzer |
40 @ 12V |
D6 |
Output |
4 |
| Push button (pulled-up @ ~20kΩ) |
|
D7-D9 |
Input |
-0.25 × 3 = -0.75 |
| MAX7219 8-digit display module |
50-100 |
D10-D12 |
SPI/Output |
±0.1 × 3 = ±0.3 |
| 2N2222A - drives a 12V fan |
50-100 @ 12V |
D14 |
Output |
10 |
| DS3231 clock module |
0.5-1.5 |
A4-A5 |
I2C |
-0.25 × 2 = -0.5 (SDA/SCL pulled LOW) |
Battery sensor: ADS1115 module & 2 x HCPL-7840 |
0.2 (ADS1115)
11 × 2 = 22 (7840)
|
Solar sensor: ADS1115 module & 2 x HCPL-7840 & B0505S |
0.2 (ADS1115)
11 × 125% = 13.75 (7840_IN)
11 (7840_OUT)
5 (B0505S)
|
Total:
- 5V MP1584: 235~295mA
- 12V MP1584: 40mA + 50-100mA + 43~58mA = 135~200mA
- Nano: 43~58mA
- Self: 15~30mA
- GPIO pins: 28mA
- B0505S: ~22mA
- HCPL-7840: 11mA × 2 = 22mA
Code
https://github.com/mirfatif/SolarBMS/blob/master/SolarBMS.ino
Libraries:
Finally
Improvement Plan
- Replace Arduino Nano with WiFi-enabled ESP32:
- Serve readings, logs, stats, and configurations over HTTP.
- Run WiFi in AP-mode if station-mode network name / password is not configured, or if configured AP is not available.
- Turn off WiFi after 5 minutes of inactivity.
- Replace 3 buttons and IR sensor with a single (capacitive touch) button only to:
- Rotate between informatory screens.
Or remove display module too?
- Turn WiFi on/off.
- Remove RTC module:
- Sync time from internet after every reboot.
- For temperature sensing use the small DS18B20
or LM35.
- Remove unnecessary isolation for battery voltage/current sensing.
- For better accuracy, revert to INA219 (or ADS1115 ?) + ADuM1250 + B0505S for PV sensing. Use INA219 directly for battery sensing.
- Convert AC sensor and UVLO circuit to detachable modules.
Convert battery power connector + battery shunt connector (2+2) to a single 3-pin T-block connector like PV connector.
- Replace voltage-divider resistors with potentiometers.
- More stabilized analog values of voltage/current sensors. But how?
Custom PCB?
Links
- https://digilog.pk/products/arduino-nano-v3-with-usb-cable-in-pakistan
- https://digilog.pk/products/ina219-bi-direction-dc-current-power-supply-sensor-module-gy-219-module-in-pakistan
- https://wolles-elektronikkiste.de/en/ina219-current-and-power-sensor
- https://www.aliexpress.com/item/1005007796473791.html
- https://digilog.pk/products/dc-0-to-25v-voltage-sensor-module-for-arduino-in-pakistan
- https://digilog.pk/products/zmpt-single-phase-ac-voltage-sensor-module-in-pakistan
- https://digilog.pk/products/ds3231-rtc-module
- https://instock.pk/ambient-light-intensity-lux-sensor-bh-1750.html
- https://digilog.pk/products/1-channel-5v-arduino-relay-module-in-pakistan
- https://digilog.pk/products/spdt-6v-or-5v-relay
- https://digilog.pk/products/max7219-8-digit-7-segment-module-assembled-in-pakistan
- https://digilog.pk/products/buzzer-alarm-active-piezo-electronic-wires-dc-3-12v
- https://digilog.pk/products/12x12x9mm-tactile-push-button-switch
- https://digilog.pk/products/411a-lm2596-buck-converter-step-down-module-power-supply
- https://digilog.pk/products/h11aa1-optocoupler-dip-6-pin-ic
- https://github.com/NorthernWidget/DS3231
- https://github.com/wollewald/INA219_WE
- https://github.com/JemRF/max7219
- https://github.com/Abdurraziq/ZMPT101B-arduino
- https://github.com/kotwatthana/TimerOne_V2
- https://digilog.pk/products/mini-360-dc-to-dc-step-down-buck-converter-module-in-pakistan
- https://digilog.pk/products/ir-infrared-obstacle-avoidance-sensor-module-in-pakistan
- https://digilog.pk/products/hcpl-7840-smd-optocoupler-in-pakistan
- https://industryparts.pk/products/fl-2c-75mv-current-meter-shunt-dc-ammeter-splitter
- https://digilog.pk/products/ca3130-operational-amplifier-in-pakistan
- https://digilog.pk/products/lm7805-7805-voltage-regulator-5v-voltage-regulator
- https://www.rcscomponents.kiev.ua/datasheets/hcpl-7840-000e-datasheet.pdf
- https://digilog.pk/products/5v-raspberry-pi-cooling-fan-in-pakistan
- https://digilog.pk/products/lm78l05-78l05-voltage-regulator-5v-voltage-regulator-to-92
- https://digilog.pk/products/6n137-high-speed-optocoupler
- https://www.ti.com/lit/ds/symlink/ina219.pdf
- https://digilog.pk/products/tl431-regulator-in-pakistan
- https://www.analog.com/en/resources/app-notes/an-913.html
- https://toshiba.semicon-storage.com/content/dam/toshiba-ss-v3/master/en/semiconductor/design-development/innovationcentre/whitepapers/TCM0646_Toshiba_Isolated_I2C_Communications_Using_Optoisolators.pdf
- https://www.vishay.com/docs/84901/opticalisolatorfoti2cvussystem.pdf
- https://www.daraz.pk/products/i433460246-s2080834429.html
- https://www.daraz.pk/products/i260624136-s1478880694.html
- https://digilog.pk/products/ads1115
- https://github.com/wollewald/ADS1115_WE
- https://digilog.pk/products/mini-mp1584en-dc-dc-buck-adjustable-step-down-module-4-5v-28v-input-0-8v-20v-output
- https://digilog.pk/products/mini-jumpers-hard-drive-jumper-in-pakistan
- https://digilog.pk/products/40mm-x-40mm-x-10mm-4010-12v-0-15a-dc-brushless-ball-bearing-cooling-fan-2pin