From bab6ae5644583d31dfd719eb7e96f523c0cfd5ee Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Thu, 23 Aug 2018 11:49:17 +0200 Subject: [PATCH] 6.1.1.8 - Fixes and Additions 6.1.1.8 * Fix MQTT reconnection detection when using TasmotaMqtt library (#3558) * Add build time setting of ButtonTopic and SwitchTopic (#3414) * Add display features and dynamic buffering --- sonoff/_changelog.ino | 7 +- sonoff/settings.h | 4 +- sonoff/settings.ino | 8 +- sonoff/sonoff_version.h | 2 +- sonoff/xdrv_13_display.ino | 217 ++++++++++++++++++++++++++++++++----- sonoff/xdsp_01_lcd.ino | 68 ++++++------ sonoff/xdsp_02_ssd1306.ino | 77 +++++++------ sonoff/xdsp_03_matrix.ino | 20 +++- sonoff/xdsp_04_ili9341.ino | 5 +- sonoff/xdsp_05_epaper.ino | 7 +- 10 files changed, 310 insertions(+), 105 deletions(-) diff --git a/sonoff/_changelog.ino b/sonoff/_changelog.ino index 5ddaa8058..9aa7f6837 100644 --- a/sonoff/_changelog.ino +++ b/sonoff/_changelog.ino @@ -1,4 +1,9 @@ -/* 6.1.1.7 +/* 6.1.1.8 + * Fix MQTT reconnection detection when using TasmotaMqtt library (#3558) + * Add build time setting of ButtonTopic and SwitchTopic (#3414) + * Add display features and dynamic buffering + * + * 6.1.1.7 * Add initial display support for Lcd, Oled, Matrix, Tft and e-paper - Need more docs * Fix SDM120 reporting wrong negative values to Domoticz (#3521) * Fix iFan02 power on state (#3412, #3530) diff --git a/sonoff/settings.h b/sonoff/settings.h index 07f288035..4beaf71b4 100644 --- a/sonoff/settings.h +++ b/sonoff/settings.h @@ -231,9 +231,7 @@ struct SYSCFG { uint8_t ledstate; // 2FB uint8_t param[PARAM8_SIZE]; // 2FC SetOption32 .. SetOption49 int16_t toffset[2]; // 30E - - byte free_312[1]; // 312 - + uint8_t display_font; // 312 char state_text[4][11]; // 313 uint8_t energy_power_delta; // 33F uint16_t domoticz_update_timer; // 340 diff --git a/sonoff/settings.ino b/sonoff/settings.ino index 2a13d71e4..7ba1b53f8 100644 --- a/sonoff/settings.ino +++ b/sonoff/settings.ino @@ -617,7 +617,10 @@ void SettingsDefaultSet_5_10_1() Settings.display_rows = 2; Settings.display_cols[0] = 16; Settings.display_cols[1] = 8; -//#if defined(USE_I2C) && defined(USE_DISPLAY) + Settings.display_dimmer = 1; + Settings.display_size = 1; + Settings.display_font = 1; + Settings.display_rotate = 0; Settings.display_address[0] = MTX_ADDRESS1; Settings.display_address[1] = MTX_ADDRESS2; Settings.display_address[2] = MTX_ADDRESS3; @@ -626,9 +629,6 @@ void SettingsDefaultSet_5_10_1() Settings.display_address[5] = MTX_ADDRESS6; Settings.display_address[6] = MTX_ADDRESS7; Settings.display_address[7] = MTX_ADDRESS8; -//#endif // USE_DISPLAY - Settings.display_dimmer = 1; - Settings.display_size = 1; } void SettingsResetStd() diff --git a/sonoff/sonoff_version.h b/sonoff/sonoff_version.h index e52cd95a9..ea98a83b6 100644 --- a/sonoff/sonoff_version.h +++ b/sonoff/sonoff_version.h @@ -20,7 +20,7 @@ #ifndef _SONOFF_VERSION_H_ #define _SONOFF_VERSION_H_ -#define VERSION 0x06010107 +#define VERSION 0x06010108 #define D_PROGRAMNAME "Sonoff-Tasmota" #define D_AUTHOR "Theo Arends" diff --git a/sonoff/xdrv_13_display.ino b/sonoff/xdrv_13_display.ino index 57360c0eb..5642a4bcc 100644 --- a/sonoff/xdrv_13_display.ino +++ b/sonoff/xdrv_13_display.ino @@ -21,10 +21,9 @@ #ifdef USE_DISPLAY #define DISPLAY_MAX_DRIVERS 16 // Max number of display drivers/models supported by xdsp_interface.ino -#define DISPLAY_MAX_COLS 40 // Max number of columns to display -#define DISPLAY_MAX_ROWS 16 // Max number of lines to display for LCD and Oled using local screen buffer +#define DISPLAY_MAX_COLS 40 // Max number of columns allowed with command DisplayCols +#define DISPLAY_MAX_ROWS 32 // Max number of lines allowed with command DisplayRows -#define DISPLAY_LOG_COLS DISPLAY_MAX_COLS +1 // Number of characters in display log buffer line +1 #define DISPLAY_LOG_ROWS 32 // Number of lines in display log buffer #define D_CMND_DISPLAY "Display" @@ -36,6 +35,7 @@ #define D_CMND_DISP_REFRESH "Refresh" #define D_CMND_DISP_ROWS "Rows" #define D_CMND_DISP_SIZE "Size" +#define D_CMND_DISP_FONT "Font" #define D_CMND_DISP_ROTATE "Rotate" #define D_CMND_DISP_TEXT "Text" @@ -45,15 +45,15 @@ enum XdspFunctions { FUNC_DISPLAY_INIT_DRIVER, FUNC_DISPLAY_INIT, FUNC_DISPLAY_E FUNC_DISPLAY_DRAW_HLINE, FUNC_DISPLAY_DRAW_VLINE, FUNC_DISPLAY_DRAW_LINE, FUNC_DISPLAY_DRAW_CIRCLE, FUNC_DISPLAY_FILL_CIRCLE, FUNC_DISPLAY_DRAW_RECTANGLE, FUNC_DISPLAY_FILL_RECTANGLE, - FUNC_DISPLAY_FONT_SIZE, FUNC_DISPLAY_ROTATION, FUNC_DISPLAY_DRAW_STRING, FUNC_DISPLAY_ONOFF }; + FUNC_DISPLAY_TEXT_SIZE, FUNC_DISPLAY_FONT_SIZE, FUNC_DISPLAY_ROTATION, FUNC_DISPLAY_DRAW_STRING, FUNC_DISPLAY_ONOFF }; enum DisplayInitModes { DISPLAY_INIT_MODE, DISPLAY_INIT_PARTIAL, DISPLAY_INIT_FULL }; enum DisplayCommands { CMND_DISP_MODEL, CMND_DISP_MODE, CMND_DISP_REFRESH, CMND_DISP_DIMMER, CMND_DISP_COLS, CMND_DISP_ROWS, - CMND_DISP_SIZE, CMND_DISP_ROTATE, CMND_DISP_TEXT, CMND_DISP_ADDRESS }; + CMND_DISP_SIZE, CMND_DISP_FONT, CMND_DISP_ROTATE, CMND_DISP_TEXT, CMND_DISP_ADDRESS }; const char kDisplayCommands[] PROGMEM = D_CMND_DISP_MODEL "|" D_CMND_DISP_MODE "|" D_CMND_DISP_REFRESH "|" D_CMND_DISP_DIMMER "|" D_CMND_DISP_COLS "|" D_CMND_DISP_ROWS "|" - D_CMND_DISP_SIZE "|" D_CMND_DISP_ROTATE "|" D_CMND_DISP_TEXT "|" D_CMND_DISP_ADDRESS ; + D_CMND_DISP_SIZE "|" D_CMND_DISP_FONT "|" D_CMND_DISP_ROTATE "|" D_CMND_DISP_TEXT "|" D_CMND_DISP_ADDRESS ; const char S_JSON_DISPLAY_COMMAND_VALUE[] PROGMEM = "{\"" D_CMND_DISPLAY "%s\":\"%s\"}"; const char S_JSON_DISPLAY_COMMAND_NVALUE[] PROGMEM = "{\"" D_CMND_DISPLAY "%s\":%d}"; @@ -65,6 +65,7 @@ uint8_t disp_refresh = 1; int16_t disp_xpos = 0; int16_t disp_ypos = 0; +uint8_t disp_autodraw = 1; uint8_t dsp_init; uint8_t dsp_font; @@ -80,12 +81,20 @@ int16_t dsp_len; char *dsp_str; #ifdef USE_DISPLAY_MODES1TO5 -char disp_log_buffer[DISPLAY_LOG_ROWS][DISPLAY_LOG_COLS]; + char disp_temp[2]; // C or F +uint8_t disp_subscribed = 0; + +char **disp_log_buffer; +uint8_t disp_log_buffer_cols = 0; uint8_t disp_log_buffer_idx = 0; uint8_t disp_log_buffer_ptr = 0; bool disp_log_buffer_active = false; -uint8_t disp_subscribed = 0; + +char **disp_screen_buffer; +uint8_t disp_screen_buffer_cols = 0; +uint8_t disp_screen_buffer_rows = 0; + #endif // USE_DISPLAY_MODES1TO5 /*********************************************************************************************/ @@ -172,9 +181,15 @@ void DisplayDrawFrame() XdspCall(FUNC_DISPLAY_DRAW_FRAME); } -void DisplaySetFontorSize(uint8_t font) +void DisplaySetSize(uint8_t size) { - Settings.display_size = font &3; + Settings.display_size = size &3; + XdspCall(FUNC_DISPLAY_TEXT_SIZE); +} + +void DisplaySetFont(uint8_t font) +{ + Settings.display_font = font &3; XdspCall(FUNC_DISPLAY_FONT_SIZE); } @@ -200,6 +215,8 @@ void DisplayOnOff(uint8_t on) XdspCall(FUNC_DISPLAY_ONOFF); } +/*-------------------------------------------------------------------------------------------*/ + // get asci number until delimiter and return asci number lenght and value uint8_t atoiv(char *cp, int16_t *res) { @@ -377,6 +394,7 @@ void DisplayText() cp += var; DisplayDrawLine(disp_xpos, disp_ypos, temp, temp1, color); disp_xpos += temp; + disp_ypos += temp1; break; case 'k': // circle @@ -419,10 +437,19 @@ void DisplayText() // force draw grafics buffer DisplayDrawFrame(); break; + case 'D': + // set auto draw mode + disp_autodraw = *cp&1; + cp += 1; + break; case 's': + // size sx + DisplaySetSize(*cp&3); + cp += 1; + break; case 'f': - // size or font sx - DisplaySetFontorSize(*cp&3); + // font sx + DisplaySetFont(*cp&3); cp += 1; break; case 'a': @@ -452,13 +479,111 @@ void DisplayText() } } // draw buffer - DisplayDrawFrame(); + if (disp_autodraw) { DisplayDrawFrame(); } } /*********************************************************************************************/ #ifdef USE_DISPLAY_MODES1TO5 +void DisplayClearScreenBuffer() +{ + if (disp_screen_buffer_cols) { + for (byte i = 0; i < disp_screen_buffer_rows; i++) { + memset(disp_screen_buffer[i], 0, disp_screen_buffer_cols); + } + } +} + +void DisplayFreeScreenBuffer() +{ + if (disp_screen_buffer != NULL) { + for (byte i = 0; i < disp_screen_buffer_rows; i++) { + if (disp_screen_buffer[i] != NULL) { free(disp_screen_buffer[i]); } + } + free(disp_screen_buffer); + disp_screen_buffer_cols = 0; + disp_screen_buffer_rows = 0; + } +} + +void DisplayAllocScreenBuffer() +{ + if (!disp_screen_buffer_cols) { + disp_screen_buffer_rows = Settings.display_rows; + disp_screen_buffer = (char**)malloc(sizeof(*disp_screen_buffer) * disp_screen_buffer_rows); + if (disp_screen_buffer != NULL) { + for (byte i = 0; i < disp_screen_buffer_rows; i++) { + disp_screen_buffer[i] = (char*)malloc(sizeof(*disp_screen_buffer[i]) * (Settings.display_cols[0] +1)); + if (disp_screen_buffer[i] == NULL) { + DisplayFreeScreenBuffer(); + break; + } + } + } + if (disp_screen_buffer != NULL) { + disp_screen_buffer_cols = Settings.display_cols[0] +1; + DisplayClearScreenBuffer(); + } + } +} + +void DisplayReAllocScreenBuffer() +{ + DisplayFreeScreenBuffer(); + DisplayAllocScreenBuffer(); +} + +/*-------------------------------------------------------------------------------------------*/ + +void DisplayClearLogBuffer() +{ + if (disp_log_buffer_cols) { + for (byte i = 0; i < DISPLAY_LOG_ROWS; i++) { + memset(disp_log_buffer[i], 0, disp_log_buffer_cols); + } + } +} + +void DisplayFreeLogBuffer() +{ + if (disp_log_buffer != NULL) { + for (byte i = 0; i < DISPLAY_LOG_ROWS; i++) { + if (disp_log_buffer[i] != NULL) { free(disp_log_buffer[i]); } + } + free(disp_log_buffer); + disp_log_buffer_cols = 0; + } +} + +void DisplayAllocLogBuffer() +{ + if (!disp_log_buffer_cols) { + disp_log_buffer = (char**)malloc(sizeof(*disp_log_buffer) * DISPLAY_LOG_ROWS); + if (disp_log_buffer != NULL) { + for (byte i = 0; i < DISPLAY_LOG_ROWS; i++) { + disp_log_buffer[i] = (char*)malloc(sizeof(*disp_log_buffer[i]) * (Settings.display_cols[0] +1)); + if (disp_log_buffer[i] == NULL) { + DisplayFreeLogBuffer(); + break; + } + } + } + if (disp_log_buffer != NULL) { + disp_log_buffer_cols = Settings.display_cols[0] +1; + DisplayClearLogBuffer(); + } + } +} + +void DisplayReAllocLogBuffer() +{ + DisplayFreeLogBuffer(); + DisplayAllocLogBuffer(); +} + +/*-------------------------------------------------------------------------------------------*/ + void DisplayLogBufferIdxInc() { disp_log_buffer_idx++; @@ -492,15 +617,21 @@ void DisplayPrintLog() void DisplayLogBufferInit() { - disp_log_buffer_idx = 0; - disp_log_buffer_ptr = 0; - disp_log_buffer_active = false; - disp_refresh = Settings.display_refresh; + if (Settings.display_mode) { + disp_log_buffer_idx = 0; + disp_log_buffer_ptr = 0; + disp_log_buffer_active = false; + disp_refresh = Settings.display_refresh; - snprintf_P(disp_log_buffer[disp_log_buffer_idx], sizeof(disp_log_buffer[disp_log_buffer_idx]), PSTR(D_VERSION " %s"), my_version); - DisplayLogBufferIdxInc(); - snprintf_P(disp_log_buffer[disp_log_buffer_idx], sizeof(disp_log_buffer[disp_log_buffer_idx]), PSTR("Display mode %d"), Settings.display_mode); - DisplayLogBufferIdxInc(); + snprintf_P(disp_temp, sizeof(disp_temp), PSTR("%c"), TempUnit()); + +// DisplayReAllocLogBuffer(); + + snprintf_P(disp_log_buffer[disp_log_buffer_idx], disp_log_buffer_cols, PSTR(D_VERSION " %s"), my_version); + DisplayLogBufferIdxInc(); + snprintf_P(disp_log_buffer[disp_log_buffer_idx], disp_log_buffer_cols, PSTR("Display mode %d"), Settings.display_mode); + DisplayLogBufferIdxInc(); + } } /*********************************************************************************************\ @@ -545,7 +676,6 @@ void DisplayJsonValue(const char *topic, const char* device, const char* mkey, c memset(spaces, 0x20, sizeof(spaces)); spaces[sizeof(spaces) -1] = '\0'; -// snprintf_P(source, sizeof(source), PSTR("%s/%s%s"), topic, mkey, (DISP_MATRIX == Settings.display_model) ? "" : spaces); // pow1/Voltage snprintf_P(source, sizeof(source), PSTR("%s/%s%s"), topic, mkey, spaces); // pow1/Voltage int quantity_code = GetCommandCode(quantity, sizeof(quantity), mkey, kSensorQuantity); @@ -588,7 +718,7 @@ void DisplayJsonValue(const char *topic, const char* device, const char* mkey, c else if (JSON_CO2 == quantity_code) { snprintf_P(svalue, sizeof(svalue), PSTR("%s" D_UNIT_PARTS_PER_MILLION), value); } - snprintf_P(disp_log_buffer[disp_log_buffer_idx], sizeof(disp_log_buffer[disp_log_buffer_idx]), PSTR("%s %s"), source, svalue); + snprintf_P(disp_log_buffer[disp_log_buffer_idx], disp_log_buffer_cols, PSTR("%s %s"), source, svalue); // snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_DEBUG "mkey [%s], source [%s], value [%s], quantity_code %d, log_buffer [%s]"), mkey, source, value, quantity_code, disp_log_buffer[disp_log_buffer_idx]); // AddLog(LOG_LEVEL_DEBUG); @@ -726,7 +856,7 @@ void DisplayInitDriver() #ifndef USE_DISPLAY_MODES1TO5 Settings.display_mode = 0; #else - snprintf_P(disp_temp, sizeof(disp_temp), PSTR("%c"), TempUnit()); + DisplayAllocLogBuffer(); DisplayLogBufferInit(); #endif // USE_DISPLAY_MODES1TO5 } @@ -787,8 +917,8 @@ boolean DisplayCommand() DisplayClear(); } if (!last_display_mode && Settings.display_mode) { // Switch to non mode 0 - DisplayInit(DISPLAY_INIT_MODE); DisplayLogBufferInit(); + DisplayInit(DISPLAY_INIT_MODE); } } } @@ -813,10 +943,32 @@ boolean DisplayCommand() } snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_DISPLAY_COMMAND_NVALUE, command, Settings.display_size); } + else if (CMND_DISP_FONT == command_code) { + if ((XdrvMailbox.payload > 0) && (XdrvMailbox.payload <= 4)) { + Settings.display_font = XdrvMailbox.payload; + } + snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_DISPLAY_COMMAND_NVALUE, command, Settings.display_font); + } else if (CMND_DISP_ROTATE == command_code) { if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload < 4)) { - Settings.display_rotate = XdrvMailbox.payload; - DisplayInit(DISPLAY_INIT_MODE); + if (Settings.display_rotate != XdrvMailbox.payload) { +/* + // Needs font info regarding height and width + if ((Settings.display_rotate &1) != (XdrvMailbox.payload &1)) { + uint8_t temp_rows = Settings.display_rows; + Settings.display_rows = Settings.display_cols[0]; + Settings.display_cols[0] = temp_rows; +#ifdef USE_DISPLAY_MODES1TO5 + DisplayReAllocScreenBuffer(); +#endif // USE_DISPLAY_MODES1TO5 + } +*/ + Settings.display_rotate = XdrvMailbox.payload; + DisplayInit(DISPLAY_INIT_MODE); +#ifdef USE_DISPLAY_MODES1TO5 + DisplayLogBufferInit(); +#endif // USE_DISPLAY_MODES1TO5 + } } snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_DISPLAY_COMMAND_NVALUE, command, Settings.display_rotate); } @@ -829,7 +981,7 @@ boolean DisplayCommand() if (!Settings.display_mode) { DisplayText(); } else { - strlcpy(disp_log_buffer[disp_log_buffer_idx], XdrvMailbox.data, sizeof(disp_log_buffer[disp_log_buffer_idx])); + strlcpy(disp_log_buffer[disp_log_buffer_idx], XdrvMailbox.data, disp_log_buffer_cols); DisplayLogBufferIdxInc(); } #endif // USE_DISPLAY_MODES1TO5 @@ -854,12 +1006,21 @@ boolean DisplayCommand() } else if ((CMND_DISP_COLS == command_code) && (XdrvMailbox.index > 0) && (XdrvMailbox.index <= 2)) { if ((XdrvMailbox.payload > 0) && (XdrvMailbox.payload <= DISPLAY_MAX_COLS)) { +#ifdef USE_DISPLAY_MODES1TO5 + if ((1 == XdrvMailbox.index) && (Settings.display_cols[0] != XdrvMailbox.payload)) { + DisplayLogBufferInit(); + DisplayReAllocScreenBuffer(); + } +#endif // USE_DISPLAY_MODES1TO5 Settings.display_cols[XdrvMailbox.index -1] = XdrvMailbox.payload; } snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_DISPLAY_COMMAND_INDEX_NVALUE, command, XdrvMailbox.index, Settings.display_cols[XdrvMailbox.index -1]); } else if (CMND_DISP_ROWS == command_code) { if ((XdrvMailbox.payload > 0) && (XdrvMailbox.payload <= DISPLAY_MAX_ROWS)) { +#ifdef USE_DISPLAY_MODES1TO5 + if (Settings.display_rows != XdrvMailbox.payload) { DisplayReAllocScreenBuffer(); } +#endif // USE_DISPLAY_MODES1TO5 Settings.display_rows = XdrvMailbox.payload; } snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_DISPLAY_COMMAND_NVALUE, command, Settings.display_rows); diff --git a/sonoff/xdsp_01_lcd.ino b/sonoff/xdsp_01_lcd.ino index b69490eb4..37f4c9bcc 100644 --- a/sonoff/xdsp_01_lcd.ino +++ b/sonoff/xdsp_01_lcd.ino @@ -26,9 +26,6 @@ #define LCD_ADDRESS1 0x27 // LCD I2C address option 1 #define LCD_ADDRESS2 0x3F // LCD I2C address option 2 -#define LCD_BUFFER_COLS 40 // Max number of columns in display shadow buffer -#define LCD_BUFFER_ROWS 8 // Max number of lines in display shadow buffer - #include #include @@ -40,8 +37,6 @@ void LcdInitMode() { lcd->init(); lcd->clear(); -// memset(lcd_screen_buffer[Settings.display_rows -1], 0x20, Settings.display_cols[0]); -// lcd_screen_buffer[Settings.display_rows -1][Settings.display_cols[0]] = 0; } void LcdInit(uint8_t mode) @@ -49,6 +44,9 @@ void LcdInit(uint8_t mode) switch(mode) { case DISPLAY_INIT_MODE: LcdInitMode(); +#ifdef USE_DISPLAY_MODES1TO5 + DisplayClearScreenBuffer(); +#endif // USE_DISPLAY_MODES1TO5 break; case DISPLAY_INIT_PARTIAL: case DISPLAY_INIT_FULL: @@ -72,6 +70,10 @@ void LcdInitDriver() if (XDSP_01 == Settings.display_model) { lcd = new LiquidCrystal_I2C(Settings.display_address[0], Settings.display_cols[0], Settings.display_rows); +#ifdef USE_DISPLAY_MODES1TO5 + DisplayAllocScreenBuffer(); +#endif // USE_DISPLAY_MODES1TO5 + LcdInitMode(); } } @@ -95,8 +97,6 @@ void LcdDisplayOnOff(uint8_t on) #ifdef USE_DISPLAY_MODES1TO5 -char lcd_screen_buffer[LCD_BUFFER_ROWS][LCD_BUFFER_COLS +1]; - void LcdCenter(byte row, char* txt) { int offset; @@ -114,32 +114,36 @@ void LcdCenter(byte row, char* txt) void LcdPrintLogLine() { - uint8_t last_row = Settings.display_rows -1; + if (!disp_screen_buffer_cols) { + DisplayAllocScreenBuffer(); + } else { + uint8_t last_row = Settings.display_rows -1; - for (byte i = 0; i < last_row; i++) { - strlcpy(lcd_screen_buffer[i], lcd_screen_buffer[i +1], sizeof(lcd_screen_buffer[i])); - lcd->setCursor(0, i); // Col 0, Row i - lcd->print(lcd_screen_buffer[i +1]); + for (byte i = 0; i < last_row; i++) { + strlcpy(disp_screen_buffer[i], disp_screen_buffer[i +1], disp_screen_buffer_cols); + lcd->setCursor(0, i); // Col 0, Row i + lcd->print(disp_screen_buffer[i +1]); + } + + char *pch = strchr(disp_log_buffer[disp_log_buffer_ptr],'~'); // = 0x7E (~) Replace degrees character (276 octal) + if (pch != NULL) { + disp_log_buffer[disp_log_buffer_ptr][pch - disp_log_buffer[disp_log_buffer_ptr]] = '\337'; // = 0xDF + } + strlcpy(disp_screen_buffer[last_row], disp_log_buffer[disp_log_buffer_ptr], disp_screen_buffer_cols); + + // Fill with spaces + byte len = disp_screen_buffer_cols - strlen(disp_screen_buffer[last_row]); + if (len) { + memset(disp_screen_buffer[last_row] + strlen(disp_screen_buffer[last_row]), 0x20, len); + disp_screen_buffer[last_row][disp_screen_buffer_cols -1] = 0; + } + + snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_DEBUG "[%s]"), disp_screen_buffer[last_row]); + AddLog(LOG_LEVEL_DEBUG); + + lcd->setCursor(0, last_row); + lcd->print(disp_screen_buffer[last_row]); } - - char *pch = strchr(disp_log_buffer[disp_log_buffer_ptr],'~'); // = 0x7E (~) Replace degrees character (276 octal) - if (pch != NULL) { - disp_log_buffer[disp_log_buffer_ptr][pch - disp_log_buffer[disp_log_buffer_ptr]] = '\337'; // = 0xDF - } - strlcpy(lcd_screen_buffer[last_row], disp_log_buffer[disp_log_buffer_ptr], sizeof(lcd_screen_buffer[last_row])); - - // Fill with spaces - byte len = sizeof(lcd_screen_buffer[last_row]) - strlen(lcd_screen_buffer[last_row]); - if (len) { - memset(lcd_screen_buffer[last_row] + strlen(lcd_screen_buffer[last_row]), 0x20, len); - lcd_screen_buffer[last_row][sizeof(lcd_screen_buffer[last_row])-1] = 0; - } - - snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_DEBUG "[%s]"), lcd_screen_buffer[last_row]); - AddLog(LOG_LEVEL_DEBUG); - - lcd->setCursor(0, last_row); - lcd->print(lcd_screen_buffer[last_row]); } void LcdPrintLog() @@ -230,6 +234,8 @@ boolean Xdsp01(byte function) // break; // case FUNC_DISPLAY_DRAW_FRAME: // break; +// case FUNC_DISPLAY_TEXT_SIZE: +// break; // case FUNC_DISPLAY_FONT_SIZE: // break; case FUNC_DISPLAY_DRAW_STRING: diff --git a/sonoff/xdsp_02_ssd1306.ino b/sonoff/xdsp_02_ssd1306.ino index 464f593a9..704daf92b 100644 --- a/sonoff/xdsp_02_ssd1306.ino +++ b/sonoff/xdsp_02_ssd1306.ino @@ -26,12 +26,12 @@ #define OLED_ADDRESS1 0x3C // Oled 128x32 I2C address #define OLED_ADDRESS2 0x3D // Oled 128x64 I2C address -#define OLED_BUFFER_COLS 40 // Max number of columns in display shadow buffer -#define OLED_BUFFER_ROWS 16 // Max number of lines in display shadow buffer - #define OLED_FONT_WIDTH 6 #define OLED_FONT_HEIGTH 8 +//#define OLED_BUFFER_COLS 21 or 11 // Max number of columns in display shadow buffer +//#define OLED_BUFFER_ROWS 8 or 16 // Max number of lines in display shadow buffer + #include #include #include @@ -62,6 +62,9 @@ void Ssd1306Init(uint8_t mode) switch(mode) { case DISPLAY_INIT_MODE: Ssd1306InitMode(); +#ifdef USE_DISPLAY_MODES1TO5 + DisplayClearScreenBuffer(); +#endif // USE_DISPLAY_MODES1TO5 break; case DISPLAY_INIT_PARTIAL: case DISPLAY_INIT_FULL: @@ -86,6 +89,10 @@ void Ssd1306InitDriver() oled = new Adafruit_SSD1306(); oled->begin(SSD1306_SWITCHCAPVCC, Settings.display_address[0]); +#ifdef USE_DISPLAY_MODES1TO5 + DisplayAllocScreenBuffer(); +#endif // USE_DISPLAY_MODES1TO5 + Ssd1306InitMode(); } } @@ -126,38 +133,41 @@ void Ssd1306OnOff() #ifdef USE_DISPLAY_MODES1TO5 -char oled_screen_buffer[OLED_BUFFER_ROWS][OLED_BUFFER_COLS +1]; - void Ssd1306PrintLogLine() { - uint8_t last_row = Settings.display_rows -1; + if (!disp_screen_buffer_cols) { + DisplayAllocScreenBuffer(); + } else { + uint8_t last_row = Settings.display_rows -1; - oled->clearDisplay(); - oled->setTextSize(Settings.display_size); - oled->setCursor(0,0); - for (byte i = 0; i < last_row; i++) { - strlcpy(oled_screen_buffer[i], oled_screen_buffer[i +1], sizeof(oled_screen_buffer[i])); - oled->println(oled_screen_buffer[i]); + oled->clearDisplay(); + oled->setTextSize(Settings.display_size); + oled->setCursor(0,0); + for (byte i = 0; i < last_row; i++) { + strlcpy(disp_screen_buffer[i], disp_screen_buffer[i +1], disp_screen_buffer_cols); + oled->println(disp_screen_buffer[i]); + } + + char *pch = strchr(disp_log_buffer[disp_log_buffer_ptr],'~'); // = 0x7E (~) Replace degrees character (276 octal) + if (pch != NULL) { + disp_log_buffer[disp_log_buffer_ptr][pch - disp_log_buffer[disp_log_buffer_ptr]] = '\370'; // = 0xF8 + } + strlcpy(disp_screen_buffer[last_row], disp_log_buffer[disp_log_buffer_ptr], disp_screen_buffer_cols); + + // Fill with spaces + byte len = disp_screen_buffer_cols - strlen(disp_screen_buffer[last_row]); + if (len) { + memset(disp_screen_buffer[last_row] + strlen(disp_screen_buffer[last_row]), 0x20, len); + disp_screen_buffer[last_row][disp_screen_buffer_cols -1] = 0; + } + + snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_DEBUG "[%s]"), disp_screen_buffer[last_row]); + AddLog(LOG_LEVEL_DEBUG); + + + oled->println(disp_screen_buffer[last_row]); + oled->display(); } - - char *pch = strchr(disp_log_buffer[disp_log_buffer_ptr],'~'); // = 0x7E (~) Replace degrees character (276 octal) - if (pch != NULL) { - disp_log_buffer[disp_log_buffer_ptr][pch - disp_log_buffer[disp_log_buffer_ptr]] = '\370'; // = 0xF8 - } - strlcpy(oled_screen_buffer[last_row], disp_log_buffer[disp_log_buffer_ptr], sizeof(oled_screen_buffer[last_row])); - - // Fill with spaces - byte len = sizeof(oled_screen_buffer[last_row]) - strlen(oled_screen_buffer[last_row]); - if (len) { - memset(oled_screen_buffer[last_row] + strlen(oled_screen_buffer[last_row]), 0x20, len); - oled_screen_buffer[last_row][sizeof(oled_screen_buffer[last_row])-1] = 0; - } - - snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_DEBUG "[%s]"), oled_screen_buffer[last_row]); - AddLog(LOG_LEVEL_DEBUG); - - oled->println(oled_screen_buffer[last_row]); - oled->display(); } void Ssd1306PrintLog() @@ -259,9 +269,12 @@ boolean Xdsp02(byte function) case FUNC_DISPLAY_DRAW_FRAME: oled->display(); break; - case FUNC_DISPLAY_FONT_SIZE: + case FUNC_DISPLAY_TEXT_SIZE: oled->setTextSize(Settings.display_size); break; + case FUNC_DISPLAY_FONT_SIZE: +// oled->setTextSize(Settings.display_font); + break; case FUNC_DISPLAY_DRAW_STRING: Ssd1306DrawStringAt(dsp_x, dsp_y, dsp_str, dsp_color, dsp_flag); break; diff --git a/sonoff/xdsp_03_matrix.ino b/sonoff/xdsp_03_matrix.ino index 3785953c7..868a2c9bd 100644 --- a/sonoff/xdsp_03_matrix.ino +++ b/sonoff/xdsp_03_matrix.ino @@ -23,6 +23,8 @@ #define XDSP_03 3 +#define MTX_MAX_SCREEN_BUFFER 80 + #include #include #include // 8x8 Matrix @@ -34,7 +36,7 @@ uint8_t mtx_counter = 0; int16_t mtx_x = 0; int16_t mtx_y = 0; -char mtx_buffer[80]; +char mtx_buffer[MTX_MAX_SCREEN_BUFFER]; uint8_t mtx_mode = 0; uint8_t mtx_loop = 0; @@ -250,7 +252,21 @@ void MatrixBufferScroll(uint8_t direction) if (direction) { MatrixScrollUp(disp_log_buffer[disp_log_buffer_ptr], 0); } else { - MatrixScrollLeft(disp_log_buffer[disp_log_buffer_ptr], 0); + // Remove extra spaces + uint8_t space = 0; + uint8_t max_cols = (disp_log_buffer_cols < MTX_MAX_SCREEN_BUFFER) ? disp_log_buffer_cols : MTX_MAX_SCREEN_BUFFER; + mtx_buffer[0] = '\0'; + for (byte i = 0; i < max_cols; i++) { + if (disp_log_buffer[disp_log_buffer_ptr][i] == ' ') { + space++; + } else { + space = 0; + } + if (space < 2) { + strncat(mtx_buffer, (const char*)disp_log_buffer[disp_log_buffer_ptr] +i, 1); + } + } + MatrixScrollLeft(mtx_buffer, 0); } if (!mtx_state) { DisplayLogBufferPtrInc(); diff --git a/sonoff/xdsp_04_ili9341.ino b/sonoff/xdsp_04_ili9341.ino index 971ae4589..34f3682da 100644 --- a/sonoff/xdsp_04_ili9341.ino +++ b/sonoff/xdsp_04_ili9341.ino @@ -248,9 +248,12 @@ boolean Xdsp04(byte function) // case FUNC_DISPLAY_DRAW_FRAME: // oled->display(); // break; - case FUNC_DISPLAY_FONT_SIZE: + case FUNC_DISPLAY_TEXT_SIZE: tft->setTextSize(Settings.display_size); break; + case FUNC_DISPLAY_FONT_SIZE: +// tft->setTextSize(Settings.display_font); + break; case FUNC_DISPLAY_DRAW_STRING: Ili9341DrawStringAt(dsp_x, dsp_y, dsp_str, dsp_color, dsp_flag); break; diff --git a/sonoff/xdsp_05_epaper.ino b/sonoff/xdsp_05_epaper.ino index a28005f8a..59a08584b 100644 --- a/sonoff/xdsp_05_epaper.ino +++ b/sonoff/xdsp_05_epaper.ino @@ -126,7 +126,7 @@ void EpdClear() paint.Clear(UNCOLORED); } -void EpdSetFontorSize(uint8_t font) +void EpdSetFont(uint8_t font) { if (1 == font) { selected_font = &Font12; @@ -230,8 +230,11 @@ boolean Xdsp05(byte function) epd.SetFrameMemory(paint.GetImage(), 0, 0, paint.GetWidth(), paint.GetHeight()); epd.DisplayFrame(); break; + case FUNC_DISPLAY_TEXT_SIZE: +// EpdSetFontorSize(Settings.display_size); + break; case FUNC_DISPLAY_FONT_SIZE: - EpdSetFontorSize(Settings.display_size); + EpdSetFont(Settings.display_font); break; case FUNC_DISPLAY_DRAW_STRING: EpdDrawStringAt(dsp_x, dsp_y, dsp_str, dsp_color, dsp_flag);