View this page on MeshCore Docs.
Heltec V4 Full native browser console - 2026-10-06
The normal Full Heltec V4 Repeater from source
c88885a315208908e050c57fc0ec0a71ff10bd6f passed fresh-flash connection,
600 seconds with the console open, and 600 seconds with it closed through the
unchanged config.meshcore.io setup GUI. Power saving was on and logging output
was off during those idle intervals. A separate fresh-flash and 600-second
open-console trial also passed with USB logging on. Both trials restored the
original settings and closed their streams. Final operator readback and owned
browser/host-service cleanup also passed. Release 1.17.1.9 remains held and
unpublished.
The subsequent button-profile correction at ebf2f082 passed host/build checks
and another native fresh-flash GUI connection with 180-second open/closed
console intervals. That updated-source checkpoint is recorded separately below;
it does not extend the older source's 600-second measurements to the new image.
On 2026-10-06, the user separately confirmed that a Heltec V4 button press wakes the screen. This is a user-reported manual confirmation; its firmware revision and CPU sleep state were not specified. It does not supply a current measurement or a V4-R8 manual result.
These results extend the earlier startup investigation to the current normal Full image and native hardware CDC. They are physical console stability checks, not a measurement of sleep current, radio traffic capacity, or every ESP32/host combination.
Image and build gates
The requested target was heltec_v4_repeater, Full profile. Its resolved
heltec_v4_repeater_observer_mqtt feature base retains the normal repeater
update identity. Runtime readback had to match the complete version
v1.17.1.9-halo-keymind-cascade-dev-c88885a3 (Build: 06-Oct-2026).
The source includes the OTA upload correction in d2983762 and WiFi ownership
correction in 95913c53. The GitHub unit workflow for c88885a3 passed;
this does not replace the physical checks below or the final release matrix.
| Artifact | Bytes | SHA-256 |
|---|---|---|
| Full application | 2,097,528 | 1f10f44149b3f56edbe0ecb2a2bab9b51da651a6d047e2c2c1555691468d2b4c |
| Merged image | 2,163,064 | 3264d7a1a5713755b5dd10ad1c81bb0588e4a072eeaa126b86307a42be77bb5b |
| Matching ELF | - | 0545eef46da30a86f86531199a91e887167d463c5981f193c0455cd75d633538 |
The package hash, linked capability, and RAM gates passed, with 20,880 bytes of margin above the required heap budget. The linked application includes HWCDC, its retained-PHY handoff and startup owner hook; no TinyUSB USBCDC class is linked. Full ESP-NOW, WiFi/LoRa OTA, and USB logging capability checks passed. These are build checks; this run did not exercise those radio/OTA features.
Both application slots are 0x640000 bytes, at 0x10000 and 0x650000.
The padded partition table SHA-256 is
9af3af2b74e944337ba85f2b0027ee80df160579a1ab746ba0f95853f618cd60.
The merged image contains that table and the exact audited application at
0x10000. The application fits either slot with 4,456,072 bytes of margin.
The merged artifact was audited, but the physical tests wrote the application
only; they do not qualify a factory erase or merged-image installation.
Native browser boundary
Chromium 154.0.8037.92 ran on the Pi with native OS Web Serial ports and
streams. The actual Vue GUI and stock SerialCLI were loaded before flashing.
The stock DOM Connect flow after the stock flasher returned sent the normal
plain time <epoch> request. Its unchanged 5,000 ms timeout covers both native
write completion and the framed response. No additional reset, cable action,
post-flash settle, command retry, or keepalive was inserted to turn that
connection into a pass.
| Website source | SHA-256 |
|---|---|
GUI index.html |
efd64d1b56d57988fc4108f3f84efc943ed4c42ade4e4dbf8139c46fb3c0476d |
GUI src/gui.js |
919034806e903fbc41e29a367a7d854837f6520f47aa34e5d0618f5dd3d29800 |
GUI lib/serial-cli.js |
fbfbdcfa8bf1a372a0396d342e018ba8ee83d33b7b98c3a546fd37cd7e8ce870 |
Flasher js/flash.js |
e9762a29f6a91f8e33736e02ff41a81cd49e7b96fe253a5d71cba7daefd46d5b |
Flasher lib/esp32.js |
2a896d5e520ea9b6ea9900223c2460df797c3b2287f441daa4e50168a50b17e6 |
Automation selected only the single preauthorized native device. Before each
write, actual ROM reads checked the partition table and valid OTA sequence/CRC,
then directed the application write to the verified active slot (app1 at
0x650000). The stock loader transfer, reset and disconnect remained in place;
full erase was disabled. Phase instrumentation recorded existing calls without
adding hardware operations. This qualifies that stock flash backend and native
GUI connection, not the complete firmware-picker selection/erase flow.
Original public identity, the ACL response, and 15 checked saved preferences were compared with the original private reference after flashing and cleanup. Only the numeric channel-busy diagnostic counter was normalized in preference comparison. No raw identities, credentials or console replies are published.
Physical results
| Check | Result |
|---|---|
| Fresh flash, then first GUI connection with logging off | PASS. Plain time clock-set acknowledgement in 1,614.4 ms; complete GUI bootstrap and exact version/reference checks passed. |
| Power saving on, logging off, console open | PASS. 600.093 seconds with zero native command writes or keepalives. Uptime advanced 18 -> 619 seconds; the first post-idle core reply took 35.9 ms. A full DOM Disconnect/Connect reread acknowledged time in 23.6 ms. |
| Power saving on, logging off, console closed | PASS. 600.100 seconds with streams closed and zero writes. Uptime advanced 627 -> 1232 seconds. The first DOM reconnect time response took 33.2 ms; it was the recognized framed clock-cannot-go-backwards rejection, not a clock-set acknowledgement. Full GUI bootstrap and version checks still passed. |
| Separate fresh flash, power saving on, USB logging | PASS. Fresh plain time acknowledgement in 696.1 ms, then 600.101 seconds open with zero writes or keepalives. Uptime advanced 18 -> 618 seconds; first post-idle core reply took 40.4 ms. Full DOM reconnect time acknowledgement took 24.8 ms. |
| Both trial cleanups | PASS. Original power saving off, logging output USB, all 15 checked preferences, public identity and ACL response were restored. The GUI port, reader and writer closed. |
Uptime gates account for the surrounding query/GUI bootstrap time. None of the three quiet intervals contains a native write event. Both trials recorded zero native command errors and no GUI modem-signal calls.
Radio observations stayed in active RX with zero physical RX errors. The core
error bitmask changed from 0 to 8, with zero received packets and one sent
packet. This is the configured receive-silence watchdog warning, consistent
with the quiet-channel recovery policy; it is not eight errors or a CPU reset.
Neither trial establishes error-free RF operation or a loaded radio soak.
Retained setup failures and host qualification
Two preceding browser attempts remain failed and unqualified. Attempt 2 timed
out before metadata completion or any GUI command was recorded; its exact
flasher substage was not instrumented. Attempt 4 timed out in the stock loader
connection/reset loop after 674 USB JTAG reset entries. It did not reach loader
main return, application writeFlash, or a GUI command. Neither failure
exercised the GUI's five-second command timer, so they are not counted as
firmware console timeout failures or silently converted into passing trials.
Before the passing logging-off attempt, the host TTY was normalized from
VMIN=0, VTIME=0 to VMIN=1, VTIME=0, with zero explicit modem-signal calls
in that preparation. No firmware or website code changed. That host setup is
part of the qualified configuration; the evidence does not isolate the original
ROM synchronization failure's cause. The second logging trial started without
another external CLI preflight or TTY change.
The pinned stock flasher also calls connect(resetMode, romBaudrate) from
detectChip, although the second connect argument is a retry count with a
default of seven. The supplied value is 115,200. This explains the excessive
retry budget after failed synchronization, not why synchronization first failed.
It is an external flasher issue; no website patch was required for the passing
GUI tests and no website deployment is claimed.
Evidence and limits
Final read-only operator verification again matched the exact version, original
15 checked preferences, public identity and ACL response; uptime was 686 seconds
and flags remained 8. The owned Chromium profile and tunnel were closed, the
serial port had no owner, and original host service states were restored:
ModemManager and mctomqtt active, mesh-logger inactive. No Pi network
configuration changed. Restored service state does not establish MQTT delivery.
The compact safe audit contains artifact/helper/report hashes and selected outcome fields. Completed sanitized reports and phase observations are retained privately; raw reference settings remain private. Failed attempts are retained separately from the qualified results.
The USB cable remained attached throughout these trials. The native-host sleep guard keeps CPU command service available while the USB host is connected, including when its serial port is closed. Power saving on is therefore not proof of CPU light-sleep entry, measured current, or an operator button test. At this source, V4 lacks the momentary-button wake profile flag. Its subsequent software/build and console validation is recorded below. The operator had no physical button access in this setup. The user's separate screen-wake confirmation does not establish this historical image's CPU sleep state.
These checks qualify this historical c88885a3 Full application, native Pi Chromium setup,
protected active-slot application flash, and measured intervals. They do not
qualify every host OS, board/role, adapter, cold power cycle, factory erase,
heavy logging volume, measured power consumption, or RF traffic load. GPIO/reset
behavior outside the unchanged stock flasher's reset sequence was not separately
qualified. The release remains unpublished; the final same-source all-board
build and release packaging are separate gates.
Updated button-profile checkpoint: ebf2f082
Source ebf2f0823ef8413987d31ccb2d044a2090e88469 enables the existing
momentary-button wake flag in the shared V4 and V4-R8 profiles. Seven ESP32
USB/sleep tests and two display-power tests passed. Configuration assertions
cover 71 firmware profiles, excluding four deliberately standalone partition
migrators. Six host cases execute actual board sleep/USB methods, real family
button constructors and implementation, role polling guards, UITask button
fragments and DisplayPowerPolicy. Three controls must fail if the profile flag,
gesture polling guard or display wake is removed. These are synthetic GPIO/sleep
results, not a physical button press.
| Updated artifact | Bytes | SHA-256 |
|---|---|---|
| Full application | 2,097,560 | aebfd06f5e35ad636f52f329bd051deb9dfeb633361dc77396c0ee9d4456e7c1 |
| Merged image | 2,163,096 | 08750bd38f9f71ea37b8739a8b3c26befa91829df6d5754ad9cffbf61a796a90 |
| Matching ELF | - | c2ec6d54c32c4b3cb331f9216607480e851933cf4865cc399be9409fdf587467 |
The normal Full target, table, two slots, capabilities and RAM gates passed, with the same 20,880-byte required-heap margin. Linked instructions now contain the GPIO0 pending-press check, active-low wake and button cleanup, plus the gesture polling guard, while retaining radio IRQ14 wake. The HWCDC PHY handoff and startup hook remain linked; no TinyUSB USBCDC class is linked. This confirms the profile flag reached the application rather than only its source recipe.
The same pinned stock native GUI/flasher and unchanged 5,000 ms deadline were
used. Before this flash, host-only TTY preparation again changed VMIN/VTIME from
0/0 to 1/0 with zero explicit modem-signal calls. The app-only ROM preflight
again selected the protected active slot. Exact runtime readback was
v1.17.1.9-halo-keymind-cascade-dev-ebf2f082 (Build: 06-Oct-2026).
| Updated-source check | Result |
|---|---|
| First stock DOM GUI Connect after fresh flash | PASS. Plain time clock-set acknowledgement in 2,036.4 ms; full GUI bootstrap, exact version and original reference checks passed. No extra reset, replug, settle or retry. |
| Power saving on, USB logging, console open | PASS. 180.061 seconds with zero native writes or keepalives; uptime 17 -> 198 seconds. First post-idle core reply took 39.7 ms; full DOM reconnect time acknowledgement took 45.0 ms. |
| Power saving on, USB logging, console closed | PASS. 180.100 seconds with streams closed and zero writes; uptime 205 -> 391 seconds. First DOM reconnect time response took 26.7 ms and was the recognized clock-cannot-go-backwards rejection, not an acknowledgement. Full GUI bootstrap passed. |
| Cleanup and operator readback | PASS. Original power saving off, USB logging, all 15 checked preferences, public identity and ACL response were restored. Streams closed; independent operator readback again matched the exact updated version and original digests at uptime 448 seconds. |
There were no native command errors or GUI modem-signal calls. Radio remained in active RX with zero physical RX errors; flags changed 0 -> 8, received packets stayed zero and one packet was sent. This remains a receive-silence watchdog warning, not a CPU crash or loaded-radio qualification. The owned browser and tunnel were closed, the serial port had no owner, original host service states were restored, and no Pi network configuration changed.
The compact safe audit records this as updated_source_checkpoint, separate
from the older 600-second trials. The updated source qualifies these
180-second console intervals. The operator did not physically press the button;
the user's manual screen-wake confirmation is recorded above without assigning
it a firmware SHA or CPU sleep state. CPU sleep and current draw were not
measured in these USB-attached tests. GitHub unit run 37426156162 for this new
source is still in progress at this checkpoint. Release 1.17.1.9 remains held
and unpublished.