Skip to content

Firmware Changelog

Every firmware version that has been released to regulators in the field, newest first. Each entry summarizes what changed since the previous release; open Full detail for the specifics.

Your regulator updates itself over WiFi — new versions appear in the app under Cloud Features → Software Update. If you would rather update over a USB cable, or need to recover a unit, see Updating Firmware over USB.


0.0.7

Released October 19, 2026. Changes since 0.0.6.

Systems at 24, 36, or 48 V can now record the field winding voltage from the alternator's datasheet, and the regulator sizes its field settings to match instead of assuming a 12 V winding; the setting starts at 12 V, which keeps existing field settings as they were. With the tachometer plausibility check on, one bad tachometer reading while charging no longer shuts the field off. A system voltage change cut short by a restart or power loss is now finished at the next start, so overvoltage protection is no longer left set for the old voltage. If a firmware update fails, the alternator on/off switch in the app goes back to its setting from before the update instead of staying off.

Full detail

Charging and control

  • New Vessel Info setting, Field Winding Voltage (FieldWindingV): 12, 24, 36, or 48 V, never above Nominal Battery Voltage. It defaults to 12 V, which matches how 0.0.6 scaled every field setting.
  • Field-duty settings, duty rates and thresholds, and current-loop gains now scale by the winding rating over the system voltage (field scale, fieldScale()) instead of 12 over the system voltage.
  • Changing the winding rescales the stored field-duty settings by new over old winding: Min Field, Duty Ramp Rate, Manual Field PWM, the keep-alive and alternator-health duty settings, and the Run Without Failed Sensors duty cap.
  • A winding change sets Max Field Volts to 1.25 times the new rating (15, 30, 45, or 60 V). That is also the new default, and a corrupt stored value now resets to it instead of a flat 15 V.
  • A winding change also resets the tachometer keep-alive floors to the 0.25% default, clears learned oscillation-damper speed ranges, and raises the re-commission notice on a commissioned unit.
  • A current-loop gain measured in commissioning (current-loop plant fit) keeps its applied value across a winding change: the stored PID Kp, Ki, and Kd move by old over new winding. Default gains follow the winding.
  • Resistance check (fieldWindingImplausible): a 24, 36, or 48 V winding with Field Resistance under 2.4, 3.6, or 4.8 ohm would draw more than the board's 10 A at its rating, so field settings stay on 12 V winding values until the owner confirms.
  • The confirmation is stored for that exact winding and resistance pair (fieldWindAck). Changing the winding or entering a new Field Resistance runs the check again.
  • A system voltage change clamps a winding rated above the new voltage down to it. The field-duty settings then move once by the combined factor, so a winding that moves with the system voltage leaves them unchanged.
  • On a system voltage change, Manual Field PWM, Detection Amplitude, and the Plant Delay Test wave amplitude now rescale with the other field-duty settings; before, they kept their old values.
  • Rescaled field-duty settings are stored to 4 decimals (most were stored to 1 or 2), so a 12 → 48 → 12 V round trip lands back on the original values.
  • The oscillation damper's detection bar (Detection Amplitude, HuntTrigPct) is now scaled for the system voltage and winding when first created and rescaled on a change. It is stored and shown to three decimals.
  • Manual Field PWM and the Plant Delay Test wave amplitude are created at their 12 V defaults times the field scale.
  • The over-voltage shed gain (KHard, amps per volt of excess) is battery-side and follows the system voltage only, never the winding.
  • Voltage-only regulation under Run Without Failed Sensors (tier 2) scales its duty rate by the field scale, and so do the commissioning rest hold (4% floor, 5%/s ramp at a field scale of 1) and the alternator current zero measurement's ramp.

Protection

  • System voltage changes and winding rescales are now saved as one journaled set (NK_rescaleJournal) and finished at boot if a reboot cuts them short. Before, an interrupted 48 → 12 V change could leave about 58 V overvoltage trips on a 12 V bank.
  • A change finished at boot also resets the keep-alive floors, clears learned damper speed ranges, raises the re-commission notice, and logs a console line.
  • Low-RPM cut (Min RPM For Field) on a field that is on now acts on the second consecutive tach reading below the minimum: about 40 ms after the first, up to about 80 ms, and at most 160 ms if no second reading arrives.
  • A field that is already off stays off from the first low reading.
  • While the tach plausibility cut (Tach Plausibility Cut) is armed, the value held after a near-zero glitch (lone-jump rejection) does not count as that second reading, so one glitch at cruising speed leaves a charging field on. The bound there is 240 ms.
  • Spin-down cut (charging off, RPM below the minimum) also acts on the second consecutive low reading, bound 160 ms. It replaces a 75 ms wait that a false reading at or above the minimum could reset, so nothing cut.
  • Stopped-engine cut now needs a second zero reading during its 200 ms hold, or 300 ms with no second reading, so one bad reading cannot cut the field across a long gap between readings.
  • The tach plausibility count no longer restarts on a lone reading below Min RPM For Field, so a false reading that dips below the minimum now and then is still cut.
  • After a stop, the restart confirmation now needs the tach above zero as well as at or above Min RPM For Field for 2 s.
  • Min RPM For Field is clamped to 0 or more when set, at boot, and on import. At 0 only the below-minimum cuts are off; the stopped-engine cut still turns the field off.
  • Load dump detection (Group 5) now counts every battery-current reading (INA228, about every 6 ms) in the sensor read path, so "consecutive" means adjacent readings. Before, it checked only the latest reading at each control update.
  • A load dump trip that lands between control updates is held and acted on at the next one, and the console message reports the peak rate among those readings.

Commissioning and tests

  • The Field curve step scales its duty steps by the field scale (start 5%, step 2%, onset fine step 0.25% at 12 V), so a 12 V winding on 48 V steps 0.5% at a time instead of 2%. It records up to 192 points (was 48).
  • A field curve stopped by the point limit before its current target or field ceiling now says so in the console.
  • Field cut, protection test, and charge health calibration start from at least 1% times the field scale (was a flat 1%). The Plant Delay Test's settling adjustment and its 5% floor scale the same way.
  • The voltage control autotuning check for two field levels that came out nearly identical uses 1.5% times the field scale (was 1.5%). The field curve's proposed test step is floored at 1% times the field scale.
  • The commissioning current-loop gain fit stores its result divided by the field scale, so the gain applied to the field equals the measurement on any winding.
  • Charge health calibration no longer offers Approve and finish, or stores its result, when its two closest cycle answers disagree by more than the allowed spread (CHC_PAIR_DISAGREE).
  • The charge health calibration's under-target abort margin now scales with system voltage: 0.02 V at 12 V, 0.08 V at 48 V.
  • The Tachometer Calibration screen now asks for Alternator Enable off before the engine is started, since a scaling-factor change needs the field off.

Sensors and inputs

  • Field Resistance is now rounded to the three decimals it is stored at and shown to three decimals (was two on screen), so a confirmed winding still matches after a reboot.

Dashboard and app

  • Field Control's two buttons now read Manual and Auto (was PID). Console lines, test refusals, and help text say Auto mode and Manual mode throughout, and tests that need it say "only allowed while charging in Auto mode".
  • CV Gain Source now reads Measured or Manual (was Auto or Manual) on the toggle, its echo, the Active gains line, and the help text.
  • Vessel Info has a Field Winding Voltage selector under Nominal Battery Voltage; ratings above the chosen system voltage are disabled.
  • While the resistance check holds the field settings, Vessel Info shows why and offers Answer now. The question's buttons are Keep, Use 12 V winding, and Decide later, with the keyboard default on Decide later.
  • An answer from a stale question (another window, or the winding or resistance changed since it was asked) is refused with a message.
  • The Vessel Info save dialog lists each field-duty setting, Max Field Volts, and current-loop gain change before saving, and says when the alternator health history will be erased.
  • The same dialog now gives the keep-alive reset value as 0.25% (it said 1%).
  • The limiter explanation panel now tells apart Max Field Volts holding the field, Max Field (%) set below 99, and a true full field. Where Max Field Volts limits, the remedy points to Field Winding Voltage first.
  • The Manual mode and Run Without Failed Sensors warnings name the winding and give the real multiple (4× for a 12 V winding at 48 V), and do not appear for a winding rated for the system voltage.
  • PID Kp, Ki, and Kd help explains the field normalization. The Min Field input step and the field sweeper's rate and floor boxes follow the field scale.
  • Dragging on the four live plots no longer zooms; the Y axis range is set by clicking its top or bottom number.
  • The Plots tab mode ribbon legend lists only modes visible in the window, and the long-term charge-stage ribbon now draws stage code 8, which it skipped.
  • The boat performance gauge's speed label now matches the selected speed source (STW or SOG) in both views.
  • Oscillation damper: the "Not the regulator" verdict now reads "wobble persisted at reduced gain" (was "full gain restored"), and the status line shows when the voltage damper is off or reduced at the present speed.
  • The state-of-charge seed explanation shows the system-voltage factor in its resistance equation on 24, 36, and 48 V systems.
  • The voltage-tuning log now marks rows where the voltage loop fired (the flag was cleared before the row was written). Both control logs record 0 instead of the off-time on the first voltage-loop step after the loop has not run.
  • Timing in help text now gives measured figures: alternator current about every 13 ms, battery readings about every 6 ms, engine speed about every 40 ms, and the voltage loop integral about every 105 ms at the 100 ms default.
  • Load dump "time to act" labels now read about N × 6 to N × 6 + 13 ms, up to N × 18 + 30 ms (was N × 5 ms). The sine sweep end limit now reads about 25 Hz, and log lengths are corrected.
  • Help text corrections: Load Dump catches a large load dropping off the bus (a battery disconnect is caught by the over-voltage protections), and Voltage Float returns to Bulk on the rebulk criteria or when Float Duration runs out.
  • The BMS on/off and switch panel input help gives 5 to 62 V (was 5 to 28 V) and places the BMS wire on Cable 2, pin 16 (was Cable 1).
  • Other help text: the keep-alive floor's purpose, solar ratio learning by the hour, the settings password reset, fuel totals under Live Data, Boat, Lifetime Statistics, and "health matrix" in place of "health record book".
  • The tachometer rescale warning lists commissioning steps 2 to 8 as the ones to run again (was "every commissioning step").

