From 7073f1ebc2ca58568a300d093a2b06305542f09e Mon Sep 17 00:00:00 2001 From: sim1988son Date: Tue, 20 Oct 2026 22:07:52 +0200 Subject: [PATCH 1/7] Fix Simpson Enter with keyboard visible --- examples/companion_radio/ui-new/UITask.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/companion_radio/ui-new/UITask.cpp b/examples/companion_radio/ui-new/UITask.cpp index 3ca4a368..1672831b 100644 --- a/examples/companion_radio/ui-new/UITask.cpp +++ b/examples/companion_radio/ui-new/UITask.cpp @@ -1128,7 +1128,7 @@ void UITask::handleSimpsonKeypadKey(uint8_t key) { enqueueKey(KEY_RIGHT); break; case SIMPSON_KEY_ENTER: - enqueueKey(_unlock_kb ? KEY_KB_ENTER : KEY_ENTER); + enqueueKey((_unlock_kb || _kb.isVisible()) ? KEY_KB_ENTER : KEY_ENTER); //enqueueKey(_unlock_kb ? KEY_KB_ENTER : KEY_ENTER); break; case SIMPSON_KEY_BLUETOOTH: if (!_unlock_kb) gotoBluetoothHomePage(); From b416b4dd1363ed045ff37d8f874402154a425c37 Mon Sep 17 00:00:00 2001 From: SimpSon Date: Thu, 22 Oct 2026 21:58:30 +0200 Subject: [PATCH 2/7] Add files via upload keypad improvements --- variants/simpson/SimpsonKeypad.cpp | 162 ++++++++++++++++------------- variants/simpson/SimpsonKeypad.h | 101 +++++++++--------- variants/simpson/platformio.ini | 45 ++++---- 3 files changed, 167 insertions(+), 141 deletions(-) diff --git a/variants/simpson/SimpsonKeypad.cpp b/variants/simpson/SimpsonKeypad.cpp index f1486ea3..470be7a9 100644 --- a/variants/simpson/SimpsonKeypad.cpp +++ b/variants/simpson/SimpsonKeypad.cpp @@ -1,70 +1,92 @@ -#include "SimpsonKeypad.h" - -#include - -namespace { -char control_keymap[19] = { - SIMPSON_KEY_CANCEL, SIMPSON_KEY_UP, 0, SIMPSON_KEY_BLUETOOTH, - SIMPSON_KEY_LEFT, SIMPSON_KEY_ENTER, SIMPSON_KEY_RIGHT, SIMPSON_KEY_BRIGHTNESS_UP, - SIMPSON_KEY_SYMBOLS, SIMPSON_KEY_DOWN, 0, SIMPSON_KEY_BRIGHTNESS_DOWN, - SIMPSON_KEY_MESSAGES, 0, SIMPSON_KEY_FN, SIMPSON_KEY_GPS, 0, 0, 0 -}; - -char alphabet_keymap[19] = { - ',', 'A', 'D', SIMPSON_KEY_BLUETOOTH, - 'G', 'J', 'M', SIMPSON_KEY_BRIGHTNESS_UP, - 'P', 'T', 'W', SIMPSON_KEY_BRIGHTNESS_DOWN, - SIMPSON_KEY_BACKSPACE, ' ', SIMPSON_KEY_FN, SIMPSON_KEY_GPS, 0, 0, 0 -}; - -char numeric_keymap[19] = { - '1', '2', '3', SIMPSON_KEY_BLUETOOTH, - '4', '5', '6', SIMPSON_KEY_BRIGHTNESS_UP, - '7', '8', '9', SIMPSON_KEY_BRIGHTNESS_DOWN, - SIMPSON_KEY_BACKSPACE, '0', SIMPSON_KEY_FN, SIMPSON_KEY_GPS, 0, 0, 0 -}; -} - -bool SimpsonKeypad::begin() { - if (!_keypad.begin()) return false; - _keypad.setKeyPadMode(I2C_KEYPAD_4x4); - _keypad.setDebounceThreshold(50); - loadModeMap(); - _ready = true; - return true; -} - -void SimpsonKeypad::loadModeMap() { - switch (_mode) { - case SIMPSON_KEYPAD_CONTROL: - _keypad.loadKeyMap(control_keymap); - break; - case SIMPSON_KEYPAD_ABC: - case SIMPSON_KEYPAD_ABC_UPPER: - _keypad.loadKeyMap(alphabet_keymap); - break; - case SIMPSON_KEYPAD_NUMERIC: - _keypad.loadKeyMap(numeric_keymap); - break; - } -} - -uint8_t SimpsonKeypad::poll() { - if (!_ready) return SIMPSON_KEY_NONE; - - uint8_t key = _keypad.getChar(); - if (key == I2C_KEYPAD_THRESHOLD) return SIMPSON_KEY_NONE; - if (key == SIMPSON_KEY_NONE) { - _last_key = SIMPSON_KEY_NONE; - return SIMPSON_KEY_NONE; - } - if (key == _last_key) return SIMPSON_KEY_NONE; - _last_key = key; - - if (key == SIMPSON_KEY_FN) { - _mode = static_cast((_mode + 1) % 4); - loadModeMap(); - return SIMPSON_KEY_MODE_CHANGED; - } - return key; -} +#include "SimpsonKeypad.h" + +static const uint32_t SIMPSON_LONG_PRESS_MS = 1200; + +#include + +namespace { +char control_keymap[19] = { + SIMPSON_KEY_CANCEL, SIMPSON_KEY_UP, 0, SIMPSON_KEY_BLUETOOTH, + SIMPSON_KEY_LEFT, SIMPSON_KEY_ENTER, SIMPSON_KEY_RIGHT, SIMPSON_KEY_BRIGHTNESS_UP, + SIMPSON_KEY_SYMBOLS, SIMPSON_KEY_DOWN, 0, SIMPSON_KEY_BRIGHTNESS_DOWN, + SIMPSON_KEY_MESSAGES, 0, SIMPSON_KEY_FN, SIMPSON_KEY_GPS, 0, 0, 0 +}; + +char alphabet_keymap[19] = { + ',', 'A', 'D', SIMPSON_KEY_BLUETOOTH, + 'G', 'J', 'M', SIMPSON_KEY_BRIGHTNESS_UP, + 'P', 'T', 'W', SIMPSON_KEY_BRIGHTNESS_DOWN, + SIMPSON_KEY_BACKSPACE, ' ', SIMPSON_KEY_FN, SIMPSON_KEY_GPS, 0, 0, 0 +}; + +char numeric_keymap[19] = { + '1', '2', '3', SIMPSON_KEY_BLUETOOTH, + '4', '5', '6', SIMPSON_KEY_BRIGHTNESS_UP, + '7', '8', '9', SIMPSON_KEY_BRIGHTNESS_DOWN, + SIMPSON_KEY_BACKSPACE, '0', SIMPSON_KEY_FN, SIMPSON_KEY_GPS, 0, 0, 0 +}; +} + +bool SimpsonKeypad::begin() { + if (!_keypad.begin()) return false; + _keypad.setKeyPadMode(I2C_KEYPAD_4x4); + _keypad.setDebounceThreshold(50); + loadModeMap(); + _ready = true; + return true; +} + +void SimpsonKeypad::loadModeMap() { + switch (_mode) { + case SIMPSON_KEYPAD_CONTROL: + _keypad.loadKeyMap(control_keymap); + break; + case SIMPSON_KEYPAD_ABC: + case SIMPSON_KEYPAD_ABC_UPPER: + _keypad.loadKeyMap(alphabet_keymap); + break; + case SIMPSON_KEYPAD_NUMERIC: + _keypad.loadKeyMap(numeric_keymap); + break; + } +} + +uint8_t SimpsonKeypad::poll() { + if (!_ready) return SIMPSON_KEY_NONE; + + uint8_t key = _keypad.getChar(); + if (key == I2C_KEYPAD_THRESHOLD) return SIMPSON_KEY_NONE; + if (key == SIMPSON_KEY_NONE) { + if (_last_key == SIMPSON_KEY_ENTER && !_enter_long_sent) { + _last_key = SIMPSON_KEY_NONE; + _enter_pressed_at = 0; + return SIMPSON_KEY_ENTER; + } + _last_key = SIMPSON_KEY_NONE; + _enter_pressed_at = 0; + _enter_long_sent = false; + return SIMPSON_KEY_NONE; + } + if (key == SIMPSON_KEY_ENTER && _last_key == SIMPSON_KEY_ENTER) { + if (!_enter_long_sent && millis() - _enter_pressed_at >= SIMPSON_LONG_PRESS_MS) { + _enter_long_sent = true; + return SIMPSON_KEY_ENTER_LONG; + } + return SIMPSON_KEY_NONE; + } + if (key == _last_key) return SIMPSON_KEY_NONE; + _last_key = key; + + if (key == SIMPSON_KEY_ENTER) { + _enter_pressed_at = millis(); + _enter_long_sent = false; + return SIMPSON_KEY_NONE; + } + + if (key == SIMPSON_KEY_FN) { + _mode = static_cast((_mode + 1) % 4); + loadModeMap(); + return SIMPSON_KEY_MODE_CHANGED; + } + return key; +} diff --git a/variants/simpson/SimpsonKeypad.h b/variants/simpson/SimpsonKeypad.h index 5fb5e2d5..63a4c52b 100644 --- a/variants/simpson/SimpsonKeypad.h +++ b/variants/simpson/SimpsonKeypad.h @@ -1,49 +1,52 @@ -#pragma once - -#include -#include - -#ifndef SIMPSON_KEYPAD_ADDR - #define SIMPSON_KEYPAD_ADDR 0x20 -#endif - -enum SimpsonKeypadMode : uint8_t { - SIMPSON_KEYPAD_CONTROL, - SIMPSON_KEYPAD_ABC, - SIMPSON_KEYPAD_ABC_UPPER, - SIMPSON_KEYPAD_NUMERIC -}; - -enum SimpsonKeypadKey : uint8_t { - SIMPSON_KEY_NONE = 0, - SIMPSON_KEY_CANCEL = 1, - SIMPSON_KEY_UP, - SIMPSON_KEY_BLUETOOTH, - SIMPSON_KEY_LEFT, - SIMPSON_KEY_ENTER, - SIMPSON_KEY_RIGHT, - SIMPSON_KEY_BRIGHTNESS_UP, - SIMPSON_KEY_SYMBOLS, - SIMPSON_KEY_DOWN, - SIMPSON_KEY_BRIGHTNESS_DOWN, - SIMPSON_KEY_MESSAGES, - SIMPSON_KEY_FN, - SIMPSON_KEY_GPS, - SIMPSON_KEY_BACKSPACE, - SIMPSON_KEY_MODE_CHANGED -}; - -class SimpsonKeypad { - I2CKeyPad _keypad; - SimpsonKeypadMode _mode = SIMPSON_KEYPAD_CONTROL; - uint8_t _last_key = SIMPSON_KEY_NONE; - bool _ready = false; - - void loadModeMap(); - -public: - SimpsonKeypad() : _keypad(SIMPSON_KEYPAD_ADDR, &Wire) {} - bool begin(); - uint8_t poll(); - SimpsonKeypadMode mode() const { return _mode; } -}; +#pragma once + +#include +#include + +#ifndef SIMPSON_KEYPAD_ADDR + #define SIMPSON_KEYPAD_ADDR 0x20 +#endif + +enum SimpsonKeypadMode : uint8_t { + SIMPSON_KEYPAD_CONTROL, + SIMPSON_KEYPAD_ABC, + SIMPSON_KEYPAD_ABC_UPPER, + SIMPSON_KEYPAD_NUMERIC +}; + +enum SimpsonKeypadKey : uint8_t { + SIMPSON_KEY_NONE = 0, + SIMPSON_KEY_CANCEL = 1, + SIMPSON_KEY_UP, + SIMPSON_KEY_BLUETOOTH, + SIMPSON_KEY_LEFT, + SIMPSON_KEY_ENTER, + SIMPSON_KEY_RIGHT, + SIMPSON_KEY_BRIGHTNESS_UP, + SIMPSON_KEY_SYMBOLS, + SIMPSON_KEY_DOWN, + SIMPSON_KEY_BRIGHTNESS_DOWN, + SIMPSON_KEY_MESSAGES, + SIMPSON_KEY_FN, + SIMPSON_KEY_GPS, + SIMPSON_KEY_BACKSPACE, + SIMPSON_KEY_MODE_CHANGED, + SIMPSON_KEY_ENTER_LONG +}; + +class SimpsonKeypad { + I2CKeyPad _keypad; + SimpsonKeypadMode _mode = SIMPSON_KEYPAD_CONTROL; + uint8_t _last_key = SIMPSON_KEY_NONE; + uint32_t _enter_pressed_at = 0; + bool _enter_long_sent = false; + bool _ready = false; + + void loadModeMap(); + +public: + SimpsonKeypad() : _keypad(SIMPSON_KEYPAD_ADDR, &Wire) {} + bool begin(); + uint8_t poll(); + SimpsonKeypadMode mode() const { return _mode; } +}; diff --git a/variants/simpson/platformio.ini b/variants/simpson/platformio.ini index 8ecd4ea1..1d1fbc9d 100644 --- a/variants/simpson/platformio.ini +++ b/variants/simpson/platformio.ini @@ -1,22 +1,23 @@ -[Simpson] -extends = Promicro -build_unflags = -D PIN_GPS_RX=3 -D PIN_GPS_TX=4 -D ENV_INCLUDE_AHTX0=1 -D ENV_INCLUDE_BME280=1 -D ENV_INCLUDE_BMP280=1 -D ENV_INCLUDE_INA3221=1 -D ENV_INCLUDE_INA219=1 -D ENV_INCLUDE_INA226=1 -build_flags = ${Promicro.build_flags} - -I variants/simpson - -D SIMPSON - -D PIN_BUZZER=0 - -D PIN_GPS_TX=3 - -D PIN_GPS_RX=4 - -D PIN_VIBRATION=1 - -D ADC_MULTIPLIER=1.71 - -D SIMPSON_KEYPAD_ADDR=0x20 - -D DISPLAY_ROTATION=2 - -D ENV_SKIP_GPS_DETECT -build_src_filter = ${nrf52_base.build_src_filter} - + - +<../variants/simpson> - +<../variants/promicro/target.cpp> - +<../variants/promicro/PromicroBoard.cpp> -lib_deps = ${Promicro.lib_deps} - adafruit/Adafruit SH110X @ ^2.1.13 - RobTillaart/I2CKeyPad @ ^0.5.2 +[Simpson] +extends = Promicro +build_unflags = -D PIN_GPS_RX=3 -D PIN_GPS_TX=4 -D ENV_INCLUDE_AHTX0=1 -D ENV_INCLUDE_BME280=1 -D ENV_INCLUDE_BMP280=1 -D ENV_INCLUDE_INA3221=1 -D ENV_INCLUDE_INA219=1 -D ENV_INCLUDE_INA226=1 +build_flags = ${Promicro.build_flags} + -I variants/simpson + -D SIMPSON + -D PIN_BUZZER=0 + -D PIN_GPS_TX=3 + -D PIN_GPS_RX=4 + -D PIN_VIBRATION=1 + -D ADC_MULTIPLIER=1.71 + -D SIMPSON_KEYPAD_ADDR=0x20 + -D DISPLAY_ROTATION=2 + -D ENV_INCLUDE_GPS=1 + -D ENV_SKIP_GPS_DETECT +build_src_filter = ${nrf52_base.build_src_filter} + + + +<../variants/simpson> + +<../variants/promicro/target.cpp> + +<../variants/promicro/PromicroBoard.cpp> +lib_deps = ${Promicro.lib_deps} + adafruit/Adafruit SH110X @ ^2.1.13 + RobTillaart/I2CKeyPad @ ^0.5.2 From 564ffe06599b685a4303226dffe6953808283b24 Mon Sep 17 00:00:00 2001 From: SimpSon Date: Thu, 22 Oct 2026 21:59:45 +0200 Subject: [PATCH 3/7] Add files via upload add -D GPS_SKYVIEW --- solo/simpson/platformio.ini | 64 +++++++++++++++++++------------------ 1 file changed, 33 insertions(+), 31 deletions(-) diff --git a/solo/simpson/platformio.ini b/solo/simpson/platformio.ini index 2f640f4a..a267779f 100644 --- a/solo/simpson/platformio.ini +++ b/solo/simpson/platformio.ini @@ -1,31 +1,33 @@ -; Solo build for Simpson, sim1988son's DIY board: a ProMicro nRF52840 with -; a RA-01S radio, an ATGM336H GPS, a 1.3" SH1106 OLED and a 4x4 keypad on a -; PCF8574 (see docs/solo/hardware.md#simpson and its schematic there). -; The _solo_dual suffix is what the release workflow builds. -[env:Simpson_companion_solo_dual] -extends = Simpson -board_build.ldscript = boards/nrf52840_s140_v6_extrafs.ld -board_upload.maximum_size = 712704 -build_unflags = ${Simpson.build_unflags} -Ofast -D OFFLINE_QUEUE_SIZE=256 -build_flags = ${Simpson.build_flags} - -I examples/companion_radio/ui-new - -D MAX_CONTACTS=350 - -D MAX_GROUP_CHANNELS=40 - -D BLE_PIN_CODE=123456 - -D DUAL_SERIAL=1 - -D OFFLINE_QUEUE_SIZE=128 - -D DISPLAY_CLASS=SH1106Display - -D FIRMWARE_SOLO_BUILD=1 - -D UI_SENSORS_PAGE=1 - -Os -build_src_filter = ${Simpson.build_src_filter} - + - + - + - + - + - +<../examples/companion_radio/*.cpp> - +<../examples/companion_radio/ui-new/*.cpp> -lib_deps = ${Simpson.lib_deps} - adafruit/RTClib @ ^2.1.3 - densaugeo/base64 @ ~1.4.0 +; Solo build for Simpson, sim1988son's DIY board: a ProMicro nRF52840 with +; a RA-01S radio, an ATGM336H GPS, a 1.3" SH1106 OLED and a 4x4 keypad on a +; PCF8574 (see docs/solo/hardware.md#simpson and its schematic there). +; The _solo_dual suffix is what the release workflow builds. +[env:Simpson_companion_solo_dual] +extends = Simpson +board_build.ldscript = boards/nrf52840_s140_v6_extrafs.ld +board_upload.maximum_size = 712704 +build_unflags = ${Simpson.build_unflags} -Ofast -D OFFLINE_QUEUE_SIZE=256 +build_flags = ${Simpson.build_flags} + -I examples/companion_radio/ui-new + -D MAX_CONTACTS=350 + -D MAX_GROUP_CHANNELS=40 + -D BLE_PIN_CODE=123456 + -D DUAL_SERIAL=1 + -D MESHCORE_VERSION='"2.0.1"' + -D OFFLINE_QUEUE_SIZE=128 + -D DISPLAY_CLASS=SH1106Display + -D FIRMWARE_SOLO_BUILD=1 + -D UI_SENSORS_PAGE=1 + -D GPS_SKYVIEW + -Os +build_src_filter = ${Simpson.build_src_filter} + + + + + + + + + + + +<../examples/companion_radio/*.cpp> + +<../examples/companion_radio/ui-new/*.cpp> +lib_deps = ${Simpson.lib_deps} + adafruit/RTClib @ ^2.1.3 + densaugeo/base64 @ ~1.4.0 From 323a9819a2a1bc2aa32df057939e69de1ea23eac Mon Sep 17 00:00:00 2001 From: SimpSon Date: Thu, 22 Oct 2026 22:01:54 +0200 Subject: [PATCH 4/7] Add files via upload Preserves the last GPS fix --- src/helpers/sensors/EnvironmentSensorManager.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/helpers/sensors/EnvironmentSensorManager.cpp b/src/helpers/sensors/EnvironmentSensorManager.cpp index b51ae62e..8ddf8e7f 100644 --- a/src/helpers/sensors/EnvironmentSensorManager.cpp +++ b/src/helpers/sensors/EnvironmentSensorManager.cpp @@ -950,6 +950,11 @@ void EnvironmentSensorManager::gpsDutyCycleLoop() { // awake -- back to sleep once we have a fix, or once we've waited long // enough that one isn't coming this cycle if (_location->isValid() || (int32_t)(now - _gps_duty_phase_until) >= 0) { + if (_location->isValid()) { + node_lat = ((double)_location->getLatitude()) / 1000000.0; + node_lon = ((double)_location->getLongitude()) / 1000000.0; + node_altitude = ((double)_location->getAltitude()) / 1000.0; + } stop_gps(); _gps_duty_phase_until = now + gps_duty_sleep_sec * 1000UL; } From fd10ac6a40de4f7c6dce6205da9dda44a79ad14d Mon Sep 17 00:00:00 2001 From: SimpSon Date: Thu, 22 Oct 2026 22:05:33 +0200 Subject: [PATCH 5/7] Add files via upload during GPS duty-cycle sleep, displays the cached position, adds long-press Enter handling --- .../companion_radio/ui-new/StatusScreen.h | 12 +++++--- examples/companion_radio/ui-new/UITask.cpp | 30 ++++++------------- 2 files changed, 17 insertions(+), 25 deletions(-) diff --git a/examples/companion_radio/ui-new/StatusScreen.h b/examples/companion_radio/ui-new/StatusScreen.h index c207f3ea..ec08ebfb 100644 --- a/examples/companion_radio/ui-new/StatusScreen.h +++ b/examples/companion_radio/ui-new/StatusScreen.h @@ -2,6 +2,7 @@ #include #include #include +#include #include "icons.h" #include "InfoKit.h" #include "PopupMenu.h" @@ -167,8 +168,9 @@ private: #endif if (!loc) { row(d, f, rsv, "Receiver", "none"); return; } const bool fix = loc->isValid(); + const bool sleeping = sensors.isGpsDutySleeping(); if (f.place(lh + 5)) { // the fix as a chip, satellites used / in view - const char* st = !on ? "OFF" : !fix ? "NO FIX" : (g && g->fix_mode == 2) ? "2D FIX" : "3D FIX"; + const char* st = !on ? "OFF" : sleeping ? "SLEEP" : !fix ? "NO FIX" : (g && g->fix_mode == 2) ? "2D FIX" : "3D FIX"; info::chip(d, 1, f.at, st, on && fix); #ifdef STATUS_HAS_SKY if (g) snprintf(a, sizeof(a), "%d/%d sats", skyview::usedCount(*g), g->count); @@ -177,15 +179,17 @@ private: snprintf(a, sizeof(a), "%ld sats", loc->satellitesCount()); d.drawTextRightAlign(d.width() - rsv - 2, f.at + 1, a); } - const long lat = loc->getLatitude(), lon = loc->getLongitude(); + const long lat = fix ? loc->getLatitude() : lround(sensors.node_lat * 1000000.0); + const long lon = fix ? loc->getLongitude() : lround(sensors.node_lon * 1000000.0); // The driver reports 999 deg before a first fix (0,0 in the simulator). const bool known = labs(lat) <= 90000000L && (lat || lon); if (known) snprintf(a, sizeof(a), "%.5f\xc2\xb0%c", labs(lat) / 1e6, lat < 0 ? 'S' : 'N'); else strcpy(a, "-"); row(d, f, rsv, fix ? "Lat" : "Lat (last)", a); if (known) snprintf(a, sizeof(a), "%.5f\xc2\xb0%c", labs(lon) / 1e6, lon < 0 ? 'W' : 'E'); else strcpy(a, "-"); row(d, f, rsv, fix ? "Lon" : "Lon (last)", a); - if (fix) { - telemetry::altText(loc->getAltitude() / 1000.0f, imperial(), L1_INFO, a, sizeof(a)); + if (fix || (sensors.node_lat != 0.0 || sensors.node_lon != 0.0)) { + const double altitude = fix ? loc->getAltitude() / 1000.0 : sensors.node_altitude; + telemetry::altText(altitude, imperial(), L1_INFO, a, sizeof(a)); row(d, f, rsv, "Altitude", a); } if (g && fix) { diff --git a/examples/companion_radio/ui-new/UITask.cpp b/examples/companion_radio/ui-new/UITask.cpp index 1672831b..ac5e5bf9 100644 --- a/examples/companion_radio/ui-new/UITask.cpp +++ b/examples/companion_radio/ui-new/UITask.cpp @@ -1097,6 +1097,12 @@ void UITask::pollSimpsonKeypad() { } void UITask::handleSimpsonKeypadKey(uint8_t key) { + if (key == SIMPSON_KEY_ENTER_LONG) { + if (_locked && !_unlock_kb) return; + enqueueKey(handleLongPress(KEY_ENTER)); + return; + } + if (checkDisplayOn(KEY_ENTER) == 0 || (_locked && !_unlock_kb)) return; const uint32_t auto_off = autoOffMillis(); @@ -1128,7 +1134,7 @@ void UITask::handleSimpsonKeypadKey(uint8_t key) { enqueueKey(KEY_RIGHT); break; case SIMPSON_KEY_ENTER: - enqueueKey((_unlock_kb || _kb.isVisible()) ? KEY_KB_ENTER : KEY_ENTER); //enqueueKey(_unlock_kb ? KEY_KB_ENTER : KEY_ENTER); + enqueueKey((_unlock_kb || _kb.isVisible()) ? KEY_KB_ENTER : KEY_ENTER); break; case SIMPSON_KEY_BLUETOOTH: if (!_unlock_kb) gotoBluetoothHomePage(); @@ -1261,7 +1267,8 @@ void UITask::loop() { #if FEAT_DISPLAY_ROTATION_SETTING && defined(JOYSTICK_UPRIGHT_ROTATION) if (_node_prefs) joy_rot += (JOYSTICK_UPRIGHT_ROTATION - _node_prefs->display_rotation) & 3; #endif - auto enterClick = [&]() { + int ev = user_btn.check(); + if (ev == BUTTON_EVENT_CLICK) { if (back_btn.isPressed() && !_unlock_kb) { // Enter clicked while Back is held — lock/unlock sequence if (_display && !_display->isOn()) { @@ -1286,25 +1293,6 @@ void UITask::loop() { } enqueueKey(checkDisplayOn(KEY_ENTER)); } - }; - int ev = user_btn.check(); -#ifdef UI_ENTER_DOUBLE_BACK - // For a joystick without a reachable Back button: a double click on Enter goes - // back. Multi-click delays a single Enter by the click window. Where text is - // typed (on-screen keyboard, PIN pad) or the lock sequence is counting, a - // double is just two Enters, so a repeated letter still works. - if (ev == BUTTON_EVENT_DOUBLE_CLICK || ev == BUTTON_EVENT_TRIPLE_CLICK) { - int n = (ev == BUTTON_EVENT_DOUBLE_CLICK) ? 2 : 3; - if (_unlock_kb || _kb.isVisible() || back_btn.isPressed()) { - for (int i = 0; i < n; i++) enterClick(); - } else { - enqueueKey(checkDisplayOn(KEY_CANCEL)); - } - ev = BUTTON_EVENT_NONE; - } -#endif - if (ev == BUTTON_EVENT_CLICK) { - enterClick(); } else if (ev == BUTTON_EVENT_LONG_PRESS) { enqueueKey(handleLongPress(KEY_ENTER)); // REVISIT: could be mapped to different key code } From b751956466995a478a872e7462f7c304c0809145 Mon Sep 17 00:00:00 2001 From: SimpSon Date: Thu, 22 Oct 2026 23:01:17 +0200 Subject: [PATCH 6/7] Add files via upload --- examples/companion_radio/ui-new/UITask.cpp | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/examples/companion_radio/ui-new/UITask.cpp b/examples/companion_radio/ui-new/UITask.cpp index ac5e5bf9..b481a398 100644 --- a/examples/companion_radio/ui-new/UITask.cpp +++ b/examples/companion_radio/ui-new/UITask.cpp @@ -1267,8 +1267,7 @@ void UITask::loop() { #if FEAT_DISPLAY_ROTATION_SETTING && defined(JOYSTICK_UPRIGHT_ROTATION) if (_node_prefs) joy_rot += (JOYSTICK_UPRIGHT_ROTATION - _node_prefs->display_rotation) & 3; #endif - int ev = user_btn.check(); - if (ev == BUTTON_EVENT_CLICK) { + auto enterClick = [&]() { if (back_btn.isPressed() && !_unlock_kb) { // Enter clicked while Back is held — lock/unlock sequence if (_display && !_display->isOn()) { @@ -1292,6 +1291,25 @@ void UITask::loop() { _lock_seq_ms = 0; } enqueueKey(checkDisplayOn(KEY_ENTER)); + }; + int ev = user_btn.check(); + #ifdef UI_ENTER_DOUBLE_BACK + // For a joystick without a reachable Back button: a double click on Enter goes + // back. Multi-click delays a single Enter by the click window. Where text is + // typed (on-screen keyboard, PIN pad) or the lock sequence is counting, a + // double is just two Enters, so a repeated letter still works. + if (ev == BUTTON_EVENT_DOUBLE_CLICK || ev == BUTTON_EVENT_TRIPLE_CLICK) { + int n = (ev == BUTTON_EVENT_DOUBLE_CLICK) ? 2 : 3; + if (_unlock_kb || _kb.isVisible() || back_btn.isPressed()) { + for (int i = 0; i < n; i++) enterClick(); + } else { + enqueueKey(checkDisplayOn(KEY_CANCEL)); + } + ev = BUTTON_EVENT_NONE; + } + #endif + if (ev == BUTTON_EVENT_CLICK) { + enterClick(); } } else if (ev == BUTTON_EVENT_LONG_PRESS) { enqueueKey(handleLongPress(KEY_ENTER)); // REVISIT: could be mapped to different key code From 2d2360fc75dbd3d68f7ed41e8b47a58b33a651e4 Mon Sep 17 00:00:00 2001 From: SimpSon Date: Thu, 22 Oct 2026 23:03:44 +0200 Subject: [PATCH 7/7] Add files via upload --- examples/companion_radio/ui-new/UITask.cpp | 36 +++++++++++----------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/examples/companion_radio/ui-new/UITask.cpp b/examples/companion_radio/ui-new/UITask.cpp index b481a398..9e9cfcae 100644 --- a/examples/companion_radio/ui-new/UITask.cpp +++ b/examples/companion_radio/ui-new/UITask.cpp @@ -1291,26 +1291,26 @@ void UITask::loop() { _lock_seq_ms = 0; } enqueueKey(checkDisplayOn(KEY_ENTER)); - }; - int ev = user_btn.check(); - #ifdef UI_ENTER_DOUBLE_BACK - // For a joystick without a reachable Back button: a double click on Enter goes - // back. Multi-click delays a single Enter by the click window. Where text is - // typed (on-screen keyboard, PIN pad) or the lock sequence is counting, a - // double is just two Enters, so a repeated letter still works. - if (ev == BUTTON_EVENT_DOUBLE_CLICK || ev == BUTTON_EVENT_TRIPLE_CLICK) { - int n = (ev == BUTTON_EVENT_DOUBLE_CLICK) ? 2 : 3; - if (_unlock_kb || _kb.isVisible() || back_btn.isPressed()) { - for (int i = 0; i < n; i++) enterClick(); - } else { - enqueueKey(checkDisplayOn(KEY_CANCEL)); - } - ev = BUTTON_EVENT_NONE; } - #endif - if (ev == BUTTON_EVENT_CLICK) { - enterClick(); + }; + int ev = user_btn.check(); +#ifdef UI_ENTER_DOUBLE_BACK + // For a joystick without a reachable Back button: a double click on Enter goes + // back. Multi-click delays a single Enter by the click window. Where text is + // typed (on-screen keyboard, PIN pad) or the lock sequence is counting, a + // double is just two Enters, so a repeated letter still works. + if (ev == BUTTON_EVENT_DOUBLE_CLICK || ev == BUTTON_EVENT_TRIPLE_CLICK) { + int n = (ev == BUTTON_EVENT_DOUBLE_CLICK) ? 2 : 3; + if (_unlock_kb || _kb.isVisible() || back_btn.isPressed()) { + for (int i = 0; i < n; i++) enterClick(); + } else { + enqueueKey(checkDisplayOn(KEY_CANCEL)); } + ev = BUTTON_EVENT_NONE; + } +#endif + if (ev == BUTTON_EVENT_CLICK) { + enterClick(); } else if (ev == BUTTON_EVENT_LONG_PRESS) { enqueueKey(handleLongPress(KEY_ENTER)); // REVISIT: could be mapped to different key code }