Skip to content

Linco work#51

Open
chris1howell wants to merge 59 commits into
masterfrom
linco-work
Open

Linco work#51
chris1howell wants to merge 59 commits into
masterfrom
linco-work

Conversation

@chris1howell

@chris1howell chris1howell commented May 24, 2026

Copy link
Copy Markdown
Member

OpenEVSE linco-work Branch — Change Summary

Branch: linco-work vs origin/master
RAPI version bumped: 5.2.1 → 6.0.0


Major Feature Changes

1. Relay Wear Protection (RELAY_ZC_SWITCH)

Relays are now switched at AC voltage zero-crossings to minimize contact arcing and wear.

  • New function measureAcFreq() detects AC frequency via:
    • SAMD: ADC sign-change on the GMI_LINE analog input (PA09)
    • m328p w/ CGMI: digital pulses on pinAC2 (HIGH = near ZC)
    • m328p non-CGMI: complementary rising edges on pinAC1/pinAC2
  • zcWaitRelayClose() / zcWaitRelayOpen() time coil energize/de-energize relative to detected ZC
  • Timing constants: RELAY_CLOSE_ADVANCE_MS = 20, RELAY_OPEN_ADVANCE_MS = 2, ZC_DETECT_TIMEOUT_MS = 35
  • Current-zero threshold check: relay only opens when current < 100 mA (CURRENT_ZERO_THRESHOLD_MA)
  • ZC switching can be toggled via RAPI $FF Z 0|1 and is saved to EEPROM

2. Per-Relay Enable/Disable Control

Individual relays (DC1, DC2, AC) can be independently enabled or disabled.

  • New EEPROM byte EOFS_RELAY_FLAGS stores bitmask:
    • ERELAYF_DC1_DISABLED (0x01) — DC relay 1
    • ERELAYF_DC2_DISABLED (0x02) — DC relay 2
    • ERELAYF_AC_DISABLED (0x04) — AC relay
  • Default: all relays enabled (ERELAYF_DEFAULT = 0x00)
  • All relay close/open code paths respect enable flags
  • New RAPI commands $SR / $GR (see table below)

3. Multi-Target Build System (PlatformIO)

The project now supports multiple MCU targets built via PlatformIO.

  • New directory structure: firmware/targets/m328p/ for AVR-specific files (GFI, LCD, pilot, I2C, etc.)
  • Removed: arduino/ directory and all Arduino IDE board/programmer definition files
  • Removed: Visual Studio project files (open_evse.sln, .vcxproj)
  • New: UF2 bootloader build and firmware UF2 conversion for SAMD targets
  • New: Atmel-ICE bootloader upload support
  • #define RTC renamed to #define HAVE_RTC throughout
  • RAPI_SERIAL_PORT is now configurable (was hardcoded to Serial)
  • Serial begin() moved into EvseSerialRapiProcessor::init() (initialization order fix)

4. Temperature Monitoring Simplification

  • $GO / $FO now use a single panic temperature (m_panicTemperature) instead of separate ambient/IR thresholds
  • Panic temp saved to EEPROM; if exceeded, EVSE enters EVSE_STATE_OVER_TEMPERATURE
  • New define TEMPERATURE_THROTTLING: if not set, only the panic threshold is enforced (no current throttling)

5. PP (Proximity Pilot) Auto-Ampacity Improvements

  • New state EVSE_STATE_PP_MISSING — cable missing PP resistor
  • New state EVSE_STATE_PP_SHORTED — PP resistor shorted
  • If no PP resistor at boot: auto-ampacity disabled and spins until cable removed
  • PP detection is only active on transition to state B/C
  • PP auto-ampacity can be toggled via $FF P 0|1

6. Boot Lock Feature (BOOTLOCK)

  • When enabled, EVSE stays locked until it receives $SB command
  • Controlled via $FF L 0|1
  • New controller flag ECF_BOOT_LOCK_DISABLED

7. Overcurrent Check Control

  • New flag ECF_OVERCURRENT_DISABLED
  • Overcurrent check can be disabled via $FF O 0|1

8. Fault Counter Reset ($FC)

  • New RAPI set command $FC resets all fault counters and total energy meter in one call

9. Signed Integer Parsing Fix

  • Internal dtou32() replaced by dtoi32() — now correctly handles negative decimal inputs across all RAPI numeric arguments

10. V6 / CGMI Detection Refactor

  • Removed old INVERT_V6_DETECTION mechanism
  • New globals g_isV6 and g_hasCGMI set by initTarget() at boot
  • CGMIisEnabled() renamed to hasCGMI()
  • V6 board detection: reads analog pin A6 five times and uses statistical mode (A6 floats on v1–v5)

11. No-Ground Record Delay (CGMI boards)

  • OEV6 w/ CGMI: power-loss transiently triggers a spurious NO GROUND fault
  • New NO_GND_RECORD_DELAY (default 2 s) suppresses recording of this false fault

