Skip to content

SolarXiao carrier profiles, MPPT and battery controls

SolarXiao Repeater and QSPI OTA Room Server firmware support the CN3791 Base, older BQ24650 Advanced and LTC4162/INA260 MPPT carriers in Full and Reduced builds. Use USB CLI or the authenticated administrator CLI over LoRa. Ship mode and saved-policy reset require local USB. Commands do not change RF settings.

Automatic detection and manual overrides

There are three power profiles: auto, basic and mppt. Base and Advanced share basic because their onboard power telemetry and software controls are the same; their different analog charger designs require no different driver. The default is auto when no carrier selection has been saved. Saved MPPT selections remain manual overrides, and saved Base/Advanced selections load as basic. Use set solar.board auto to enable detection on such an installation. The firmware environment, hardware/OTA identity and flash layout are unchanged.

get solar.board
set solar.board auto
get solar
get solar capabilities
get solar readings
get solar history

Auto mode checks the INA260 manufacturer's ID (0xfe = 0x5449) and device ID (0xff & 0xfff0 = 0x2270) at carrier address 0x40. An address ACK alone is not enough: another device such as INA219 can share that address. Detection only reads identity registers; it does not configure/reset either chip. The first probe occurs in the loop after initialization, then retries every five seconds until a valid identity is found. A positive result identifies MPPT for these carrier designs and is retained until reboot or a new board selection. Temporary communication loss does not relabel a previously detected MPPT.

Without a verified INA260, auto reports self-only and keeps retrying. It does not claim to distinguish Base from Advanced: neither has a digital identity, and missing responses can also mean an MPPT power/bus fault. Charger access, saved-override replay and native carrier telemetry stay blocked until a valid INA260 identity is found. XIAO self readings remain available throughout. The MPPT carrier's INA260 was previously read with USB power only; detection does not require the LTC4162 charger to respond at SOLAR/VIN.

Manual settings are available when the physical carrier is known:

Setting Behavior
set solar.board auto Verify INA260 before enabling MPPT; otherwise self-only, retrying.
set solar.board basic Base/Advanced self battery voltage and MCU temperature; no native I2C access.
set solar.board mppt Enable native access without requiring INA260 detection; existing charger write identity checks still apply.

Legacy base and advanced command values are compatibility aliases for basic; they are not separate modes. Readbacks and help use the three canonical names. Existing Base/Advanced records load as basic without being rewritten; new Basic saves use the original Advanced record value, preserving the same self-only behavior across upgrades.

For Base or Advanced, basic reports the common hardware capabilities and live XIAO battery ADC and processor temperature. It does not claim which analog charger is fitted. The existing self telemetry stays on channel 1, with voltage and temperature as different LPP types. It adds no invented charger flags, current, watts, battery NTC temperature or panel measurements. get solar battery aliases the self readings; the MCU temperature is not a battery or charger temperature. If a node already reports battery voltage and MCU temperature on channel 1, this profile adds no further physical measurements. It adds carrier detection, manual overrides and capability reporting; the voltage/temperature history commands also already exist in builds that include telemetry history.

The 2025 Base Standard schematic uses a CN3791 analog charger with no digital interface or INA monitor. Battery voltage reaches the XIAO BAT input. Charge status drives an LED, and the other charger signals are not connected to XIAO measurement/control inputs. Base therefore needs no extra telemetry driver: only self battery voltage and MCU temperature are available, just like Advanced. Base Lite publishes a README but no schematic, so its exact connections are not independently qualified here.

The 2025 Advanced schematic has no INA monitor or digital charger interface. Charger status pins drive LEDs, NTC goes only to the charger, and current/voltage/MPP setpoints use hardware resistors, switches and a solder jumper. An OTA update cannot measure those signals or change those setpoints without additional hardware connections.

Manual Basic mode suppresses native LTC4162/INA260 polling, register reads/writes, replay and native measurements on channels 2..13. get mppt, set mppt ... and mppt ... explain that Basic Base/Advanced layouts have no digital charger interface. Pending auto mode only probes INA260 identity; it does not access the charger. The generic sensor scanner still reserves native addresses 0x40 and 0x68, so it cannot bypass that policy. Optional external sensor channels still start at 14. Historical samples retained from a previous carrier selection describe the old samples, not current sensor availability.

Voltage history reserves native channel IDs 2..5 at boot, even while Auto is pending or Basic is selected. This is schema allocation, not chip access or a measurement. It lets later detection, charger input power or a manual mode change supply valid samples without restarting or clearing unrelated history. Inactive readings remain missing, and empty channels do not appear in populated history results. Native and optional I2C voltage history use the existing get telemetry.volt.i2c <channel> [1-4] reader: four days of 30-minute RAM samples.

