1393 Commits
Author SHA1 Message Date
JakubandClaude Opus 5.5 782f8aa567 feat(ui-lvgl): Diagnostics > Noise tab for RF noise hunting
The LoRa noise floor with the board's parts off one at a time, sweeps of
850-930 MHz, the mesh channel and a 7.8 kHz zoom on its loudest point; a
slow cycle of the same states for a second radio beside the device; and
a spike hunt over 864-876 MHz listing the lines over the floor and their
spacing (how the I2S MCLK comb was found).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-27 13:54:25 +02:00
JakubandClaude Opus 5.5 b50ecc83d5 fix(wio-tracker-l2): stop the I2S clock between sounds; GPS and TCXO fixes
The speaker's I2S channel was only disabled when idle, which leaves MCLK
running. Its fractional divider (160 MHz / 39 1/16 = 4.096 MHz) makes a
comb of lines every 256 kHz: one at 869.632 MHz, in the EU narrow mesh
channel, lifted the LoRa noise floor from ~-102 to ~-85 dBm, and others
land near GPS L1 and BeiDou B1. The channel is now deleted and its pins
held low after each sound, and made again for the next one. Measured:
noise floor -102 dBm, outdoor first fix 87 s (was 620 s and more).

Also: TCXO at 3.0 V (the L2's part, as Meshtastic has it); GLONASS
enabled on the L76K after each power-up; begin() on a running receiver
no longer resets it (a reset threw away the acquisition in progress).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-27 13:54:25 +02:00
Liam CottleandGitHub db7a5f942f Merge pull request #3508 from marcelverdult/fix/rak11310-attach-dynamic-prefs
Fix RAK11310 build: add no-op attachDynamicPrefs()
2026-09-27 20:03:59 +13:00
JakubandClaude Opus 5.5 23caa11f51 feat(ui-lvgl): power saving, review fixes, shared helpers
Power: the UI loop sleeps until something is due (never with packets
queued); screen off puts the CPU at 80 MHz, the GT911 to sleep (unless a
tap wakes the screen) and the LP5814 in standby. GPS off now cuts the
L76K's rail and UART on the L2 (L2GpsProvider). The battery divider is
powered only for a reading (measured: settles at once); readings within
2 s are reused. The SD mount is retried at most every 5 s.

Fixes: WiFi left on after leaving a scan, live tiles' WiFi kept with the
screen off on the map, an ADC read every second for the status bar, touch
polled on every pass while dark, a scan cutting an update's WiFi, relay
count not refreshing in a channel thread, raw @[nick] in room previews.
Labels skip unchanged text (no redraw).

Helpers: scrollList, dimOverlay, settingRow, flexBox, nvs::get/put,
trailFilePath (a second save in the same minute no longer overwrites),
unreadTotal. Dead code removed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-27 00:12:08 +02:00
JakubandClaude Opus 5.5 f849ee0b00 fix(wio-tracker-l2): USB power detection works - charge bolt, Power row, GPS hint
- The AW35615 USB-C controller (FUSB302-style registers, ID 0x91) only
  reports VBUSOK with its measure block on; POWER resets to bandgap only,
  so isExternalPowered() was always false. Board init turns it on
- Status bar shows a charge bolt on the cable, Diagnostics > Live has a
  Power row, the GPS screen notes that charging disturbs GPS, and the
  low-battery warning is skipped on USB as intended
- Roadmap: USB detection closed; GPS indoors still worse than the L1
  even on battery, left open for later

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-26 22:12:05 +02:00
JakubandClaude Opus 5.5 70921cd865 feat(ui-lvgl): GPS screen - sky plot, signal per satellite, fix details
- Home > GPS and Settings > System > GPS details: satellites on a sky plot
  (filled = used in the fix, colour = C/N0), a bar per satellite with its
  dB-Hz, fix state with time to first fix, DOPs, position, altitude, speed,
  UTC and per-constellation counts; a Turn on button while GPS is off
- helpers/sensors/GpsSky.h parses GSV / GSA / GGA / RMC from any talker,
  fed from MicroNMEALocationProvider behind -D GPS_SKYVIEW (L2 and the
  sim only; L1 unchanged); the sim feeds it made-up NMEA
- Roadmap: GPS indoors diagnosed with it - on the USB cable the L76K
  tracks satellites but never decodes navigation data; on battery it
  gets UTC within seconds and a fix

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-26 21:50:48 +02:00
fdlamotteandGitHub 1934a4988d Merge pull request #3202 from F4FPR/m6-power-observability
ThinkNode M6: expose external-power and charger state
2026-09-26 13:51:11 -04:00
JakubandClaude Opus 5.5 277c0cddf1 feat(ui-lvgl): roadmap stage 3 - message history on SD, Storage screen, saved trails
- Message history archived per conversation on the SD card (HIST_ARCHIVE):
  restored on boot, Older/Newer paging in threads, kept count selectable
- Settings > System > Storage: card and flash usage, breakdown by maps,
  messages, trails and other, kept-per-chat setting, delete history;
  reads the mounted volume and warns when the FAT partition is much
  smaller than the card
- Saved trails on the card: every Save is a new file, Load opens a list
  with load (framed on the map), GPX export and delete
- Diagnostics: GPS data rows, last start reason, last crash summary
- Messages restored before the clock is set show their date instead of 0s

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-26 19:17:08 +02:00
Marcel Verdult d07803bd9b Fix RAK11310 build: add no-op attachDynamicPrefs() 2026-09-26 14:07:28 +02:00
JakubandClaude Opus 5.5 4f5357031f feat(l2): Arduino 3.x as the published env, limits sized for the PSRAM, stage 7 findings
- Wio_Tracker_L2_companion_solo_lvgl now builds on Arduino-ESP32 3.3.12
  (pioarduino); the 2.0.17 build stays as _solo_lvgl_arduino2 (not published)
- Per-board limits (defaults unchanged, L1 byte-for-byte the same):
  TRAIL_CAPACITY, WAYPOINT_CAPACITY, HIST_CH_MAX / HIST_DM_MAX, NEARBY_MAX;
  the L2 sets 4096 / 64 / 256 / 128 / 64 (in PSRAM with UiCore; internal
  heap 154 KB free after). ui-lvgl: 32 trail segments, contact list 256,
  rooms 32, 50 bubbles per conversation, pickers 128, WiFi scan 20
- Map trail drawing drops points under 2 px apart
- "Nearby" is "Nodes"; advert options "Zero hop" / "Flood"
- Roadmap stage 7: LVGL on other displays -- e-ink stays ui-new, an OLED
  spike after this roadmap, Cardputer as a colour candidate

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-26 13:51:08 +02:00
JakubandClaude Opus 5.5 9e50470a51 fix(wio-tracker-l2): keep the last good battery reading when the ADC read fails
A failed ADS1115 read returned 0 mV, so the status bar showed 0 % (and the
low-battery shutdown could see an empty battery) until a reboot. Retry once,
then keep the last good value.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-26 09:14:58 +02:00
JakubandClaude Opus 5.5 ba4d01aa77 feat(ui-lvgl): roadmap stage 1 - keyboard close key, all bot placeholders, WAKE/USER button roles with hold-to-mute, WiFi switch, shorter descriptions
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-26 01:23:54 +02:00
JakubandClaude Opus 5.5 938dfefba6 feat(ui-core,ui-lvgl): sound in the Core, L2 speaker via ES8311, Sound settings, melody editor
- genericBuzzer I2S path (BUZZER_I2S): an audio task synthesises the notes
  with eased edges and keeps the DMA queue fed with silence between sounds;
  ES8311 setup; amp powered through the board only around sounds
- ui-core/SoundControl.h (mode, volume, built-in sounds, melody model),
  SoundNotifier moved to the Core, chanctl::melody, schema Sound page
- L2: notifications, alarm / timer ring, locator sounds, Settings > Sound,
  melody editor with the playing note lit, per-chat sound, mute icon
- noteIndex() on every buzzer backend; scrolling popups past screen height

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-26 00:27:52 +02:00
JakubandClaude Opus 5.5 6d82da877e feat(ui-core,ui-lvgl): room sessions and contact helpers in the Core, L2 rooms, conversation options, message actions
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-25 20:27:32 +02:00
JakubandClaude Opus 5.5 84d8a4df2a feat(ui-lvgl): navigation map, clock tools, settings pages, radio
- Home > Map is the navigation map: waypoints (list, add at GPS / by
  coordinates / long-press spot), live shares, trail recording + tools
  (save, load, GPX export, track back), live share controls, target bar
  with ETA; the nodes map opens from Nearby.
- Map: smooth panning (no decode during a drag, idle read-ahead, cached
  coarser stand-ins), overzoom limited to 2 levels, resumable downloads,
  map credit behind a "©" and in Settings > About; target ring and trail
  computed in double.
- Home in swipeable pages; Clock (alarm, timer, stopwatch, ring card).
- Settings rendered from the Core schema (display & power with a
  brightness slider, messages & contacts, trail / live share / alerts),
  GPS switch, Radio screen; low-battery shutdown.
- WioTrackerL2Display: honour the 0-4 brightness level.
- docs: L2 hardware checklist, ui-core notes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-25 19:20:42 +02:00
JakubandClaude Opus 5.5 0fa7966280 feat(ui-lvgl): on-device map download over WiFi
The map's download button fetches the visible area (overview levels up to
a chosen zoom) into /sdcard/maps from OpenTopoMap or maps/source.txt,
skipping tiles already on the card and rejecting placeholder answers.
Settings > WiFi stores the network in NVS (with scan); WiFi is on only
while a download runs. HTTP runs on a worker task on core 0; the popup
shows link, internal heap and the last TLS/HTTP error.

