181 lines
5.5 KiB
Markdown
Executable File
181 lines
5.5 KiB
Markdown
Executable File
# 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`)
|
|
- 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 `/data` SPIFFS 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_task` that receives button press/release notifications via `xTaskNotify`.
|
|
|
|
### Storage
|
|
|
|
- SPIFFS used for:
|
|
- `/cfg` partition: persistent configuration.
|
|
- `/data` partition: 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_driver` abstracts LEDC timer + channels.
|
|
- `led` module 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)
|
|
|
|
### Load Balancer
|
|
|
|
- `loadbalancer` component:
|
|
- 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_LIMIT`
|
|
- `LOADBALANCER_EVENT_SLAVE_CURRENT_LIMIT`
|
|
- Fail-safe behavior:
|
|
- If GRID meter data times out, clamps connectors to minimum safe current instead of ramping up.
|
|
|
|
### Scheduler
|
|
|
|
- Scheduler component (`scheduler`) emits `SCHED_EVENTS` with `allowed_now` flag:
|
|
- EVSE manager revokes authorization when the window closes.
|
|
- In OPEN mode, automatic re-authorization only happens when scheduler allows.
|
|
|
|
### OCPP
|
|
|
|
- `ocpp` module integration:
|
|
- Listens to OCPP events (`OCPP_EVENTS`).
|
|
- Handles:
|
|
- RemoteStart/Stop
|
|
- Authorization results
|
|
- ChangeAvailability (operative/inoperative) → mapped into local `enabled` config.
|
|
- EVSE manager mediates OCPP decisions with scheduler + load balancer.
|
|
|
|
### Logger
|
|
|
|
- `logger` + `output_buffer` components:
|
|
- 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`).
|
|
- 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):
|
|
|
|
```text
|
|
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.
|