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
This commit is contained in:
Theo Arends 2018-08-23 11:49:17 +02:00
parent 1e3a8975c5
commit bab6ae5644
10 changed files with 310 additions and 105 deletions

View File

@ -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)

View File

@ -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

View File

@ -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()

View File

@ -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"

View File

@ -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);

View File

@ -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 <Wire.h>
#include <LiquidCrystal_I2C.h>
@ -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:

View File

@ -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 <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
@ -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;

View File

@ -23,6 +23,8 @@
#define XDSP_03 3
#define MTX_MAX_SCREEN_BUFFER 80
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_LEDBackpack.h> // 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();

View File

@ -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;

View File

@ -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);