Settings import and export

  • Exports carry Field Winding Voltage and the winding the field-duty values are scaled for (fieldWindApplied). An import converts every field-duty value onto that scale, written or not, and boot moves them onto this regulator's own winding.
  • The owner's resistance-check confirmation and the alternator-health winding record are export-only. An invalid winding value in a file is skipped with a console warning.
  • The import preview warns when the file's winding differs and that applying it erases the alternator health history. Picking a field-duty or current-loop gain row also picks the winding-scale row.
  • An import that changes the winding logs a console warning, and a negative Min RPM For Field in a file imports as 0.

Cloud and updates

  • If a firmware update does not install, Alternator Enable goes back to its setting before the update instead of staying off, with a console line. The update dialog now says so.
  • When the winding the field settings run on changes, the alternator health record (My History, the engine-hours trend, and session stats) is cleared on the regulator and in the cloud.
  • Alternator health records field drive (excitation) in 12 V-winding-equivalent volts, so the cloud reference compares windings on one scale. Nothing changes for a 12 V winding.
  • Delete My Account and the cloud sign-up text now state that a record of which firmware versions this regulator has installed, and when, is kept under its serial number for safety recalls and support.

NMEA 2000 and other networks

  • Water depth debug printing now runs only with NMEA 2000 verbose output on.

Internal

  • Settings telemetry adds Field Winding Voltage and the applied winding, and sends Field Resistance and Detection Amplitude ×1000 (was ×100). Vessel Info data includes field_winding_v.
  • The normal field mode is now named MODE_NORMAL_AUTO (was MODE_NORMAL_AUTO_PID), and the console line for a Field Control change names Auto mode (it said PID).
  • Console spelling fixes, including "Max Alternator Temp".

0.0.6

Released October 13, 2026. Changes since 0.0.5.

After this update the regulator will not charge until the alternator's field resistance has been measured with a new engine-off test in the dashboard; a 12-volt system with no battery shunt may skip it. Charging also needs a battery temperature reading, so a boat without a battery temperature sensor must set the source to Not fitted. A sensor that stops reading now stops charging and is named on the dashboard, and a new screen replaces the old emergency overrides so you can charge without a failed sensor, one sensor at a time. The regulator also eases off the alternator when its own drive circuit nears its current or heat rating, and adds an alarm silence button, an optional settings password, and support for Victron and NMEA 2000 battery monitors.

Full detail

Upgrading from 0.0.5

  • The field stays off until Field Resistance is measured. A value stored by 0.0.5 has no recorded alternator temperature, so it counts as never entered (FieldResistance now starts as NAN).
  • Measure it under Setup > Alternator > Basic > Output Control > Field Resistance > Measure, or in commissioning. A 12 V system with no battery shunt may skip the test and use 2 Ω (FieldResDefault).
  • A battery temperature is required unless the source is Not fitted (battTempSource 6). With Automatic and nothing reporting, the field is held off for 90 s, then charging stops (REASON_BATT_TEMP_WAIT, REASON_BATT_TEMP_LOST).
  • The regulator board no longer stands in for battery temperature. A stored Board source (5) loads as Automatic, and the board-temperature switch (battTempProxyEnable) and Regulator Location (regulatorMountLoc) are removed.
  • Battery Current Source (BatteryCurrentSource) is retired and its value is not carried over. To use a network battery monitor, turn on Use as Battery Monitor under Setup > Integrations (BattMonSrc).
  • If the voltage loop was commissioned without a measured battery temperature, the battery-temperature gain derate stays off until Voltage Control Autotuning is re-run (CommissionTempSrc 0 or 5).
  • Two alternator-health learning gate settings are rewritten on first boot: altRpmLineRms 12 to 48 and altThermSec 40 to 20 s (settings schema 3 to 4).

Charging and control

  • Charge stage changes (bulk, absorption, float, rebulk) can follow an external battery voltage from NMEA 2000 or Victron VE.Direct (BatteryVoltageSource). Control loops and protections stay on the onboard sensor (INA228).
  • A stale external charge-decision voltage falls back to the onboard sensor, with a console message when it drops out and when it returns (getChargeDecisionVoltage()).
  • Without a regulator shunt, a network battery monitor's current now ends absorption on tail current and triggers the current rebulk (stageBattCurrentA()). A stale reading makes the stage wait.
  • A state of charge frozen at an old value no longer blocks rebulk (socDecisionOk()).
  • The final shutdown ramp is now a proportional decay: each second the field drops by a share of what is left (Shutdown Ramp Time, ShutdownRampTauS, default 4 s, range 0 to 60 s).
  • Shutdown Slow Ramp Rate is renamed Shutdown Final Ramp Rate and is now the slowest the ramp may go (DutySlowRampRate).
  • If output stays above No-Output Current for 0.3 s during the ramp, the field sheds at Duty Ramp Rate (NoOutputAmps, default 2 A, range 0.1 to 50 A). It also replaces the fixed tachometer plausibility threshold.
  • Shunt Location (ShuntLead): with the shunt in the negative lead, the shunt's own voltage drop is removed from the battery voltage reading.
  • With the battery shunt reading stale, the battery charge current limit caps alternator current directly at BattCurrentLimitA.
  • The Max Field Volts ceiling's 2 s voltage filter now runs on its own time step. It had been settling in tens of milliseconds.

Protection

  • Board field-current limit: field duty is capped where field current would reach 10 A, the rating of the board's field drive (10 A field-current ceiling, limiter code 15).
  • The 10 A limit is estimated from Field Resistance corrected for alternator temperature, with a 12 % margin (fdRcOhm, FD_MARGIN).
  • Drive heat limit: field duty is capped to keep the field connector (105 °C) or the freewheel diode's heat spreader (120 °C) in rating, from the INA228 chip temperature (field-drive heat ceiling, limiter code 16).
  • Field Wiring (FieldWiring: P-type, N-type, or Not set) chooses which part the heat limit protects. Not set checks both.
  • Both board limits override every duty floor, including Min Field and the per-RPM floors, and they also hold Manual mode down (boardDutyCeiling()).
  • Alternator health alerts are judged against the alternator-side ceiling only, so a hot regulator holding the field down does not read as a weak alternator (altFieldCeiling()).
  • New field cuts for lost sensors: main battery voltage stale (immediate cut), second battery voltage stale, and regulator drive temperature missing for 10 s, which applies in every mode including Manual.
  • Two or more required sensors failing at once cuts the field (REASON_MULTI_SENSOR_FAULT).
  • Cold- and hot-charge lockouts now hold while the battery temperature is missing. They clear on a real reading past the hysteresis, when set to Not fitted, or when turned off.
  • Hardware overvoltage protection is re-armed after the INA228 chip resets or reconnects. Its threshold is read back every 30 s and re-applied if it does not match.
  • The INA228 overvoltage latch, hard overcurrent, fast overvoltage, and timed overvoltage tiers now take priority over a switch-off, so a BMS dropping its enable line during a spike still gets the fast response.
  • Hard overcurrent trips only on a fresh alternator current sample, so a dead sensor's last value cannot hold it.
  • The shutdown ramp now runs on every control pass. A current sensor failing mid-ramp had left the field frozen at its last duty.
  • Current-sensor stale and alternator critical temperature now outrank the battery-temperature lockout ramps.
  • With engine speed ignored, the thermal derate uses the fixed current limit. The RPM table's 0 A first row had clamped it to nothing.
  • Temperature control interval is clamped to 500 to 60000 ms (TempPIDIntervalMs). MinChargeTempF is clamped to -40 to 120 °F and MaxChargeTempF to 32 to 200 °F.

Running without a failed sensor

  • Emergency Overrides is replaced by Run Without Failed Sensors (Setup > System). Each sensor can be ignored on its own, and the screen lists the protection that removes before Apply is enabled.
  • Sensors that can be ignored: alternator temperature, engine speed, alternator current, main battery voltage, and second battery voltage (IgnoreTemperature, IgnoreRPM, IgnoreAltCurrent, IgnoreBattVMain, IgnoreBattV2).
  • A missing battery temperature is handled by setting its source to Not fitted.
  • The result is a reduced-control tier (g_limpTier): normal control, voltage-only regulation without alternator current, fixed duty capped by the second voltage reading, or fixed duty.
  • Fixed duty (LimpHome) uses Limp Duty (LimpDutyPct, default 30 % at 12 V, scaled by system voltage). It still respects the switch, ignition, and BMS inputs, which the old Limp Home bypassed.
  • Ignoring engine speed requires a fixed alternator current limit (NoRpmCurrentA). Before, the RPM table's first row set the limit, and its default is 0 A.
  • Commissioning and the field resistance test refuse to run while any sensor is ignored, and system identification while engine speed or alternator current is.