12. MCU ID ($GI) — SAMD Support

  • AVR: 6 ASCII chars + 8 hex digits (was 4)
  • SAMD: 128-bit serial number returned as 32-character hex string

13. OpenEVSE NXT USB VID/PID Update

  • USB VID/PID changed to official Microchip/OpenEVSE values

New & Changed RAPI Commands

Command Direction Syntax Description Conditional
$FC Set $FC Reset all fault counters and total energy meter to zero Always
$FF L Set $FF L 0|1 Disable (0) / enable (1) boot lock feature BOOTLOCK
$FF O Set $FF O 0|1 Disable (0) / enable (1) overcurrent check OVERCURRENT_THRESHOLD
$FF P Set $FF P 0|1 Disable (0) / enable (1) PP auto-ampacity detection PP_AUTO_AMPACITY
$FF Z Set $FF Z 0|1 Disable (0) / enable (1) zero-crossing relay switching RELAY_ZC_SWITCH
$FO Set $FO panicthresh Set over-temperature panic threshold in 1/10 °C. E.g. $FO 705 = 70.5 °C. If exceeded, EVSE enters OVER_TEMPERATURE fault. TEMPERATURE_MONITORING
$SR Set $SR n 0|1 Enable (1) or disable (0) relay n (1=DC relay 1, 2=DC relay 2, 3=AC relay). Saved to EEPROM, applied at boot. RELAY_ZC_SWITCH
$GR Get $GR Get relay enable status. Response: $OK dc1 dc2 ac (1=enabled, 0=disabled) Always
$GO Get $GO Changed: now returns single panicthresh instead of ambientthresh irthresh TEMPERATURE_MONITORING
$GI Get $GI Extended: SAMD now returns 32-char hex string; AVR returns 6 ASCII + 8 hex (was 4) MCU_ID_LEN
$GZ Get $GZ Get measured AC line frequency × 100. E.g. 6012 = 60.12 Hz. 0 = not yet measured. RELAY_ZC_SWITCH

Existing Commands — Behavioral Notes

Command Note
$FF R Stuck relay check — unchanged, but now listed alongside new L/O/P/Z sub-commands
$FF T Temperature monitoring — unchanged
$FF V Vent required check — unchanged
$FF D Diode check — unchanged
$FF F GFI self-test — unchanged
$FF G Ground check — unchanged
$SY Heartbeat supervision — minor doc fix ("heartbeat" spelling corrected)
$S1 Set RTC — unchanged, compile guard renamed from RTC to HAVE_RTC
$G1/$GT Get RTC — unchanged, compile guard renamed from RTC to HAVE_RTC

Files Changed

File Change Type
firmware/open_evse/rapi_proc.cpp New commands FC, FO, FF L/O/P/Z, SR, GR, GZ; dtou32dtoi32; serial port abstraction
firmware/open_evse/rapi_proc.h RAPIVER 5.2.1 → 6.0.0; updated command docs; RAPI serial port abstraction
firmware/open_evse/J1772EvseController.h ERELAYF flags; ECF flags; relay/ZC/PP/overcurrent/bootlock methods; GetAcFreqX100(); ResetFaultCounters()
firmware/open_evse/J1772EvseController.cpp ZC detection/timing; per-relay enable enforcement; hasCGMI() rename; SAMD ADC init
firmware/open_evse/open_evse.h Multi-target refactor; RTCHAVE_RTC; ZC timing constants; PP/overcurrent/bootlock flags
firmware/open_evse/main.cpp SAMD support; target init; no-ground delay
firmware/open_evse/AutoCurrentCapacityController.cpp/.h PP auto-ampacity enable flag integration
firmware/open_evse/EnergyMeter.cpp/.h ResetTotkWh() added for $FC
firmware/open_evse/Language_default.h PP_MISSING / PP_SHORTED LCD strings
firmware/targets/m328p/ AVR-specific files relocated here
firmware/CHANGELOG Moved from firmware/open_evse/CHANGELOG
.github/workflows/ Actions updated to Node.js 24; SAMD/v5/v6 build targets added; Arduino build removed
platformio.ini Refactored; RELAY_ZC_SWITCH moved to per-target config
arduino/ Deleted — all Arduino IDE board/programmer/SDK files removed

lincomatic and others added 30 commits February 3, 2026 12:23
…nd RTC year range to 2036

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- build.yml: trigger on linco-work branch, reference @linco-work workflows
- build_platformio.yml: replace old environments with m328p_v5, m328p_v6,
  m328p_v5_RTC_BTN_LCD, m328p_v6_RTC_BTN_LCD, samd; add SAMD .bin handling
