From 8765b3d040776b698899938a31d52553de850ea3 Mon Sep 17 00:00:00 2001 From: Florent de Lamotte Date: Wed, 18 Jun 2025 11:52:16 +0200 Subject: [PATCH 1/5] Gps toggle on 4 clicks --- examples/companion_radio/Button.cpp | 8 +++++++- examples/companion_radio/Button.h | 3 +++ examples/companion_radio/UITask.cpp | 7 +++++++ examples/companion_radio/UITask.h | 1 + src/MeshCore.h | 1 + {src/helpers/nrf52 => variants/t1000-e}/T1000eBoard.cpp | 5 +++++ {src/helpers/nrf52 => variants/t1000-e}/T1000eBoard.h | 2 ++ variants/t1000-e/target.h | 3 ++- 8 files changed, 28 insertions(+), 2 deletions(-) rename {src/helpers/nrf52 => variants/t1000-e}/T1000eBoard.cpp (96%) rename {src/helpers/nrf52 => variants/t1000-e}/T1000eBoard.h (98%) diff --git a/examples/companion_radio/Button.cpp b/examples/companion_radio/Button.cpp index ec1f0f69..f9e83dba 100644 --- a/examples/companion_radio/Button.cpp +++ b/examples/companion_radio/Button.cpp @@ -50,9 +50,12 @@ void Button::update() { triggerEvent(SHORT_PRESS); } else if (_clickCount == 2) { triggerEvent(DOUBLE_PRESS); - } else if (_clickCount >= 3) { + } else if (_clickCount == 3) { triggerEvent(TRIPLE_PRESS); + } else if (_clickCount >= 4) { + triggerEvent(QUADRUPLE_PRESS); } + _clickCount = 0; _state = IDLE; } @@ -116,6 +119,9 @@ void Button::triggerEvent(EventType event) { case TRIPLE_PRESS: if (_onTriplePress) _onTriplePress(); break; + case QUADRUPLE_PRESS: + if (_onQuadruplePress) _onQuadruplePress(); + break; case LONG_PRESS: if (_onLongPress) _onLongPress(); break; diff --git a/examples/companion_radio/Button.h b/examples/companion_radio/Button.h index 47c792bd..9df809b2 100644 --- a/examples/companion_radio/Button.h +++ b/examples/companion_radio/Button.h @@ -16,6 +16,7 @@ public: SHORT_PRESS, DOUBLE_PRESS, TRIPLE_PRESS, + QUADRUPLE_PRESS, LONG_PRESS, ANY_PRESS }; @@ -32,6 +33,7 @@ public: void onShortPress(EventCallback callback) { _onShortPress = callback; } void onDoublePress(EventCallback callback) { _onDoublePress = callback; } void onTriplePress(EventCallback callback) { _onTriplePress = callback; } + void onQuadruplePress(EventCallback callback) { _onQuadruplePress = callback; } void onLongPress(EventCallback callback) { _onLongPress = callback; } void onAnyPress(EventCallback callback) { _onAnyPress = callback; } @@ -68,6 +70,7 @@ private: EventCallback _onShortPress = nullptr; EventCallback _onDoublePress = nullptr; EventCallback _onTriplePress = nullptr; + EventCallback _onQuadruplePress = nullptr; EventCallback _onLongPress = nullptr; EventCallback _onAnyPress = nullptr; diff --git a/examples/companion_radio/UITask.cpp b/examples/companion_radio/UITask.cpp index 01906f90..eef8b54b 100644 --- a/examples/companion_radio/UITask.cpp +++ b/examples/companion_radio/UITask.cpp @@ -72,6 +72,7 @@ void UITask::begin(DisplayDriver* display, NodePrefs* node_prefs) { _userButton->onShortPress([this]() { handleButtonShortPress(); }); _userButton->onDoublePress([this]() { handleButtonDoublePress(); }); _userButton->onTriplePress([this]() { handleButtonTriplePress(); }); + _userButton->onQuadruplePress([this]() { handleButtonQuadruplePress(); }); _userButton->onLongPress([this]() { handleButtonLongPress(); }); _userButton->onAnyPress([this]() { handleButtonAnyPress(); }); #endif @@ -383,6 +384,12 @@ void UITask::handleButtonTriplePress() { #endif } +void UITask::handleButtonQuadruplePress() { + MESH_DEBUG_PRINTLN("UITask: quad press triggered"); + _board->toggleGps(); + _need_refresh = true; +} + void UITask::handleButtonLongPress() { MESH_DEBUG_PRINTLN("UITask: long press triggered"); if (millis() - ui_started_at < 8000) { // long press in first 8 seconds since startup -> CLI/rescue diff --git a/examples/companion_radio/UITask.h b/examples/companion_radio/UITask.h index 93a2ef89..e9a67085 100644 --- a/examples/companion_radio/UITask.h +++ b/examples/companion_radio/UITask.h @@ -53,6 +53,7 @@ class UITask { void handleButtonShortPress(); void handleButtonDoublePress(); void handleButtonTriplePress(); + void handleButtonQuadruplePress(); void handleButtonLongPress(); diff --git a/src/MeshCore.h b/src/MeshCore.h index 98134e50..3c425487 100644 --- a/src/MeshCore.h +++ b/src/MeshCore.h @@ -41,6 +41,7 @@ public: virtual void onAfterTransmit() { } virtual void reboot() = 0; virtual void powerOff() { /* no op */ } + virtual bool toggleGps() { return false; } // could be a board_toggle depending on the board features ... virtual uint8_t getStartupReason() const = 0; virtual bool startOTAUpdate(const char* id, char reply[]) { return false; } // not supported }; diff --git a/src/helpers/nrf52/T1000eBoard.cpp b/variants/t1000-e/T1000eBoard.cpp similarity index 96% rename from src/helpers/nrf52/T1000eBoard.cpp rename to variants/t1000-e/T1000eBoard.cpp index a17711db..81486acd 100644 --- a/src/helpers/nrf52/T1000eBoard.cpp +++ b/variants/t1000-e/T1000eBoard.cpp @@ -1,6 +1,7 @@ #include #include "T1000eBoard.h" #include +#include "target.h" #include @@ -26,6 +27,10 @@ void T1000eBoard::begin() { delay(10); // give sx1262 some time to power up } +bool T1000eBoard::toggleGps() { + return sensors.toggle_gps(); +} + #if 0 static BLEDfu bledfu; diff --git a/src/helpers/nrf52/T1000eBoard.h b/variants/t1000-e/T1000eBoard.h similarity index 98% rename from src/helpers/nrf52/T1000eBoard.h rename to variants/t1000-e/T1000eBoard.h index 24584757..831a8ccb 100644 --- a/src/helpers/nrf52/T1000eBoard.h +++ b/variants/t1000-e/T1000eBoard.h @@ -66,6 +66,8 @@ public: return 0; } + virtual bool toggleGps() override; + void powerOff() override { #ifdef HAS_GPS digitalWrite(GPS_VRTC_EN, LOW); diff --git a/variants/t1000-e/target.h b/variants/t1000-e/target.h index 1b569481..7ade0117 100644 --- a/variants/t1000-e/target.h +++ b/variants/t1000-e/target.h @@ -3,7 +3,7 @@ #define RADIOLIB_STATIC_ONLY 1 #include #include -#include +#include "T1000eBoard.h" #include #include #include @@ -28,6 +28,7 @@ public: const char* getSettingName(int i) const override; const char* getSettingValue(int i) const override; bool setSettingValue(const char* name, const char* value) override; + bool toggle_gps() { gps_active ? stop_gps() : start_gps(); return gps_active;} }; #ifdef DISPLAY_CLASS From 588a9869765f60c7a1778ca65ac318c3a000a228 Mon Sep 17 00:00:00 2001 From: Florent de Lamotte Date: Thu, 19 Jun 2025 17:26:58 +0200 Subject: [PATCH 2/5] t1000e: gps toggle not using board class --- examples/companion_radio/UITask.cpp | 7 +++++-- examples/companion_radio/UITask.h | 6 ++++-- examples/companion_radio/main.cpp | 2 +- src/MeshCore.h | 1 - src/helpers/SensorManager.h | 2 ++ variants/t1000-e/T1000eBoard.cpp | 5 ----- variants/t1000-e/T1000eBoard.h | 2 -- variants/t1000-e/target.h | 3 ++- 8 files changed, 14 insertions(+), 14 deletions(-) diff --git a/examples/companion_radio/UITask.cpp b/examples/companion_radio/UITask.cpp index eef8b54b..3e477fe9 100644 --- a/examples/companion_radio/UITask.cpp +++ b/examples/companion_radio/UITask.cpp @@ -34,8 +34,9 @@ static const uint8_t meshcore_logo [] PROGMEM = { 0xe3, 0xe3, 0x8f, 0xff, 0x1f, 0xfc, 0x3c, 0x0e, 0x1f, 0xf8, 0xff, 0xf8, 0x70, 0x3c, 0x7f, 0xf8, }; -void UITask::begin(DisplayDriver* display, NodePrefs* node_prefs) { +void UITask::begin(DisplayDriver* display, SensorManager* sensors, NodePrefs* node_prefs) { _display = display; + _sensors = sensors; _auto_off = millis() + AUTO_OFF_MILLIS; clearMsgPreview(); _node_prefs = node_prefs; @@ -386,7 +387,9 @@ void UITask::handleButtonTriplePress() { void UITask::handleButtonQuadruplePress() { MESH_DEBUG_PRINTLN("UITask: quad press triggered"); - _board->toggleGps(); + if (_sensors != NULL) { + _sensors->toggleGps(); + } _need_refresh = true; } diff --git a/examples/companion_radio/UITask.h b/examples/companion_radio/UITask.h index e9a67085..664a7659 100644 --- a/examples/companion_radio/UITask.h +++ b/examples/companion_radio/UITask.h @@ -2,6 +2,7 @@ #include #include +#include #include #ifdef PIN_BUZZER @@ -24,6 +25,7 @@ class UITask { DisplayDriver* _display; mesh::MainBoard* _board; + SensorManager* _sensors; #ifdef PIN_BUZZER genericBuzzer buzzer; #endif @@ -59,12 +61,12 @@ class UITask { public: - UITask(mesh::MainBoard* board) : _board(board), _display(NULL) { + UITask(mesh::MainBoard* board) : _board(board), _display(NULL), _sensors(NULL) { _next_refresh = 0; ui_started_at = 0; _connected = false; } - void begin(DisplayDriver* display, NodePrefs* node_prefs); + void begin(DisplayDriver* display, SensorManager* sensors, NodePrefs* node_prefs); void setHasConnection(bool connected) { _connected = connected; } bool hasDisplay() const { return _display != NULL; } diff --git a/examples/companion_radio/main.cpp b/examples/companion_radio/main.cpp index b46cdaab..098baf99 100644 --- a/examples/companion_radio/main.cpp +++ b/examples/companion_radio/main.cpp @@ -186,7 +186,7 @@ void setup() { sensors.begin(); #ifdef DISPLAY_CLASS - ui_task.begin(disp, the_mesh.getNodePrefs()); // still want to pass this in as dependency, as prefs might be moved + ui_task.begin(disp, &sensors, the_mesh.getNodePrefs()); // still want to pass this in as dependency, as prefs might be moved #endif } diff --git a/src/MeshCore.h b/src/MeshCore.h index 3c425487..98134e50 100644 --- a/src/MeshCore.h +++ b/src/MeshCore.h @@ -41,7 +41,6 @@ public: virtual void onAfterTransmit() { } virtual void reboot() = 0; virtual void powerOff() { /* no op */ } - virtual bool toggleGps() { return false; } // could be a board_toggle depending on the board features ... virtual uint8_t getStartupReason() const = 0; virtual bool startOTAUpdate(const char* id, char reply[]) { return false; } // not supported }; diff --git a/src/helpers/SensorManager.h b/src/helpers/SensorManager.h index 0e4bc27d..6ef1192a 100644 --- a/src/helpers/SensorManager.h +++ b/src/helpers/SensorManager.h @@ -21,4 +21,6 @@ public: virtual const char* getSettingName(int i) const { return NULL; } virtual const char* getSettingValue(int i) const { return NULL; } virtual bool setSettingValue(const char* name, const char* value) { return false; } + virtual bool getGpsStatus() { return false; } + virtual bool toggleGps() { return false; } }; diff --git a/variants/t1000-e/T1000eBoard.cpp b/variants/t1000-e/T1000eBoard.cpp index 81486acd..a17711db 100644 --- a/variants/t1000-e/T1000eBoard.cpp +++ b/variants/t1000-e/T1000eBoard.cpp @@ -1,7 +1,6 @@ #include #include "T1000eBoard.h" #include -#include "target.h" #include @@ -27,10 +26,6 @@ void T1000eBoard::begin() { delay(10); // give sx1262 some time to power up } -bool T1000eBoard::toggleGps() { - return sensors.toggle_gps(); -} - #if 0 static BLEDfu bledfu; diff --git a/variants/t1000-e/T1000eBoard.h b/variants/t1000-e/T1000eBoard.h index 831a8ccb..24584757 100644 --- a/variants/t1000-e/T1000eBoard.h +++ b/variants/t1000-e/T1000eBoard.h @@ -66,8 +66,6 @@ public: return 0; } - virtual bool toggleGps() override; - void powerOff() override { #ifdef HAS_GPS digitalWrite(GPS_VRTC_EN, LOW); diff --git a/variants/t1000-e/target.h b/variants/t1000-e/target.h index 7ade0117..221db614 100644 --- a/variants/t1000-e/target.h +++ b/variants/t1000-e/target.h @@ -28,7 +28,8 @@ public: const char* getSettingName(int i) const override; const char* getSettingValue(int i) const override; bool setSettingValue(const char* name, const char* value) override; - bool toggle_gps() { gps_active ? stop_gps() : start_gps(); return gps_active;} + bool getGpsStatus() override { return gps_active; } + bool toggleGps() override { gps_active ? sleep_gps() : start_gps(); return gps_active; } }; #ifdef DISPLAY_CLASS From bbde446bdfe06389d5a205b44c145cf65613aafa Mon Sep 17 00:00:00 2001 From: JQ Date: Thu, 19 Jun 2025 16:27:42 -0700 Subject: [PATCH 3/5] refactoring thinknode to use radio.std_init --- variants/thinknode_m1/target.cpp | 34 +------------------------------- 1 file changed, 1 insertion(+), 33 deletions(-) diff --git a/variants/thinknode_m1/target.cpp b/variants/thinknode_m1/target.cpp index 70b5c61e..19230232 100644 --- a/variants/thinknode_m1/target.cpp +++ b/variants/thinknode_m1/target.cpp @@ -18,41 +18,9 @@ ThinkNodeM1SensorManager sensors = ThinkNodeM1SensorManager(nmea); DISPLAY_CLASS display; #endif -#ifndef LORA_CR - #define LORA_CR 5 -#endif - bool radio_init() { rtc_clock.begin(Wire); - -#ifdef SX126X_DIO3_TCXO_VOLTAGE - float tcxo = SX126X_DIO3_TCXO_VOLTAGE; -#else - float tcxo = 1.6f; -#endif - - SPI.setPins(P_LORA_MISO, P_LORA_SCLK, P_LORA_MOSI); - SPI.begin(); - int status = radio.begin(LORA_FREQ, LORA_BW, LORA_SF, LORA_CR, RADIOLIB_SX126X_SYNC_WORD_PRIVATE, LORA_TX_POWER, 8, tcxo); - if (status != RADIOLIB_ERR_NONE) { - Serial.print("ERROR: radio init failed: "); - Serial.println(status); - return false; // fail - } - - radio.setCRC(1); - -#ifdef SX126X_CURRENT_LIMIT - radio.setCurrentLimit(SX126X_CURRENT_LIMIT); -#endif -#ifdef SX126X_DIO2_AS_RF_SWITCH - radio.setDio2AsRfSwitch(SX126X_DIO2_AS_RF_SWITCH); -#endif -#ifdef SX126X_RX_BOOSTED_GAIN - radio.setRxBoostedGainMode(SX126X_RX_BOOSTED_GAIN); -#endif - - return true; // success + return radio.std_init(&SPI); } uint32_t radio_get_rng_seed() { From e7b0e9e5261f55a5ebeb95529c392fe954548754 Mon Sep 17 00:00:00 2001 From: taco Date: Fri, 20 Jun 2025 11:22:34 +1000 Subject: [PATCH 4/5] refactor: promicro with CustomSX1262::std_init() added check in CustomSX1262.h to support both txco and non-txco radios switched promicro to use CustomSX1262::std_init() --- src/helpers/CustomSX1262.h | 6 ++++++ variants/promicro/target.cpp | 42 +----------------------------------- 2 files changed, 7 insertions(+), 41 deletions(-) diff --git a/src/helpers/CustomSX1262.h b/src/helpers/CustomSX1262.h index 8c93d384..6d17c162 100644 --- a/src/helpers/CustomSX1262.h +++ b/src/helpers/CustomSX1262.h @@ -30,6 +30,12 @@ class CustomSX1262 : public SX1262 { #endif #endif int status = begin(LORA_FREQ, LORA_BW, LORA_SF, cr, RADIOLIB_SX126X_SYNC_WORD_PRIVATE, LORA_TX_POWER, 8, tcxo); + // if radio init fails with -707/-706, try again with tcxo voltage set to 0.0f + if (status == RADIOLIB_ERR_SPI_CMD_FAILED || status == RADIOLIB_ERR_SPI_CMD_INVALID) { + #define SX126X_DIO3_TCXO_VOLTAGE (0.0f); + tcxo = SX126X_DIO3_TCXO_VOLTAGE; + status = begin(LORA_FREQ, LORA_BW, LORA_SF, cr, RADIOLIB_SX126X_SYNC_WORD_PRIVATE, LORA_TX_POWER, 8, tcxo); + } if (status != RADIOLIB_ERR_NONE) { Serial.print("ERROR: radio init failed: "); Serial.println(status); diff --git a/variants/promicro/target.cpp b/variants/promicro/target.cpp index 2369bd7a..03a5a16a 100644 --- a/variants/promicro/target.cpp +++ b/variants/promicro/target.cpp @@ -2,9 +2,6 @@ #include "target.h" #include -#if ENV_INCLUDE_GPS -#endif - PromicroBoard board; RADIO_CLASS radio = new Module(P_LORA_NSS, P_LORA_DIO_1, P_LORA_RESET, P_LORA_BUSY, SPI); @@ -25,47 +22,10 @@ AutoDiscoverRTCClock rtc_clock(fallback_clock); DISPLAY_CLASS display; #endif -#ifndef LORA_CR - #define LORA_CR 5 -#endif - bool radio_init() { rtc_clock.begin(Wire); -#ifdef SX126X_DIO3_TCXO_VOLTAGE - float tcxo = SX126X_DIO3_TCXO_VOLTAGE; -#else - float tcxo = 1.6f; -#endif - - SPI.setPins(P_LORA_MISO, P_LORA_SCLK, P_LORA_MOSI); - SPI.begin(); - radio.setRfSwitchPins(SX126X_RXEN, SX126X_TXEN); - int status = radio.begin(LORA_FREQ, LORA_BW, LORA_SF, LORA_CR, RADIOLIB_SX126X_SYNC_WORD_PRIVATE, LORA_TX_POWER, 8, tcxo); - if (status == RADIOLIB_ERR_SPI_CMD_FAILED || status == RADIOLIB_ERR_SPI_CMD_INVALID) { - #define SX126X_DIO3_TCXO_VOLTAGE (0.0f); - tcxo = SX126X_DIO3_TCXO_VOLTAGE; - status = radio.begin(LORA_FREQ, LORA_BW, LORA_SF, LORA_CR, RADIOLIB_SX126X_SYNC_WORD_PRIVATE, LORA_TX_POWER, 8, tcxo); - } - if (status != RADIOLIB_ERR_NONE) { - Serial.print("ERROR: radio init failed: "); - Serial.println(status); - return false; // fail - } - - radio.setCRC(1); - -#ifdef SX126X_CURRENT_LIMIT - radio.setCurrentLimit(SX126X_CURRENT_LIMIT); -#endif -#ifdef SX126X_DIO2_AS_RF_SWITCH - radio.setDio2AsRfSwitch(SX126X_DIO2_AS_RF_SWITCH); -#endif -#ifdef SX126X_RX_BOOSTED_GAIN - radio.setRxBoostedGainMode(SX126X_RX_BOOSTED_GAIN); -#endif - - return true; // success + return radio.std_init(&SPI); } uint32_t radio_get_rng_seed() { From b865ac6c23f3d135770cf95904722e8a89c5c0c7 Mon Sep 17 00:00:00 2001 From: Scott Powell Date: Fri, 20 Jun 2025 13:44:58 +1000 Subject: [PATCH 5/5] * refactored SensorManager::toggleGps() --- examples/companion_radio/UITask.cpp | 13 ++++++++++++- src/helpers/SensorManager.h | 2 -- variants/t1000-e/target.h | 2 -- 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/examples/companion_radio/UITask.cpp b/examples/companion_radio/UITask.cpp index 3e477fe9..f57d5f80 100644 --- a/examples/companion_radio/UITask.cpp +++ b/examples/companion_radio/UITask.cpp @@ -388,7 +388,18 @@ void UITask::handleButtonTriplePress() { void UITask::handleButtonQuadruplePress() { MESH_DEBUG_PRINTLN("UITask: quad press triggered"); if (_sensors != NULL) { - _sensors->toggleGps(); + // toggle GPS onn/off + int num = _sensors->getNumSettings(); + for (int i = 0; i < num; i++) { + if (strcmp(_sensors->getSettingName(i), "gps") == 0) { + if (strcmp(_sensors->getSettingValue(i), "1") == 0) { + _sensors->setSettingValue("gps", "0"); + } else { + _sensors->setSettingValue("gps", "1"); + } + break; + } + } } _need_refresh = true; } diff --git a/src/helpers/SensorManager.h b/src/helpers/SensorManager.h index 6ef1192a..0e4bc27d 100644 --- a/src/helpers/SensorManager.h +++ b/src/helpers/SensorManager.h @@ -21,6 +21,4 @@ public: virtual const char* getSettingName(int i) const { return NULL; } virtual const char* getSettingValue(int i) const { return NULL; } virtual bool setSettingValue(const char* name, const char* value) { return false; } - virtual bool getGpsStatus() { return false; } - virtual bool toggleGps() { return false; } }; diff --git a/variants/t1000-e/target.h b/variants/t1000-e/target.h index 221db614..855c4d67 100644 --- a/variants/t1000-e/target.h +++ b/variants/t1000-e/target.h @@ -28,8 +28,6 @@ public: const char* getSettingName(int i) const override; const char* getSettingValue(int i) const override; bool setSettingValue(const char* name, const char* value) override; - bool getGpsStatus() override { return gps_active; } - bool toggleGps() override { gps_active ? sleep_gps() : start_gps(); return gps_active; } }; #ifdef DISPLAY_CLASS