diff --git a/Marlin/Configuration.h b/Marlin/Configuration.h index 8dd0a8f7ddefd..cea89a3c6d62f 100644 --- a/Marlin/Configuration.h +++ b/Marlin/Configuration.h @@ -2696,19 +2696,6 @@ // //#define K3D_242_OLED_CONTROLLER // Software SPI -// ========================================================================= -// ===============Screen Sleep Feature =================================== -// ========================================================================= -// For DOGM Diaplays for which U8g graphics library supports Sleep/Wake -// functions. Can be used to to reduce energy consumption and reduce -// OLED pixel burn-in. U8g supports sleep/wake functions of -// SH1106/SSD1306/SSD1309 and other DOGM displays. Feature adds Screen -// Timeout setting menu to the LCD menu under Configuration. Use menu -// to set timeout period between 0 and 99 minutes. Setting to '0' -// disables screen sleep feature. - -//#define SCREEN_TIMEOUT 1 // ( 0 - 99 minutes ) Turn off screen with timeout - //============================================================================= //========================== Extensible UI Displays =========================== //============================================================================= diff --git a/Marlin/Configuration_adv.h b/Marlin/Configuration_adv.h index 9c438e0406ca3..e6b5ff05bcd11 100644 --- a/Marlin/Configuration_adv.h +++ b/Marlin/Configuration_adv.h @@ -1697,6 +1697,17 @@ // Western only. Not available for Cyrillic, Kana, Turkish, Greek, or Chinese. //#define USE_SMALL_INFOFONT + /** + * Graphical Display Sleep + * + * The U8G library provides sleep / wake functions for SH1106, SSD1306, + * SSD1309, and some other DOGM displays. + * Enable this option to save energy and prevent OLED pixel burn-in. + * Adds the menu item Configuration > Display Timeout to set a wait period + * from 0 (disabled) to 99 minutes. + */ + //#define DISPLAY_SLEEP_MINUTES 2 // (minutes) Timeout before turning off the screen + /** * ST7920-based LCDs can emulate a 16 x 4 character display using * the ST7920 character-generator for very fast screen updates. diff --git a/Marlin/src/core/language.h b/Marlin/src/core/language.h index 89c0babc2568b..a7710333c1832 100644 --- a/Marlin/src/core/language.h +++ b/Marlin/src/core/language.h @@ -303,6 +303,7 @@ #define STR_MATERIAL_HEATUP "Material heatup parameters" #define STR_LCD_CONTRAST "LCD Contrast" #define STR_LCD_BRIGHTNESS "LCD Brightness" +#define STR_DISPLAY_SLEEP "Display Sleep" #define STR_UI_LANGUAGE "UI Language" #define STR_Z_PROBE_OFFSET "Z-Probe Offset" #define STR_TEMPERATURE_UNITS "Temperature Units" diff --git a/Marlin/src/gcode/gcode.h b/Marlin/src/gcode/gcode.h index a4ce273e51f9b..215d0d4f9b927 100644 --- a/Marlin/src/gcode/gcode.h +++ b/Marlin/src/gcode/gcode.h @@ -202,6 +202,7 @@ * M226 - Wait until a pin is in a given state: "M226 P S" (Requires DIRECT_PIN_CONTROL) * M240 - Trigger a camera to take a photograph. (Requires PHOTO_GCODE) * M250 - Set LCD contrast: "M250 C" (0-63). (Requires LCD support) + * M255 - Set LCD sleep time: "M255 S" (0-99). (Requires an LCD with brightness or sleep/wake) * M256 - Set LCD brightness: "M256 B" (0-255). (Requires an LCD with brightness control) * M260 - i2c Send Data (Requires EXPERIMENTAL_I2CBUS) * M261 - i2c Request Data (Requires EXPERIMENTAL_I2CBUS) @@ -879,6 +880,11 @@ class GcodeSuite { static void M250_report(const bool forReplay=true); #endif + #if HAS_DISPLAY_SLEEP + static void M255(); + static void M255_report(const bool forReplay=true); + #endif + #if HAS_LCD_BRIGHTNESS static void M256(); static void M256_report(const bool forReplay=true); diff --git a/Marlin/src/gcode/lcd/M255.cpp b/Marlin/src/gcode/lcd/M255.cpp new file mode 100644 index 0000000000000..cfdf27b8a1fc3 --- /dev/null +++ b/Marlin/src/gcode/lcd/M255.cpp @@ -0,0 +1,58 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2022 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#include "../../inc/MarlinConfig.h" + +#if HAS_GCODE_M255 + +#include "../gcode.h" +#include "../../lcd/marlinui.h" + +/** + * M255: Set the LCD sleep timeout (in minutes) + * S - Period of inactivity required for display / backlight sleep + */ +void GcodeSuite::M255() { + if (parser.seenval('S')) { + #if HAS_DISPLAY_SLEEP + const int m = parser.value_int(); + ui.sleep_timeout_minutes = constrain(m, SLEEP_TIMEOUT_MIN, SLEEP_TIMEOUT_MAX); + #else + const int s = parser.value_int() * 60; + ui.lcd_backlight_timeout = constrain(s, LCD_BKL_TIMEOUT_MIN, LCD_BKL_TIMEOUT_MAX); + #endif + } + else + M255_report(); +} + +void GcodeSuite::M255_report(const bool forReplay/*=true*/) { + report_heading_etc(forReplay, F(STR_DISPLAY_SLEEP)); + SERIAL_ECHOLNPGM(" M255 S", + #if HAS_DISPLAY_SLEEP + ui.sleep_timeout_minutes, " ; (minutes)" + #else + ui.lcd_backlight_timeout, " ; (seconds)" + #endif + ); +} + +#endif // HAS_GCODE_M255 diff --git a/Marlin/src/inc/Conditionals_LCD.h b/Marlin/src/inc/Conditionals_LCD.h index 32058037bd952..5adc04fe2da0f 100644 --- a/Marlin/src/inc/Conditionals_LCD.h +++ b/Marlin/src/inc/Conditionals_LCD.h @@ -1505,10 +1505,3 @@ #if defined(NEOPIXEL_BKGD_INDEX_FIRST) && !defined(NEOPIXEL_BKGD_INDEX_LAST) #define NEOPIXEL_BKGD_INDEX_LAST NEOPIXEL_BKGD_INDEX_FIRST #endif - -/** - * Screen Timeout Feature - */ -#if defined(SCREEN_TIMEOUT) - #define HAS_SCREEN_TIMEOUT 1 -#endif diff --git a/Marlin/src/inc/Conditionals_adv.h b/Marlin/src/inc/Conditionals_adv.h index 3e43db4ad6cc9..1042c2eeb216f 100644 --- a/Marlin/src/inc/Conditionals_adv.h +++ b/Marlin/src/inc/Conditionals_adv.h @@ -628,6 +628,12 @@ #if ALL(HAS_RESUME_CONTINUE, PRINTER_EVENT_LEDS, SDSUPPORT) #define HAS_LEDS_OFF_FLAG 1 #endif +#ifdef DISPLAY_SLEEP_MINUTES + #define HAS_DISPLAY_SLEEP 1 +#endif +#if HAS_DISPLAY_SLEEP || LCD_BACKLIGHT_TIMEOUT + #define HAS_GCODE_M255 1 +#endif #if EITHER(DIGIPOT_MCP4018, DIGIPOT_MCP4451) #define HAS_MOTOR_CURRENT_I2C 1 diff --git a/Marlin/src/inc/SanityCheck.h b/Marlin/src/inc/SanityCheck.h index 138bf469e4aad..34b1d2a86d783 100644 --- a/Marlin/src/inc/SanityCheck.h +++ b/Marlin/src/inc/SanityCheck.h @@ -2984,21 +2984,14 @@ static_assert(Y_MAX_LENGTH >= Y_BED_SIZE, "Movement bounds (Y_MIN_POS, Y_MAX_POS #endif /** - * Screen Timeout feature not supported by these common displays -*/ -#if HAS_SCREEN_TIMEOUT - #if ENABLED(REPRAPWORLD_GRAPHICAL_LCD) - #error "SCREEN_TIMEOUT feature not supported by REPRAPWORLD_GRAPHICAL_LCD" - #elif IS_U8GLIB_ST7920 - #error "SCREEN_TIMEOUT feature not supported by Reprap Discount Full Graphics Smart Controller using ST7920" - #elif IS_U8GLIB_LM6059_AF - #error "SCREEN_TIMEOUT feature not supported by U8GLIB_LM6059_AF ST7565" - #elif IS_U8GLIB_ST7565_64128 - #error "SCREEN_TIMEOUT feature not supported by U8GLIB_ST7565_64128" - #elif ANY(FYSETC_MINI, MKS_MINI_12864, ENDER2_STOCKDISPLAY) - #error "SCREEN_TIMEOUT feature not supported by FYSETC_MINI, MKS_MINI_12864, or ENDER2_STOCKDISPLAY" - #elif ENABLED(MINIPANEL) - #error "SCREEN_TIMEOUT feature not supported by MINIPANEL display" + * Display Sleep is not supported by these common displays + */ +#if HAS_DISPLAY_SLEEP + #if ANY(IS_U8GLIB_ST7920, IS_U8GLIB_LM6059_AF, IS_U8GLIB_ST7565_64128, \ + REPRAPWORLD_GRAPHICAL_LCD, FYSETC_MINI, MKS_MINI_12864, ENDER2_STOCKDISPLAY, MINIPANEL) + #error "DISPLAY_SLEEP_MINUTES is not supported by your display." + #elif !WITHIN(DISPLAY_SLEEP_MINUTES, 0, 255) + #error "DISPLAY_SLEEP_MINUTES must be between 0 and 255." #endif #endif diff --git a/Marlin/src/lcd/dogm/marlinui_DOGM.cpp b/Marlin/src/lcd/dogm/marlinui_DOGM.cpp index 8fc9ec2eb0699..19611f678d318 100644 --- a/Marlin/src/lcd/dogm/marlinui_DOGM.cpp +++ b/Marlin/src/lcd/dogm/marlinui_DOGM.cpp @@ -342,12 +342,10 @@ void MarlinUI::draw_kill_screen() { void MarlinUI::clear_lcd() { } // Automatically cleared by Picture Loop -void MarlinUI::sleep_on () { - u8g.sleepOn(); -} -void MarlinUI::sleep_off () { - u8g.sleepOff(); -} +#if HAS_DISPLAY_SLEEP + void MarlinUI::sleep_on() { u8g.sleepOn(); } + void MarlinUI::sleep_off() { u8g.sleepOff(); } +#endif #if HAS_LCD_BRIGHTNESS diff --git a/Marlin/src/lcd/language/language_en.h b/Marlin/src/lcd/language/language_en.h index 83bb6d8e51db3..01470f8007371 100644 --- a/Marlin/src/lcd/language/language_en.h +++ b/Marlin/src/lcd/language/language_en.h @@ -422,7 +422,7 @@ namespace Language_en { LSTR MSG_CONTRAST = _UxGT("LCD Contrast"); LSTR MSG_BRIGHTNESS = _UxGT("LCD Brightness"); LSTR MSG_LCD_TIMEOUT_SEC = _UxGT("LCD Timeout (s)"); - LSTR MSG_SCREEN_TIMEOUT = _UxGT("ScreenTimeout(m)"); + LSTR MSG_SCREEN_TIMEOUT = _UxGT("LCD Timeout (m)"); LSTR MSG_BRIGHTNESS_OFF = _UxGT("Backlight Off"); LSTR MSG_STORE_EEPROM = _UxGT("Store Settings"); LSTR MSG_LOAD_EEPROM = _UxGT("Load Settings"); diff --git a/Marlin/src/lcd/marlinui.cpp b/Marlin/src/lcd/marlinui.cpp index 36460f918fce1..b6a5793b1be23 100644 --- a/Marlin/src/lcd/marlinui.cpp +++ b/Marlin/src/lcd/marlinui.cpp @@ -192,15 +192,15 @@ constexpr uint8_t epps = ENCODER_PULSES_PER_STEP; WRITE(LCD_BACKLIGHT_PIN, HIGH); } -#endif +#elif HAS_DISPLAY_SLEEP -#if HAS_SCREEN_TIMEOUT - uint16_t MarlinUI::screen_timeout; // Initialized by settings.load( ) + uint8_t MarlinUI::sleep_timeout_minutes; // Initialized by settings.load() millis_t MarlinUI::screen_timeout_millis = 0; void MarlinUI::refresh_screen_timeout() { - screen_timeout_millis = screen_timeout ? millis() + screen_timeout * 60000UL : 0; + screen_timeout_millis = sleep_timeout_minutes ? millis() + sleep_timeout_minutes * 60UL * 1000UL : 0; sleep_off(); } + #endif void MarlinUI::init() { @@ -1070,9 +1070,7 @@ void MarlinUI::init() { #if LCD_BACKLIGHT_TIMEOUT refresh_backlight_timeout(); - #endif - - #if HAS_SCREEN_TIMEOUT + #elif HAS_DISPLAY_SLEEP refresh_screen_timeout(); #endif @@ -1185,12 +1183,9 @@ void MarlinUI::init() { WRITE(LCD_BACKLIGHT_PIN, LOW); // Backlight off backlight_off_ms = 0; } - #endif - - #if HAS_SCREEN_TIMEOUT - if (screen_timeout_millis && ELAPSED(ms, screen_timeout_millis)) { + #elif HAS_DISPLAY_SLEEP + if (screen_timeout_millis && ELAPSED(ms, screen_timeout_millis)) sleep_on(); - } #endif // Change state of drawing flag between screen updates diff --git a/Marlin/src/lcd/marlinui.h b/Marlin/src/lcd/marlinui.h index bf6b62dc203fe..4cff3c30f271b 100644 --- a/Marlin/src/lcd/marlinui.h +++ b/Marlin/src/lcd/marlinui.h @@ -245,9 +245,6 @@ class MarlinUI { // LCD implementations static void clear_lcd(); - static void sleep_on(); - static void sleep_off(); - #if BOTH(HAS_MARLINUI_MENU, TOUCH_SCREEN_CALIBRATION) static void check_touch_calibration() { if (touch_calibration.need_calibration()) currentScreen = touch_calibration_screen; @@ -282,14 +279,14 @@ class MarlinUI { static uint16_t lcd_backlight_timeout; static millis_t backlight_off_ms; static void refresh_backlight_timeout(); - #endif - - #if HAS_SCREEN_TIMEOUT - #define SCREEN_TIMEOUT_MIN 0 // units in minutes - #define SCREEN_TIMEOUT_MAX 99 // units in minutes - static uint16_t screen_timeout; + #elif HAS_DISPLAY_SLEEP + #define SLEEP_TIMEOUT_MIN 0 + #define SLEEP_TIMEOUT_MAX 99 + static uint8_t sleep_timeout_minutes; static millis_t screen_timeout_millis; static void refresh_screen_timeout(); + static void sleep_on(); + static void sleep_off(); #endif #if HAS_DWIN_E3V2_BASIC diff --git a/Marlin/src/lcd/menu/menu_configuration.cpp b/Marlin/src/lcd/menu/menu_configuration.cpp index 5c9ba18cca738..b8267caef610c 100644 --- a/Marlin/src/lcd/menu/menu_configuration.cpp +++ b/Marlin/src/lcd/menu/menu_configuration.cpp @@ -547,10 +547,8 @@ void menu_configuration() { // #if LCD_BACKLIGHT_TIMEOUT && LCD_BKL_TIMEOUT_MIN < LCD_BKL_TIMEOUT_MAX EDIT_ITEM(uint16_4, MSG_LCD_TIMEOUT_SEC, &ui.lcd_backlight_timeout, LCD_BKL_TIMEOUT_MIN, LCD_BKL_TIMEOUT_MAX, ui.refresh_backlight_timeout); - #endif - - #if HAS_SCREEN_TIMEOUT - EDIT_ITEM(uint16_3, MSG_SCREEN_TIMEOUT, &ui.screen_timeout, SCREEN_TIMEOUT_MIN, SCREEN_TIMEOUT_MAX, ui.refresh_screen_timeout); + #elif HAS_DISPLAY_SLEEP + EDIT_ITEM(uint8, MSG_SCREEN_TIMEOUT, &ui.sleep_timeout_minutes, SLEEP_TIMEOUT_MIN, SLEEP_TIMEOUT_MAX, ui.refresh_screen_timeout); #endif #if ENABLED(FWRETRACT) diff --git a/Marlin/src/module/settings.cpp b/Marlin/src/module/settings.cpp index d139ef14dcc18..6526a3c1922d5 100644 --- a/Marlin/src/module/settings.cpp +++ b/Marlin/src/module/settings.cpp @@ -402,14 +402,9 @@ typedef struct SettingsDataStruct { // Display Sleep // #if LCD_BACKLIGHT_TIMEOUT - uint16_t lcd_backlight_timeout; // (G-code needed) - #endif - - // - // SCREEN_TIMEOUT - // - #if HAS_SCREEN_TIMEOUT - uint16_t screen_timeout; + uint16_t lcd_backlight_timeout; // M255 S + #elif HAS_DISPLAY_SLEEP + uint8_t sleep_timeout_minutes; // M255 S #endif // @@ -638,9 +633,7 @@ void MarlinSettings::postprocess() { #if LCD_BACKLIGHT_TIMEOUT ui.refresh_backlight_timeout(); - #endif - - #if HAS_SCREEN_TIMEOUT + #elif HAS_DISPLAY_SLEEP ui.refresh_screen_timeout(); #endif } @@ -1157,16 +1150,10 @@ void MarlinSettings::postprocess() { // #if LCD_BACKLIGHT_TIMEOUT EEPROM_WRITE(ui.lcd_backlight_timeout); + #elif HAS_DISPLAY_SLEEP + EEPROM_WRITE(ui.sleep_timeout_minutes); #endif - // - // Screen Timeout - // - #if HAS_SCREEN_TIMEOUT - EEPROM_WRITE(ui.screen_timeout); - #endif - - // // Controller Fan // @@ -2114,13 +2101,8 @@ void MarlinSettings::postprocess() { // #if LCD_BACKLIGHT_TIMEOUT EEPROM_READ(ui.lcd_backlight_timeout); - #endif - - // - // Screen Timeout - // - #if HAS_SCREEN_TIMEOUT - EEPROM_READ(ui.screen_timeout); + #elif HAS_DISPLAY_SLEEP + EEPROM_READ(ui.sleep_timeout_minutes); #endif // @@ -3198,13 +3180,8 @@ void MarlinSettings::reset() { // #if LCD_BACKLIGHT_TIMEOUT ui.lcd_backlight_timeout = LCD_BACKLIGHT_TIMEOUT; - #endif - - // - // Screen Timeout - // - #if HAS_SCREEN_TIMEOUT - ui.screen_timeout = SCREEN_TIMEOUT; + #elif HAS_DISPLAY_SLEEP + ui.sleep_timeout_minutes = DISPLAY_SLEEP_MINUTES; #endif // @@ -3535,6 +3512,11 @@ void MarlinSettings::reset() { // TERN_(HAS_LCD_CONTRAST, gcode.M250_report(forReplay)); + // + // Display Sleep + // + TERN_(HAS_GCODE_M255, gcode.M255_report(forReplay)); + // // LCD Brightness // diff --git a/ini/features.ini b/ini/features.ini index fac9cf9b57904..149c976be0108 100644 --- a/ini/features.ini +++ b/ini/features.ini @@ -202,6 +202,7 @@ HAS_RESUME_CONTINUE = src_filter=+ LCD_SET_PROGRESS_MANUALLY = src_filter=+ HAS_STATUS_MESSAGE = src_filter=+ HAS_LCD_CONTRAST = src_filter=+ +HAS_GCODE_M255 = src_filter=+ HAS_LCD_BRIGHTNESS = src_filter=+ HAS_BUZZER = src_filter=+ TOUCH_SCREEN_CALIBRATION = src_filter=+