Internal RAM was the blocker (~13 KB free with WiFi + Bluedroid): the L2
LVGL env now allocates the_mesh in PSRAM (MESH_IN_PSRAM, static RAM
210 -> 87 KB) and mbedTLS allocates from PSRAM. Confirmed on hardware.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-25 11:26:44 +02:00
JakubandClaude Opus 5.5 64321bf12b feat(ui-lvgl): offline raster map from the microSD
Map screen (Home > Map): Web-Mercator tiles from /maps/{z}/{x}/{y}.png on
the card (Meshtastic MUI layout; per-column TPK1 .pak also read), drag to
pan, +/- zoom, re-centre/follow GPS, Nearby nodes with a position as
markers opening node detail. Tiles decode one per loop pass into a
12-slot RGB565 cache in PSRAM. map/TileProvider.h is the swap point for a
later vector renderer: the screen only calls renderTile(). The tile set's
credit line comes from maps/attribution.txt.

L2 mounts the card over SDMMC 1-bit (CLK 2, CMD 3, D0 1). LVGL's lodepng
is enabled; note its LVGL patch returns an lv_draw_buf_t*, not pixels.
LVGL pool 2 MB for PNG decoding. Fonts gain map / users icons.

tools/maps/fetch_tiles.py prepares a card for an area (presets for
Poland), requires an explicit tile URL (tile.openstreetmap.org blocks
offline use) and stops on placeholder images. The LVGL sim preloads
web/maps into the L2's /sdcard and puts its GPS on Kraków.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-25 10:57:46 +02:00
liamcottle aa1c46e1db disable hibernate ui on 1watt wio tracker variant 2026-09-25 16:55:17 +12:00
JakubandClaude Opus 5.5 3e5ccd28c7 feat(ui-lvgl): Nearby screen, node detail, scan popup; NearbyModel in the Core
ui-core/NearbyModel.h builds the Nearby list (contacts + live [LOC] shares
+ heard adverts, or discover-scan results) with type filter and sort,
moved verbatim out of ui-new's NearbyScreen, which now inherits it.