Sensors and inputs

  • Field Resistance Test, engine off: by battery shunt (field switched on and off at four levels, median of three cycles, about a minute) or by the owner's clamp meter or multimeter.
  • The test result is stored with the alternator temperature it was measured at (FieldResTrefC, 30 °C assumed with no probe).
  • A typed Field Resistance must be 0.05 to 100 Ω and is entered together with its alternator temperature.
  • INA228 and ADS1115 readings are kept only when the read succeeds (commit-on-valid). A failed read holds the last good value and marks it stale.
  • The INA228 is re-initialized when it answers after a disconnect, and the ADS1115 is retried every 30 s. A disconnected ADS1115 no longer stops the board pressure and temperature sensor.
  • Alternator current: the negative range limit is now 40, 60, or 100 A for the 100, 150, and 250 A scales, so an unplugged sensor no longer reads as -249 A. Out-of-range values are not published.
  • Alternator temperature probe (DS18B20): a missing probe is no longer replaced by another probe on the bus, and an all-zero read no longer shows as 32 °F.
  • The unplugged-probe warning now fires, and the temperature task alarm no longer stays latched after recovery.
  • The thermistor input holds its last valid value instead of writing -99. A failed INA228 chip temperature read now counts as missing instead of 0 °C.
  • Ignition input: off is taken at once and on must hold 1 s, so a flickering feed no longer restarts the charge cycle in bulk.
  • The VE.Direct state of charge is read (VictronSoc). Its presence marks the device as a battery monitor (BMV, SmartShunt) rather than a solar charger.
  • A Victron monitor's current no longer feeds the regulator's own state-of-charge count or any control loop.

Alarms

  • Silence Alarm button (SilenceAlarm), which works while settings are locked: it mutes the conditions sounding now, and a new condition sounds again. Alarm status shows Silenced (Alarm_Status 2).
  • The silence clears after 10 s with nothing sounding, or when alarms are turned off.
  • Alarm on General Fault Condition (GeneralFaultAlarm, default on): sounds for a required sensor or chip that stops reading, a stalled temperature task, and the INA228 hardware overvoltage trip.
  • New alarms: required-sensor fault, battery temperature lost, and battery current lost for 10 s. Battery current lost is an alarm only; charging continues on voltage.
  • Alternator high and low temperature alarms ignore a held reading from a dead probe. The temperature-sensor stale alarm no longer fires with the engine off.
  • High alternator and battery current alarms ignore stale or ignored readings. The low state-of-charge alarm works with a network battery monitor.

NMEA 2000 and other networks

  • Received NMEA 2000 values must fall in a plausible range (n2kIn()). Reserved codes had decoded as real numbers, such as a battery temperature near 720 °F.
  • Use as Battery Monitor, for NMEA 2000 or VE.Direct (BattMonSrc 1 or 3): that monitor's state of charge becomes the one shown and used. Only one source can be on.
  • Stale or ignored readings are sent as not available instead of their last value: battery and alternator voltage and current, engine speed, and alternator temperature, on NMEA 2000 and RV-C.
  • DC Status state of charge is sent from a VE.Direct monitor too. An NMEA 2000 monitor's own state of charge is never echoed back onto the bus.
  • The Engine Dynamic charge indicator uses the shared fault classification (fieldReasonIsFault()), so the new sensor faults set it.
  • RV-C: new fault codes for battery temperature lost, voltage stale, drive temperature lost, and multiple sensor faults. The drive heat limit reports as high internal temperature derating.

Settings password and multiple regulators

  • Optional settings password, 4 to 32 characters (Setup > System > Settings Password). Settings opened with it stay open only on the phone or browser that typed it, and only a salted hash is stored.
  • Five wrong passwords refuse every attempt for the next 60 s. Grounding pin 11 at boot clears the password along with the WiFi credentials.
  • Live readings, switching the alternator off, and Silence Alarm never need the password. Passwords and session tokens are kept out of the console log.
  • Regulators on This Boat (Setup > System): pair up to 8 units. The pairing is stored on both units, and Remove clears both.
  • alternator.local asks which regulator is yours when more than one is on the network, and the browser remembers the answer. Paired units are listed first.
  • Switch Regulator lists the units this regulator already hears through a new discovery service (_xreg._tcp, browsed every 30 s). The full network search runs on request or when none are heard.

Commissioning and setup

  • Prerequisites now asks for Field Wiring and, with a shunt installed, Shunt Location, and offers the charge-decision voltage source. A failed settings read stops there with Retry.
  • A Field Resistance step follows Prerequisites. Commissioning also waits until a battery temperature is found or Not fitted on this boat is chosen.
  • Start needs ignition on, the field switched on, and every required sensor reading, as well as engine speed. Test buttons explain when ignition or Alternator Enable is off.
  • Steps advance only after the regulator confirms. Refused writes (settings locked, a different regulator answering) and failed stop or cancel commands are reported.
  • The plant sweep aborts if a field ceiling clips the test wave (abort reason 253), because a clipped wave would propose gains that are too high.
  • Field-curve points are recorded at the duty the regulator applied, which removes a false knee at the capped last step. Messages name the limit that capped a test.
  • The ripple map game places targets at idle, the next two 50 RPM steps, and every 200 RPM to 2000. More appear where ripple peaks or changes quickly.
  • Keep-Alive floor Apply also stores the maximum working RPM used by Charge Health Calibration.
  • Charge Health Calibration discards cycles where a field ceiling moved the frozen field. It aborts when no fresh battery voltage is available.
  • Stress test fixes show the exact before and after values. Softening the loop under the Measured gain source raises CvKdTd so damping stays the same.
  • The stress test counts a re-trip within 300 ms as one overvoltage event (CVS_EVENT_MERGE_MS).
  • Autotune abort reasons were labeled one place off; the table is corrected.
  • The battery defaults recommender proposes the temperature-based settings only when a battery temperature is measured.

Dashboard and app

  • A header banner names a failed sensor with Options, Set to Not fitted, and Silence buttons. It also says when an ignored sensor has read normally for 10 minutes.
  • Header badges read 10 A FIELD or DRIVE HEAT when a board limit holds the field, and NO FIELD Ω when Field Resistance is missing.
  • The why panel shows Alternator = Battery + House and lists every current ceiling, with the binding one marked Limiting.
  • New readouts: the two board field ceilings under Output Control, time held at each (lifetime and session), Victron State of Charge, and four sensor-loss event counters.
  • Field Amps is estimated from the measured Field Resistance, corrected for alternator temperature, and stays blank until a resistance is entered.
  • Field-off reasons for no output, sustained overvoltage, and the new sensor faults show as FAULT in red.
  • Readings now gray out after a data stall.
  • Motorboats (Trawler, Powerboat, Other) see only the motoring performance view. Sailing time, distance, and VMG records count only on a Monohull or Catamaran.
  • Ignition Override now reads On/Off and is described as the choice for boats with no ignition wire. Turning it on with engine speed ignored asks for confirmation.
  • Setup popups no longer darken the page, so the header stays usable, and in a browser any popup can be dragged by its title bar.
  • State of charge shows with a network battery monitor even without a shunt.
  • Battery internal resistance is normalized to 25 °C only with a measured battery temperature. Stored results are migrated and their old board temperature column is blanked.

Cloud, weather, and updates

  • Solar forecast learning works by the hour and counts only hours when the solar charger was tracking freely. A battery that is full by noon no longer reads as weak panels.
  • Weather fetches add a 3-day hourly solar radiation forecast. The solar ledger export moves to v2 with qualifying-hour columns.
  • A failed daily settings upload is retried, starting at 60 s and doubling to a 1 h cap.
  • Readings that are missing upload as empty (null) instead of placeholder numbers. A NaN no longer invalidates the daily upload.
  • Cloud uploads, weather fetches, and update checks wait for the field to be switched off at the hardware. They never run with the field on unless a button asked.
  • A remote settings push that arrives incomplete is no longer applied, and its download buffer grows from 24 KB to 64 KB.
  • A forced-update flag that names an older or equal version is cleared, so a stale Update Now prompt no longer appears.
  • Settings import takes Field Resistance only together with its recorded alternator temperature, and skips values that are not finite numbers.

Statistics and history

  • With engine speed ignored, engine hours and starts stop counting. The fuel curve, ripple map, alternator health learning, and performance learning pause.
  • Sensor history leaves out stale or ignored readings, and engine-on averages divide by each sensor's own time instead of a shared one.
  • Alternator on-time, energy, and fuel are credited only from fresh, trusted readings.
  • State-of-charge counting stops while the shunt reading is stale, and the gap is dropped.
  • The capacity tracker and the boot state-of-charge estimate use battery temperature in place of board temperature.
  • Capsize and pitchpole events are not counted when the IMU install check failed.
  • With the engine stopped for 1 h and the ignition on, sensor history and usage counters are saved once.
  • Alternator health gains an output slope cap (altAmpsSlewPct 1 %/s, altAmpsSlewFloorA 0.15 A/s). The gate capture log records a per-axis verdict and holds 18.2 minutes.
  • The alternator current auto-zero equation is cleared when its history is discarded (ZFIT_VER 1 to 2).