- release.yml: include *.bin artifacts alongside *.hex for SAMD releases

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
chris1howell and others added 29 commits May 24, 2026 20:19
actions/cache v2 -> v4, actions/checkout v2 -> v4, actions/setup-python v2 -> v5

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…o-work

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
checkout v4->v5, cache v4->v5, setup-python v5->v6,
upload-artifact v4->v6, download-artifact v4->v7.
Remove FORCE_JAVASCRIPT_ACTIONS_TO_NODE24 workaround.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Raise ADC6 CGMI detection threshold from 512 to 1000; CGMI boards
  pull A6 to VCC via 330 ohm (~1023), floating pin on non-CGMI boards
  was falsely triggering above 512
- Move pinChargingAC.write(1) outside OEV6 if/else in chargingOn() so
  PB1 (AC relay) is driven HIGH for V6 boards, matching master behavior
- Update platformio.ini and prepare-release.sh for unified autodetect envs

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replace separate m328p_v5/v6 matrix entries with m328p_autodetect
and m328p_RTC_BTN_LCD to match consolidated platformio.ini envs.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…loader upload

- Copy uf2-samdx1 bootloader source into repo (SAMD21/OpenEVSE_NXT board)
- Add PlatformIO pre-build extra_script (build_bootloader.py) that compiles the
  bootloader using PlatformIO's own arm-none-eabi toolchain (no make required),
  copies the .bin to the PlatformIO build dir, and converts firmware.bin to .uf2
- Add post-upload extra_script (upload_bootloader.py) for env:samd_ice that
  flashes the bootloader to 0x0 via Atmel-ICE after the firmware upload
- Update GitHub Actions: fix renamed m328p env names, upload firmware.uf2 and
  bootloader-*.bin as artifacts, add *.uf2 to release assets
- Fix env names throughout: m328p_autodetect -> m328p_TFT_WIFI,
  m328p_RTC_BTN_LCD -> m328p_noWiFi_RTC_BTN_LCD

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Switch convert_firmware_to_uf2 post-action from .bin to .elf target:
  SCons does not track .bin as a build node so AddPostAction on it never fired
- Generate .bin via objcopy in the callback if the platform hasn't created it yet
- Add if-no-files-found: warn to SAMD artifact upload so missing files are
  reported rather than silently dropped

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Change VID from 0x1B4F (SparkFun) to 0x04D8 (Microchip)
Change PID from 0x0D22 to 0xE437

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…y measurement

- Add RELAY_ZC_SWITCH feature: close relay at voltage ZC (CGMI hardware),
  open relay at voltage ZC (all hardware with valid AC signal)
- Add waitCurrentZero(): block until ammeter drops below 100 mA before
  opening relay; called from chargingOff() non-emergency path (#ifdef AMMETER)
- Add measureAcFreq(): three-path implementation —
    SAMD: ADC sign-change on GMI_LINE (PA09)
    m328p CGMI: midpoint of pinAC2 HIGH off-period pulses
    m328p non-CGMI: alternating rising edges on pinAC1/pinAC2 half-wave
      channels; diode threshold offset cancels in the interval measurement
- GFI trip calls chargingOff(1) — emergency flag bypasses ZC wait and
  waitCurrentZero() for minimum-latency fault response
- Add $FF Z RAPI command to enable/disable ZC relay switching (persisted)
- Add $GZ RAPI command to read measured AC frequency × 100
- Non-CGMI boards: frequency updated on relay open only (AC pins are
  load-side on older non-V6 boards; no valid signal at relay close)
- Enable RELAY_ZC_SWITCH in common platformio.ini build flags

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Removes RELAY_ZC_SWITCH from the shared EU common flags in the root
platformio.ini and adds it explicitly to the m328p and samd target
configs, keeping target-specific features out of the common section.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Allows individual DC1, DC2, and AC relay outputs to be enabled or
disabled at runtime via new $SR and $GR RAPI commands. Settings are
persisted to EEPROM (offset 39) and applied on boot.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
When PP_AUTO_AMPACITY is compiled in but the ECF_PP_AUTO_AMPACITY EEPROM
flag is not set (default), the ACCController is disabled and ppMaxAmps
is never initialized — it stays 0 from global zero-init.
GetMaxCurrentCapacity() was reading this stale zero via GetPPMaxAmps()
without checking IsEnabled(), causing ampacity to clamp to
MIN_CURRENT_CAPACITY_J1772 (6A) during STATE_B/C.

Any nosave=1 SetCurrentCapacity call (e.g. heartbeat supervision
fallback) would then cap the pilot to 6A instead of the intended value.

Fix: guard the PP cache read with g_ACCController.IsEnabled().

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- platformio.ini: m328p_noWiFi extends env:m328p_TFT_WIFI (stale after
  rename); update to extends env:m328p_core
- prepare-release.sh: SAMD copy path was .pio/build/samd_us/ (old name);
  correct to .pio/build/samd/
- build_platformio.yml: m328p_noWiFi matrix entry missing python: 3.x;
  add to match other AVR entries and avoid empty version in setup-python

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants