enhancement on the UI and support for power off and status_led for t1000e

This commit is contained in:
Florent de Lamotte
2025-03-10 17:11:55 +01:00
parent 676ba6d066
commit 7bb16cd7f3
7 changed files with 157 additions and 63 deletions

View File

@@ -28,7 +28,16 @@ void UITask::begin(const char* node_name, const char* build_date, uint32_t pin_c
_node_name = node_name;
_build_date = build_date;
_pin_code = pin_code;
_display->turnOn();
if (_display != NULL) {
_display->turnOn();
}
}
void UITask::msgRead(int msgcount) {
_msgcount = msgcount;
if (msgcount == 0) {
clearMsgPreview();
}
}
void UITask::clearMsgPreview() {
@@ -36,7 +45,9 @@ void UITask::clearMsgPreview() {
_msg[0] = 0;
}
void UITask::showMsgPreview(uint8_t path_len, const char* from_name, const char* text) {
void UITask::newMsg(uint8_t path_len, const char* from_name, const char* text, int msgcount) {
_msgcount = msgcount;
if (path_len == 0xFF) {
sprintf(_origin, "(F) %s", from_name);
} else {
@@ -44,67 +55,121 @@ void UITask::showMsgPreview(uint8_t path_len, const char* from_name, const char*
}
StrHelper::strncpy(_msg, text, sizeof(_msg));
if (!_display->isOn()) _display->turnOn();
_auto_off = millis() + AUTO_OFF_MILLIS; // extend the auto-off timer
if (_display != NULL) {
if (!_display->isOn()) _display->turnOn();
_auto_off = millis() + AUTO_OFF_MILLIS; // extend the auto-off timer
}
}
void UITask::renderCurrScreen() {
char tmp[80];
if (_origin[0] && _msg[0]) {
// render message preview
_display->setCursor(0, 0);
_display->setTextSize(1);
_display->print(_node_name);
if (_display != NULL) {
char tmp[80];
if (_origin[0] && _msg[0]) {
// render message preview
_display->setCursor(0, 0);
_display->setTextSize(1);
_display->print(_node_name);
_display->setCursor(0, 12);
_display->print(_origin);
_display->setCursor(0, 24);
_display->print(_msg);
_display->setCursor(0, 12);
_display->print(_origin);
_display->setCursor(0, 24);
_display->print(_msg);
//_display->setCursor(100, 9); TODO
//_display->setTextSize(2);
//_display->printf("%d", msgs);
} else {
// render 'home' screen
_display->drawXbm(0, 0, meshcore_logo, 128, 13);
_display->setCursor(0, 20);
_display->setTextSize(1);
_display->print(_node_name);
sprintf(tmp, "Build: %s", _build_date);
_display->setCursor(0, 32);
_display->print(tmp);
if (_connected) {
//_display->printf("freq : %03.2f sf %d\n", _prefs.freq, _prefs.sf);
//_display->printf("bw : %03.2f cr %d\n", _prefs.bw, _prefs.cr);
} else if (_pin_code != 0) {
_display->setCursor(100, 9);
_display->setTextSize(2);
_display->setCursor(0, 43);
sprintf(tmp, "Pin:%d", _pin_code);
sprintf(tmp, "%d", _msgcount);
_display->print(tmp);
} else {
// render 'home' screen
_display->drawXbm(0, 0, meshcore_logo, 128, 13);
_display->setCursor(0, 20);
_display->setTextSize(1);
_display->print(_node_name);
sprintf(tmp, "Build: %s", _build_date);
_display->setCursor(0, 32);
_display->print(tmp);
if (_connected) {
//_display->printf("freq : %03.2f sf %d\n", _prefs.freq, _prefs.sf);
//_display->printf("bw : %03.2f cr %d\n", _prefs.bw, _prefs.cr);
} else if (_pin_code != 0) {
_display->setTextSize(2);
_display->setCursor(0, 43);
sprintf(tmp, "Pin:%d", _pin_code);
_display->print(tmp);
}
}
}
}
void UITask::loop() {
if (millis() >= _next_read) {
int btnState = digitalRead(PIN_USER_BTN);
if (btnState != _prevBtnState) {
if (btnState == LOW) { // pressed?
if (_display->isOn()) {
clearMsgPreview();
} else {
_display->turnOn();
}
_auto_off = millis() + AUTO_OFF_MILLIS; // extend auto-off timer
void UITask::userLedHandler() {
#ifdef PIN_STATUS_LED
static int state = 0;
static int next_change = 0;
int cur_time = millis();
if (cur_time > next_change) {
if (state == 0) {
state = 1; // led on, short = unread msg
if (_msgcount > 0) {
next_change = cur_time + 500;
} else {
next_change = cur_time + 2000;
}
} else {
state = 0;
if (_board->getBattMilliVolts() > 3800) {
next_change = cur_time + 2000;
} else {
next_change = cur_time + 4000; // 4s blank if bat level low
}
_prevBtnState = btnState;
}
_next_read = millis() + 100; // 10 reads per second
digitalWrite(PIN_STATUS_LED, state);
}
#endif
}
if (_display->isOn()) {
void UITask::buttonHandler() {
#ifdef PIN_USER_BTN
static int prev_btn_state = HIGH;
static unsigned long btn_state_change_time = 0;
static unsigned long next_read = 0;
int cur_time = millis();
if (cur_time >= next_read) {
int btn_state = digitalRead(PIN_USER_BTN);
if (btn_state != prev_btn_state) {
if (btn_state == USER_BTN_PRESSED) { // pressed?
if (_display != NULL) {
if (_display->isOn()) {
clearMsgPreview();
} else {
_display->turnOn();
}
_auto_off = cur_time + AUTO_OFF_MILLIS; // extend auto-off timer
}
} else { // unpressed ? check pressed time ...
if ((cur_time - btn_state_change_time) > 5000) {
Serial.println("power off");
#ifdef PIN_STATUS_LED
digitalWrite(PIN_STATUS_LED, LOW);
delay(10);
#endif
_board->powerOff();
}
}
btn_state_change_time = millis();
prev_btn_state = btn_state;
}
next_read = millis() + 100; // 10 reads per second
}
#endif
}
void UITask::loop() {
buttonHandler();
userLedHandler();
if (_display != NULL && _display->isOn()) {
if (millis() >= _next_refresh) {
_display->startFrame();
renderCurrScreen();

View File

@@ -1,10 +1,12 @@
#pragma once
#include <MeshCore.h>
#include <helpers/ui/DisplayDriver.h>
class UITask {
DisplayDriver* _display;
unsigned long _next_read, _next_refresh, _auto_off;
mesh::MainBoard* _board;
unsigned long _next_refresh, _auto_off;
int _prevBtnState;
bool _connected;
uint32_t _pin_code;
@@ -12,14 +14,23 @@ class UITask {
const char* _build_date;
char _origin[62];
char _msg[80];
int _msgcount;
void renderCurrScreen();
void buttonHandler();
void userLedHandler();
public:
UITask(DisplayDriver& display) : _display(&display) { _next_read = _next_refresh = 0; _connected = false; }
UITask(mesh::MainBoard* board, DisplayDriver* display) : _board(board), _display(display){
_next_refresh = 0;
_connected = false;
}
void begin(const char* node_name, const char* build_date, uint32_t pin_code);
void setHasConnection(bool connected) { _connected = connected; }
void clearMsgPreview();
void showMsgPreview(uint8_t path_len, const char* from_name, const char* text);
void msgRead(int msgcount);
void newMsg(uint8_t path_len, const char* from_name, const char* text, int msgcount);
void loop();
};
};

View File

@@ -97,12 +97,16 @@
#endif
#ifdef DISPLAY_CLASS
#include "UITask.h"
#include <helpers/ui/SSD1306Display.h>
static DISPLAY_CLASS display;
static UITask ui_task(&board, &display);
#define HAS_UI
#elif defined(HAS_UI)
#include "UITask.h"
static UITask ui_task(display);
static UITask ui_task(&board, NULL);
#endif
// Believe it or not, this std C function is busted on some platforms!
@@ -508,8 +512,8 @@ protected:
} else {
soundBuzzer();
}
#ifdef DISPLAY_CLASS
ui_task.showMsgPreview(path_len, from.name, text);
#ifdef HAS_UI
ui_task.newMsg(path_len, from.name, text, offline_queue_len);
#endif
}
@@ -550,8 +554,8 @@ protected:
} else {
soundBuzzer();
}
#ifdef DISPLAY_CLASS
ui_task.showMsgPreview(in_path_len < 0 ? 0xFF : in_path_len, "Public", text);
#ifdef HAS_UI
ui_task.newMsg(in_path_len < 0 ? 0xFF : in_path_len, "Public", text, offline_queue_len);
#endif
}
@@ -1010,6 +1014,9 @@ public:
int out_len;
if ((out_len = getFromOfflineQueue(out_frame)) > 0) {
_serial->writeFrame(out_frame, out_len);
#ifdef HAS_UI
ui_task.msgRead(offline_queue_len);
#endif
} else {
out_frame[0] = RESP_CODE_NO_MORE_MESSAGES;
_serial->writeFrame(out_frame, 1);
@@ -1190,7 +1197,7 @@ public:
checkConnections();
}
#ifdef DISPLAY_CLASS
#ifdef HAS_UI
ui_task.setHasConnection(_serial->isConnected());
ui_task.loop();
#endif
@@ -1315,6 +1322,8 @@ void setup() {
#ifdef DISPLAY_CLASS
display.begin();
#endif
#ifdef HAS_UI
ui_task.begin(the_mesh.getNodeName(), FIRMWARE_BUILD_DATE, the_mesh.getBLEPin());
#endif
}

View File

@@ -22,6 +22,7 @@ build_flags = -w -DNDEBUG -DRADIOLIB_STATIC_ONLY=1 -DRADIOLIB_GODMODE=1
-D LORA_FREQ=867.5
-D LORA_BW=250
-D LORA_SF=10
-D USER_BTN_PRESSED=LOW
build_src_filter =
+<*.cpp>
+<helpers/*.cpp>
@@ -774,10 +775,14 @@ board = tracker-t1000-e
board_build.ldscript = boards/nrf52840_s140_v7.ld
build_flags = ${nrf52840_t1000e.build_flags}
-Ivariants/t1000-e
-DT1000_E
-D T1000_E
-D PIN_USER_BTN=6
-D USER_BTN_PRESSED=HIGH
-D PIN_STATUS_LED=24
-D RADIO_CLASS=CustomLR1110
-D WRAPPER_CLASS=CustomLR1110Wrapper
-D MAX_LORA_TX_POWER=22
-D LORA_TX_POWER=22
build_src_filter = ${nrf52840_t1000e.build_src_filter}
+<helpers/*.cpp>
+<helpers/nrf52/T1000eBoard.cpp>
@@ -794,6 +799,7 @@ build_flags = ${t1000-e.build_flags}
-D BLE_DEBUG_LOGGING=1
-D MESH_PACKET_LOGGING=1
-D MESH_DEBUG=1
-D HAS_UI
build_src_filter = ${t1000-e.build_src_filter}
+<helpers/nrf52/SerialBLEInterface.cpp>
+<../examples/companion_radio/*.cpp>

View File

@@ -40,6 +40,7 @@ public:
virtual void onBeforeTransmit() { }
virtual void onAfterTransmit() { }
virtual void reboot() = 0;
virtual void powerOff() { while (1) { }}; // hope it's overriden or never called ;)
virtual uint8_t getStartupReason() const = 0;
virtual bool startOTAUpdate() { return false; } // not supported
};

View File

@@ -67,6 +67,10 @@ public:
esp_deep_sleep_start(); // CPU halts here and never returns!
}
void powerOff() override {
enterDeepSleep(0);
}
uint16_t getBattMilliVolts() override {
analogReadResolution(10);
digitalWrite(PIN_ADC_CTRL, PIN_ADC_CTRL_ACTIVE);

View File

@@ -3,8 +3,6 @@
#include <MeshCore.h>
#include <Arduino.h>
#define HAS_T1000e_POWEROFF
// LoRa and SPI pins
#define P_LORA_DIO_1 (32 + 1) // P1.1
#define P_LORA_NSS (0 + 12) // P0.12
@@ -61,7 +59,7 @@ public:
return 0;
}
void powerOff() {
void powerOff() override {
#ifdef HAS_GPS
digitalWrite(GPS_VRTC_EN, LOW);
digitalWrite(GPS_RESET, LOW);