mirror of
https://github.com/justcallmekoko/ESP32Marauder.git
synced 2026-03-12 21:22:59 -07:00
Add PWM brightness control with 10-level adjustment
4-level to 10-level PWM backlight control (10%-100% in 10% steps), persisted to NVS flash. Adds touch gesture (hold top/bottom zone 1.5s), Device menu entry, and CLI command (brightness -c/-s <0-9>). Replaces digitalWrite on/off with ledcWrite PWM for smooth dimming. Closes justcallmekoko/ESP32Marauder#1091 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,5 +1,9 @@
|
||||
#include "CommandLine.h"
|
||||
|
||||
// Brightness functions defined in esp32_marauder.ino
|
||||
extern void brightnessCycle();
|
||||
extern uint8_t getBrightnessLevel();
|
||||
|
||||
CommandLine::CommandLine() {
|
||||
}
|
||||
|
||||
@@ -284,6 +288,7 @@ void CommandLine::runCommand(String input) {
|
||||
#endif
|
||||
Serial.println(HELP_BT_SKIM_CMD);
|
||||
#endif
|
||||
Serial.println(HELP_BRIGHTNESS_CMD);
|
||||
Serial.println(HELP_FOOT);
|
||||
return;
|
||||
}
|
||||
@@ -1381,6 +1386,28 @@ void CommandLine::runCommand(String input) {
|
||||
#endif
|
||||
}
|
||||
|
||||
// Brightness command
|
||||
else if (cmd_args.get(0) == BRIGHTNESS_CMD) {
|
||||
int c_arg = this->argSearch(&cmd_args, "-c");
|
||||
int s_arg = this->argSearch(&cmd_args, "-s");
|
||||
if (c_arg != -1) {
|
||||
brightnessCycle();
|
||||
} else if (s_arg != -1) {
|
||||
uint8_t lvl = cmd_args.get(s_arg + 1).toInt();
|
||||
if (lvl < 10) {
|
||||
extern void brightnessSave(uint8_t level);
|
||||
brightnessSave(lvl);
|
||||
Serial.print(F("[Brightness] Set to level "));
|
||||
Serial.println(lvl);
|
||||
} else {
|
||||
Serial.println(F("Level must be 0-9"));
|
||||
}
|
||||
} else {
|
||||
Serial.print(F("[Brightness] Current level: "));
|
||||
Serial.println(getBrightnessLevel());
|
||||
}
|
||||
}
|
||||
|
||||
// Update command
|
||||
if (cmd_args.get(0) == UPDATE_CMD) {
|
||||
//int w_sw = this->argSearch(&cmd_args, "-w"); // Web update
|
||||
|
||||
@@ -195,6 +195,10 @@ const char PROGMEM HELP_BT_SPOOFAT_CMD[] = "spoofat -t <index>";
|
||||
//onst char PROGMEM HELP_BT_SPAM_ALL_CMD[] = "btspamall";
|
||||
const char PROGMEM HELP_BT_WARDRIVE_CMD[] = "btwardrive";
|
||||
const char PROGMEM HELP_BT_SKIM_CMD[] = "sniffskim";
|
||||
|
||||
const char PROGMEM BRIGHTNESS_CMD[] = "brightness";
|
||||
const char PROGMEM HELP_BRIGHTNESS_CMD[] = "brightness [-c cycle] [-s <0-9>]";
|
||||
|
||||
const char PROGMEM HELP_FOOT[] = "==================================";
|
||||
|
||||
|
||||
|
||||
@@ -190,6 +190,33 @@ void MenuFunctions::main(uint32_t currentTime)
|
||||
#endif
|
||||
|
||||
|
||||
// Brightness gesture: hold top or bottom zone 1.5s to enter brightness mode
|
||||
#ifdef HAS_ILI9341
|
||||
if (pressed && (wifi_scan_obj.currentScanMode == WIFI_SCAN_OFF ||
|
||||
wifi_scan_obj.currentScanMode == WIFI_CONNECTED)) {
|
||||
uint16_t zoneUp = TFT_HEIGHT * 25 / 100;
|
||||
uint16_t zoneDown = TFT_HEIGHT * 75 / 100;
|
||||
if (t_y < zoneUp || t_y >= zoneDown) {
|
||||
uint32_t hold_start = millis();
|
||||
uint16_t hx, hy;
|
||||
bool held = false;
|
||||
while (display_obj.updateTouch(&hx, &hy)) {
|
||||
if (millis() - hold_start >= 1500) {
|
||||
held = true;
|
||||
break;
|
||||
}
|
||||
delay(10);
|
||||
}
|
||||
if (held) {
|
||||
// Wait for release before entering brightness mode
|
||||
while (display_obj.updateTouch(&hx, &hy)) delay(10);
|
||||
this->brightnessMode();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// This is if there are scans/attacks going on
|
||||
#ifdef HAS_ILI9341
|
||||
if ((wifi_scan_obj.currentScanMode != WIFI_SCAN_OFF) &&
|
||||
@@ -2682,6 +2709,10 @@ void MenuFunctions::RunSetup()
|
||||
this->changeMenu(&saveFileMenu, true);
|
||||
});
|
||||
|
||||
this->addNodes(&deviceMenu, "Brightness", TFTYELLOW, NULL, KEYBOARD_ICO, [this]() {
|
||||
this->brightnessMode();
|
||||
});
|
||||
|
||||
this->addNodes(&deviceMenu, text_table1[17], TFTWHITE, NULL, DEVICE_INFO, [this]() {
|
||||
wifi_scan_obj.currentScanMode = SHOW_INFO;
|
||||
this->changeMenu(&infoMenu, true);
|
||||
@@ -3706,5 +3737,83 @@ void MenuFunctions::displayCurrentMenu(int start_index)
|
||||
this->displayMenuButtons();
|
||||
}
|
||||
|
||||
// ============================================================
|
||||
// BRIGHTNESS ADJUSTMENT MODE
|
||||
// Hold top/bottom zone 1.5s to enter. TAP TOP = brighter, TAP BOTTOM = dimmer.
|
||||
// TAP MIDDLE or wait 3s = save & exit.
|
||||
// ============================================================
|
||||
void MenuFunctions::brightnessMode() {
|
||||
extern void brightnessSave(uint8_t level);
|
||||
extern uint8_t getBrightnessLevel();
|
||||
|
||||
const uint8_t levels[] = {26, 51, 77, 102, 128, 153, 179, 204, 230, 255};
|
||||
const uint8_t numLevels = 10;
|
||||
uint8_t level = getBrightnessLevel();
|
||||
|
||||
display_obj.tft.fillScreen(TFT_BLACK);
|
||||
display_obj.tft.setTextColor(TFT_CYAN, TFT_BLACK);
|
||||
display_obj.tft.drawCentreString("BRIGHTNESS", TFT_WIDTH/2, 30, 2);
|
||||
|
||||
display_obj.tft.setTextColor(TFT_DARKGREY, TFT_BLACK);
|
||||
display_obj.tft.drawCentreString("TAP TOP = BRIGHTER", TFT_WIDTH/2, 10, 1);
|
||||
display_obj.tft.drawCentreString("TAP BOTTOM = DIMMER", TFT_WIDTH/2, TFT_HEIGHT - 20, 1);
|
||||
display_obj.tft.setTextColor(TFT_RED, TFT_BLACK);
|
||||
display_obj.tft.drawCentreString("TAP MIDDLE or WAIT 3s = SAVE", TFT_WIDTH/2, TFT_HEIGHT/2 + 50, 1);
|
||||
|
||||
auto drawBar = [&]() {
|
||||
uint16_t barX = 30, barY = TFT_HEIGHT/2 - 25, barW = TFT_WIDTH - 60, barH = 30;
|
||||
display_obj.tft.drawRect(barX, barY, barW, barH, TFT_WHITE);
|
||||
uint16_t fillW = (barW - 4) * (level + 1) / numLevels;
|
||||
display_obj.tft.fillRect(barX + 2, barY + 2, barW - 4, barH - 4, TFT_BLACK);
|
||||
display_obj.tft.fillRect(barX + 2, barY + 2, fillW, barH - 4, TFT_CYAN);
|
||||
display_obj.tft.fillRect(0, barY + barH + 5, TFT_WIDTH, 20, TFT_BLACK);
|
||||
display_obj.tft.setTextColor(TFT_WHITE, TFT_BLACK);
|
||||
String pct = String(levels[level] * 100 / 255) + "%";
|
||||
display_obj.tft.drawCentreString(pct, TFT_WIDTH/2, barY + barH + 8, 2);
|
||||
};
|
||||
drawBar();
|
||||
|
||||
uint16_t zoneUp = TFT_HEIGHT * 25 / 100;
|
||||
uint16_t zoneDown = TFT_HEIGHT * 75 / 100;
|
||||
uint32_t lastTouch = millis();
|
||||
|
||||
while (true) {
|
||||
// Auto-save after 3s of no touch
|
||||
if (millis() - lastTouch >= 3000) {
|
||||
brightnessSave(level);
|
||||
break;
|
||||
}
|
||||
|
||||
uint16_t tx, ty;
|
||||
if (display_obj.updateTouch(&tx, &ty)) {
|
||||
lastTouch = millis();
|
||||
// Wait for release
|
||||
while (display_obj.updateTouch(&tx, &ty)) delay(10);
|
||||
|
||||
if (ty < zoneUp) {
|
||||
if (level < numLevels - 1) {
|
||||
level++;
|
||||
ledcWrite(TFT_BL, levels[level]);
|
||||
drawBar();
|
||||
}
|
||||
} else if (ty >= zoneDown) {
|
||||
if (level > 0) {
|
||||
level--;
|
||||
ledcWrite(TFT_BL, levels[level]);
|
||||
drawBar();
|
||||
}
|
||||
} else {
|
||||
// Middle = save now
|
||||
brightnessSave(level);
|
||||
break;
|
||||
}
|
||||
delay(150);
|
||||
}
|
||||
delay(30);
|
||||
}
|
||||
|
||||
this->changeMenu(current_menu, true);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -277,6 +277,7 @@ class MenuFunctions
|
||||
void changeMenu(Menu* menu, bool simple_change = false);
|
||||
void drawStatusBar();
|
||||
void displayCurrentMenu(int start_index = 0);
|
||||
void brightnessMode();
|
||||
void main(uint32_t currentTime);
|
||||
void RunSetup();
|
||||
void orientDisplay();
|
||||
|
||||
@@ -123,27 +123,69 @@ const String PROGMEM version_number = MARAUDER_VERSION;
|
||||
|
||||
uint32_t currentTime = 0;
|
||||
|
||||
// PWM Brightness Control
|
||||
#ifdef HAS_SCREEN
|
||||
#include <Preferences.h>
|
||||
#define BL_CHANNEL 0
|
||||
#define BL_FREQ 5000
|
||||
#define BL_RESOLUTION 8
|
||||
const uint8_t BL_LEVELS[] = {26, 51, 77, 102, 128, 153, 179, 204, 230, 255};
|
||||
const uint8_t BL_NUM_LEVELS = 10;
|
||||
uint8_t bl_level_idx = 9; // default full brightness
|
||||
Preferences bl_prefs;
|
||||
#endif
|
||||
|
||||
void brightnessInit() {
|
||||
#ifdef HAS_SCREEN
|
||||
ledcAttach(TFT_BL, BL_FREQ, BL_RESOLUTION);
|
||||
bl_prefs.begin("backlight", false);
|
||||
bl_level_idx = bl_prefs.getUChar("level", 9);
|
||||
if (bl_level_idx >= BL_NUM_LEVELS) bl_level_idx = 9;
|
||||
ledcWrite(TFT_BL, BL_LEVELS[bl_level_idx]);
|
||||
#endif
|
||||
}
|
||||
|
||||
void brightnessCycle() {
|
||||
#ifdef HAS_SCREEN
|
||||
bl_level_idx = (bl_level_idx + 1) % BL_NUM_LEVELS;
|
||||
ledcWrite(TFT_BL, BL_LEVELS[bl_level_idx]);
|
||||
bl_prefs.putUChar("level", bl_level_idx);
|
||||
Serial.print(F("[Brightness] Level "));
|
||||
Serial.print(bl_level_idx + 1);
|
||||
Serial.print(F("/"));
|
||||
Serial.print(BL_NUM_LEVELS);
|
||||
Serial.print(F(" ("));
|
||||
Serial.print(BL_LEVELS[bl_level_idx] * 100 / 255);
|
||||
Serial.println(F("%)"));
|
||||
#endif
|
||||
}
|
||||
|
||||
uint8_t getBrightnessLevel() {
|
||||
#ifdef HAS_SCREEN
|
||||
return bl_level_idx;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
void brightnessSave(uint8_t level) {
|
||||
#ifdef HAS_SCREEN
|
||||
if (level >= BL_NUM_LEVELS) level = BL_NUM_LEVELS - 1;
|
||||
bl_level_idx = level;
|
||||
ledcWrite(TFT_BL, BL_LEVELS[bl_level_idx]);
|
||||
bl_prefs.putUChar("level", bl_level_idx);
|
||||
#endif
|
||||
}
|
||||
|
||||
void backlightOn() {
|
||||
#ifdef HAS_SCREEN
|
||||
#if defined(MARAUDER_MINI)
|
||||
digitalWrite(TFT_BL, LOW);
|
||||
#endif
|
||||
|
||||
#if !defined(MARAUDER_MINI)
|
||||
digitalWrite(TFT_BL, HIGH);
|
||||
#endif
|
||||
ledcWrite(TFT_BL, BL_LEVELS[bl_level_idx]);
|
||||
#endif
|
||||
}
|
||||
|
||||
void backlightOff() {
|
||||
#ifdef HAS_SCREEN
|
||||
#if defined(MARAUDER_MINI)
|
||||
digitalWrite(TFT_BL, HIGH);
|
||||
#endif
|
||||
|
||||
#if !defined(MARAUDER_MINI)
|
||||
digitalWrite(TFT_BL, LOW);
|
||||
#endif
|
||||
ledcWrite(TFT_BL, 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -235,6 +277,8 @@ void setup()
|
||||
display_obj.tft.setTextColor(TFT_WHITE, TFT_BLACK);
|
||||
#endif
|
||||
|
||||
// Init PWM brightness AFTER display init (so ledcAttach overrides TFT_eSPI's pinMode)
|
||||
brightnessInit();
|
||||
backlightOff();
|
||||
|
||||
#ifdef HAS_SCREEN
|
||||
|
||||
Reference in New Issue
Block a user