mirror of
https://github.com/ratspeak/ratdeck.git
synced 2026-10-23 01:41:17 +00:00
Fix screen wake on idle, add regional frequency presets and Hz input
Screen idle: - Remove powerMgr.activity() from radio yield callback — screen no longer wakes on LoRa RX, auto-announce, or RSSI polls - Add [POWER] state transition logging for on-device diagnostics Radio regions: - Add 4-region system: Americas (915), Europe (868), Australia (915), Asia (923) with timezone-to-region mapping - Region picker in Radio settings (always visible) - Presets now apply region-appropriate frequency + modulation params - Timezone change warns if it suggests a different radio region Frequency input (developer mode): - Hz-precision input (9 digits) displayed as MHz with trimmed decimals - Left/right arrows step by 125 kHz, digit keys for direct entry - Inspired by @strijar in https://github.com/ratspeak/ratdeck/pull/12
This commit is contained in:
1 parent
b2fcfe526e
commit
a77fb594a2
7 files changed
+94
-28
No files matched your search
@@ -61,6 +61,23 @@
|
||||
#define SCREEN_OFF_TIMEOUT_MS 60000
|
||||
#define SCREEN_DIM_BRIGHTNESS 64
|
||||
|
||||
// --- Radio Regions ---
|
||||
enum RadioRegion : uint8_t {
|
||||
REGION_AMERICAS = 0, // 915 MHz (902-928 ISM)
|
||||
REGION_EUROPE = 1, // 868 MHz (863-870)
|
||||
REGION_AUSTRALIA = 2, // 915 MHz (915-928)
|
||||
REGION_ASIA = 3, // 923 MHz (AS923)
|
||||
REGION_COUNT = 4
|
||||
};
|
||||
|
||||
static constexpr uint32_t REGION_FREQ[REGION_COUNT] = {
|
||||
915000000, 868000000, 915000000, 923000000
|
||||
};
|
||||
|
||||
static const char* const REGION_LABELS[REGION_COUNT] = {
|
||||
"Americas (915)", "Europe (868)", "Australia (915)", "Asia (923)"
|
||||
};
|
||||
|
||||
// --- Serial Debug ---
|
||||
#define SERIAL_BAUD 115200
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@ bool UserConfig::parseJson(const String& json) {
|
||||
return false;
|
||||
}
|
||||
|
||||
_settings.radioRegion = constrain((int)(doc["radio_region"] | 0), 0, REGION_COUNT - 1);
|
||||
_settings.loraFrequency = doc["lora_freq"] | (long)LORA_DEFAULT_FREQ;
|
||||
_settings.loraSF = doc["lora_sf"] | (int)LORA_DEFAULT_SF;
|
||||
_settings.loraBW = doc["lora_bw"] | (long)LORA_DEFAULT_BW;
|
||||
@@ -75,6 +76,7 @@ bool UserConfig::parseJson(const String& json) {
|
||||
String UserConfig::serializeToJson() const {
|
||||
JsonDocument doc;
|
||||
|
||||
doc["radio_region"] = _settings.radioRegion;
|
||||
doc["lora_freq"] = _settings.loraFrequency;
|
||||
doc["lora_sf"] = _settings.loraSF;
|
||||
doc["lora_bw"] = _settings.loraBW;
|
||||
|
||||
@@ -18,6 +18,7 @@ struct TCPEndpoint {
|
||||
|
||||
struct UserSettings {
|
||||
// Radio
|
||||
uint8_t radioRegion = REGION_AMERICAS;
|
||||
uint32_t loraFrequency = LORA_DEFAULT_FREQ;
|
||||
uint8_t loraSF = LORA_DEFAULT_SF;
|
||||
uint32_t loraBW = LORA_DEFAULT_BW;
|
||||
|
||||
@@ -91,6 +91,8 @@ void Power::loop() {
|
||||
|
||||
void Power::setState(State newState) {
|
||||
if (newState == _state) return;
|
||||
const char* names[] = {"ACTIVE", "DIMMED", "SCREEN_OFF"};
|
||||
Serial.printf("[POWER] %s -> %s\n", names[_state], names[newState]);
|
||||
State oldState = _state;
|
||||
_state = newState;
|
||||
|
||||
|
||||
+10
-2
@@ -683,13 +683,12 @@ void setup() {
|
||||
ui.statusBar().setTransportMode("RatDeck");
|
||||
ui.lvStatusBar().setTransportMode("RatDeck");
|
||||
|
||||
// Keep UI alive during blocking radio TX (endPacket wait loop)
|
||||
// Keep LVGL responsive during blocking radio operations (if screen is on)
|
||||
// Re-entrancy guard prevents nested lv_timer_handler() calls
|
||||
radio.setYieldCallback([]() {
|
||||
static bool inYield = false;
|
||||
if (inYield) return;
|
||||
inYield = true;
|
||||
powerMgr.activity(); // Keep screen alive during TX
|
||||
if (powerMgr.isScreenOn()) {
|
||||
lv_timer_handler();
|
||||
}
|
||||
@@ -847,6 +846,15 @@ void setup() {
|
||||
gps.setPosixTZ(tz);
|
||||
}
|
||||
#endif
|
||||
// Warn if timezone suggests a different radio region
|
||||
uint8_t tzRegion = TIMEZONE_TABLE[tzIdx].radioRegion;
|
||||
if (tzRegion != userConfig.settings().radioRegion) {
|
||||
char msg[64];
|
||||
snprintf(msg, sizeof(msg), "TZ suggests %s region", REGION_LABELS[tzRegion]);
|
||||
ui.lvStatusBar().showToast(msg, 3000);
|
||||
Serial.printf("[REGION] Timezone suggests %s, current is %s\n",
|
||||
REGION_LABELS[tzRegion], REGION_LABELS[userConfig.settings().radioRegion]);
|
||||
}
|
||||
goHome();
|
||||
});
|
||||
|
||||
|
||||
@@ -47,6 +47,7 @@ void LvSettingsScreen::applyPreset(int presetIdx) {
|
||||
const auto& p = LV_PRESETS[presetIdx];
|
||||
s.loraSF = p.sf; s.loraBW = p.bw; s.loraCR = p.cr;
|
||||
s.loraTxPower = p.txPower; s.loraPreamble = p.preamble;
|
||||
s.loraFrequency = REGION_FREQ[constrain(s.radioRegion, 0, REGION_COUNT - 1)];
|
||||
}
|
||||
|
||||
bool LvSettingsScreen::isEditable(int idx) const {
|
||||
@@ -230,6 +231,20 @@ void LvSettingsScreen::buildItems() {
|
||||
// Radio
|
||||
int radioStart = idx;
|
||||
{
|
||||
// Region picker — always visible
|
||||
SettingItem regionItem;
|
||||
regionItem.label = "Region";
|
||||
regionItem.type = SettingType::ENUM_CHOICE;
|
||||
regionItem.getter = [&s]() { return (int)s.radioRegion; };
|
||||
regionItem.setter = [this, &s](int v) {
|
||||
s.radioRegion = constrain(v, 0, REGION_COUNT - 1);
|
||||
if (_ui) _ui->lvStatusBar().showToast("Select a preset to apply frequency", 2500);
|
||||
};
|
||||
regionItem.minVal = 0; regionItem.maxVal = REGION_COUNT - 1; regionItem.step = 1;
|
||||
regionItem.enumLabels = {REGION_LABELS[0], REGION_LABELS[1], REGION_LABELS[2], REGION_LABELS[3]};
|
||||
_items.push_back(regionItem);
|
||||
idx++;
|
||||
|
||||
SettingItem presetItem;
|
||||
presetItem.label = "Preset";
|
||||
presetItem.type = SettingType::ENUM_CHOICE;
|
||||
@@ -243,13 +258,25 @@ void LvSettingsScreen::buildItems() {
|
||||
// Custom radio parameters — only visible in Developer Mode
|
||||
if (s.devMode) {
|
||||
_items.push_back({"Frequency", SettingType::INTEGER,
|
||||
[&s]() { return (int)(s.loraFrequency / 1000); },
|
||||
[&s](int v) { s.loraFrequency = (uint32_t)v * 1000; },
|
||||
[&s]() { return (int)(s.loraFrequency); },
|
||||
[&s](int v) { s.loraFrequency = (uint32_t)v; },
|
||||
[](int v) -> String {
|
||||
char buf[16]; snprintf(buf, sizeof(buf), "%d.%03d MHz", v / 1000, v % 1000);
|
||||
char buf[20];
|
||||
int mhz = v / 1000000;
|
||||
int rem = v % 1000000;
|
||||
if (rem == 0) {
|
||||
snprintf(buf, sizeof(buf), "%d MHz", mhz);
|
||||
} else {
|
||||
char frac[8];
|
||||
snprintf(frac, sizeof(frac), "%06d", rem);
|
||||
int len = 6;
|
||||
while (len > 0 && frac[len - 1] == '0') len--;
|
||||
frac[len] = '\0';
|
||||
snprintf(buf, sizeof(buf), "%d.%s MHz", mhz, frac);
|
||||
}
|
||||
return String(buf);
|
||||
},
|
||||
137000, 1020000, 125});
|
||||
137000000, 1020000000, 125000});
|
||||
idx++;
|
||||
_items.push_back({"TX Power", SettingType::INTEGER,
|
||||
[&s]() { return s.loraTxPower; }, [&s](int v) { s.loraTxPower = v; },
|
||||
@@ -282,7 +309,14 @@ void LvSettingsScreen::buildItems() {
|
||||
idx++;
|
||||
}
|
||||
_categories.push_back({"Radio", radioStart, idx - radioStart,
|
||||
[this]() { int p = detectPreset(); return (p >= 0) ? String(LV_PRESETS[p].name) : String("Custom"); }});
|
||||
[this]() {
|
||||
int p = detectPreset();
|
||||
auto& s = _cfg->settings();
|
||||
String label = (p >= 0) ? String(LV_PRESETS[p].name) : String("Custom");
|
||||
label += " ";
|
||||
label += REGION_LABELS[constrain(s.radioRegion, 0, REGION_COUNT - 1)];
|
||||
return label;
|
||||
}});
|
||||
|
||||
// Network
|
||||
int netStart = idx;
|
||||
|
||||
@@ -1,37 +1,39 @@
|
||||
#pragma once
|
||||
|
||||
#include "ui/UIManager.h"
|
||||
#include "config/Config.h"
|
||||
#include <functional>
|
||||
|
||||
struct TimezoneEntry {
|
||||
const char* label; // Display name (e.g., "New York (EST/EDT)")
|
||||
const char* posixTZ; // POSIX TZ string for setenv("TZ", ...)
|
||||
int8_t baseOffset; // Base UTC offset for display (e.g., -5 for EST)
|
||||
uint8_t radioRegion; // Mapped RadioRegion for ISM band defaults
|
||||
};
|
||||
|
||||
// Major world timezones with DST rules where applicable
|
||||
static const TimezoneEntry TIMEZONE_TABLE[] = {
|
||||
{"Honolulu", "HST10", -10},
|
||||
{"Anchorage", "AKST9AKDT,M3.2.0,M11.1.0", -9},
|
||||
{"Los Angeles", "PST8PDT,M3.2.0,M11.1.0", -8},
|
||||
{"Denver", "MST7MDT,M3.2.0,M11.1.0", -7},
|
||||
{"Phoenix", "MST7", -7},
|
||||
{"Chicago", "CST6CDT,M3.2.0,M11.1.0", -6},
|
||||
{"New York", "EST5EDT,M3.2.0,M11.1.0", -5},
|
||||
{"San Juan", "AST4", -4},
|
||||
{"Sao Paulo", "<-03>3", -3},
|
||||
{"London", "GMT0BST,M3.5.0/1,M10.5.0", 0},
|
||||
{"Paris", "CET-1CEST,M3.5.0,M10.5.0/3", 1},
|
||||
{"Cairo", "EET-2", 2},
|
||||
{"Moscow", "MSK-3", 3},
|
||||
{"Dubai", "<+04>-4", 4},
|
||||
{"Karachi", "PKT-5", 5},
|
||||
{"Kolkata", "IST-5:30", 5},
|
||||
{"Bangkok", "<+07>-7", 7},
|
||||
{"Singapore", "<+08>-8", 8},
|
||||
{"Tokyo", "JST-9", 9},
|
||||
{"Sydney", "AEST-10AEDT,M10.1.0,M4.1.0/3", 10},
|
||||
{"Auckland", "NZST-12NZDT,M9.5.0,M4.1.0/3", 12},
|
||||
{"Honolulu", "HST10", -10, REGION_AMERICAS},
|
||||
{"Anchorage", "AKST9AKDT,M3.2.0,M11.1.0", -9, REGION_AMERICAS},
|
||||
{"Los Angeles", "PST8PDT,M3.2.0,M11.1.0", -8, REGION_AMERICAS},
|
||||
{"Denver", "MST7MDT,M3.2.0,M11.1.0", -7, REGION_AMERICAS},
|
||||
{"Phoenix", "MST7", -7, REGION_AMERICAS},
|
||||
{"Chicago", "CST6CDT,M3.2.0,M11.1.0", -6, REGION_AMERICAS},
|
||||
{"New York", "EST5EDT,M3.2.0,M11.1.0", -5, REGION_AMERICAS},
|
||||
{"San Juan", "AST4", -4, REGION_AMERICAS},
|
||||
{"Sao Paulo", "<-03>3", -3, REGION_AMERICAS},
|
||||
{"London", "GMT0BST,M3.5.0/1,M10.5.0", 0, REGION_EUROPE},
|
||||
{"Paris", "CET-1CEST,M3.5.0,M10.5.0/3", 1, REGION_EUROPE},
|
||||
{"Cairo", "EET-2", 2, REGION_EUROPE},
|
||||
{"Moscow", "MSK-3", 3, REGION_EUROPE},
|
||||
{"Dubai", "<+04>-4", 4, REGION_EUROPE},
|
||||
{"Karachi", "PKT-5", 5, REGION_EUROPE},
|
||||
{"Kolkata", "IST-5:30", 5, REGION_EUROPE},
|
||||
{"Bangkok", "<+07>-7", 7, REGION_ASIA},
|
||||
{"Singapore", "<+08>-8", 8, REGION_ASIA},
|
||||
{"Tokyo", "JST-9", 9, REGION_ASIA},
|
||||
{"Sydney", "AEST-10AEDT,M10.1.0,M4.1.0/3", 10, REGION_AUSTRALIA},
|
||||
{"Auckland", "NZST-12NZDT,M9.5.0,M4.1.0/3", 12, REGION_AUSTRALIA},
|
||||
};
|
||||
|
||||
static constexpr int TIMEZONE_COUNT = sizeof(TIMEZONE_TABLE) / sizeof(TIMEZONE_TABLE[0]);
|
||||
|
||||
Reference in new issue
Block a user