Where telemetry history is included, get solar history points to the existing get telemetry.volt [1-7] and get telemetry.temp [1-7] commands: 30-minute samples, seven days in RAM. History starts filling after boot and resets at reboot. Voltage trends can help assess a remote installation, but are not a measurement of solar power, charge current or charge state. Radio/status and history-transfer commands remain the existing role commands.

The selection is stored separately in an eight-byte, versioned checked record at /solar_board, using atomic publication and full public readback. A corrupt, unreadable or unconfirmed selection blocks native access and replay. Self ADC and MCU readings remain available. An explicit successful set solar.board recovers selection. With an unavailable filesystem, the selection cannot be saved and native access remains blocked.

When auto verifies MPPT or a manual MPPT selection re-enables native access, the firmware reloads any retained /solar_power charger overrides. Changing the carrier does not erase those overrides, change RF/PA settings, modify battery protection, or write charger defaults. The INA260 identity verifies the monitor; LTC4162 chemistry and cell-count checks still independently guard charger writes.

Radio target and role selection remain separate from the power profile:

Fitted module Repeater Room Server
E22 M30S solarxiao_30S_repeater solarxiao_30S_room_server_lora_ota
E22 M33S solarxiao_33S_repeater solarxiao_33S_room_server_lora_ota

All three power profiles work in these role builds. Room uses its existing onboard-QSPI OTA target, identity and application layout, with the matching board/storage-aware OTAFIX bootloader. The older plain *_room_server targets remain separate compatibility/recovery recipes; this native interface is qualified on the QSPI OTA Room targets. No legacy identity is remapped.

The published Base Standard schematic specifies M30S; the pictured 2W Advanced uses M33S. Charger detection cannot identify the PA variant or select its TX power limits.

A remotely deployed node must first receive compatible firmware before these commands can be used. Deployment still requires its installed target and bootloader compatibility to be checked when it is reachable.

See the Room Server and late-detection history validation and three-profile validation. This adds no measurements beyond existing self voltage/MCU temperature and has not been installed on the remote Advanced board.

MPPT carrier commands

Start with:

get mppt
get mppt battery
get mppt power
get mppt alerts
get mppt saved
get mppt fields 0

fields returns three names per page with rw, ro or locked. Increment the page to enumerate the register interface. get mppt <field> returns units and the raw register. get mppt raw 0x43 reads a documented register; arbitrary register writes are not exposed. nan in a summary means unavailable, not zero.

Identity and readings

The carrier bus uses SDA P0.09 and SCL P0.10. INA260 at 0x40 must match its TI manufacturer and device IDs. Its signed current, voltage and power readings do not require charger input power. The driver does not reset/configure INA260. LTC4162 at 0x68 uses little-endian SMBus words. Access normally requires power at SOLAR/VIN; USB alone can leave the charger unavailable.

get mppt info reports the chemistry/profile code, live cell count, last observed nonzero cell count, MPPT, JEITA, charger state and telemetry validity. The actual bench board identified as FST (chemistry code 6); this distinguishes it from FAD, FFS, Li-ion and SLA variants. The ID does not uniquely identify the M suffix or package/temperature grade. Cell count comes from hardware straps; zero means unknown while the charger is inactive. Software cannot change chemistry/cells.

Readings cover battery/input/output voltage, signed battery/input current, charger die and modeled NTC temperature, battery series resistance, charge/CV/ absorb timers, JEITA region, actual DAC settings, system/status bits and all three alert banks. A retained ADC bank is not presented as live while telemetry is off. Battery ADC voltage/resistance need a currently valid cell count. Questionable resistance and an open/disconnected NTC return unavailable in the summaries.

Settings on the 4S FST carrier

Use set mppt <field> <value>. Booleans accept on or off only.

Fields Behavior
mppt.enabled Enable automatic solar maximum power tracking.
charge.enabled Suspend/resume charging; does not disconnect the battery or system output.
telemetry.force, telemetry.fast Force the charger ADC on, or use fast telemetry. These affect power consumption.
input.limit_ma Input current limit; rounds down to the hardware step, never above the request; maximum request 3200 mA.
input.minimum_mv Manual input-voltage floor; MPPT must be off. Rounds up in 140.625 mV steps, maximum request 35000 mV.
jeita.enabled Select the fixed multi-region JEITA profile or basic temperature-qualified manual targets.
charge.current_ma, charge.cell_mv Manual targets require JEITA off. Current rounds down in resistor-dependent steps, up to 3200 mA. This 4S board interface limits voltage requests to 3412.5..3600 mV/cell in 12.5 mV steps.
thermal.start_c, thermal.end_c Die thermal regulation thresholds, -40..125 C; start must remain below end.
termination.enabled, termination.current_ma C/x termination switch and nonnegative current threshold.
termination.cv_seconds, termination.total_minutes 16-bit safety timers; zero disables the corresponding timer.
alert.* Voltage/current/die/NTC/resistance thresholds and enabled alert masks; use field names/units from fields.

