Skip to content

fix: Heltec V4 board config for Detector and Gateway (VBAT_Read + 16MB flash)#55

Open
popshark1 wants to merge 27 commits into
batear-io:mainfrom
popshark1:main
Open

fix: Heltec V4 board config for Detector and Gateway (VBAT_Read + 16MB flash)#55
popshark1 wants to merge 27 commits into
batear-io:mainfrom
popshark1:main

Conversation

@popshark1

Copy link
Copy Markdown

Problem

The sdkconfig.detector and sdkconfig.gateway files ship with CONFIG_BATEAR_BOARD_HELTEC_V3=y and CONFIG_ESPTOOLPY_FLASHSIZE_8MB=y, but the Heltec WiFi LoRa 32 V4 boards have different hardware that requires updated settings.

Root Cause

On V4 hardware with V3 config:

  • GPIO37 (VBAT_CTRL) is misconfigured at boot, pulling the LDO enable line LOW — this prevents boot from battery
  • battery_v always reads 0 mV because the ADC control pin is not initialized correctly for V4
  • 8MB flash size leaves the upper 8MB of the 16MB chip inaccessible, shrinking available OTA partition space

Changes

sdkconfig.detector

  • CONFIG_BATEAR_BOARD_HELTEC_V3=yCONFIG_BATEAR_BOARD_HELTEC_V4=y
  • CONFIG_ESPTOOLPY_FLASHSIZE_8MB=yCONFIG_ESPTOOLPY_FLASHSIZE_16MB=y

sdkconfig.gateway

  • CONFIG_BATEAR_BOARD_HELTEC_V3=yCONFIG_BATEAR_BOARD_HELTEC_V4=y
  • CONFIG_ESPTOOLPY_FLASHSIZE_8MB=yCONFIG_ESPTOOLPY_FLASHSIZE_16MB=y

Verification

Tested on Heltec WiFi LoRa 32 V4 hardware:

  • ✅ Device boots from battery
  • vbat reads correctly (~4090 mV on full charge)
  • ✅ LoRa TX packets sent successfully with correct battery voltage in telemetry
  • ✅ Serial log: battery monitor ready (adc=GPIO1 ctrl=GPIO37 ratio=4.90)

popshark1 added 22 commits June 3, 2026 00:20
Added matrix builds for detector and gateway with V3 and V4 configurations. Updated artifact handling and size reporting for new binaries.
Move env variable to same line as idf.py command.
The previous syntax had env on a separate line which didn't apply to idf.py.
This prevented sdkconfig_{role} files from being loaded during build.
Update Detector and Gateway role specs to indicate support for both Heltec WiFi LoRa 32 V3 and V4 boards. This reflects the separate firmware builds now available for each board version.
Update Detector role specs to indicate support for both Heltec WiFi LoRa 32 V3 and V4 boards. This aligns the UI text with the separate firmware builds now available for each board version.
Adds a Board Version selector (V3/V4) to the Web Flasher UI, allowing users to choose between Heltec WiFi LoRa 32 V3 (8MB) and V4 (16MB) before flashing detector or gateway firmware.

- New boardSelect dropdown with V3/V4 options
- Updated fwUrl() to append _v3 or _v4 suffix to firmware filenames for detector/gateway roles
- Added event listener to trigger manifest update when board version changes
- Wired detector remains unchanged (no version suffix needed)
Hide board version selector for wired_detector role.

@TN666 TN666 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for tackling V4 support and adding the build matrix — the 16MB flash change is correct (V4 is 16MB external + 2MB PSRAM, per the Heltec V4 hardware update log). A few things need addressing before this is mergeable, and the stated root cause is inaccurate.