Internal

  • Settings writes and imports refuse values that are not finite numbers and log the refusal (paramOk(), floatTokenValid()). The rest of the request still applies.
  • The live console drains from the 200-line history, so bursts of messages are no longer dropped.
  • Deleting the sensor history backup and saving capsize counters now happen at field-off time.
  • Text sent as JSON escapes control characters, such as those in a regulator name.

0.0.5

Released September 17, 2026. Changes since 0.0.4.

The alternator's off and on control is now two labeled buttons showing what the regulator is doing, and a lost press is sent again instead of dropped. A battery that finished charging with float charging turned off used to leave both that control and Manual mode dead, with nothing on screen to explain it. The dashboard now says the battery is full, switching off and back on starts a new charge cycle, and two cases where the field drive stayed powered after charging stopped are fixed. A new setup step also measures the current sensor's zero with the engine running, removing a fixed error from every current reading.

Full detail

Charging and control

  • Both field limits, Max Field % (MaxDuty) and Max Field Volts (MaxFieldVolts), now apply on every system voltage and in every mode, Manual mode included. The percentage cap was previously skipped in Manual mode on 12 V banks.
  • Neither limit is rescaled when you change system voltage any more. They describe the alternator rather than the bank, and the enforced ceiling is re-derived from Max Field Volts against the measured bus voltage each tick (ccDutyCeiling).
  • On a new install Max Field % seeds at 99% on every bank, and Max Field Volts at 15 V, which works out to roughly 52%, 35%, and 26% duty on 24, 36, and 48 V banks at absorption. Enter the winding's rated voltage from the alternator's datasheet to raise it.
  • The two Setup rows now mark which of the pair is limiting right now, and show what Max Field Volts works out to as a duty against the live bus. The separate read-only Field Ceiling row was removed.
  • A charge cycle that finished with float turned off now reports itself as complete (REASON_CHARGE_COMPLETE_IDLE) instead of as charging simply being disabled.
  • Turning the master switch off and back on restarts the charge cycle from bulk while the battery rests full, and the Restart Charge Cycle button now works in that state too.
  • Manual mode is exempt from the resting-full hold (IDLE stage). A 24 V bank parked there previously left the master switch and Manual mode both dead with nothing on screen to explain it.
  • A stop you or an external authority asked for, whether the master switch, the battery management input, the solar forecast pause, or a finished cycle, now leaves the regulator in its off state instead of registering a fault for a tick.
  • When charging is switched off on a stopped engine, the console and the off-reason banner name what stopped it rather than blaming engine speed.
  • Repeated cut and restart messages back off from one a minute to one every 5 and then 30 minutes per episode. A fixed one-minute heartbeat filled the whole 200-line console history in about 100 minutes of unattended cycling.
  • The cooldown-complete message is held for five seconds and dropped if another cut lands first, so a grinding cycle reports through the heartbeat alone.

Protection

  • The field enable line is now opened after the settle when the battery management input or the solar forecast pause stops charging. Both previously fell through to a default that left the line asserted and the gate driver powered while the dashboard read the field as off.
  • That default is now to open the enable line rather than hold it up, so an unrecognized shutdown reason fails to the safe side.
  • Editing either rung of the over-voltage ladder offers to move the other with it. A software cut typed at or above the hardware backstop used to be clamped back on the device with no explanation on screen.
  • The Over-Voltage Ladder card has a shortcut link from Battery > Safety, and the protections cards are now indexed by the Setup search box. The whole ladder was previously unsearchable by name.
  • The protection cue in the header is quieter: a brown P and brown duty digits in place of a pulsing red word and a red pill. The field is still live when it shows, and the charge stage word is no longer replaced by it.

Sensors and inputs

  • New measured zero for the alternator current sensor, under Setup > Alternator > Measured Zero (Engine Running). Above 400 RPM the regulator holds the field at 0% by itself, waits out the rotor drain, averages for ten seconds, and releases the field. Charging pauses for under a minute.
  • The result is held for you to apply. Apply folds it into the Alternator Current Offset (AlternatorCOffset) as a delta, so a hand-entered offset already in place stays in place. Nothing is written unless you press Apply.
  • A reading noisier than 2 A peak to peak, or larger than 10 A, is refused with the reason named on screen. So is a request made while another test is driving the alternator.
  • The commissioning wizard offers the same measurement at Finish, while the alternator is at its warmest.
  • Applying an offset now shifts the recorded zero-drift log and its fit history by the same amount (zeroHistoryShiftAmps), so the 30-day temperature fit does not straddle the seam.
  • The zero-drift log now stores the absolute sensor zero rather than what was left after the live correction (log version 3). The old form made every fit after the first a fit of its own residual, and the running blend settled the applied correction on half the true offset. Version 1 and 2 logs are discarded on load.
  • New reading of the shunt monitor's own die temperature (inaDieTempF) and its session peak, on the Diagnostics panel and in the daily upload. It is the only sensor sitting at the power stage; the board temperature sensor is bulk and lags it badly.
  • The peak only accepts a value the previous second's reading agrees with, within 15 °F, and only after a warm-up discard. One bad value off the chip cannot lodge itself there permanently.

Alternator health

  • Learning is armed only once the regulator is commissioned and the Charge Health Calibration step has run (altLearnArmed). The status line names which of the two is outstanding.
  • Before this, the wizard's own held-field sweeps, usually on a cold machine, could set best-ever records. A record only ratchets upward, so one early high point capped its cell until Start Over.
  • Start Over now deletes the cloud copy of the history as well (reset-alt-health), retrying every minute until it succeeds. Uploads and sync-back stay suppressed until it lands, because the cloud rebuilds the record book from every raw point it holds and would otherwise hand the cleared one straight back.

Commissioning

  • Charge Health Calibration (step 10) is rebuilt around a fixed schedule. You enter the engine's maximum working RPM once (maxWorkingRpm, 800 to 8,000), and the run works between idle and half that figure: climb at 200 rpm/s, hold at the top, ease back down, four times.
  • The first cycle sizes the field at the top and freezes the duty there, which is the fastest the machine turns all run. The three that follow use that frozen duty and are each fitted on their own; the closest two answers are averaged and the third is set aside.
  • The cycles run back to back on the regulator's clock with no button press between them. A button between cycles pinned the frozen field while nobody was driving the throttle.
  • The wizard draws the schedule as a live chart: a shaded band to keep engine speed inside, a marker that turns amber when you drift outside it, a running in-range percentage, and the trace you drove.
  • The step refuses to start until the maximum working RPM is entered, and checks that figure against live idle. The top has to clear idle by 400 rpm for the passes to have any range.
  • Fault Threshold Autotuning gained a "Move ahead with defaults" button at the top of the step, shown once both halves have a measured fit of their own to recommend from.
  • The voltage-loop plant fit only advises raising engine speed when the alternator came up short of the current the test commanded, rather than every time it suggests a stronger step.
  • The wizard holds the screen awake on browsers without the Wake Lock API by looping a silent video. A phone screen sleeping mid-run no longer aborts a test as a lost connection.

Dashboard and app

  • The Alternator Enable control is two buttons rather than a slider. Each half sends an absolute command, so what the control is painting can never decide what a press sends. The filled half is the regulator's own state, the hollow half prints the action a press would take, and before the first frame neither is filled.
  • That state comes off the fast telemetry frame at about 10 Hz now, the same frame as the field status word. It used to come off the settings echo, which could lag the field by up to 60 seconds.
  • Control writes are retried three times against a 1.6 second timeout, with a second copy sent at 500 ms if the first has not answered. Only a silent failure is retried; any reply from the regulator, refusal included, is final.
  • Each control write carries the sending tab's identity and a press counter. The regulator logs the sender's address, request, and browser for both directions, and refuses an ON that arrives out of order or twice over. An OFF is never refused.
  • Every write names the regulator it is meant for, and a regulator refuses one addressed to another unit with a 409. On a boat where two regulators answer the same address, a page could show one board while its presses landed on the other.
  • If the live stream turns out to come from a different unit than the page connected to, the dashboard offers to move the tab to that unit's own xreg-id.local address.
  • Browsers search the network for the regulator the same way the app does and move the tab to whatever answers. A page opened by address settles onto the unit's own name, which follows it across every address it is given.
  • Switch Regulator works in a browser instead of refusing and telling you to browse to the other unit yourself.
  • Settings stay open for writing until you press Lock Settings, another client locks them, or the regulator reboots. Nothing relocks on a 30 minute timer any more; the unattended relock had stranded a user mid-session and silently refused the next write.
  • Gaps in the plots are judged by the regulator's own frame clock rather than by arrival time. Frames held up by a network retransmit and then delivered in a burst no longer draw a break in traces that are on screen.
  • New Remote Diagnostics switch under Setup > System, on by default and separate from Cloud Features. It gates the app's check for a support log request; nothing is requested unless you have asked for support.
  • The time source choice "Phone only" is now "This device only", since it is whatever device has the app open.
  • Readouts wrap inside their card instead of running past its edge, and a value stays joined to its unit. Buttons wrap at phone width, and the barometer conditions row fits its own columns to the card rather than to the viewport.
  • Contrast work through the dark theme and the wizard dialogs. Dark-mode body text was plain gray at 4.2:1 against a card, and several wizard headings were rendering near 1.3:1.
  • A settings warning that names a control on another tab offers a third button that takes you there.
  • The state-of-charge estimate after a Vessel Info save is polled on a front-loaded ladder started when the save responds, and the waiting box is shown on every save rather than only the first.

NMEA 2000 and other networks

  • A finished charge cycle at rest no longer raises the charge-indicator warning bit on the engine data message, matching how charging-disabled and manual are already treated.
  • The source address this node claimed on the bus is no longer carried in a configuration import, so restoring a configuration onto a second regulator cannot aim both at the same address.
  • The accelerometer's own zero offsets are likewise no longer imported. They are measured from this board's bolted-down attitude and belong to it.
  • A receipt for an administrator configuration push is no longer imported either, so it cannot arrive on a unit that never received the push.

Cloud and updates

  • Per-window telemetry (payload version 6) now carries the battery temperature in use, the extra temperature probe, and VE.Direct panel power and voltage as minimum, maximum, and average. The temperature-margin and WiFi-strength accumulators were dropped.
  • An absent source uploads as absent rather than as zero. A boat with no barometer drew a flat 0 hPa line, one with no alternator temperature probe a 0 °F line, one with no accelerometer a 0 g line, and any window where the engine never ran a 0 V engine-on average.
  • Fixed a counter wrap in the window accumulator that produced a record of 0.00 averages beside real minimums and maximums, once per 71.6 minutes of uptime. The window clock is now 64-bit.
  • Engine speed uploads as a whole number instead of a decimal, matching the column it lands in.
  • New once-a-day block of single figures (configuration payload version 5): the alternator health verdict, the insulation, grease, and brush wear model, protection trip counters, memory and loop stability, the previous session's last-alive snapshot, bus and sensor error counters, the 1-Wire probe census, charge-limit follow health, VE.Direct charger codes and daily yield, the battery temperature source in use, and the die temperature peak.

Internal

  • Every dashboard stream event goes out through one sender (sseSend) that counts frames the network library refused to queue. Queue depth, peak, stall count, longest stall, and dropped frames are summarized on the debug page, and a stall of a second or more prints a console line.
  • The slower stream channels, meaning settings, the five-second telemetry block, timestamps, navigation, console lines, and the health and performance echoes, hold off while a client's send queue is backed up. They carry current state, so the next tick resends and the queue budget goes to the plot frames.
  • The shunt monitor runs in continuous shunt, bus, and temperature mode now, with the temperature conversion time pinned at its 50 µs minimum. The register's own reset value drags the fast-mode cycle to 8.5 ms, past the 5 ms poll, and halves the voltage loop's update rate.
  • The zero-fit history ring is flushed to flash when it is shifted, instead of waiting up to a day for the next accepted daily fit.
  • Turning the master switch off now marks the settings echo dirty, so a second browser or the cloud snapshot sees it immediately rather than at the 60 second fallback.
  • The cloud payload buffer grew from 4 to 6 kB for the larger window record, and the capture buffer for the charge health run from 150 to 260 seconds.

0.0.4

Released September 14, 2026. Changes since 0.0.3.

The regulator now measures battery temperature directly, from a probe at the bank or from a battery monitor on the boat's network, and can stop charging when the battery is too cold or too hot. Over-voltage protection gained two timed steps: voltage held above the charge target for a set time shuts the alternator down, well before a battery's own protection circuit would disconnect. Tapping a reading at the top of the screen names what is limiting charging and where that setting is changed. Two regulators can share one boat without answering to the same network name, missing instruments show a dash instead of a fabricated zero, and the solar forecast learns what your panels really deliver.

Full detail

Charging and control

  • Field ceiling can be set in volts (MaxFieldVolts), the unit an alternator datasheet uses. The enforced ceiling (ccDutyCeiling) is the lower of Max Field % and this volts term, re-solved against the measured bus every control tick.
  • The switch panel wires on data Cable 3 are read: pin 5 asks for the High charge rate, pin 7 asks for Maintain Mode. A new Physical Panel Override setting (PhysicalPanelOverride) decides whether the panel or the app owns those two modes; the app's own choice is kept either way (HiLowUserSel, MaintainModeUserSel) and returns when the override goes off.
  • Both panel wires are read, debounced, and reported live whether or not they have authority, so wiring can be proved before it is given control.
  • Voltage float no longer requires a battery shunt. Only zero-current float and Maintain Mode are gated on it; absorption ends on its time limit and the voltage loop then holds the float voltage.
  • The per-speed minimum field column is renamed Keep-Alive, and an unmeasured speed bin carries a 0.25% baseline (KNEE_BASELINE_PCT) instead of zero. An all-zero column used to make the Min Field % setting inert at every engine speed with nothing said.
  • Manual mode is open loop all the way down: the tachometer keep-alive floor no longer holds duty up. The Max Field ceiling still bounds it.
  • The Low charge-rate default fell from half the Normal table to a third (LOW_MODE_CAP_FRACTION).
  • One function applies every charge-rate change (applyChargeRateMode), so the app toggle, the panel switch, and a commissioning revert all get the same table swap and the same High-to-Low ceiling glide.
  • The header limit banner gained five reasons: Manual mode, the keep-alive floor holding output up, a deliberate zero-current command, the warm-up ramp, and the High-to-Low glide. The priority order was corrected so a thermal or battery derate can no longer hide behind the floor.
  • The voltage-loop gain temperature correction follows the selected battery temperature source, and goes inert (cvTempDerateInert) when that source class differs from the one commissioning recorded, until the voltage fit is re-run.
  • Editing the anti-windup tracking gain (PIDTrackingGain) now takes effect at once instead of at the next entry into Auto mode.
  • Saving both charge-rate tables writes one block per control-loop pass (capBothPersistService) instead of five inside the web request, which used to freeze the dashboard stream. A status endpoint reports when the write has landed.
  • The oscillation damper's detection bar is a setting (HuntTrigPct, default 0.5% field-duty swing) rather than a fixed constant.
  • Default tachometer scaling changed from 1330 to 1470 (RPMScalingFactor).