ui-lvgl: Home is three tiles (Messages, Nearby, Settings). Nearby lists
known nodes with filter chips and a Dist/Recent toggle; tapping a row opens
node detail (distance/bearing, position, last heard, ID) with Message,
Ping, favourite, Add and two-tap Delete. Scan is a popup over the list
with its own model: nodes in range now, not the known set. Fonts gain the
FontAwesome star for favourites. The LVGL sim page adds an optional
repeater so Scan has something to find.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-25 00:53:23 +02:00
JakubandClaude Opus 5.5 87fad71af3 feat(ui-lvgl): 320x240 browser simulator, compose field fixes
Simulator: SIM_UI=lvgl variants/sim/build_wasm.sh builds ui-lvgl for the
browser. SimLcdDisplay blits LVGL's RGB565 flush to a 320x240 canvas and
LvglPort.h's sim branch feeds the mouse in as touch; LVGL comes from the
L2 env's libdeps, its objects cached in web/build/obj_lvgl/. web/lvgl.html
runs it beside a ui-new peer on a direct link, with a window.sim API for
headless checks. New hooks: sim_lcd_touch, sim_lcd_button,
sim_test_send_channel_msg.

Compose: the theme's padding left less than one line in the field, so it
scrolled vertically and text jumped; pad it to fit exactly one line. The
cursor is drawn only while FOCUSED, now set while the keyboard is up.
With the keyboard up the screen header hides so the conversation keeps a
message in view; the accent popup stays inside the keyboard, clear of the
field; channel bubbles put the age next to the sender (one line shorter);
the thread scrollbar shows only while scrolling.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-25 00:36:26 +02:00
JakubandClaude Opus 5.5 221c33ec5f feat(wio-tracker-l2): board layer + ui-new bring-up env
Seeed Wio Tracker L2 (ESP32-S3R8 16MB/8MB PSRAM, SX1262, NV3031B 320x240
QSPI LCD + GT911 touch + LP5814 backlight, TCA9535 expander gating every
rail, ADS1115 battery ADC, AW35615 USB-C, L76K GNSS).

