ChargeFlow EVSE Firmware (ESP32, ESP-IDF 5.x)
Firmware for an AC EVSE (EV charger) based on ESP32 and ESP-IDF 5.x, with:
- IEC-style EVSE state machine (Control Pilot A/B/C/D)
- Wi-Fi (STA + AP for local configuration)
- REST API served from SPIFFS
- Local authentication and OCPP integration
- Load balancing (master + slaves)
- Scheduler (time windows)
- Audible feedback (buzzer) and RGB LED status
- On-device ring-buffer logger
Features
Core EVSE
- EVSE manager (
evse_manager) coordinating:- Hardware layer (
evse_hardware) - State machine (
evse_state) - Error handling (
evse_error) - Energy metering (
evse_meter/meter_manager) - Session tracking (
evse_session)
- Hardware layer (
- Runs a periodic tick (
evse_manager_tick()) in its own FreeRTOS task. - Supports multiple auth modes (OPEN / RFID / OCPP), with scheduling and load-balancer aware logic.
Networking & REST
- Wi-Fi:
- Station mode for normal operation.
- Access point mode for local configuration, enabled by a physical button.
- REST server (
rest_main) serving from/dataSPIFFS mount:- For configuration, status, logs, etc. (exact endpoints depend on your REST implementation).
Button & User Input
- One physical button (configured via
board_config):- Short press → Starts Wi-Fi AP mode for configuration.
- Long press (~30s) → Erases NVS and reboots (factory-like reset).
- Robust handling:
- ISR with software debounce and spinlock.
- Dedicated
user_input_taskthat receives button press/release notifications viaxTaskNotify.
Storage
- SPIFFS used for:
/cfgpartition: persistent configuration./datapartition: web assets, runtime data, logs, etc.
- Two separate mounts:
cfg_conf→/cfg(label:cfg)data_conf→/data(label:data)
LED Subsystem
- RGB LED driven by LEDC:
ledc_driverabstracts LEDC timer + channels.ledmodule maps EVSE state & sessions to colors/patterns.
- LED patterns per EVSE state:
- IDLE → Green solid.
- WAITING (vehicle plugged, not charging) → Blue slow blink.
- CHARGING → Blue “breathing” effect.
- FAULT → Red fast blink.
- Session effects:
- Distinct visual patterns when a session starts/finishes.
- Uses a one-shot timer and a dedicated effect state machine.
Buzzer
- Buzzer with multiple patterns (
buzzer+buzzer_events):- Plugged/unplugged, card read/denied, AP start, charging, fault, etc.
- Supported modes:
- Active buzzer (ON/OFF).
- Passive buzzer with LEDC PWM (frequency & duty configurable).
- Features:
- Central queue + dedicated
buzzer_task. - Quiet hours support (optionally suppress non-critical sounds at night).
- Anti-spam mechanism to avoid excessively frequent beeps.
- Integrated with:
- EVSE events (state changes & faults)
- Auth events (RFID card success/denied/added)
- Network events (AP/STA up)
- Central queue + dedicated
Load Balancer
loadbalancercomponent:- Monitors GRID meter and EVSE meter via
meter_events. - Supports one master + up to 255 slaves (connectors array).
- Fair distribution of current with:
- Headroom calculation based on grid limit and measured current.
- Min current guarantees (e.g. 6 A) using a “water-filling” algorithm.
- Session-age based priority (oldest sessions first).
- Per-connector hysteresis and LB suspension/resume flags.
- Publishes limits via
LOADBALANCER_EVENTS:LOADBALANCER_EVENT_MASTER_CURRENT_LIMITLOADBALANCER_EVENT_SLAVE_CURRENT_LIMIT
- Monitors GRID meter and EVSE meter via
- Fail-safe behavior:
- If GRID meter data times out, clamps connectors to minimum safe current instead of ramping up.
Scheduler
- Scheduler component (
scheduler) emitsSCHED_EVENTSwithallowed_nowflag:- EVSE manager revokes authorization when the window closes.
- In OPEN mode, automatic re-authorization only happens when scheduler allows.
OCPP
ocppmodule integration:- Listens to OCPP events (
OCPP_EVENTS). - Handles:
- RemoteStart/Stop
- Authorization results
- ChangeAvailability (operative/inoperative) → mapped into local
enabledconfig.
- EVSE manager mediates OCPP decisions with scheduler + load balancer.
- Listens to OCPP events (
Logger
logger+output_buffercomponents:- Central log sink with ring buffer in RAM.
- Thread-safe via FreeRTOS mutex.
- Integrated with ESP log system via
esp_log_set_vprintf(logger_vprintf);- Optionally mirrors to UART (controlled via
CONFIG_ESP_CONSOLE_UART).
- Optionally mirrors to UART (controlled via
- Simple reader API:
- Iterate entries using an index.
- Handy for exposing logs over REST/Web UI.
Project Structure (Relevant Parts)
Approximate layout (names may vary slightly in your repo):
main/
main.c # System entrypoint, button setup, module init
components/
evse/
evse_manager.c/.h # High-level EVSE orchestration
evse_state.c/.h # State machine & events
evse_error.c/.h # Error handling
evse_hardware.c/.h # Hardware abstraction
evse_session.c/.h # Session metrics
loadbalancer/
src/
loadbalancer.c
loadbalancer_events.c
input_filter.c
include/
loadbalancer.h
loadbalancer_events.h
input_filter.h
buzzer/
src/
buzzer.c
buzzer_events.c
include/
buzzer.h
buzzer_events.h
led/
src/
led.c
ledc_driver.c
include/
led.h
ledc_driver.h
logger/
src/
logger.c
output_buffer.c
include/
logger.h
output_buffer.h
# ... other modules: auth, ocpp, scheduler, meter_manager, evse_link, etc.
Description
Languages
C
96.8%
Python
1.1%
C++
0.6%
JavaScript
0.5%
CMake
0.4%
Other
0.6%