FST locks the six JEITA thresholds, regional current/voltage values, recharge threshold and absorb voltage/time. These remain readable. Manual target registers are continuously overwritten by JEITA when JEITA is on; read actual dac.* fields to see the active regulation targets. Basic temperature-qualified charging still uses the fixed outer temperature limits when JEITA is off.

All configuration writes require a fresh FST identity and a live cell count of 4 or unknown. Other variants remain readable but cannot receive this board's saved settings. Every setting uses a masked register update and verifies readback before success. Unrelated bits are preserved; one-shot BSR is not replayed by configuration writes. A failed write/save attempts to restore the previous field and reports whether rollback was verified.

Saving and actions

Successful settings save an explicit override in a versioned, CRC-protected /solar_power record, using atomic file replacement plus public-file readback. The board reapplies only saved overrides after restart or charger power loss, with a five-second retry interval. It does not write default settings on first boot. JEITA-owned targets are not repeatedly written while JEITA is enabled. A failed/corrupt settings file blocks configuration saves and automatic replay.

  • mppt reload: reload saved policy and retry applying it.
  • mppt forget: remove saved register overrides; keep calibration and live chip settings.
  • mppt reset: local USB only; reset saved policy/calibration to reference values, including recovery from a corrupt record. Live charger registers are unchanged.
  • mppt bsr run: request one battery-resistance measurement; not saved.
  • mppt ship arm / mppt ship disarm: local USB only; not saved. Arming takes effect when VIN drops below approximately 1 V and can remove system power.
  • mppt alerts clear limits|states|status <mask>: clear selected latched alerts using write-zero-to-clear semantics; unselected/new alerts are preserved.

These actions acknowledge the request, not completion of charging, resistance measurement or entry into ship mode. Read the corresponding status afterward.

See the bench acceptance report for exact firmware identity, measured readouts and test limits.

Conversion defaults and carrier revisions

The supplied Standard schematic shows R5/RSNSI and R14/RSNSB at 10 milliohms, a 10 kohm NTC bias and a 10 kohm NTC. It shows an L42M single-cell charger, so it does not independently confirm component values on this 12 V FSTM revision. Defaults use those resistor values and the LTC4162 reference thermistor beta of 3490 K. Readings identify the model as reference until the corresponding calibration values are explicitly set.

Calibration settings, saved without changing hardware target registers:

get mppt cal.rsnsb_mohm
get mppt cal.rsnsi_mohm
get mppt cal.ntc_bias_ohm
get mppt cal.ntc_r25_ohm
get mppt cal.ntc_beta

Set these with the same set mppt syntax after confirming actual components. Allowed sense resistance is 0.1..1000 milliohms, NTC/bias resistance 100..1000000 ohms, beta 1000..10000 K. The simple beta temperature model assumes an unpadded NTC divider. It does not model series/parallel thermistor dilution networks. Changing calibration changes units/conversions, not already saved register codes. INA260 uses its integrated shunt and does not use these sense-resistor values.

Telemetry channels

The following carrier channels apply to MPPT mode. Advanced mode reports the existing self voltage/MCU temperature on channel 1 and omits native channels.

Carrier telemetry requires the environmental telemetry permission. Channel 1 remains the XIAO internal ADC; it is separate from the 4S carrier battery and its existing startup/low-voltage policy is unchanged.

Channel Values
2 INA260 battery voltage, signed current, power
3 LTC4162 input voltage, signed current, computed nonnegative input power
4 Charger system output voltage
5 Charger battery ADC voltage and signed current
6, 7 Die temperature, modeled NTC temperature
8, 9, 10 Generic sensor integers: charger state, charge status, system bits
11, 12, 13 Generic sensor integers: limit, state and status alert masks
14 onward Optional environmental sensors, in discovery order

Unavailable values are omitted. Voltage history reserves channels 2..5 and marks unavailable samples invalid. The generic sensor scanner cannot claim carrier addresses 0x40/0x68; this prevents an INA219 driver from configuring the INA260 and keeps carrier channels stable across profiles and power states. No state-of-charge percentage or coulomb counting is inferred from voltage.

References: SolarXaio hardware, LTC4162-F Rev A, INA260.