Add Channel Picker to LoRa Options

This commit is contained in:
Jason P
2026-01-17 21:24:20 -06:00
parent 6905b87e54
commit bcb287fe7d
2 changed files with 78 additions and 3 deletions

View File

@@ -65,12 +65,12 @@ uint8_t test_count = 0;
void menuHandler::loraMenu()
{
static const char *optionsArray[] = {"Back", "Device Role", "Radio Preset", "LoRa Region"};
enum optionsNumbers { Back = 0, device_role_picker = 1, radio_preset_picker = 2, lora_picker = 3 };
static const char *optionsArray[] = {"Back", "Device Role", "Radio Preset", "Channel Picker", "LoRa Region"};
enum optionsNumbers { Back = 0, device_role_picker = 1, radio_preset_picker = 2, channel_picker = 3, lora_picker = 4 };
BannerOverlayOptions bannerOptions;
bannerOptions.message = "LoRa Actions";
bannerOptions.optionsArrayPtr = optionsArray;
bannerOptions.optionsCount = 4;
bannerOptions.optionsCount = 5;
bannerOptions.bannerCallback = [](int selected) -> void {
if (selected == Back) {
// No action
@@ -78,6 +78,8 @@ void menuHandler::loraMenu()
menuHandler::menuQueue = menuHandler::device_role_picker;
} else if (selected == radio_preset_picker) {
menuHandler::menuQueue = menuHandler::radio_preset_picker;
} else if (selected == channel_picker) {
menuHandler::menuQueue = menuHandler::channel_picker;
} else if (selected == lora_picker) {
menuHandler::menuQueue = menuHandler::lora_picker;
}
@@ -248,6 +250,74 @@ void menuHandler::DeviceRolePicker()
screen->showOverlayBanner(bannerOptions);
}
void menuHandler::ChannelPicker()
{
enum ReplyOptions : int { Back = -1 };
constexpr int MAX_CHANNEL_OPTIONS = 201;
static const char *optionsArray[MAX_CHANNEL_OPTIONS];
static int optionsEnumArray[MAX_CHANNEL_OPTIONS];
static char channelText[MAX_CHANNEL_OPTIONS - 1][8];
int options = 0;
optionsArray[options] = "Back";
optionsEnumArray[options++] = Back;
optionsArray[options] = "Ch 0 (Auto)";
optionsEnumArray[options++] = 0;
// Calculate number of channels (copied from RadioInterface::applyModemConfig())
meshtastic_Config_LoRaConfig &loraConfig = config.lora;
double bw = loraConfig.bandwidth;
if (bw == 31)
bw = 31.25;
if (bw == 62)
bw = 62.5;
if (bw == 200)
bw = 203.125;
if (bw == 400)
bw = 406.25;
if (bw == 800)
bw = 812.5;
if (bw == 1600)
bw = 1625.0;
uint32_t numChannels = (uint32_t)floor((myRegion->freqEnd - myRegion->freqStart) / (myRegion->spacing + (bw / 1000.0)));
if (numChannels > (uint32_t)(MAX_CHANNEL_OPTIONS - 1))
numChannels = (uint32_t)(MAX_CHANNEL_OPTIONS - 1);
for (uint32_t ch = 1; ch <= numChannels; ch++) {
snprintf(channelText[ch - 1], sizeof(channelText[ch - 1]), "Ch %lu", (unsigned long)ch);
optionsArray[options] = channelText[ch - 1];
optionsEnumArray[options++] = (int)ch;
}
BannerOverlayOptions bannerOptions;
bannerOptions.message = "Channel Picker";
bannerOptions.optionsArrayPtr = optionsArray;
bannerOptions.optionsEnumPtr = optionsEnumArray;
bannerOptions.optionsCount = options;
// Start highlight on current channel if possible, otherwise on "1"
int initial = (int)config.lora.channel_num + 1;
if (initial < 2 || initial > (int)numChannels)
initial = 1;
bannerOptions.InitialSelected = initial;
bannerOptions.bannerCallback = [](int selected) -> void {
if (selected == Back) {
menuHandler::menuQueue = menuHandler::lora_Menu;
screen->runNow();
return;
}
config.lora.channel_num = selected;
service->reloadConfig(SEGMENT_CONFIG);
rebootAtMsec = (millis() + DEFAULT_REBOOT_SECONDS * 1000);
};
screen->showOverlayBanner(bannerOptions);
}
void menuHandler::RadioPresetPicker()
{
static const RadioPresetOption presetOptions[] = {
@@ -2552,6 +2622,9 @@ void menuHandler::handleMenuSwitch(OLEDDisplay *display)
case radio_preset_picker:
RadioPresetPicker();
break;
case channel_picker:
ChannelPicker();
break;
case no_timeout_lora_picker:
LoraRegionPicker(0);
break;

View File

@@ -13,6 +13,7 @@ class menuHandler
lora_picker,
device_role_picker,
radio_preset_picker,
channel_picker,
no_timeout_lora_picker,
TZ_picker,
twelve_hour_picker,
@@ -63,6 +64,7 @@ class menuHandler
static void loraMenu();
static void DeviceRolePicker();
static void RadioPresetPicker();
static void ChannelPicker();
static void handleMenuSwitch(OLEDDisplay *display);
static void showConfirmationBanner(const char *message, std::function<void()> onConfirm);
static void clockMenu();