Board layer ported from meshcore-dev/MeshCore PR #3381 (Hacuchino-hash),
kept at the same paths for an easy upstream merge. Differences:
- display: dropped the UIColor theme (not adopted in this fork)
- GpsTap diagnostics wrapper omitted; GNSS reads Serial1 directly
- nv3031b ODR fix dropped: LovyanGFX >= 1.2.30 (now pinned) defines
  Panel_NV3031B::init_cmds itself -- the fix became a duplicate symbol
- MESH_DEBUG_PRINTLN with a non-literal format fixed (broke MESH_DEBUG builds)
- upload_speed 115200: baud is virtual on native USB; skips the switch

solo/wio-tracker-l2 adds Wio_Tracker_L2_companion_solo_bringup: ui-new
zoomed 2x, BOOT button only, no touch -- a hardware smoke test, not a
release target (deliberately not *_solo_dual, so CI doesn't publish it).
The real UI for this board will be a new LVGL frontend.

Verified on hardware: boot, display, radio, GPS, battery, BLE app link.
First boot takes tens of seconds while SPIFFS formats its 3.4 MB partition.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-24 21:53:18 +02:00
Liam CottleandGitHub c423dece36 Merge pull request #3490 from liamcottle/fix/heltec-ct62
Fix Heltec CT62 boot loop
2026-09-23 17:48:04 +12:00
liamcottle c13b312188 fix heltec ct62 boot loop 2026-09-23 15:04:51 +12:00
Wessel Nieboer b5787757a7 Thinknode m4 - don't touch crystal and OTA name 2026-09-21 15:55:44 +02:00
Florent 8bf072a6f0 M4: Handle poweroff 2026-09-20 16:13:15 -04:00
Florent 0a15c487d8 m4: inital port 2026-09-20 15:25:18 -04:00
Liam CottleandGitHub 0886259701 Merge pull request #3108 from tjdownes/muzi-base
Add Muzi Base board support (Duo + Uno + SuperIO)
2026-09-20 22:56:32 +12:00
TJ DownesandAudit Bot 114cf9f4fc Use the default BLE TX power on Muzi Base
Drop BLE_TX_POWER=0 from the companion envs so they use the default of
4 dBm, like most other variants. The lower power was carried over from
the original Base Duo PR and real-world range is better at the default.
2026-09-20 03:46:25 -07:00
TJ DownesandAudit Bot 798ce636df Address review feedback on Muzi Base support
- rename the board class and files to MuziBaseBoard
- uppercase the build flags (MUZI_BASE, MUZI_BASE_SUPERIO)
- name the superIO envs muzi_base_{duo,uno}_superIO_companion_radio_ble so
  build.sh picks them up
- set MAX_CONTACTS to 350 like the other variants
- move the pin setup from initVariant() into MuziBaseBoard::begin()
2026-09-19 21:47:24 -07:00
liamcottle 4021a341f8 add wifi support to thinknode m7 ble variant 2026-09-20 15:11:21 +12:00
JakubandClaude Sonnet 5 dafd6c1266 ci(sim): show the real version in the WASM demo's splash
build_wasm.sh now takes FIRMWARE_VERSION (tag name for a release,
dev-<commit> otherwise) exported by build-solo-sim.yml, so the live demo
no longer falls back to "dev-<compile date>" on tagged releases.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-19 14:22:27 +02:00
JakubandClaude Sonnet 5 1981826a85 fix(heltec_v3/v4): user_btn needs pull-up + multiclick=false in joystick mode
With UI_HAS_JOYSTICK, user_btn (Enter) was left with pulldownup=false and
multiclick=true (the plain-PRG-button defaults), instead of matching the
other wired joystick contacts. Two effects on a wired Enter button:

- No internal pull-up on the Enter pin, unlike the direction/back contacts.
- multiclick=true buffers a click for ~280ms waiting for a possible double/
  triple click, but UITask.cpp's UI_HAS_JOYSTICK loop only ever checks
  user_btn for CLICK/LONG_PRESS — so a quick double-tap collapses into a
  DOUBLE_CLICK event that's silently dropped, making Enter feel laggy and
  unreliable.

wio-tracker-l1 (factory joystick) already builds user_btn with
pulldownup/multiclick matching its other contacts; apply the same pattern
here, conditional on UI_HAS_JOYSTICK so the stock external-pull-up PRG
button path (no joystick) is unchanged.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-18 09:57:29 +02:00
liamcottle cd54ee9754 add missing null display driver class for thinknode m7 ethernet variant 2026-09-17 15:52:46 +12:00
JakubandClaude Sonnet 5 95e3cf2618 feat(radio): honest TX power for GAT562 30S external PA
gat562_30s_mesh_kit has an always-on external PA rated at +30dBm, but the
firmware wrote tx_power_dbm straight to the SX1262 register (capped at 22),
so the app/CLI/UI never matched the real radiated power and couldn't ask
for more than 22 even though the hardware supports it.

Add a generic, macro-gated PA gain-curve resolution in
RadioLibWrapper::setTxPower() (the single choke point every TX-power path
already funnels through), reusable by any future board with a similar PA.
For this board, reuse the vendor-measured 869MHz curve from the open
upstream Meshtastic PR that added it for the same physical module
(meshtastic/firmware#11212): pick the lowest SX1262 setting whose measured
output reaches the requested dBm, clamped at the PA's saturation knee.
Bump LORA_TX_POWER/MAX_LORA_TX_POWER to 30 for this variant only -- the
other three GAT562 boards use the SX1262's own PA_BOOST (22dBm, no
external PA) and are unaffected.

Since a request below the PA's floor gain (14dBm) still radiates at that
floor, also make CommonCLICallbacks::setTxPower() return what was actually
applied, and have every setter (BLE CMD_SET_RADIO_TX_POWER, CLI "tx",
simple_repeater/room_server/sensor) persist and report that value instead
of the raw request -- so tx_power_dbm never silently disagrees with the
physical output in either direction.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-16 12:54:48 +02:00
Frieder SchrempfandGitHub 9d0e2f2fac Merge branch 'dev' into dev 2026-09-15 22:59:09 +02:00
Scott Powell 3a3c13a143 * refactor to support new Board::handleCommand(), and "get/set radio.fem.*" commands 2026-09-15 18:41:11 +10:00
Scott Powell 53b6476409 Merge branch 'dev' into wio-tracker-L1-1W 2026-09-15 18:24:52 +10:00
AvamanderandGitHub 61fcc49c8a Fix Heltec Mesh Node T1 GNSS pins 2026-09-14 17:53:50 +03:00
TadyTheFish a88de69486 Enable INA226 support for ProMicro nRF52840 2026-09-13 08:27:48 +02:00
ripplebizandGitHub 34404309ae Merge pull request #3350 from Quency-D/fix-heltec_v4r8-lna
fix-heltec_v4r8-lna
2026-09-13 12:05:35 +10:00
ripplebizandGitHub 000a1b6cda Merge pull request #3371 from agessaman/feat/tbeam-1w-thermal-fan
Add thermal fan control for T-Beam 1W
2026-09-13 12:01:37 +10:00
21cdd7b319 Add Muzi Base board support (Duo + Uno + SuperIO)
One nRF52840 variant shared across both radios, picked per env: Duo runs
the LR1121, Uno the SX1262. Same PCB, only the radio and its DIO1 pin
change.

SuperIO adds the SH1107 OLED, GPS, buzzer and joystick. GPS is driven by
the 3-position mode switch (Mode 2 = on), polled live the way thinknode_m1
does it.

Five quick user-button presses power the unit off; a press wakes it back
on (arms the button as an nRF52 GPIO SENSE source before SYSTEMOFF).

Consolidates #2054 and andyshinn's shared-base/uno work, rebased on dev.

Co-authored-by: lbibass <ewdries02@gmail.com>
Co-authored-by: Andy Shinn <andys@andyshinn.as>
2026-09-12 05:41:26 -07:00
liamcottle cee43752c7 add new ENABLE_WIFI_INTERFACE build flag for companions without providing ssid and pwd 2026-09-08 22:54:50 +12:00
Michael Graff 7c2b4d88be WiFi on/off tri-state: on when SSID set unless explicitly disabled; PicoW ships no default SSID 2026-09-06 22:18:00 -05:00
Michael Graff b11a779843 Address review: per-variant wifi src, real SSID reply, rename PicoW env 2026-09-06 21:28:04 -05:00
Michael Graff b9fa450f52 Fix review findings on Pico W WiFi/BLE 2026-09-06 20:43:37 -05:00
Michael Graff 88cc014f55 Add BLE companion support for Pico W 2026-09-06 20:15:45 -05:00
Michael Graff 0b2c47a932 Add WiFi companion support for Pico W
SerialWifiInterface has no ESP32-specific code, so move it to
helpers/wifi and reuse it on RP2040. Guard the ESP32-only WiFi
event/auto-reconnect calls and poll link state on RP2040 instead.
2026-09-05 23:15:13 -05:00
agessaman 6c1f4c09a6 Fix T-Beam 1W fan races and remove PWM controls 2026-09-04 16:51:53 -07:00
agessaman 8fd6893117 feat: add T-Beam 1W thermal fan control 2026-09-04 16:03:41 -07:00