diff --git a/CHANGELOG.md b/CHANGELOG.md index 1bea88447..f5a49ac34 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,7 @@ All notable changes to this project will be documented in this file. ### Changed - M5 Stack Core2 uses UNIVERSAL_DISPLAY with enabled LVGL as default now +- ``DisplayDimmer`` has now range 0..100 instead of 0..15 ### Fixed - OpenTherm invalid JSON (#13028) diff --git a/lib/lib_display/Display_Renderer-gemu-1.0/src/renderer.cpp b/lib/lib_display/Display_Renderer-gemu-1.0/src/renderer.cpp index 7449ff647..fb223680b 100644 --- a/lib/lib_display/Display_Renderer-gemu-1.0/src/renderer.cpp +++ b/lib/lib_display/Display_Renderer-gemu-1.0/src/renderer.cpp @@ -58,6 +58,11 @@ uint16_t Renderer::GetColorFromIndex(uint8_t index) { } void Renderer::dim(uint8_t contrast) { + uint8_t contrast8 = ((uint32_t)contrast * 255) / 15; + dim8(contrast8, contrast8); +} + +void Renderer::dim8(uint8_t contrast, uint8_t contrast_gamma) { } diff --git a/lib/lib_display/Display_Renderer-gemu-1.0/src/renderer.h b/lib/lib_display/Display_Renderer-gemu-1.0/src/renderer.h index 8ec0f3cde..49f4d7b5e 100644 --- a/lib/lib_display/Display_Renderer-gemu-1.0/src/renderer.h +++ b/lib/lib_display/Display_Renderer-gemu-1.0/src/renderer.h @@ -71,7 +71,8 @@ public: virtual void DisplayInit(int8_t p,int8_t size,int8_t rot,int8_t font); virtual void Begin(int16_t p1,int16_t p2,int16_t p3); virtual void Updateframe(); - virtual void dim(uint8_t contrast); + virtual void dim(uint8_t contrast); // input has range 0..15 + virtual void dim8(uint8_t contrast, uint8_t contrast_gamma); // input has range 0..255, second arg has gamma correction for PWM virtual void pushColors(uint16_t *data, uint16_t len, boolean first); virtual void setAddrWindow(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1); virtual void invertDisplay(boolean i); diff --git a/lib/lib_display/UDisplay/uDisplay.cpp b/lib/lib_display/UDisplay/uDisplay.cpp index 0a089b6f1..7bca0f723 100755 --- a/lib/lib_display/UDisplay/uDisplay.cpp +++ b/lib/lib_display/UDisplay/uDisplay.cpp @@ -423,9 +423,9 @@ Renderer *uDisplay::Init(void) { if (bpanel >= 0) { #ifdef ESP32 - ledcSetup(ESP32_PWM_CHANNEL, 4000, 8); + ledcSetup(ESP32_PWM_CHANNEL, 977, 8); // use 10 bits resolution like in Light ledcAttachPin(bpanel, ESP32_PWM_CHANNEL); - ledcWrite(ESP32_PWM_CHANNEL, 128); + ledcWrite(ESP32_PWM_CHANNEL, 8); // 38/255 correspond roughly to 50% visual brighness (with Gamma) #else pinMode(bpanel, OUTPUT); digitalWrite(bpanel, HIGH); @@ -1343,7 +1343,7 @@ void uDisplay::DisplayOnff(int8_t on) { if (dsp_on != 0xff) spi_command_one(dsp_on); if (bpanel >= 0) { #ifdef ESP32 - ledcWrite(ESP32_PWM_CHANNEL, dimmer); + ledcWrite(ESP32_PWM_CHANNEL, dimmer8_gamma); #else digitalWrite(bpanel, HIGH); #endif @@ -1386,39 +1386,38 @@ void uDisplay::invertDisplay(boolean i) { void udisp_dimm(uint8_t dim); -void uDisplay::dim(uint8_t dim) { - dimmer = dim; +// input value is 0..15 +// void uDisplay::dim(uint8_t dim) { +// dim8(((uint32_t)dim * 255) / 15); +// } +// dim is 0..255 +void uDisplay::dim8(uint8_t dim, uint8_t dim_gamma) { // dimmer with 8 bits resolution, 0..255. Gamma correction must be done by caller + dimmer8 = dim; + dimmer8_gamma = dim_gamma; if (ep_mode) { return; } - if (interface == _UDSP_SPI) { - if (dimmer > 15) dimmer = 15; - dimmer = ((float)dimmer / 15.0) * 255.0; -#ifdef ESP32 - if (bpanel >= 0) { - ledcWrite(ESP32_PWM_CHANNEL, dimmer); - } else { - //udisp_dimm(dim); - if (dim_cbp) { - dim_cbp(dim); - } - } +#ifdef ESP32 // TODO should we also add a ESP8266 version for bpanel? + if (bpanel >= 0) { // is the BaclPanel GPIO configured + ledcWrite(ESP32_PWM_CHANNEL, dimmer8_gamma); + } else if (dim_cbp) { + dim_cbp(dim); + } #endif - - if (dim_op != 0xff) { + if (interface == _UDSP_SPI) { + if (dim_op != 0xff) { // send SPI command if dim configured SPI_BEGIN_TRANSACTION SPI_CS_LOW spi_command(dim_op); - spi_data8(dim); + spi_data8(dimmer8); SPI_CS_HIGH SPI_END_TRANSACTION } } } - // the cases are PSEUDO_OPCODES from MODULE_DESCRIPTOR // and may be exapnded with more opcodes void uDisplay::TS_RotConvert(int16_t *x, int16_t *y) { diff --git a/lib/lib_display/UDisplay/uDisplay.h b/lib/lib_display/UDisplay/uDisplay.h index 42b8f47a3..8ce012bf5 100755 --- a/lib/lib_display/UDisplay/uDisplay.h +++ b/lib/lib_display/UDisplay/uDisplay.h @@ -90,7 +90,8 @@ class uDisplay : public Renderer { uint16_t fgcol(void); uint16_t bgcol(void); int8_t color_type(void); - void dim(uint8_t dim); +// void dim(uint8_t dim); // original version with 4 bits resolution 0..15 + virtual void dim8(uint8_t dim, uint8_t dim_gamma); // dimmer with 8 bits resolution, 0..255. Gamma correction must be done by caller uint16_t GetColorFromIndex(uint8_t index); void setRotation(uint8_t m); void fillScreen(uint16_t color); @@ -180,9 +181,10 @@ class uDisplay : public Renderer { int8_t spi_clk; int8_t spi_mosi; int8_t spi_dc; - int8_t bpanel; + int8_t bpanel; // backbanel GPIO, -1 if none int8_t spi_miso; - uint8_t dimmer; + uint8_t dimmer8; // 8 bits resolution, 0..255 + uint8_t dimmer8_gamma; // 8 bits resolution, 0..255, gamma corrected SPIClass *uspi; uint8_t sspi; SPISettings spiSettings; diff --git a/tasmota/settings.h b/tasmota/settings.h index 2ceb536b4..a2d6dfefe 100644 --- a/tasmota/settings.h +++ b/tasmota/settings.h @@ -469,7 +469,7 @@ typedef struct { uint8_t display_rows; // 2D5 uint8_t display_cols[2]; // 2D6 uint8_t display_address[8]; // 2D8 - uint8_t display_dimmer; // 2E0 + int8_t display_dimmer_protected; // 2E0 - if positive range 0..15, if negative range 0..100 (neg) - don't use directly uint8_t display_size; // 2E1 TimeRule tflag[2]; // 2E2 uint16_t pwm_frequency; // 2E6 diff --git a/tasmota/settings.ino b/tasmota/settings.ino index 132e438f2..e56c9743d 100644 --- a/tasmota/settings.ino +++ b/tasmota/settings.ino @@ -1116,7 +1116,7 @@ void SettingsDefaultSet2(void) { Settings->display_rows = 2; Settings->display_cols[0] = 16; Settings->display_cols[1] = 8; - Settings->display_dimmer = 1; + Settings->display_dimmer_protected = -10; // 10% Settings->display_size = 1; Settings->display_font = 1; // Settings->display_rotate = 0; diff --git a/tasmota/xdrv_13_display.ino b/tasmota/xdrv_13_display.ino index 24f9cf567..609be6015 100755 --- a/tasmota/xdrv_13_display.ino +++ b/tasmota/xdrv_13_display.ino @@ -395,6 +395,30 @@ uint32_t decode_te(char *line) { return skip; } +/*-------------------------------------------------------------------------------------------*/ +// Getter and Setter for DisplayDimer +// Original encoding is range 0..15 +// New encoding is range 0..100 using negative numbers, i.e. 0..-100 +uint8_t GetDisplayDimmer(void) { + if (Settings->display_dimmer_protected > 0) { + return changeUIntScale(Settings->display_dimmer_protected, 0, 15, 0, 100); + } else { + if (Settings->display_dimmer_protected < -100) { Settings->display_dimmer_protected = -100; } + return - Settings->display_dimmer_protected; + } +} + +// retro-compatible call to get range 0..15 +uint8_t GetDisplayDimmer16(void) { + return changeUIntScale(GetDisplayDimmer(), 0, 100, 0, 15); +} + +// In: 0..100 +void SetDisplayDimmer(uint8_t dimmer) { + if (dimmer > 100) { dimmer = 100; } + Settings->display_dimmer_protected = - dimmer; +} + /*-------------------------------------------------------------------------------------------*/ #define DISPLAY_BUFFER_COLS 128 // Max number of characters in linebuf @@ -1750,6 +1774,7 @@ void DisplayLocalSensor(void) void DisplayInitDriver(void) { XdspCall(FUNC_DISPLAY_INIT_DRIVER); + ApplyDisplayDimmer(); #ifdef USE_MULTI_DISPLAY Set_display(0); @@ -1821,7 +1846,7 @@ void CmndDisplay(void) { D_CMND_DISP_MODE "\":%d,\"" D_CMND_DISP_DIMMER "\":%d,\"" D_CMND_DISP_SIZE "\":%d,\"" D_CMND_DISP_FONT "\":%d,\"" D_CMND_DISP_ROTATE "\":%d,\"" D_CMND_DISP_INVERT "\":%d,\"" D_CMND_DISP_REFRESH "\":%d,\"" D_CMND_DISP_COLS "\":[%d,%d],\"" D_CMND_DISP_ROWS "\":%d}}"), Settings->display_model, Settings->display_options.type, Settings->display_width, Settings->display_height, - Settings->display_mode, changeUIntScale(Settings->display_dimmer, 0, 15, 0, 100), Settings->display_size, Settings->display_font, + Settings->display_mode, GetDisplayDimmer(), Settings->display_size, Settings->display_font, Settings->display_rotate, Settings->display_options.invert, Settings->display_refresh, Settings->display_cols[0], Settings->display_cols[1], Settings->display_rows); } @@ -1896,22 +1921,30 @@ void CmndDisplayMode(void) { ResponseCmndNumber(Settings->display_mode); } +// Apply the current display dimmer +void ApplyDisplayDimmer(void) { + uint8_t dimmer8 = changeUIntScale(GetDisplayDimmer(), 0, 100, 0, 255); + uint8_t dimmer8_gamma = ledGamma(dimmer8); + if (dimmer8 && !(disp_power)) { + ExecuteCommandPower(disp_device, POWER_ON, SRC_DISPLAY); + } + else if (!dimmer8 && disp_power) { + ExecuteCommandPower(disp_device, POWER_OFF, SRC_DISPLAY); + } + if (renderer) { + renderer->dim8(dimmer8, dimmer8_gamma); // provide 8 bits and gamma corrected dimmer in 8 bits + } else { + XdspCall(FUNC_DISPLAY_DIM); + } +} + void CmndDisplayDimmer(void) { if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 100)) { - Settings->display_dimmer = changeUIntScale(XdrvMailbox.payload, 0, 100, 0, 15); // Correction for Domoticz (0 - 15) - if (Settings->display_dimmer && !(disp_power)) { - ExecuteCommandPower(disp_device, POWER_ON, SRC_DISPLAY); - } - else if (!Settings->display_dimmer && disp_power) { - ExecuteCommandPower(disp_device, POWER_OFF, SRC_DISPLAY); - } - if (renderer) { - renderer->dim(Settings->display_dimmer); - } else { - XdspCall(FUNC_DISPLAY_DIM); - } + uint8_t dimmer = XdrvMailbox.payload; + SetDisplayDimmer(dimmer); + ApplyDisplayDimmer(); } - ResponseCmndNumber(changeUIntScale(Settings->display_dimmer, 0, 15, 0, 100)); + ResponseCmndNumber(GetDisplayDimmer()); } void CmndDisplaySize(void) { diff --git a/tasmota/xdsp_03_matrix.ino b/tasmota/xdsp_03_matrix.ino index 5a133debc..09d8b8587 100644 --- a/tasmota/xdsp_03_matrix.ino +++ b/tasmota/xdsp_03_matrix.ino @@ -67,7 +67,7 @@ void MatrixFixed(char* txt) matrix[i]->clear(); matrix[i]->setCursor(-i *8, 0); matrix[i]->print(txt); - matrix[i]->setBrightness(Settings->display_dimmer); + matrix[i]->setBrightness(GetDisplayDimmer16()); } MatrixWrite(); } @@ -82,7 +82,7 @@ void MatrixCenter(char* txt) matrix[i]->clear(); matrix[i]->setCursor(-(i *8)+offset, 0); matrix[i]->print(txt); - matrix[i]->setBrightness(Settings->display_dimmer); + matrix[i]->setBrightness(GetDisplayDimmer16()); } MatrixWrite(); } @@ -106,7 +106,7 @@ void MatrixScrollLeft(char* txt, int loop) matrix[i]->clear(); matrix[i]->setCursor(mtx_x - i *8, 0); matrix[i]->print(txt); - matrix[i]->setBrightness(Settings->display_dimmer); + matrix[i]->setBrightness(GetDisplayDimmer16()); } MatrixWrite(); // Move text position left by 1 pixel. @@ -151,7 +151,7 @@ void MatrixScrollUp(char* txt, int loop) matrix[i]->setCursor(-i *8, mtx_y + (j *8)); matrix[i]->println(words[j]); } - matrix[i]->setBrightness(Settings->display_dimmer); + matrix[i]->setBrightness(GetDisplayDimmer16()); } MatrixWrite(); if (((mtx_y %8) == 0) && mtx_counter) { @@ -172,7 +172,7 @@ void MatrixInitMode(void) { for (uint32_t i = 0; i < mtx_matrices; i++) { matrix[i]->setRotation(Settings->display_rotate); // 1 - matrix[i]->setBrightness(Settings->display_dimmer); + matrix[i]->setBrightness(GetDisplayDimmer16()); matrix[i]->blinkRate(0); // 0 - 3 matrix[i]->setTextWrap(false); // Allow text to run off edges // matrix[i]->setTextSize(Settings->display_size); diff --git a/tasmota/xdsp_04_ili9341.ino b/tasmota/xdsp_04_ili9341.ino index 7e638cf5a..e4142b6c0 100755 --- a/tasmota/xdsp_04_ili9341.ino +++ b/tasmota/xdsp_04_ili9341.ino @@ -97,7 +97,7 @@ void ILI9341_InitDriver() #endif renderer->DisplayInit(DISPLAY_INIT_MODE, Settings->display_size, Settings->display_rotate, Settings->display_font); - renderer->dim(Settings->display_dimmer); + renderer->dim(GetDisplayDimmer16()); #ifdef SHOW_SPLASH // Welcome text diff --git a/tasmota/xdsp_08_ILI9488.ino b/tasmota/xdsp_08_ILI9488.ino index 4fdf6c178..5c3cd2f5d 100644 --- a/tasmota/xdsp_08_ILI9488.ino +++ b/tasmota/xdsp_08_ILI9488.ino @@ -72,7 +72,7 @@ void ILI9488_InitDriver(void) { ili9488->begin(); renderer = ili9488; renderer->DisplayInit(DISPLAY_INIT_MODE,Settings->display_size,Settings->display_rotate,Settings->display_font); - renderer->dim(Settings->display_dimmer); + renderer->dim(GetDisplayDimmer16()); #ifdef SHOW_SPLASH // Welcome text diff --git a/tasmota/xdsp_09_SSD1351.ino b/tasmota/xdsp_09_SSD1351.ino index 9a5eed7e1..7d6d28d31 100644 --- a/tasmota/xdsp_09_SSD1351.ino +++ b/tasmota/xdsp_09_SSD1351.ino @@ -68,7 +68,7 @@ void SSD1351_InitDriver() { ssd1351->begin(); renderer = ssd1351; renderer->DisplayInit(DISPLAY_INIT_MODE,Settings->display_size,Settings->display_rotate,Settings->display_font); - renderer->dim(Settings->display_dimmer); + renderer->dim(GetDisplayDimmer16()); #ifdef SHOW_SPLASH // Welcome text diff --git a/tasmota/xdsp_10_RA8876.ino b/tasmota/xdsp_10_RA8876.ino index 8524f48f5..305f26c7f 100644 --- a/tasmota/xdsp_10_RA8876.ino +++ b/tasmota/xdsp_10_RA8876.ino @@ -61,7 +61,7 @@ void RA8876_InitDriver(void) { ra8876->begin(); renderer = ra8876; renderer->DisplayInit(DISPLAY_INIT_MODE,Settings->display_size,Settings->display_rotate,Settings->display_font); - renderer->dim(Settings->display_dimmer); + renderer->dim(GetDisplayDimmer16()); //testall(); #ifdef SHOW_SPLASH diff --git a/tasmota/xdsp_11_sevenseg.ino b/tasmota/xdsp_11_sevenseg.ino index 7f200e44a..f2c48adb9 100644 --- a/tasmota/xdsp_11_sevenseg.ino +++ b/tasmota/xdsp_11_sevenseg.ino @@ -106,7 +106,7 @@ void SevensegLog(void) void SevensegDim(void) { for (uint32_t i = 0; i < sevensegs; i++) { - sevenseg[i]->setBrightness(Settings->display_dimmer); + sevenseg[i]->setBrightness(GetDisplayDimmer16()); } } @@ -130,7 +130,7 @@ void SevensegClear(void) void SevensegInitMode(void) { for (uint32_t i = 0; i < sevensegs; i++) { - sevenseg[i]->setBrightness(Settings->display_dimmer); + sevenseg[i]->setBrightness(GetDisplayDimmer16()); sevenseg[i]->blinkRate(0); } SevensegClear(); diff --git a/tasmota/xdsp_12_ST7789.ino b/tasmota/xdsp_12_ST7789.ino index 9b982090b..fb55f6d91 100644 --- a/tasmota/xdsp_12_ST7789.ino +++ b/tasmota/xdsp_12_ST7789.ino @@ -93,7 +93,7 @@ void ST7789_InitDriver(void) { st7789->init(Settings->display_width,Settings->display_height); renderer = st7789; renderer->DisplayInit(DISPLAY_INIT_MODE,Settings->display_size,Settings->display_rotate,Settings->display_font); - renderer->dim(Settings->display_dimmer); + renderer->dim(GetDisplayDimmer16()); #ifdef SHOW_SPLASH // Welcome text diff --git a/tasmota/xdsp_14_SSD1331.ino b/tasmota/xdsp_14_SSD1331.ino index b939bedeb..aaefeedd4 100644 --- a/tasmota/xdsp_14_SSD1331.ino +++ b/tasmota/xdsp_14_SSD1331.ino @@ -73,7 +73,7 @@ void SSD1331_InitDriver() { renderer = ssd1331; // Rotation is currently broken, https://github.com/adafruit/Adafruit-SSD1331-OLED-Driver-Library-for-Arduino/issues/26 renderer->DisplayInit(DISPLAY_INIT_MODE, Settings->display_size, Settings->display_rotate, Settings->display_font); - renderer->dim(Settings->display_dimmer); + renderer->dim(GetDisplayDimmer16()); #ifdef SHOW_SPLASH // Welcome text diff --git a/tasmota/xdsp_15_tm1637.ino b/tasmota/xdsp_15_tm1637.ino index 038698f3c..75bacdf89 100644 --- a/tasmota/xdsp_15_tm1637.ino +++ b/tasmota/xdsp_15_tm1637.ino @@ -233,7 +233,8 @@ void TM1637Init(void) Settings->display_cols[0] = Settings->display_width; Settings->display_height = 1; Settings->display_rows = Settings->display_height; - if(!Settings->display_dimmer || Settings->display_dimmer < 2 || Settings->display_dimmer > 15) Settings->display_dimmer = 8; + uint8_t dimmer16 = GetDisplayDimmer16(); + if(!dimmer16 || dimmer16 < 2 || dimmer16 > 15) SetDisplayDimmer(50); if (TM1637 == TM1637Data.display_type) { @@ -1074,8 +1075,8 @@ bool TM1637MainFunc(uint8_t fn) void TM1637Dim(void) { - // Settings->display_dimmer = 0 - 15 - uint8_t brightness = Settings->display_dimmer >> 1; // 0 - 7 + // GetDisplayDimmer16() = 0 - 15 + uint8_t brightness = GetDisplayDimmer16() >> 1; // 0 - 7 if (TM1637 == TM1637Data.display_type) { diff --git a/tasmota/xdsp_17_universal.ino b/tasmota/xdsp_17_universal.ino index 6151e2c95..013f45175 100644 --- a/tasmota/xdsp_17_universal.ino +++ b/tasmota/xdsp_17_universal.ino @@ -312,7 +312,7 @@ uDisplay *udisp; #endif renderer->DisplayInit(DISPLAY_INIT_MODE, Settings->display_size, Settings->display_rotate, Settings->display_font); - renderer->dim(Settings->display_dimmer); + ApplyDisplayDimmer(); #ifdef SHOW_SPLASH renderer->Splash();