English | Deutsch
Professional intelligent battery charger controller for OWON SPE series programmable power supplies running on Raspberry Pi.
Supported models: SPE3102, SPE3103, SPE6103, SPE6205 (and likely other SCPI-compatible PSUs)
Headless operation - fully controlled via MQTT and monitored remotely.
- OWON SPE Series Support - Full SCPI control (SPE3102/3103/6103/6205)
- Multiple Charging Modes - IUoU (3-stage), CV, Pulse, Trickle
- MQTT Integration - Complete monitoring and control
- Energy Accounting - Ah/Wh delivered and stored (Coulomb counting)
- Safety Monitoring - Multi-layer protection with automatic shutdown
- Data Logging - CSV logs with complete charging history
- 26 Battery Profiles - Pre-configured for 2V/6V/12V/24V batteries (sealed & flooded)
- Battery Profile Switching - Change battery via MQTT without config edits
- Charge Scheduling - Schedule charging with start time and duration limits
- Battery History Tracking - Track charge cycles, capacity, and health over time
- Error Recovery - Auto-reconnect PSU and MQTT on connection failures
- Multi-Voltage Support - 0.01V to 60V (2V cells to 48V battery packs)
- Voltage Plateau Detection - Auto-stop for high-voltage flooded battery charging
- Power Monitoring - Real-time V/A/W measurements
- Temperature Sensor - Optional DS18B20 support for battery temperature
- Charging Efficiency Tracking - Accounts for 17% losses (heat/gas)
- Improved Progress Calculation - Smoother 0→70%→95%→100% progression
- Systemd Service - Auto-start, watchdog, automatic restart
- Home Assistant - Full integration with sensors and switches
- Remote Control - MQTT control from any client
- Web Dashboards - Compatible with Node-RED, Grafana, etc.
- SSH Access - Full Linux debugging and monitoring
Modern batteries need DIFFERENT voltages than old batteries!
This project includes TWO configurations:
-
Lead-Calcium (Ca/Ca) - Modern batteries (2010+)
- Uses 15.2V for charging
- Default configuration
- Most automotive batteries since 2010
-
Lead-Antimony (Sb) - Legacy batteries (pre-2010)
- Uses 14.4V for charging
- Separate configuration file
- Older serviceable batteries
Quick check: When was your battery manufactured?
- 2010 or later → Use default config (lead-calcium)
- Before 2010 → Use
charging_config_lead_antimony.yaml
Label check: Look for these markings:
- "Calcium", "Ca/Ca", "Maintenance Free" → Lead-calcium (15.2V)
- "Sb", "Antimony", removable caps → Lead-antimony (14.4V)
Full guide: See docs/BATTERY_TYPES.md for detailed identification
Using wrong voltages:
- 14.4V on lead-calcium → Battery never fully charges → premature failure
- 15.2V on lead-antimony → Excessive gassing → water loss
Most "dead" batteries just need the correct charging voltage!
# Modern lead-calcium battery (DEFAULT)
config/charging_config.yaml # 15.2V charging
# Legacy lead-antimony battery
config/charging_config_lead_antimony.yaml # 14.4V charging
# To use legacy config:
python3 src/charger_main.py --config config/charging_config_lead_antimony.yamlTechnical References:
- German Battery Technical Wiki - Complete technical specifications
- Microcharge Forum: High-Voltage Charging - Expert charging methods
- OWON SPE/SP/SPS Programming Manual - Official SCPI command reference
These resources explain:
- Lead-calcium vs lead-antimony chemistry differences
- Correct charging voltages (Ladeschlussspannung: 17-17.5V for flooded)
- Traditional constant current method (150 years proven)
- State-of-charge voltage tables
- 12.5V critical threshold (80% SOC - must recharge immediately)
- Charging efficiency and losses
OWON SPE Series USB → Raspberry Pi USB Port (/dev/ttyUSB0)
↓
Ethernet/WiFi
↓
MQTT Broker
↓
Home Assistant / Dashboard
| Model | Voltage | Current | Power | Best For |
|---|---|---|---|---|
| SPE3102 | 30V | 10A | 200W | Batteries up to 70-80Ah (12V only) |
| SPE3103 | 30V | 10A | 300W | Batteries up to 70-80Ah (12V only) |
| SPE6103 | 60V | 10A | 300W | Batteries up to 70-80Ah (12V, 24V, 48V) |
| SPE6205 | 60V | 20A | 500W | Batteries up to 200Ah+ (12V, 24V, 48V) |
Configuration templates are provided in config/psu_templates/ for each model.
See config/psu_templates/README.md for detailed PSU selection guide.
New to Raspberry Pi or Linux? → See Complete Installation Guide for step-by-step instructions!
Experienced users:
# 1. Install dependencies
sudo apt update
sudo apt install python3 python3-serial python3-paho-mqtt python3-yaml git mosquitto mosquitto-clients
# 2. Clone project
cd ~
git clone https://github.com/packerlschupfer/scpi-battery-charger.git battery-charger
cd battery-charger
# 3. Add user to dialout group (for USB access)
sudo usermod -a -G dialout $USER
# Log out and back in for this to take effect
# 4. Choose PSU template and configure for your battery
cp config/psu_templates/SPE6205_config.yaml config/charging_config.yaml
nano config/charging_config.yaml # Edit battery capacity and current
# 5. Test manually first
python3 src/charger_main.py --auto-start
# 6. Install as systemd service (after testing!)
sudo cp battery-charger.service /etc/systemd/system/
sudo systemctl daemon-reload
sudo systemctl enable battery-charger
sudo systemctl start battery-chargerEdit config/charging_config.yaml:
# Power Supply
power_supply:
model: "OWON SPE6205"
port: "/dev/ttyUSB0"
baudrate: 115200
max_voltage: 60.0 # SPE6205: 60V max (0.01-60V range)
max_current: 20.0 # SPE6205: 20A max (0.001-20A range)
# Battery
battery:
type: "lead_calcium_flooded" # Modern battery (2010+)
nominal_voltage: 12.0
capacity: 95.0 # Ah
# Charging Mode - Lead-Calcium Configuration
charging:
default_mode: "IUoU"
IUoU:
bulk_current: 9.5 # 9.5A = C/10 rate for 95Ah
absorption_voltage: 15.2 # Lead-calcium needs 15-15.4V!
float_voltage: 13.8
absorption_current_threshold: 1.0
enable_float: true
# Safety Limits
safety:
absolute_max_voltage: 16.5 # Safe for lead-calcium
absolute_max_current: 20.0 # Hardware limit
max_charging_duration: 43200 # 12 hours
# MQTT
mqtt:
enabled: true
broker: "localhost"
port: 1883
base_topic: "battery-charger"
update_interval: 5.0 # secondsbattery-charger/status/online # "true" / "false"
battery-charger/status/voltage # 13.45 (V)
battery-charger/status/current # 4.23 (A)
battery-charger/status/power # 56.79 (W)
battery-charger/status/mode # "IUoU"
battery-charger/status/state # "charging" / "idle" / "completed"
battery-charger/status/stage # "bulk" / "absorption" / "float" (IUoU mode)
battery-charger/status/elapsed # 3600 (seconds)
battery-charger/status/progress # 75 (%)
# Energy Accounting (Coulomb Counting)
battery-charger/status/ah_delivered # 12.345 (Ah from PSU)
battery-charger/status/wh_delivered # 175.23 (Wh energy consumed)
battery-charger/status/ah_stored # 10.246 (Ah stored in battery, 83% efficiency)
# Complete JSON status
battery-charger/status/json # Complete status as JSON
battery-charger/cmd/start # Payload: "" (start charging)
battery-charger/cmd/stop # Payload: "" (stop charging)
battery-charger/cmd/mode # Payload: "IUoU" / "CV" / "Pulse" / "Trickle"
battery-charger/cmd/current # Payload: "5.0" (set current in A)
battery-charger/cmd/profile # Payload: "12v_sealed_20ah" (switch battery profile)
# Charge Scheduling
battery-charger/cmd/schedule # Payload: JSON {"start_time": "14:30", "duration": "2h", "profile": "lucas_44ah"}
battery-charger/cmd/schedule/cancel # Payload: "" (cancel scheduled charge)
Battery Profile Examples:
12v_sealed_20ah- 12V 20Ah sealed/AGM battery12v_flooded_75ah- 12V 75Ah flooded/wet battery6v_flooded_200ah- 6V 200Ah golf cart battery2v_sealed_100ah- 2V 100Ah industrial cell24v_battery- 24V battery packlucas_44ah- Lucas Premium LP063 44Ah (specific battery)
26 profiles available - See config/ directory or NEW_FEATURES.md
Add to configuration.yaml:
mqtt:
sensor:
- name: "Battery Voltage"
state_topic: "battery-charger/status/voltage"
unit_of_measurement: "V"
device_class: voltage
- name: "Battery Current"
state_topic: "battery-charger/status/current"
unit_of_measurement: "A"
device_class: current
- name: "Charging State"
state_topic: "battery-charger/status/state"
- name: "Charging Progress"
state_topic: "battery-charger/status/progress"
unit_of_measurement: "%"
switch:
- name: "Battery Charger"
command_topic: "battery-charger/cmd/start"
state_topic: "battery-charger/status/state"
payload_on: ""
payload_off: ""
state_on: "charging"
state_off: "idle"# Subscribe to all topics
mosquitto_sub -h localhost -t "battery-charger/#" -v
# Start charging
mosquitto_pub -h localhost -t "battery-charger/cmd/start" -m ""
# Stop charging
mosquitto_pub -h localhost -t "battery-charger/cmd/stop" -m ""
# Change mode
mosquitto_pub -h localhost -t "battery-charger/cmd/mode" -m "CV"# Real-time logs
sudo journalctl -u battery-charger -f
# CSV data logs
tail -f ~/battery-charger/logs/charge_*.csv- Voltage Limits - Absolute max (18V), operational max (17.2V), warning (12.5V)
- Current Limits - Hardware enforced (20A max from SPE6205)
- Power Monitoring - Real-time V×A calculation
- Timeout Protection - Configurable max charging duration (default 12 hours)
- Temperature Monitoring - Optional DS18B20 sensor with high/low limits
- Voltage Plateau Detection - Auto-stop for flooded batteries above 16V
- 12.5V Warning Threshold - Critical SOC alert (80% - recharge immediately)
- Automatic Shutdown - On safety violations, completion, or errors
- Systemd Watchdog - Auto-restart on crash
- MQTT Status - Real-time health monitoring
- Last Will Testament - Offline detection
- Complete Logging - All sessions logged to CSV with full history
- Energy Accounting - Track Ah/Wh delivered and stored
- Bulk: Constant current (C/10) until absorption voltage
- Absorption: Hold absorption voltage until current tapers
- Float: Maintain 13.5V (reduced from 13.8V to prevent grid corrosion)
- Automatic transitions between stages
- Pure constant current charging (C/10 rate)
- Best for open flooded batteries
- Uses voltage plateau detection for auto-stop
- Battery naturally reaches 17-17.5V when full
- Extended high-voltage (15.4-15.6V) for 24-48 hours
- For batteries that won't hold charge properly
- Improves resting voltage and charge retention
- Includes electrolysis detection
- Better than continuous float for storage batteries
- Hold target voltage, current tapers naturally
- Good for maintenance charging
- Desulfation mode for neglected batteries
- Voltage pulses with rest periods
- For recovery of sulfated batteries
- Low current maintenance
- Now uses 13.5V (reduced from 13.8V)
- For long-term storage
# Check status
sudo systemctl status battery-charger
# Check logs
sudo journalctl -u battery-charger -n 50
# Run manually to see errors
cd ~/battery-charger
python3 src/charger_main.py# Check USB device
ls -l /dev/ttyUSB0
# Check permissions
sudo usermod -a -G dialout pi
# Log out and back in
# Test SCPI
python3 /tmp/test_owon.py# Check mosquitto running
sudo systemctl status mosquitto
# Test manually
mosquitto_pub -h localhost -t "test" -m "hello"
mosquitto_sub -h localhost -t "test"scpi-battery-charger/
├── README.md
├── battery-charger.service # Systemd service file
├── requirements.txt # Python dependencies
│
├── src/
│ ├── charger_main.py # Main entry point
│ ├── owon_psu.py # OWON SCPI driver
│ ├── charging_modes.py # Charging algorithms
│ ├── safety_monitor.py # Safety checks
│ └── mqtt_client.py # MQTT integration
│
├── config/
│ └── charging_config.yaml # Main configuration
│
├── logs/ # Data logs (auto-created)
│ └── charge_*.csv
│
└── docs/
├── CHARGING_MODES.md # Mode details
└── MQTT_API.md # MQTT topic reference
- Installation Guide - Complete beginner-friendly setup guide
- PSU Selection Guide - Choose the right OWON model
- Battery Types Guide - Lead-calcium vs lead-antimony
- Systemd Service Setup - Auto-start configuration
- NEW_FEATURES.md - Battery profiles, scheduling, history tracking, error recovery
- 26 Battery Profiles -
config/charging_config_*.yamlfiles for 2V-24V batteries- 12V Sealed (AGM/Gel): 7Ah, 12Ah, 20Ah, 35Ah, 75Ah, 100Ah
- 12V Flooded: 45Ah, 60Ah, 75Ah, 100Ah, 200Ah
- 6V Golf Cart: 200Ah, 250Ah
- 2V Industrial: 100Ah, 200Ah, 600Ah
- 24V Battery Packs, plus specific batteries (Lucas, Banner, 4MAX)
- GitHub Issues: https://github.com/packerlschupfer/scpi-battery-charger/issues
- Configuration Help: See
config/psu_templates/README.md - Logs:
~/battery-charger/logs/andjournalctl -u battery-charger -f - MQTT Testing:
mosquitto_sub -h localhost -t 'battery-charger/#' -v
MIT License - See LICENSE file for details