Protection

  • Two timed over-voltage cut tiers (OvTierLoMarginV/OvTierLoDwellMs, OvTierMidMarginV/OvTierMidDwellMs). Holding above the charge target by a tier's margin for its whole dwell cuts the field; any dip under the line restarts the clock, and a dwell of 0 disables that tier. Both use the escalating fast over-voltage lockout ladder.
  • The hardware shutdown voltage (VoltageHardwareLimit, the shunt monitor's own comparator) is a persisted user setting instead of a chemistry-derived value. The software cut (AlternatorHardShutdownV) is clamped below it on every write, and an inverted pair inherited from an older release is repaired at boot.
  • Hot-charge lockout (hotChargeLockoutEnable, MaxChargeTempF), the mirror of the cold one. It acts only on a measured battery temperature, never the board stand-in, and re-arms 2 °F below the ceiling.
  • Cold-charge lockout reads the battery temperature source chain rather than board temperature alone, and its console line names the source it used.
  • Load-dump tiers gained per-tier consecutive-sample counts (LoadDumpN1, LoadDumpN2, LoadDumpN3), clamped at boot as well as in the handler so an imported zero cannot latch the detector on permanently.
  • Battery charge current limit range raised to 2000 A, and the over-current trip-line ranges to 200 A ceiling and 150 A base, for large banks and large alternators.
  • A BMS withholding charge permission is now its own field-off reason (REASON_BMS_DISABLED) instead of the generic "charging disabled".
  • Stored ripple and voltage-slope fits are discarded automatically when a setting that defines them changes (ripFitForget): the averaging time constant, the capture window, the voltage filter, or a tachometer rescale. A stale fit used to draw a live false alarm on the protections plot.
  • Hard over-current debounce default raised from 20 ms to 40 ms.
  • Both timed tiers keep a rising-edge trip count, session and lifetime, on the diagnostics panel.
  • Turning protections off for tuning now names the timed tiers among what it bypasses. The absolute cuts, load dump, and the hardware trips stay live either way.
  • The load-dump panel prints the time each consecutive-sample count works out to, next to the count itself.
  • The protections page was reorganized. Every over-voltage rung sits in one Over-Voltage Ladder card under Detection, and the battery-safety card keeps the sensor cross-checks and the shutdown timing.

Sensors and inputs

  • Up to six temperature probes on the one-wire bus (OW_MAX_PROBES). Roles (alternator, battery, extra) bind by the probe's serial number rather than its bus position, so swapping a probe cannot silently reassign another. Setup, Temperature lists every probe with its live reading, age, and success and failure counts, plus a Scan button.
  • Battery temperature source chain (battTempSource): automatic, the battery probe, NMEA 2000 battery status, a VE.Direct battery monitor, RV-C, the regulator board, or none. battTempProxyEnable decides whether the board may stand in when nothing else qualifies.
  • High and low alarms for the extra probe (extraTempAlarmHiF, extraTempAlarmLoF), advisory only.
  • The BMS on/off input is read on the pin it is wired to. The control path had been reading a different pin from the one configured at boot.
  • Position and clock are separate settings (gpsPositionSource, timeSourceMode), so a phone can set the regulator's clock without sharing where the boat is. The app asks for location permission only when the position source is the phone.
  • An absent instrument reports "not available" instead of a plausible number. Wind speed and angle, true wind, boat speed, VMG, leeway, heading, course, board temperature, alternator temperature, and the VE.Direct shunt current all show a dash, and the wind needle hides rather than pointing dead ahead.
  • One bus-wide convert command covers every probe, so adding probes does not slow the alternator reading, and an engine start forces an immediate read so the first control passes see a fresh figure.
  • Ignition-cycle high and low marks no longer record 0 for a sensor that was absent the whole cycle.
  • The motion sensor's freshness stamp is written when a sample lands, not when a read is attempted.
  • Engine start and stop console lines are held while the tachometer is known to be lying after a field cut (g_rpmTachMasked), so a commissioning cut no longer reports a stop and a start the engine never made.
  • NMEA 0183 baud and polarity changes are applied from the control core, and now apply even while the receiver is switched off.

NMEA 2000 and other networks

  • RV-C transmit (rvcTxEnable), sharing the existing CAN port and claimed address: charger status and configuration, DC source status at the alternator's own instance, and the RV-C diagnostic message carrying the active fault. Each group has its own toggle, and the instances and device priority are settable.
  • NMEA 2000 charger configuration (127510) is transmitted; its charge-current-limit field carries field drive percentage. The charger mode label (standalone, primary, or secondary) is now a setting.
  • Battery status (127508) carries battery temperature when the battery probe is fitted and enabled.
  • A second temperature transmit slot for the extra probe (130312), with its own instance and source code.
  • Battery temperature is decoded from RV-C DC source status and from the VE.Direct "T" field, both selectable as the battery temperature source.
  • Charge-limit follow: a Victron target-voltage register reading all ones is treated as a withdrawal of the limit rather than an unrecognized frame, which used to hold the last clamp until the silence timeout. The allowed-to-charge bits in the BMS I/O register are decoded per Victron's own published decoder.
  • A roster of bus nodes is built passively from address claims and product information. The dashboard names whoever is publishing the charge limits, and the frame capture carries a header with the firmware, the dialect, the follow state, the roster, and the boat's own battery record.

Dashboard and app

  • Tapping any reading at the top of the screen opens a panel naming what is limiting charging, the number it is held against, and where that setting lives. It covers all fifteen limit codes, including the three that raise output rather than lower it.
  • The header carries a charging-system-health figure and a battery temperature reading.
  • More than one regulator per boat. Each unit answers at its own network name, xreg-.local, and broadcasts its own default hotspot name, with alternator.local kept as a shared alias. A regulator can be named in Vessel Info, and the app remembers a unit by identity rather than address, asking which to use when more than one answers. A Switch Regulator button forces the question.
  • The app can join the regulator's own hotspot from inside the app, and reacts to a phone network change at once instead of waiting out the stream's retry budget.
  • A stall of a few seconds shows a notice saying the connection dropped, rather than leaving readings frozen with nothing said. After a gap the console is backfilled from the regulator's own message history, so the log has no silent hole.
  • An interface that does not match the running firmware raises a dialog offering to sync or reload, instead of blanking gauges under a green connection.
  • The session health plot is served by the regulator, so a page opened mid-run, or reconnecting after a drop, recovers the whole session instead of starting blank.
  • A setting that cannot act is grayed with a line saying why: no battery shunt fitted, the panel override on, access-point mode, or a trust latch that is not set. Those settings used to disappear.
  • Fuel consumption table moved onto the settings page with a live burn curve underneath, plus a fuel volume preference (displayVolUnit, US gallons or liters) that carries through the flow and economy readouts.
  • Solar ledger view under Live Data, Weather: predicted against actual harvest and consumption per day, in a 30-day or 90-day window, with a summary line and a clear button.
  • The settings write window stays open while an interface is attached, and the next client to connect is told that settings relocked themselves and when.
  • Level Zero is now Zero Now, with a live heel and pitch readout under it.
  • The dashboard opens on Live Data, Diag so charging system health is the first thing seen. First-time setup on a phone-sized screen suggests a laptop.

Commissioning and calibration

  • Commissioning gained a tenth step, Charge Health Calibration, and a Stop for now that keeps every finished step and undoes only the step in progress. Abort restores the device's pre-run commissioning record (commissionRestorePreRun) instead of demoting a device that was already commissioned. A registration offer closes a finished pass.
  • Charge health calibration measures how far alternator output runs behind engine speed on this installation (altLeadSec), which the health tracker needs to grade readings taken under way. With the field frozen at a level the tuned current loop sized at a held speed, three throttle passes are recorded, and the fit finds the delay that collapses the disagreement between the rising and falling passes.
  • Stop and Abort now put back everything a step wrote, not just the current-loop values: the plant delay, the voltage-rise deadband and its slope, the voltage-loop plant constants and gain mode, the field-drain timings, the alternator output lead, and the keep-alive column.
  • Abort with no run in progress does nothing. It used to fall through to the old zeroing path and wipe every completion mark on a finished device while reporting that settings were left alone.
  • The run plan fills in a step's prerequisites and says why it added them. A step whose feeder is ticked is locked, because re-measuring the feeder makes that step's result stale, and unticking the feeder releases it. The plan is fixed while the wizard is open, and a paused pass comes back to the plan it left.
  • A step that had no measurement of its own to size a run from says so before it runs, naming what it had to fall back on. That used to happen silently after a page reload.
  • The required steps alone mark a device commissioned. The stress test and charge health calibration are optional and never hold the badge back, and a run that finished without being committed is offered a Finish rather than a clear-and-restart.
  • Running the whole wizard again on a commissioned device no longer reverts anything first. The committed tune stays as the starting point and is snapshotted again at Start, which is what a later Abort returns to.
  • The stress-test verdict is discarded whenever the loop it graded is retuned, instead of being served beside a tune that no longer exists.
  • The wizard's applied-settings summary reads the regulator's own echoes, so it stays true across a page reload instead of claiming nothing had been applied.

Alternator health

  • The alternator health admission gate judges engine speed, field, and output by how straight they run over their window rather than how still, so a smooth acceleration becomes recordable data instead of a barrier. Output and bus voltage are delayed against engine speed by a measured lead (altLeadSec), and the temperature gate is a trailing window that survives the eligibility barrier.
  • Gate-tuning capture: a 10 Hz session logger into 192 KB of PSRAM, plus a field sweeper that ramps duty up and back down at a set rate, turning around short of every control limit, with a Reverse now button.
  • The high-field, low-output alert reads as a share of the live field ceiling rather than absolute duty. An absolute 80% is unreachable on 24, 36, and 48 V banks, where the ceiling sits near 50%, 33%, and 25%, which had left the alert dead on those banks.
  • The count of graded points taken this session is shown on its own line. It is the only useful figure in the first minutes, before the mean and the tenth percentile have the ten samples that make them mean anything.

Solar

  • Solar energy ledger: one record per local day holding what the forecast promised, what the panels delivered over VE.Direct, and what the boat consumed, for the last 90 days.
  • The array's performance ratio is learned from each complete day's result (solarLearnEnable, solarLearnRatePct) instead of staying at a typed guess.
  • The bar a day must clear before the alternator rests can be sized from the consumption the ledger predicts, plus a margin (solarUseConsEnable, solarConsMarginPct), instead of a fixed threshold.
  • The ledger and the day in progress survive a reboot or a power cut, and flash writes happen only with the field cut.

Cloud and updates

  • The update partition is promoted at boot only when it holds exactly the image a completed, signature-verified install recorded. A fully downloaded image that then failed verification used to be promoted by the next factory boot.
  • The web asset partition is erased before an update writes to it, so a renamed asset cannot leave its predecessor behind. Its usage is measured at boot and reported, with a warning above 85% full.
  • The update path no longer deletes the cloud task mid-operation. Both background tasks retire themselves, and a supervisor (ensureCore0Tasks) re-creates them afterwards, retrying and raising an alarm when memory is too fragmented.
  • An update flag stuck for more than 40 minutes is retired and a maintenance reboot requested (checkOtaWedge), instead of silencing the console, the temperature-task health alarm, and the reboot ladder indefinitely.
  • The signature fetch has a 12-second budget per phase and a bounded, stall-guarded read, in place of an inherited 120-second handshake default.
  • Time sync waits for a real time packet rather than accepting any plausible clock. The old test passed on the restored clock at every cold boot, which stamped uploads with timestamps days old and blocked the phone from correcting it.
  • Cloud history past the on-board month runs back until the cloud answers empty, stepping over up to six empty 30-day windows, instead of stopping at one year. A boat laid up for a season no longer truncates its own history.
  • The queued-record backup file is deleted once the queue drains, so a power cycle no longer re-uploads everything already sent.
  • An instrument the boat does not have uploads as a blank rather than 0: true and apparent wind speed and angle, speed and course over ground, heading, VMG, leeway, and VE.Direct shunt current. A boat with no wind instrument had been banking a solid 0-knot line.
  • Engine speed averages in the uploaded records were 100 times too low, and now carry real engine RPM.
  • Charge cycles upload as a fractional count instead of a whole number.
  • Config import: a system-voltage change converts the whole profile before the rest of the import lands, an invalid class is refused rather than silently coerced to 12 V, and settings renamed between releases are matched by their old names.
  • Browser-based USB installation (Improv Serial) reports the running firmware name, version, and serial before flashing, so a reinstall is offered as an update rather than an erase. Ship's WiFi credentials can be set over the same USB connection.

Internal

  • The settings echo channel is generated from a single declaration (CSV3_LIST) with a compile-time field-count check, which catches a truncated macro that the build's own count gate cannot see.
  • Every telemetry channel carries a boot identity and its build time, so a cached block from a previous boot, or from a channel being rejected outright, can be told from live data. The diagnostics snapshot reports per-channel freshness.
  • Lifetime averages for state of charge, voltage, and speed moved to double precision, and the speed average no longer counts an unstamped zero for the first ten seconds of every boot.
  • Vessel information text fields moved from dynamic strings to fixed buffers, removing a cross-core use-after-free when a save lands while the control loop is reading them.
  • Voltage-control autotuning gained a return-to-base phase so both replayed field levels are learned one settle apart, its voltage cushions now scale with the system voltage class, and engine drift across the run is measured and reported.
  • A temperature that has never been read is written as a blank rather than a fabricated value in the thermal log, the fast-scope header, the black box line, and the tuning, plant-delay, and voltage-tuning records.
  • Rounding on the Peukert exponent and the charged-voltage entry: 1.05 was being stored as 1.04.
  • A configuration import that begins while the field is driving says so on the console, since each setting written to storage can briefly pause the control loop.
  • A settings-schema migration retires the dead switch-panel key and the alternator-health tolerance knobs whose measured quantity changed, so an old value is dropped rather than reinterpreted as a limit on something else.
  • Web handlers that reboot defer the restart so the HTTP response is sent. The WiFi setup page shows a countdown instead of hanging on "Saving...".
  • Captive-portal probes are answered per operating system, so no sign-in sheet pops up in access-point mode, and the access point can be raised again after standby without a reboot.
  • A hidden ship's WiFi network is found by active scan, which a passive scan can never match.
  • WiFi drops and reconnects are logged with the disconnect reason and the outage length, and a dashboard-stream outage is reported with its duration once the stream returns.
  • The event stream's acknowledgement timeout was raised from 5 seconds to 20 seconds, so a brief radio stall no longer destroys the dashboard connection.
  • The WiFi nap can be switched on after a standby has already powered the radio down.
  • The ignition-off upload drain keeps the reconnect engine running for its whole 30-minute window.
  • Test runs carry a token minted by the browser, so a status frame or a commit can be matched to the run that asked for it and a stale result cannot be filed against a different run.

0.0.3

Released August 21, 2026. Changes since 0.0.2.

This release connects the regulator to the rest of the boat's electronics. It can now broadcast its own battery, alternator, charger and temperature readings onto the NMEA 2000 network so a chartplotter or instrument display can show them and alarm on them, read a second instrument feed through the separate NMEA 0183 input, and — where a managed battery or its management system publishes charge limits on that network — hold its charge voltage and current below what the battery is asking for, with every built-in protection still in charge.

Automatic maintenance restarts are no longer on a fixed twelve-hour clock. The regulator now waits for a genuinely quiet moment with the engine off and nobody connected, gives a ten-minute warning if someone is watching, and only forces a restart after three days of continuous running.

Also here: 36-volt banks are supported, the Celsius preference now covers every temperature the regulator shows or asks for, and the settings pages have been reorganized so everything the regulator talks to lives on one Integrations page.

Full detail

Charging and control

  • 36-volt banks are now a supported system voltage class alongside 12, 24 and 48 V (SYSTEM_VOLTAGE_CLASS, renamed from BATTERY_VOLTAGE). Every class-scaled quantity — charge profile, protection margins, control-loop gains, field-duty ceiling, resting-voltage table, plausibility windows — scales for it.
  • The critical voltage-disagreement threshold is now derived from the system voltage class instead of banding on bulk voltage, which mis-bucketed a 36 V bank into the 48 V band.
  • The oscillation damper (hunt governor) was rebuilt around a persistent engine-speed map. It makes one test cut to HuntCutPct of your integral gain, keeps it only if measured ripple drops by at least HuntVerifyPct, and then applies that reduction proactively whenever the engine returns to that speed, tapering back to full gain across HuntWingPct of speed either side.
  • The damper gained a second lever: a wobble that keeps the voltage loop's derivative term (D-term) alternating direction is tested by pausing the D-term instead of cutting gain. A verified result switches the D-term off at that speed only; it is never reduced partway.
  • The damper is now opt-in (HuntGovEnable defaults off on new units; units with a stored value keep it). New settings: HuntCutPct, HuntVerifyPct, HuntWingPct, HuntCooldownMin, HuntSteadyPct, HuntQualifyScans. The learned map clears on a voltage-class change, an engine-speed recalibration, an alternator health reset, or from the dashboard.
  • Discharge counting was inverted in the Peukert correction: heavier-than-rated discharge was counting slower instead of faster. Now dischargeCurrent_A / PeukertRatedCurrent_A.
  • Automatic shunt gain correction now reads an unsaturated shadow coulomb count (shadowCoulombX100), so over-reading is visible as well as under-reading — the live counter's clamp at full capacity hid one direction of drift entirely.
  • Alternator statistics and voltage averaging in UpdateBatterySOC now run without a battery shunt; only the battery-side sections (coulomb count, state of charge, capacity tracker, full-charge detection) are gated on one.
  • Field duty is hard-capped at 99% in setDutyPercent, so the high-side gate driver's bootstrap always gets a refresh slice. Switching frequency is clamped to 100–19455 Hz and the timer clock source is forced to APB, so the top of that range attaches at boot. The 400 Hz default is unchanged.
  • Commissioning's between-step rest hold now re-asserts the field enable line, so the tachometer pickup keeps its keep-alive load through a rest resumed after a cut.
  • Manual mode is exempt from the engine-stopped immediate cut, which previously fought the manual path at loop rate.
  • Post-protection recovery hands off bumplessly: integrator state is capped to the flared ceiling at release, so a banked reserve no longer steps the setpoint on exit. The stress test's pinned target gets the same bumpless seed and keeps the down-glide pacing floor.
  • The learned minimum-field floor table forces its top bin to zero when the ceiling anchor lands at or above the last speed breakpoint — the table holds its last bin flat forever above that point, so a non-zero floor would have ridden to unlimited overspeed.
  • Knee learning no longer trains during a CV plant fit, and the plant fit's setup phases bypass the learned floor so all three phases can reach distinct currents.
  • "Defer to Solar" (weather mode) now reports itself as its own field-off reason instead of reading as a plain disable, and the flag is set last so the banner never blames the forecast when the key, the on/off switch, the battery management input or a full battery is the real cause.
  • A forecast that can no longer be refreshed releases the solar pause after the refresh interval plus a 30-minute grace, and the analysis runs in every mode — previously an access-point boot or a run of failed fetches could latch the alternator off with nothing left to re-evaluate it. The fetch also honors WeatherUpdateInterval instead of a hardcoded hour, and the on-demand "Update Weather Now" button no longer requires the field to be off.

Protection

  • Every flash write on the control task is now gated on the hardware field-cut signal (fieldCutSettled) rather than commanded duty. The old duty-based gate read "off" during a live zero-duty voltage hold, letting flash commits land on live control passes. The two staggered field-off flushes moved to +20 s and +28 s, twice the fast-overvoltage lockout ceiling, so cut-and-retry churn can never reach a flash write.
  • A staged firmware install now waits for the field to be de-energized before it starts. The install blocks the control task for the whole download and flash, which would freeze the field at its last commanded duty with software protections dead.
  • A protection cut during the closed-loop sine sweep now latches an abort, stops the sweep and discards the results, and reports the real cause. Points spanning the cut and lockout measured the outage, not the plant, and were being graded as field saturation.
  • The low-temperature alarm no longer fires on the thermistor's disconnected sentinel value, and that sentinel is no longer converted from Celsius into a plausible-looking Fahrenheit reading that passed every downstream check.
  • The garbage-reject ceilings on both voltage inputs now scale with the system voltage class instead of a fixed 70 V, which rejected legitimate readings on 48 V banks.
  • "Time since last overheat" stays pinned at zero until an overheat has been recorded.
  • The engine-dynamic warning bits sent on the network cover a hard over-temperature cut and protective field cuts, deliberately never a normal thermal derate.

Dashboard and app

  • New Integrations settings page, with one collapsible card per external system: NMEA 2000, NMEA 0183, Victron VE.Direct, Victron CAN (DVCC), RV-C, and the shared Charge-Limit Follow card. A matching Live Data → Integrations tab shows what each one is receiving.
  • New Engine settings page holding tachometer scaling (RPMScalingFactor) and pulley ratio.
  • Commissioning is now the first Alternator tab rather than a sub-tab of Tuning.
  • The Celsius/Fahrenheit preference now covers console and alarm messages, settings input fields and their limits, and plot axes — not just readouts.
  • New ESP32-tab rows: free data storage, age of the last acknowledged cloud upload, and a device clock converted into the viewing device's time zone with a skew note when the two disagree by more than half a minute. The tab is now split into collapsible sections (System Overview, Sensor Health, Timing & Diagnostics, App Usage, About).
  • New Oscillation Damper panel under Live Data → Diag: live state, current-loop gain as a share of your setting, D-term state, a plot of the learned speed map, the episode record, and a Clear System button.
  • Charging system health is now graded on the same sustained multi-second average the record book stores, on both sides of the comparison, so a momentary dip can no longer read as lost health. The trend's lower line is each hour's low-10% mark rather than that hour's single worst sample.
  • A "BMS LIMIT" chip appears in the stage banner when a followed charge limit is the binding constraint (limiter codes 8 and 9).
  • A one-time explainer describes the maintenance-restart tiers during first setup, and the ten-minute restart warning popup was rewritten to say what happens.
  • The WiFi setup page gained a "Forget saved ship's WiFi" checkbox, and a blank SSID field no longer silently wipes working credentials.
  • The Solar page was rewritten in plain English: where the position comes from, where the forecast comes from and what leaves the boat, when it refreshes, a forecast-age line under the table, and an access-point-mode note explaining that only the forecast needs internet.
  • Selecting phone GPS as the speed source now shows what it costs before it applies: battery drain, foreground-only behavior without the native background plugin, and exclusion from the cloud speed leaderboard.
  • Recommend Initial Charging Settings gained tiered notices — a warning about charging lithium below freezing, and plain statements of where the regulator does not yet compensate for temperature.
  • Settings search moved from a tab to a bare icon in the tab-row gutter. Card grids now pack like masonry instead of stretching every card to the tallest in its row, and tooltip boxes are repositioned to stay on screen.
  • All five static assets now revalidate as a matched set, so a browser can no longer pair a cached hour-old stylesheet with just-updated markup.
  • iOS focus-zoom handling was reworked: label taps, keyboard next-field arrows and programmatic focus no longer leave the page stuck zoomed.

Sensors and inputs

  • NMEA 0183 receive on its own protected serial input, independent of VE.Direct. Selectable speed (4800/9600/19200/38400) and signal polarity, checksum-validated sentence and error counters, and heading decoding from HDT/THS/HDG/HDM. The drain is held to a hard 500 µs per pass by four independent limits and reports itself to the console if it ever exceeds that.
  • Victron VE.Direct is more robust: a larger receive buffer, a per-tick drain budget raised from 256 to 2048 bytes, and — importantly — values are only read when a new checksum-valid frame lands. Previously any arriving bytes marked the data fresh, which kept stale values alive and integrated phantom solar power.
  • A missing or failed BMP388 barometer no longer hangs the boot in an infinite loop; it retries once, warns, and marks itself disconnected (BMP388Disconnected). Its sample cycle dropped from 8 s to 4 s so a single missed read stays inside the 10 s staleness window.
  • The DS18B20 temperature sensor's address is now filled in before its resolution is set (previously a no-op on a zeroed address), and a failed read is retried in place before it counts as a miss.
  • Maximum speed, session and lifetime, is now the best 60-second average (sogSust1m) rather than a single-sample peak, integrated time-weighted with a gap rule so a dropout cannot manufacture a record. The reset button is relabeled "Sustained Speed".
  • Phone GPS is selectable as the speed and course source (speedSourceMode) — a deliberate choice, never an automatic fallback. In that mode the app posts fixes every ~2 s, and records set that way are flagged in cloud uploads.
  • True wind angle now converts heading into the wind reading's reference frame using the variation the heading message carries, instead of subtracting a magnetic heading from a true-north wind direction.
  • Fuel economy and the fuel-economy curve now check speed-over-ground freshness; a frozen speed after GPS loss was keeping economy looking live and freezing curve bins with it.
  • With no battery shunt fitted, battery current, its rate of change, state of charge and the battery-current watermark now report as unavailable everywhere — dashboard, downloadable logs and cloud uploads — instead of publishing the current input's noise as a measurement.

NMEA 2000 and other networks

  • Transmit (producer) mode, off by default (n2kTxEnable). The regulator claims an address and publishes, with per-message switches and instance numbers: battery status and DC detailed status (127508 + 127506), the alternator as its own DC instance, alternator temperature (130312), charger status with charge stage (127507), engine speed (127488), engine dynamic parameters with warning bits (127489), and battery configuration (127513). One message per loop pass, on a rotating scan, so transmit cost never stacks inside a control tick.
  • Missing sources publish the standard not-available encoding rather than a stale or invented number; alternator temperature is skipped entirely while the sensor is dead, so the display's own data-lost alarm owns that case. A charge-stage change transmits promptly instead of waiting out its interval.
  • Receive of battery status and DC detailed status from a chosen instance (n2kRxBattInstance) — voltage, current, temperature, state of charge and state of health from a shunt, battery monitor or a managed battery's gateway. Display and telemetry only; charge control always runs on the regulator's own sensors.
  • Charge-limit follow (DVCC-style), off by default (dvccEn), reading charge voltage and current limits from either Victron VE.Can proprietary registers or RV-C DC source messages. A decoded limit is a clamp-only request: it can lower the regulator's voltage target or current ceiling, never raise anything, and every local protection outranks it.
  • The follower vets its authority before obeying it: values must stay inside a plausibility window (dvccCvlMin/dvccCvlMax), arrive steadily for dvccSettleS, and not flap. An implausible or flapping value latches UNTRUSTED and hands control back to local targets until manually reset. Silence for dvccSilenceS reverts the clamps.
  • A current limit of zero is obeyed as "stop charging". While a followed voltage limit is holding the bus below the absorption target, the absorption stage's overall time ceiling pauses with it, so a long clamp cannot force the bank out of absorption half-charged.
  • A raw frame capture (paused-and-snapshotted so lines can never tear) exposes the candidate CAN frames as hex text, for validating the decode against real equipment before enabling follow.
  • The NMEA 2000 driver is now a fork whose transmit never blocks; the stock driver waited up to 100 ms per frame on a full queue with no bus attached. Transmit accepted and dropped counts, the claimed address, and timing for parse, transmit and the follow tick are all published.
  • Console output from the receive handlers is now gated behind the verbose switch — battery configuration, attitude, boat speed and DC status were printing unconditionally at bus rate.

Cloud and updates

  • Registration, profile update and account deletion moved off the web-server task onto the background worker, with the dashboard polling for the result. A dead uplink used to starve every other endpoint for up to ~45 seconds.
  • A periodic six-hour re-check re-reports the firmware version and re-reads the forced-update flag. With uptimes now reaching 24–72 hours, a staged update sat dormant until the next reboot and a canceled one left the notice stuck on screen.
  • Remote configuration pushes are now visible to the owner: a notice when one is queued (with the administrator's description and a restart-now option), and a receipt after one lands listing exactly which settings it changed.
  • Update robustness: a web-file open, write or size mismatch now fails the whole update rather than shipping a corrupt bundle behind a valid signature; an oversize firmware image is rejected before the stream starts; the running application remounts the factory filesystem after a failed update instead of losing it until the next power cycle; and the recovery jumper now clears staged-update flags from the namespace they live in.
  • Learned-surface sync-back responses are de-chunked and checked for completeness. A truncated body parses cleanly and would otherwise have wholesale-replaced the learned reference surface.
  • Uploads gained sustained-speed maximum and a phone-source flag; battery current and state of charge upload as null when no shunt was present for the window, rather than as zero.
  • App usage counting: page opens, visible dwell time and button presses are counted on the regulator and uploaded once per local calendar day when it is registered and online. Counts survive a maintenance restart and are shown under Live Data → ESP32 → App Usage.

Internal

  • Maintenance restarts run a three-tier ladder in checkAndRestart: at 24 hours only in a fully quiet window held five minutes (engine and field off, no connected client, cloud queue drained, state of charge and battery voltage above their floors); at 48 hours without the client and state-of-charge preferences, with a ten-minute countdown if someone is watching; at 72 hours regardless of engine state, with brown-out voltage the only remaining hold. A restart is also requested early if the largest contiguous internal RAM block sits below 20 KB for 30 minutes straight.
  • Worst-pass blame capture: when a field-on loop pass sets a new session worst, the top three timed consumers of that pass are recorded and published to the diagnostics panel. Field-on-only splits were added for the loop worst, the current-sense read interval and both slow ADC read gaps, so field-off background work no longer inflates the control-relevant numbers.
  • Battery health history moved from NVS strings to filesystem blobs. The NVS string cap silently truncated the capacity ring at roughly 120 points; a legacy string migrates once and is removed only after the blob write succeeds. Integer fields in the legacy format now parse as integers — routing epochs through a float was shifting every timestamp by up to a minute per reboot.
  • Free data storage is refreshed event-driven: writers set a dirty flag and the roughly 100 ms filesystem traversal runs at the next heap walk with the field cut, never on a live control pass.
  • Settings loaded from storage are now range-clamped on the load path, not just in the web handler — configuration import and remote pushes write storage directly and only take effect through a reboot.
  • Commissioning start and cancel are serialized under a mutex; the previous lock-free double-check left an instruction-wide window where a mid-sequence cancel could be overwritten and the torn-down start marched to completion.
  • Configuration export now includes runtime, lifecycle and debug state as export-only entries, and publishes the list of names import refuses so the dashboard's diff can separate device state from importable changes.
  • Alternator-health emit windowing was reworked: a 2-second trailing average with a trimmed-range cleanliness test replaced a continuous-steadiness clock that one 100 ms blip could reset, which was starving the record book. Temperature dwell dropped from 80 s to 40 s, the excitation and temperature cell sizes were retuned from a sensitivity study, a case-temperature slope tag rides every record, and simulator-generated points are no longer queued for upload.
  • Boat-performance pending points gained an admission policy: best-ever points always get a slot and evict ordinary ones, and ordinary points are rate-limited per conditions cell, so weeks offline cannot drop the records that matter.
  • The CPU load sampler discards and re-baselines on the 71-minute microsecond counter wrap instead of latching a phantom 100% into telemetry.
  • Assorted fixes: the filesystem mutex is only released by its actual holder; the background HTTPS task self-deletes instead of returning into a panic; live event payloads are truncation-guarded rather than overrunning their stack buffer; the thermal log download no longer drops its newest row; imported alternator-health files are rejected unless the header declares the right system and axis count; and FieldAdjustmentInterval, which gated nothing, was retired along with several obsolete storage-key migrations.

0.0.2

Released July 30, 2026.

Pre tracking system.