Must fix (blocking)

  1. docs/flasher/index.html hardcodes your fork. const REPO = "popshark1/batear", the footer GitHub/Issues/Datasets links, and the datasets link were all changed from batear-io/... to popshark1/.... This is the upstream page — revert all of these.

  2. The Gateway and Wired Detector role-info panels are broken. Both lost their <p> description paragraph and gained a stray <span>Heltec WiFi LoRa 32 V3 / V4</span> floating outside .specs. Also: Wired Detector runs on the LILYGO T-ETH-Lite S3, not Heltec — that label is wrong.

  3. Duplicate sdkconfig variants. You added both sdkconfig.detector_v3/sdkconfig.gateway_v3 (used by CI) and sdkconfig.detector.v3/sdkconfig.gateway.v3 (unreferenced). Drop the .v3 ones.

  4. CI size-report regression. The size-vs-firmware-latest delta comparison was removed, leaving only a flat current-size table. Please keep the delta logic and loop it over the 5 roles instead of deleting it. Also stat ... || echo 0 silently masks a missing binary — make it fail the job.

Root cause is inaccurate (important)

The PR description says GPIO37 "pulls the LDO enable line LOW, prevents boot from battery" and that battery_v=0 is fixed by switching the board flag. Verified against Heltec datasheets, this is not right:

  • GPIO37 is ADC_Ctrl, not an LDO enable. It does not gate boot.
  • V3 and V4 have opposite ADC_Ctrl polarity. V3 schematic: GPIO37 pulled LOW connects the divider to GPIO1. V4.2.0 official datasheet: "the ADC_CTRL(37) pin needs to be pulled HIGH" (confirmed by MeshCore's HeltecV4Board::getBattMilliVolts() which drives it HIGH to read).
  • main/battery.c hardcodes the V3 polarity (drive LOW to read, HIGH to disconnect), and main/pin_config.h shares one #if block for V3 and V4. This PR changes neither. So per the datasheets, flipping only the sdkconfig flag should still read 0 mV on V4 — the real fix belongs in battery.c (invert GPIO37 polarity for CONFIG_BATEAR_BOARD_HELTEC_V4), not in the sdkconfig label.

Could you confirm with a scope/measurement which V4 hardware revision you tested, and whether battery.c was modified out-of-band? The reported ~4090 mV reading contradicts the official V4 datasheet polarity.

Heads-up: V4.3.1 GPIO5 reassignment

The detector uses GPIO5 as I2S WS (PIN_I2S_WS). Heltec V4.3.1 (2026-02-25) reassigned GPIO5 as the FEM control pin (KCT8103L). Advertising a generic "V4" detector will break on V4.3.1 boards. Please scope the claim to V4.2 (GC1109) or reassign I2S WS.

Minor

  • fwUrl() indentation is off and the closing brace is on the return line; prefer role === 'wired_detector' ? '' : '_' + boardVer so future LoRa roles don't get missed.
  • Keep the ENDOFBODY/ENDOFTAG heredoc markers — EOF is more likely to collide with report content.
  • 22 commits with repeated "fix CI / fix flash size / fix env syntax" churn; please squash into ~3 logical commits.

popshark1 and others added 3 commits June 9, 2026 22:10
V3 uses active-LOW GPIO37 to connect the VBAT divider; V4 uses
active-HIGH (per V4.2.0 datasheet). Introduce VBAT_CTRL_CONNECT /
VBAT_CTRL_DISCONNECT macros selected at compile time via
CONFIG_BATEAR_BOARD_HELTEC_V4, replacing the hardcoded 0/1 values
that caused incorrect readings on V4 boards.
Addresses review:
- Revert REPO const + footer/datasets links from popshark1/* to batear-io/*
- Restore the <p> descriptions and drop the stray floating <span> on the
  gateway and wired_detector role-info panels
- fwUrl(): fix indentation and use wired_detector-exclusion so future LoRa
  roles also get the board-version suffix
- Drop unreferenced sdkconfig.detector.v3 / sdkconfig.gateway.v3 (CI uses
  the underscore _v3 variants; the dot variants were duplicates)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- size-report: loop the current-vs-firmware-latest delta over all 5 roles
  instead of a flat size-only table; 'set -euo pipefail' + bare stat so a
  missing build artifact fails the job instead of silently reporting 0 B
- Restore ENDOFBODY/ENDOFTAG heredoc markers (EOF can collide with content)
- battery.c: restore the cppcheck-suppress for cali_init() dropped by the
  polarity commit (re-introduced a knownConditionTrueFalse warning)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@TN666

TN666 commented Jun 16, 2026

Copy link
Copy Markdown
Member

Pushed two commits onto this branch addressing the blocking review items (battery polarity fix you added is kept as-is). Summary:

0c61064 — flasher + sdkconfig

  • Reverted REPO const + footer GitHub/Issues/Datasets links from popshark1/* back to batear-io/* (this is the upstream page).
  • Restored the <p> descriptions on the Gateway and Wired Detector role-info panels and removed the stray floating <span> that was breaking the markup. Wired Detector keeps its correct LILYGO T-ETH-Lite S3 label.
  • fwUrl(): fixed indentation and switched to a wired_detector-exclusion (role === 'wired_detector' ? '' : '_'+boardVer) so future LoRa roles also get a board suffix.
  • Dropped the unreferenced sdkconfig.detector.v3 / sdkconfig.gateway.v3 duplicates (CI uses the _v3 underscore variants).

c969178 — CI + battery cppcheck

  • Restored the firmware-size delta vs firmware-latest, now looped over all 5 roles. Added set -euo pipefail + bare stat so a missing build artifact fails the job instead of silently reporting 0 B.
  • Restored the ENDOFBODY/ENDOFTAG heredoc markers (EOF risks colliding with report content).
  • Restored the cppcheck-suppress knownConditionTrueFalse on cali_init() that the polarity commit dropped — without it cppcheck CI fails again.

Please re-flash and confirm on your V4 board that detector + gateway still boot and vbat reads correctly after these changes (none of them touch battery logic beyond the comment, so it should be unchanged — just want a sanity check on real hardware).

Still needs your call (not changed): the V4.3.1 GPIO5 reassignment. The detector uses GPIO5 as I2S WS, but Heltec V4.3.1 reassigned GPIO5 to the FEM control pin. A generic "V4" detector firmware will break on V4.3.1 boards. Which do you want:

  1. Scope the V4 detector to V4.2 (GC1109) in the flasher label, or
  2. Reassign I2S WS to a free GPIO for V4.

Once that's decided and the V4 hardware check passes, this should be mergeable. (For history, recommend "Squash and merge" given the commit count.)

Fork PRs get a read-only GITHUB_TOKEN, so thollander/actions-comment-pull-request
fails with 'Resource not accessible by integration' and reddens the whole
check even though the size report generated fine. Gate the comment step on
same-repo PRs and add continue-on-error; the table remains in the job log.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@TN666

TN666 commented Jun 16, 2026

Copy link
Copy Markdown
Member

Firmware Size Report

Posted manually — fork PRs run with a read-only GITHUB_TOKEN, so the CI job can't auto-comment (see note below). Figures are from the green run 27621184521 (4c6023e); firmware is unchanged from c969178.

Role Current Previous Delta
detector_v3 490528 B new
detector_v4 490528 B new
gateway_v3 1089696 B new
gateway_v4 1089696 B new
wired_detector 905104 B 906096 B -992 B

Compared against firmware-latest. The _v3/_v4 artifact names are new, so detector/gateway show "new".

idf.py size details

detector_v3: Total image size: 424875 bytes (.bin may be padded larger)
detector_v4: Total image size: 424875 bytes (.bin may be padded larger)
gateway_v3: Total image size: 1024047 bytes (.bin may be padded larger)
gateway_v4: Total image size: 1024047 bytes (.bin may be padded larger)
wired_detector: Total image size: 839450 bytes (.bin may be padded larger)


Note on automated commenting: the build job runs in the fork-PR context, where GitHub forces GITHUB_TOKEN to read-only regardless of declared permissions, so actions-comment-pull-request can't post (this is what was reddening the check). The proper fix for auto-commenting on fork PRs is a separate workflow_run-triggered workflow that runs in the base-repo context — but workflow_run only uses the workflow file from main, so it has to be merged to main before it takes effect on fork PRs. Happy to add that as a follow-up.

The size-report job runs in the (fork) PR context where GITHUB_TOKEN is
read-only, so it cannot comment. Instead it now uploads the rendered report
+ PR number as the 'size-report' artifact, and a new pr-size-comment.yml
(triggered by workflow_run, running in the base-repo context with a write
token) downloads it and upserts the comment — working for fork PRs too.

workflow_run only uses the default-branch copy of the workflow, so this
takes effect for fork PRs only once merged to main.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants