From bc57e68b7e4a0e067226322133eee24c33c68667 Mon Sep 17 00:00:00 2001 From: Ajith Vasudevan Date: Sun, 14 Feb 2021 16:52:08 +0530 Subject: [PATCH] Merged latest changes to TM1637 code --- tasmota/my_user_config.h | 7 +- tasmota/tasmota_configurations.h | 22 ++- tasmota/xdrv_13_display.ino | 171 +++++++++++++------- tasmota/xdsp_15_tm1637.ino | 266 ++++++++++++++++++------------- 4 files changed, 289 insertions(+), 177 deletions(-) diff --git a/tasmota/my_user_config.h b/tasmota/my_user_config.h index e3da15393..f80c527b8 100644 --- a/tasmota/my_user_config.h +++ b/tasmota/my_user_config.h @@ -683,6 +683,9 @@ #define USE_PZEM_AC // Add support for PZEM014,016 Energy monitor (+1k1 code) #define USE_PZEM_DC // Add support for PZEM003,017 Energy monitor (+1k1 code) #define USE_MCP39F501 // Add support for MCP39F501 Energy monitor as used in Shelly 2 (+3k1 code) +//#define USE_SDM72 // Add support for Eastron SDM72-Modbus energy monitor (+0k3 code) + #define SDM72_SPEED 9600 // SDM72-Modbus RS485 serial speed (default: 9600 baud) + // #define SDM72_IMPEXP // Show additonal import/export active energy and power in MQTT and Web (+0k5 code) //#define USE_SDM120 // Add support for Eastron SDM120-Modbus energy monitor (+1k1 code) #define SDM120_SPEED 2400 // SDM120-Modbus RS485 serial speed (default: 2400 baud) //#define USE_SDM630 // Add support for Eastron SDM630-Modbus energy monitor (+0k6 code) @@ -865,8 +868,8 @@ #define USE_ADC // Add support for ADC on GPIO32 to GPIO39 //#define USE_SPI // Add support for hardware SPI -#define USE_MI_ESP32 // Add support for ESP32 as a BLE-bridge (+9k2 mem, +292k flash) -//#define USE_BLE_ESP32 // Add support for ESP32 as a BLE-bridge (+9k2? mem, +292k? flash) +//#define USE_MI_ESP32 // Add support for ESP32 as a BLE-bridge (+9k2 mem, +292k flash) +//#define USE_BLE_ESP32 // Add support for ESP32 as a BLE-bridge (+9k2? mem, +292k? flash) //#define USE_IBEACON // Add support for bluetooth LE passive scan of ibeacon devices (uses HM17 module) //#define USE_IBEACON_ESP32 //#define USE_WEBCAM // Add support for webcam diff --git a/tasmota/tasmota_configurations.h b/tasmota/tasmota_configurations.h index 23c42350d..25e3cb2a5 100644 --- a/tasmota/tasmota_configurations.h +++ b/tasmota/tasmota_configurations.h @@ -171,8 +171,8 @@ //#define USE_GPS // Add support for GPS and NTP Server for becoming Stratus 1 Time Source (+ 3.1kb flash, +132 bytes RAM) #define USE_HM10 // (ESP8266 only) Add support for HM-10 as a BLE-bridge for the LYWSD03 (+5k1 code) #ifdef ESP32 - #define USE_BLE_ESP32 // (ESP32 only) Add support for native BLE on ESP32 - use new driver - #define USE_MI_ESP32 // (ESP32 only) Add support for ESP32 as a BLE-bridge (+9k2 mem, +292k flash) +// #define USE_BLE_ESP32 // (ESP32 only) Add support for native BLE on ESP32 - use new driver +// #define USE_MI_ESP32 // (ESP32 only) Add support for ESP32 as a BLE-bridge (+9k2 mem, +292k flash) #endif #define USE_HRXL // Add support for MaxBotix HRXL-MaxSonar ultrasonic range finders (+0k7) //#define USE_TASMOTA_CLIENT // Add support for Arduino Uno/Pro Mini via serial interface including flashing (+2k3 code, 44 mem) @@ -185,6 +185,7 @@ #define USE_PZEM_AC // Add support for PZEM014,016 Energy monitor (+1k1 code) #define USE_PZEM_DC // Add support for PZEM003,017 Energy monitor (+1k1 code) #define USE_MCP39F501 // Add support for MCP39F501 Energy monitor as used in Shelly 2 (+3k1 code) +#define USE_SDM72 // Add support for Eastron SDM72-Modbus energy monitor (+0k3 code) #define USE_SDM120 // Add support for Eastron SDM120-Modbus energy monitor (+1k1 code) #define USE_SDM630 // Add support for Eastron SDM630-Modbus energy monitor (+0k6 code) #define USE_DDS2382 // Add support for Hiking DDS2382 Modbus energy monitor (+0k6 code) @@ -236,7 +237,7 @@ #undef USE_EMULATION_WEMO // Disable Belkin WeMo emulation for Alexa (+6k code, +2k mem common) #undef USE_DEEPSLEEP // Disable support for deepsleep (+1k code) #undef USE_DEVICE_GROUPS // Disable support for device groups (+3k5 code) -#undef USE_BLE_ESP32 // (ESP32 only) Disable support for native BLE on ESP32 - use new driver +#undef USE_BLE_ESP32 // (ESP32 only) Disable support for native BLE on ESP32 - use new driver #undef USE_MI_ESP32 // (ESP32 only) Disable support for ESP32 as a BLE-bridge (+9k2 mem, +292k flash) #undef USE_PWM_DIMMER_REMOTE // Disbale support for remote switches to PWM Dimmer @@ -287,6 +288,7 @@ #undef USE_PZEM_AC // Disable PZEM014,016 Energy monitor #undef USE_PZEM_DC // Disable PZEM003,017 Energy monitor #undef USE_MCP39F501 // Disable MCP39F501 Energy monitor as used in Shelly 2 + #undef USE_SDM72 // Disable support for Eastron SDM72-Modbus energy meter #undef USE_SDM120 // Disable support for Eastron SDM120-Modbus energy meter #undef USE_SDM630 // Disable support for Eastron SDM630-Modbus energy monitor (+0k6 code) #undef USE_DDS2382 // Disable support for Hiking DDS2382 Modbus energy monitor (+0k6 code) @@ -296,7 +298,7 @@ #undef USE_TELEINFO // Disable support for French Energy Provider metering telemetry #undef USE_IEM3000 // Disable support for Schneider Electric iEM3000-Modbus series energy monitor (+0k8 code) #undef USE_WE517 // Disable support for Orno WE517-Modbus energy monitor (+1k code) -#undef USE_BLE_ESP32 // (ESP32 only) Disable support for native BLE on ESP32 - use new driver +#undef USE_BLE_ESP32 // (ESP32 only) Disable support for native BLE on ESP32 - use new driver #undef USE_MI_ESP32 // (ESP32 only) Disable support for ESP32 as a BLE-bridge (+9k2 mem, +292k flash) @@ -389,6 +391,7 @@ #undef USE_PZEM_AC // Disable PZEM014,016 Energy monitor #undef USE_PZEM_DC // Disable PZEM003,017 Energy monitor #undef USE_MCP39F501 // Disable MCP39F501 Energy monitor as used in Shelly 2 + #undef USE_SDM72 // Disable support for Eastron SDM72-Modbus energy meter #undef USE_SDM120 // Disable support for Eastron SDM120-Modbus energy meter #undef USE_SDM630 // Disable support for Eastron SDM630-Modbus energy monitor (+0k6 code) #undef USE_DDS2382 // Disable support for Hiking DDS2382 Modbus energy monitor (+0k6 code) @@ -422,7 +425,7 @@ #undef USE_IBEACON // Disable support for bluetooth LE passive scan of ibeacon devices (uses HM17 module) #undef USE_GPS // Disable support for GPS and NTP Server for becoming Stratus 1 Time Source (+ 3.1kb flash, +132 bytes RAM) #undef USE_HM10 // (ESP8266 only) Disable support for HM-10 as a BLE-bridge for the LYWSD03 (+5k1 code) -#undef USE_BLE_ESP32 // (ESP32 only) Disable support for native BLE on ESP32 - use new driver +#undef USE_BLE_ESP32 // (ESP32 only) Disable support for native BLE on ESP32 - use new driver #undef USE_MI_ESP32 // (ESP32 only) Disable support for ESP32 as a BLE-bridge (+9k2 mem, +292k flash) #undef USE_HRXL // Disable support for MaxBotix HRXL-MaxSonar ultrasonic range finders (+0k7) #undef USE_TASMOTA_CLIENT // Disable support for Arduino Uno/Pro Mini via serial interface including flashing (+2k3 code, 44 mem) @@ -551,7 +554,7 @@ #undef USE_IBEACON // Disable support for bluetooth LE passive scan of ibeacon devices (uses HM17 module) #undef USE_GPS // Disable support for GPS and NTP Server for becoming Stratus 1 Time Source (+ 3.1kb flash, +132 bytes RAM) #undef USE_HM10 // (ESP8266 only) Disable support for HM-10 as a BLE-bridge for the LYWSD03 (+5k1 code) -#undef USE_BLE_ESP32 // (ESP32 only) Disable support for native BLE on ESP32 - use new driver +#undef USE_BLE_ESP32 // (ESP32 only) Disable support for native BLE on ESP32 - use new driver #undef USE_MI_ESP32 // (ESP32 only) Disable support for ESP32 as a BLE-bridge (+9k2 mem, +292k flash) #undef USE_HRXL // Disable support for MaxBotix HRXL-MaxSonar ultrasonic range finders (+0k7) #undef USE_TASMOTA_CLIENT // Disable support for Arduino Uno/Pro Mini via serial interface including flashing (+2k3 code, 44 mem) @@ -564,6 +567,7 @@ #undef USE_PZEM_AC // Disable PZEM014,016 Energy monitor #undef USE_PZEM_DC // Disable PZEM003,017 Energy monitor #undef USE_MCP39F501 // Disable MCP39F501 Energy monitor as used in Shelly 2 +#undef USE_SDM72 // Disable support for Eastron SDM72-Modbus energy meter #undef USE_SDM120 // Disable support for Eastron SDM120-Modbus energy meter #undef USE_SDM630 // Disable support for Eastron SDM630-Modbus energy monitor (+0k6 code) #undef USE_DDS2382 // Disable support for Hiking DDS2382 Modbus energy monitor (+0k6 code) @@ -689,7 +693,7 @@ #undef USE_IBEACON // Disable support for bluetooth LE passive scan of ibeacon devices (uses HM17 module) #undef USE_GPS // Disable support for GPS and NTP Server for becoming Stratus 1 Time Source (+ 3.1kb flash, +132 bytes RAM) #undef USE_HM10 // (ESP8266 only) Disable support for HM-10 as a BLE-bridge for the LYWSD03 (+5k1 code) -#undef USE_BLE_ESP32 // (ESP32 only) Disable support for native BLE on ESP32 - use new driver +#undef USE_BLE_ESP32 // (ESP32 only) Disable support for native BLE on ESP32 - use new driver #undef USE_MI_ESP32 // (ESP32 only) Disable support for ESP32 as a BLE-bridge (+9k2 mem, +292k flash) #undef USE_HRXL // Disable support for MaxBotix HRXL-MaxSonar ultrasonic range finders (+0k7) #undef USE_TASMOTA_CLIENT // Disable support for Arduino Uno/Pro Mini via serial interface including flashing (+2k3 code, 44 mem) @@ -701,6 +705,7 @@ #undef USE_PZEM_AC // Disable PZEM014,016 Energy monitor #undef USE_PZEM_DC // Disable PZEM003,017 Energy monitor //#undef USE_MCP39F501 // Disable MCP39F501 Energy monitor as used in Shelly 2 +#undef USE_SDM72 // Disable support for Eastron SDM72-Modbus energy meter #undef USE_SDM120 // Disable support for Eastron SDM120-Modbus energy meter #undef USE_SDM630 // Disable support for Eastron SDM630-Modbus energy monitor (+0k6 code) #undef USE_DDS2382 // Disable support for Hiking DDS2382 Modbus energy monitor (+0k6 code) @@ -829,7 +834,7 @@ #undef USE_IBEACON // Disable support for bluetooth LE passive scan of ibeacon devices (uses HM17 module) #undef USE_GPS // Disable support for GPS and NTP Server for becoming Stratus 1 Time Source (+ 3.1kb flash, +132 bytes RAM) #undef USE_HM10 // (ESP8266 only) Disable support for HM-10 as a BLE-bridge for the LYWSD03 (+5k1 code) -#undef USE_BLE_ESP32 // (ESP32 only) Disable support for native BLE on ESP32 - use new driver +#undef USE_BLE_ESP32 // (ESP32 only) Disable support for native BLE on ESP32 - use new driver #undef USE_MI_ESP32 // (ESP32 only) Disable support for ESP32 as a BLE-bridge (+9k2 mem, +292k flash) #undef USE_HRXL // Disable support for MaxBotix HRXL-MaxSonar ultrasonic range finders (+0k7) #undef USE_TASMOTA_CLIENT // Disable support for Arduino Uno/Pro Mini via serial interface including flashing (+2k3 code, 44 mem) @@ -842,6 +847,7 @@ #undef USE_PZEM_AC // Disable PZEM014,016 Energy monitor #undef USE_PZEM_DC // Disable PZEM003,017 Energy monitor #undef USE_MCP39F501 // Disable MCP39F501 Energy monitor as used in Shelly 2 +#undef USE_SDM72 // Disable support for Eastron SDM72-Modbus energy meter #undef USE_SDM120 // Disable support for Eastron SDM120-Modbus energy meter #undef USE_SDM630 // Disable support for Eastron SDM630-Modbus energy monitor (+0k6 code) #undef USE_DDS2382 // Disable support for Hiking DDS2382 Modbus energy monitor (+0k6 code) diff --git a/tasmota/xdrv_13_display.ino b/tasmota/xdrv_13_display.ino index 32efb0c31..2b7c99b2a 100755 --- a/tasmota/xdrv_13_display.ino +++ b/tasmota/xdrv_13_display.ino @@ -76,6 +76,7 @@ const uint8_t DISPLAY_LOG_ROWS = 32; // Number of lines in display log #define D_CMND_DISP_SEVENSEG_TEXTNC "SevensegTextNC" // NC - "No Clear" #define D_CMND_DISP_SCROLLDELAY "ScrollDelay" #define D_CMND_DISP_CLOCK "Clock" +#define D_CMND_DISP_TEXTNC "TextNC" // NC - "No Clear" enum XdspFunctions { FUNC_DISPLAY_INIT_DRIVER, FUNC_DISPLAY_INIT, FUNC_DISPLAY_EVERY_50_MSECOND, FUNC_DISPLAY_EVERY_SECOND, FUNC_DISPLAY_MODEL, FUNC_DISPLAY_MODE, FUNC_DISPLAY_POWER, @@ -97,14 +98,14 @@ const char kDisplayCommands[] PROGMEM = D_PRFX_DISPLAY "|" // Prefix D_CMND_DISP_ROTATE "|" D_CMND_DISP_TEXT "|" D_CMND_DISP_ADDRESS "|" D_CMND_DISP_BLINKRATE "|" D_CMND_DISP_CLEAR "|" D_CMND_DISP_NUMBER "|" D_CMND_DISP_FLOAT "|" D_CMND_DISP_NUMBERNC "|" D_CMND_DISP_FLOATNC "|" D_CMND_DISP_BRIGHTNESS "|" D_CMND_DISP_RAW "|" D_CMND_DISP_LEVEL "|" D_CMND_DISP_SEVENSEG_TEXT "|" D_CMND_DISP_SEVENSEG_TEXTNC "|" - D_CMND_DISP_SCROLLDELAY "|" D_CMND_DISP_CLOCK; + D_CMND_DISP_SCROLLDELAY "|" D_CMND_DISP_CLOCK "|" D_CMND_DISP_TEXTNC; void (* const DisplayCommand[])(void) PROGMEM = { &CmndDisplay, &CmndDisplayModel, &CmndDisplayWidth, &CmndDisplayHeight, &CmndDisplayMode, &CmndDisplayRefresh, &CmndDisplayDimmer, &CmndDisplayColumns, &CmndDisplayRows, &CmndDisplaySize, &CmndDisplayFont, &CmndDisplayRotate, &CmndDisplayText, &CmndDisplayAddress, &CmndDisplayBlinkrate, &CmndDisplayClear, &CmndDisplayNumber, &CmndDisplayFloat, &CmndDisplayNumberNC, &CmndDisplayFloatNC, &CmndDisplayBrightness, &CmndDisplayRaw, - &CmndDisplayLevel, &CmndDisplaySevensegText, &CmndDisplaySevensegTextNC, &CmndDisplayScrollDelay, &CmndDisplayClock }; + &CmndDisplayLevel, &CmndDisplaySevensegText, &CmndDisplaySevensegTextNC, &CmndDisplayScrollDelay, &CmndDisplayClock, &CmndDisplayTextNC }; char *dsp_str; @@ -517,7 +518,7 @@ void DisplayText(void) cp += var; linebuf[fill] = 0; break; -#if (defined(USE_SCRIPT_FATFS) && defined(USE_SCRIPT)) || defined(USE_UFILESYS) +#ifdef USE_UFILESYS case 'P': { char *ep=strchr(cp,':'); if (ep) { @@ -528,7 +529,7 @@ void DisplayText(void) } } break; -#endif // USE_SCRIPT_FATFS +#endif // USE_UFILESYS case 'h': // hor line to var = atoiv(cp, &temp); @@ -792,17 +793,17 @@ void DisplayText(void) #ifdef USE_TOUCH_BUTTONS case 'b': - { int16_t num,gxp,gyp,gxs,gys,outline,fill,textcolor,textsize; uint8_t dflg=1; - if (*cp=='e' || *cp=='d') { + { int16_t num, gxp, gyp, gxs, gys, outline, fill, textcolor, textsize; uint8_t dflg = 1, sbt = 0; + if (*cp == 'e' || *cp == 'd') { // enable disable - uint8_t dis=0; - if (*cp=='d') dis=1; + uint8_t dis = 0; + if (*cp == 'd') dis = 1; cp++; - var=atoiv(cp,&num); - num=num%MAX_TOUCH_BUTTONS; - cp+=var; + var = atoiv(cp, &num); + num = num % MAX_TOUCH_BUTTONS; + cp += var; if (buttons[num]) { - buttons[num]->vpower.disable=dis; + buttons[num]->vpower.disable = dis; if (!dis) { if (buttons[num]->vpower.is_virtual) buttons[num]->xdrawButton(buttons[num]->vpower.on_off); else buttons[num]->xdrawButton(bitRead(TasmotaGlobal.power,num)); @@ -810,15 +811,33 @@ void DisplayText(void) } break; } - if (*cp=='-') { + if (*cp == '-') { cp++; - dflg=0; + dflg = 0; + } + if (*cp == 's') { + cp++; + sbt = 1; } var=atoiv(cp,&num); cp+=var; - cp++; uint8_t bflags=num>>8; num=num%MAX_TOUCH_BUTTONS; + if (*cp == 's') { + cp++; + var=atoiv(cp,&gxp); + if (buttons[num]) { + // set slider or button + if (buttons[num]->vpower.slider) { + buttons[num]->UpdateSlider(-gxp, -gxp); + } else { + buttons[num]->vpower.on_off = gxp; + buttons[num]->xdrawButton(buttons[num]->vpower.on_off); + } + } + break; + } + cp++; var=atoiv(cp,&gxp); cp+=var; cp++; @@ -845,32 +864,42 @@ void DisplayText(void) cp++; // text itself char bbuff[32]; - cp=get_string(bbuff,sizeof(bbuff),cp); - + if (!sbt) { + // text itself + cp = get_string(bbuff, sizeof(bbuff), cp); + } if (buttons[num]) { delete buttons[num]; } if (renderer) { buttons[num]= new VButton(); if (buttons[num]) { - buttons[num]->initButtonUL(renderer,gxp,gyp,gxs,gys,renderer->GetColorFromIndex(outline),\ - renderer->GetColorFromIndex(fill),renderer->GetColorFromIndex(textcolor),bbuff,textsize); - if (!bflags) { - // power button - if (dflg) buttons[num]->xdrawButton(bitRead(TasmotaGlobal.power,num)); - buttons[num]->vpower.is_virtual=0; - } else { - // virtual button - buttons[num]->vpower.is_virtual=1; - if (bflags==2) { - // push - buttons[num]->vpower.is_pushbutton=1; + if (!sbt) { + buttons[num]->vpower.slider = 0; + buttons[num]->initButtonUL(renderer, gxp, gyp, gxs, gys, renderer->GetColorFromIndex(outline),\ + renderer->GetColorFromIndex(fill), renderer->GetColorFromIndex(textcolor), bbuff, textsize); + if (!bflags) { + // power button + if (dflg) buttons[num]->xdrawButton(bitRead(TasmotaGlobal.power, num)); + buttons[num]->vpower.is_virtual = 0; } else { - // toggle - buttons[num]->vpower.is_pushbutton=0; + // virtual button + buttons[num]->vpower.is_virtual = 1; + if (bflags==2) { + // push + buttons[num]->vpower.is_pushbutton = 1; + } else { + // toggle + buttons[num]->vpower.is_pushbutton = 0; + } + if (dflg) buttons[num]->xdrawButton(buttons[num]->vpower.on_off); + buttons[num]->vpower.disable = !dflg; } - if (dflg) buttons[num]->xdrawButton(buttons[num]->vpower.on_off); - buttons[num]->vpower.disable=!dflg; + } else { + // slider + buttons[num]->vpower.slider = 1; + buttons[num]->SliderInit(renderer, gxp, gyp, gxs, gys, outline, renderer->GetColorFromIndex(fill),\ + renderer->GetColorFromIndex(textcolor), renderer->GetColorFromIndex(textsize)); } } } @@ -1534,6 +1563,14 @@ void CmndDisplaySevensegText(void) ResponseCmndChar(XdrvMailbox.data); } +void CmndDisplayTextNC(void) +{ + if (!renderer) { + XdspCall(FUNC_DISPLAY_SEVENSEG_TEXTNC); + } + ResponseCmndChar(XdrvMailbox.data); +} + void CmndDisplaySevensegTextNC(void) { if (!renderer) { @@ -1609,7 +1646,9 @@ void CmndDisplayText(void) #ifndef USE_DISPLAY_MODES1TO5 DisplayText(); #else - if (!Settings.display_mode) { + if(Settings.display_model == 15) { + XdspCall(FUNC_DISPLAY_SEVENSEG_TEXT); + } else if (!Settings.display_mode) { DisplayText(); } else { DisplayLogBufferAdd(XdrvMailbox.data); @@ -1701,7 +1740,7 @@ char get_jpeg_size(unsigned char* data, unsigned int data_size, unsigned short * #endif // JPEG_PICTS #endif // ESP32 -#if (defined(USE_SCRIPT_FATFS) && defined(USE_SCRIPT)) || defined(USE_UFILESYS) +#ifdef USE_UFILESYS extern FS *ufsp; #define XBUFF_LEN 128 void Draw_RGB_Bitmap(char *file,uint16_t xp, uint16_t yp, bool inverted ) { @@ -1801,7 +1840,7 @@ void Draw_RGB_Bitmap(char *file,uint16_t xp, uint16_t yp, bool inverted ) { #endif // ESP32 } } -#endif // USE_SCRIPT_FATFS +#endif // USE_UFILESYS #ifdef USE_AWATCH #define MINUTE_REDUCT 4 @@ -2314,9 +2353,11 @@ uint8_t vbutt=0; //AddLog(LOG_LEVEL_INFO, PSTR("touch %d - %d"), pLoc.x, pLoc.y); // now must compare with defined buttons - for (uint8_t count=0; countvpower.disable) { - if (buttons[count]->contains(pLoc.x, pLoc.y)) { + for (uint8_t count = 0; count < MAX_TOUCH_BUTTONS; count++) { + if (buttons[count]) { + if (!buttons[count]->vpower.slider) { + if (!buttons[count]->vpower.disable) { + if (buttons[count]->contains(pLoc.x, pLoc.y)) { // did hit buttons[count]->press(true); if (buttons[count]->justPressed()) { @@ -2342,12 +2383,20 @@ uint8_t vbutt=0; Touch_MQTT(count, cp, buttons[count]->vpower.on_off); } } + } + if (!buttons[count]->vpower.is_virtual) { + rbutt++; + } else { + vbutt++; + } } - if (!buttons[count]->vpower.is_virtual) { - rbutt++; - } else { - vbutt++; + } else { + // slider + if (buttons[count]->didhit(pLoc.x, pLoc.y)) { + uint16_t value = buttons[count]->UpdateSlider(pLoc.x, pLoc.y); + Touch_MQTT(count, "SLD", value); } + } } } } @@ -2363,27 +2412,29 @@ uint8_t vbutt=0; } } #endif - for (uint8_t count=0; countpress(false); - if (buttons[count]->justReleased()) { - if (buttons[count]->vpower.is_virtual) { - if (buttons[count]->vpower.is_pushbutton) { - // push button - buttons[count]->vpower.on_off = 0; - Touch_MQTT(count,"PBT", buttons[count]->vpower.on_off); - buttons[count]->xdrawButton(buttons[count]->vpower.on_off); + if (!buttons[count]->vpower.slider) { + buttons[count]->press(false); + if (buttons[count]->justReleased()) { + if (buttons[count]->vpower.is_virtual) { + if (buttons[count]->vpower.is_pushbutton) { + // push button + buttons[count]->vpower.on_off = 0; + Touch_MQTT(count,"PBT", buttons[count]->vpower.on_off); + buttons[count]->xdrawButton(buttons[count]->vpower.on_off); + } } } - } - if (!buttons[count]->vpower.is_virtual) { - // check if power button stage changed - uint8_t pwr = bitRead(TasmotaGlobal.power, rbutt); - uint8_t vpwr = buttons[count]->vpower.on_off; - if (pwr != vpwr) { - Touch_RDW_BUTT(count, pwr); + if (!buttons[count]->vpower.is_virtual) { + // check if power button stage changed + uint8_t pwr = bitRead(TasmotaGlobal.power, rbutt); + uint8_t vpwr = buttons[count]->vpower.on_off; + if (pwr != vpwr) { + Touch_RDW_BUTT(count, pwr); + } + rbutt++; } - rbutt++; } } } diff --git a/tasmota/xdsp_15_tm1637.ino b/tasmota/xdsp_15_tm1637.ino index 4c1c8687a..843814c70 100644 --- a/tasmota/xdsp_15_tm1637.ino +++ b/tasmota/xdsp_15_tm1637.ino @@ -22,27 +22,72 @@ This driver enables the display of numbers (both integers and floats) and basic text on the inexpensive TM1637-based seven-segment module. Raw segments can also be displayed. - In addition, it is also possible to clear the display, set brightness (7 levels) and display - a rudimentary bar graph. + In addition, it is also possible to clear the display, set brightness (8 levels), display + a rudimentary bar graph, and a Clock. - To use, compile Tasmota with USE_SPI, USE_DISPLAY and USE_DISPLAY_TM1637 - This adds the following - Pins: - * TM 1637 DIO - * TM 1637 CLK - - Connect the TM1637 display module's DIO and CLK pins to any free GPIOs of the ESP8266 module - and assign the above pins accordingly, from Tasmota's GUI. - Once the device restarts the following commands become available: - * TM1637Clear - * TM1637Number - * TM1637Float - * TM1637Brightness - * TM1637Raw - * TM1637Level - * TM1637Text + To use, compile Tasmota with USE_DISPLAY and USE_DISPLAY_TM1637, or build the tasmota-display env. + + The pins to use are "SSPI MOSI" and "SSPI SCLK". + + Connect the TM1637 display module's DIO and CLK pins to any free GPIOs of the ESP8266 module + and assign the pins as follows from Tasmota's GUI: + + DIO hardware pin --> "SSPI MOSI" + CLK hardware pin --> "SSPI SCLK" + + Once the device restarts the following "Display" commands become available: + + DisplayClear + Blanks the display, command: "DisplayClear" + + DisplayNumber num [,leading_zeros {0|1} [,length {1-4} [,position {0-3} [,dot {0-4} ]]]] + Clears and then displays integer number (-999 to 9999). command e.g., "DisplayNumber 1234" + Control 'leading zeros', 'length' and 'position' with "DisplayNumber 1234, , , , " + 'leading zeros' can be 1 or 0 (default), 'length' can be 1 to 4 (default), 'position' can be 0 (left-most) to 3 (right-most), + 'dot' can be 0,(no dot), 1 (left-most) to 4 (right-most). See function description below for more details. + + DisplayNumberNC num [,leading_zeros {0|1} [,length {1-4} [,position {0-3} [,dot {0-4} ]]]] + Display integer number as above, but without clearing first. e.g., "DisplayNumberNC 1234". Usage is same as above. + + DisplayFloat num [,precision {0-4} [,length {1-4} [,position {0-3} ]]] + Clears and then displays float (with decimal point) (0.001 to 9999.) command e.g., "DisplayFloat 12.34" + See function description below for more details. + + DisplayFloatNC num [,precision {0-4} [,length {1-4} [,position {0-3} ]]] + Displays float (with decimal point) as above, but without clearing first. command e.g., "DisplayFloatNC 12.34" + See function description below for more details. + + DisplayBrightness num {0-7} + Set brightness (1 to 7) command e.g., "DisplayBrightness 2" Note: Brightness takes effect only after a new display command is sent. + + DisplayRaw num1, num2, num3, num4 [,length {1-4} [,position {0-3}] ] + Takes 4 comma-separated integers (0-255) and displays raw segments + Each 7-segment display unit is represented by an 8-bit(8th bit for decimap point) number. + For example, the command "DisplayRaw 255, 255, 255, 255" would display "[8.8.8.8.]" + + DisplayLevel num {0-100} + Display a horizontal bar graph (0-100) command e.g., "DisplayLevel 50" will display [|||| ] + + DisplayText text [, length {1-4} [, position {0-3}]] + Clears and then displays basic text (scrolls if > 4 characters) command e.g., "DisplayText ajith vasudevan" + Control 'length' and 'position' with "DisplayText , , " + 'length' can be 1 to 4 (default), 'position' can be 0 (left-most) to 3 (right-most) + Note: A caret sign '^' in the input text would be replaced by a "degrees" symbol. This is handy for displaying temperature! + Other Characters whose ASCII > 127 or ASCII < 32 would simply be blank. + + DisplayTextNC text [, length {1-4} [, position {0-3}]] + Clear first, then display text. Usage is same as above. + + DisplayScrollDelay delay_in_milliseconds // default = 200 + Sets the speed of text scroll. Takes effect only after a new TEXT command is sent with 4 chars or more. + + DisplayClock 1|2|0 + Displays a clock. + Commands "DisplayClock 1" // 12 hr format + "DisplayClock 2" // 24 hr format + "DisplayClock 0" // turn off clock + - The usage of these commands are explained in code comments below. */ @@ -60,12 +105,7 @@ TM1637TinyDisplay *display; bool showClock = false; bool clock24 = false; -uint8_t length = 4; -uint8_t position = 0; -bool leadingzeros = false; -uint8_t length2 = 4; -uint8_t precision = 4; - +char tm[5]; char msg[60]; @@ -76,55 +116,13 @@ char msg[60]; #define LEVEL_MAX 100 -#define D_CMND_TM1637 "TM1637" - -const char S_TM1637_COMMAND_NVALUE[] PROGMEM = "{\"" D_CMND_TM1637 "%s\":%s}"; -const char S_TM1637_COMMAND_SVALUE[] PROGMEM = "{\"" D_CMND_TM1637 "%s\":\"%s\"}"; -const char S_TM1637_RAWCOMMAND_NVALUE[] PROGMEM = "{\"" D_CMND_TM1637 "%s\":\"%d,%d,%d,%d\"}"; -const char S_TM1637_MESSAGE_SVALUE[] PROGMEM = "{\"" "\"%s\":\"%s\"}"; -const char kTM1637_Commands[] PROGMEM = "Clear|Number|NumberC|Float|FloatC|Brightness|Raw|Level|Text|TextC|ScrollDelay|Clock"; - -enum TM1637_Commands { // commands useable in console/MQTT or rules - - CMND_TM1637_CLEAR, // Blanks the display, command: "TM1637Clear" - - CMND_TM1637_NUMBER, // Display integer number (-999 to 9999). command e.g., "TM1637Number 1234" - // Control 'leading zeros', 'length' and 'position' with "TM1637Number 1234, , , " - // 'leading zeros' can be 1 or 0 (default), 'length' can be 1 to 4 (default), 'position' can be 0 (left-most) to 3 (right-most) - - CMND_TM1637_NUMBERC, // Clear first, then display integer number (-999 to 9999). e.g., "TM1637NumberC 1234". Usage is same as above. - - CMND_TM1637_FLOAT, // Display float (with decimal point) (0.001 to 9999.) command e.g., "TM1637Float 12.34" - - CMND_TM1637_FLOATC, // Clear first, then display float (with decimal point) (0.001 to 9999.) command e.g., "TM1637FloatC 12.34" - - CMND_TM1637_BRIGHTNESS, // Set brightness (1 to 7) command e.g., "TM1637Brightness 2" Note: Brightness takes effect only after a new display command is sent. - - CMND_TM1637_RAW, // Takes 4 comma-separated integers (0-255) and displays raw segments - // Each 7-segment display unit is represented by an 8-bit(8th bit for decimap point) number. - // For example, the command "TM1637Raw 255, 255, 255, 255" would display "[8.8.8.8.]" - - CMND_TM1637_LEVEL, // Display a horizontal bar graph (0-100) command e.g., "TM1637Level 50" will display [|||| ] - - CMND_TM1637_TEXT, // Display basic text (scrolls if > 4 characters) command e.g., "TM1637Text ajith vasudevan" - // Control 'length' and 'position' with "TM1637Text abcd, , " - // 'length' can be 1 to 4 (default), 'position' can be 0 (left-most) to 3 (right-most) - // Note: A caret sign '^' in the input text would be replaced by a "degrees" symbol. This is handy for displaying temperature! - // Other Characters whose ASCII > 127 or ASCII < 32 would simply be blank. - - CMND_TM1637_TEXTC, // Clear first, then display text. Usage is same as above. - - CMND_TM1637_SCROLLDELAY, // Sets the speed of text scroll. Takes effect only after a new TEXT command is sent with 4 chars or more. - - CMND_TM1637_CLOCK // Displays a clock. To start clock, command "TM1637Clock 1". To turn offclock, "TM1637Clock 0" -}; /*********************************************************************************************\ * Init function \*********************************************************************************************/ bool TM1637Init(void) { - display = new TM1637TinyDisplay(Pin(GPIO_TM1637_CLK), Pin(GPIO_TM1637_DIO)); - display->setBrightness(BRIGHT_5); + display = new TM1637TinyDisplay(Pin(GPIO_SSPI_SCLK), Pin(GPIO_SSPI_MOSI) ); + display->setBrightness(BRIGHT_4); display->clear(); if (!Settings.display_model) { Settings.display_model = XDSP_15; @@ -135,17 +133,28 @@ bool TM1637Init(void) { /*********************************************************************************************\ -* Displays number without decimal, with/without leading zeros, specifying length -* and position, optionally skipping clearing display before displaying the number. -* commands: DisplayNumber num [,leading_zeros {0|1} [,length {1-4} [,position {0-3} ]]] -* DisplayNumberNC num [,leading_zeros {0|1} [,length {1-4} [,position {0-3} ]]] // "NC" --> "No Clear" +* Displays number with/without decimal, with/without leading zeros, specifying length, start-position +* and dot-position, optionally skipping clearing display before displaying the number. +* commands: DisplayNumber num [,leading_zeros {0|1} [,length {1-4} [,position {0-3} [,dot {0-4} ]]]] +* DisplayNumberNC num [,leading_zeros {0|1} [,length {1-4} [,position {0-3} [,dot {0-4} ]]]] // "NC" --> "No Clear" \*********************************************************************************************/ bool CmndTM1637Number(bool clear) { - char sNum[15]; char sLeadingZero[5]; char sLength[5]; char sPos[5]; + char sNum[CMD_MAX_LEN]; + char sLeadingZero[CMD_MAX_LEN]; + char sLength[CMD_MAX_LEN]; + char sPos[CMD_MAX_LEN]; + char sDot[CMD_MAX_LEN]; + uint8_t dot = 0; + uint8_t length = 4; + uint8_t position = 0; + bool leadingzeros = false; uint32_t num; switch (ArgC()) { + case 5 : + subStr(sDot, XdrvMailbox.data, ",", 5); + dot = atoi(sDot); case 4 : subStr(sPos, XdrvMailbox.data, ",", 4); position = atoi(sPos); @@ -163,14 +172,17 @@ bool CmndTM1637Number(bool clear) { if(position > 3) position = 3; if(position < 0) position = 0; if((length <= 0) || (length > 4)) length = 4; + if((dot < 0) || (dot > 4)) dot = 0; AddLog(LOG_LEVEL_DEBUG, PSTR("LOG: TM1637: num=%d"), num); AddLog(LOG_LEVEL_DEBUG, PSTR("LOG: TM1637: leadingzeros=%d"), leadingzeros); AddLog(LOG_LEVEL_DEBUG, PSTR("LOG: TM1637: length=%d"), length); AddLog(LOG_LEVEL_DEBUG, PSTR("LOG: TM1637: position=%d"), position); + AddLog(LOG_LEVEL_DEBUG, PSTR("LOG: TM1637: dot=%d"), dot); if(clear) display->clear(); - display->showNumber(num, leadingzeros, length, position); + if(!dot) display->showNumber(num, leadingzeros, length, position); + else display->showNumberDec(num, (1 << ( 8 - dot )), leadingzeros, length, position); return true; } @@ -184,14 +196,19 @@ bool CmndTM1637Number(bool clear) { \*********************************************************************************************/ bool CmndTM1637Float(bool clear) { - char sNum[15]; char sPrecision[5]; char sLength[5]; + char sNum[CMD_MAX_LEN]; + char sPrecision[CMD_MAX_LEN]; + char sLength[CMD_MAX_LEN]; + uint8_t length = 4; + uint8_t precision = 4; + float fnum = 0.0f; switch (ArgC()) { case 3 : subStr(sLength, XdrvMailbox.data, ",", 3); - length2 = atoi(sLength); + length = atoi(sLength); case 2 : subStr(sPrecision, XdrvMailbox.data, ",", 2); precision = atoi(sPrecision); @@ -201,16 +218,16 @@ bool CmndTM1637Float(bool clear) { } if((precision < 0) || (precision > 4)) precision = 4; - if((length2 <= 0) || (length2 > 4)) length2 = 4; + if((length <= 0) || (length > 4)) length = 4; char s[30]; ext_snprintf_P(s, sizeof(s), PSTR("LOG: TM1637: num=%*_f"), 4, &fnum); AddLog(LOG_LEVEL_DEBUG, PSTR("%s"), s); AddLog(LOG_LEVEL_DEBUG, PSTR("LOG: TM1637: precision=%d"), precision); - AddLog(LOG_LEVEL_DEBUG, PSTR("LOG: TM1637: length2=%d"), length2); + AddLog(LOG_LEVEL_DEBUG, PSTR("LOG: TM1637: length=%d"), length); if(clear) display->clear(); - display->showNumber(fnum, precision, length2, 0); + display->showNumber(fnum, precision, length, 0); return true; } @@ -253,7 +270,13 @@ bool CmndTM1637Level(void) { bool CmndTM1637Raw(void) { uint8_t DATA[4] = { 0, 0, 0, 0 }; - char as[5]; char bs[5]; char cs[5]; char ds[5]; char sLength[5]; char sPos[5]; + char as[CMD_MAX_LEN]; + char bs[CMD_MAX_LEN]; + char cs[CMD_MAX_LEN]; + char ds[CMD_MAX_LEN]; + char sLength[CMD_MAX_LEN]; + char sPos[CMD_MAX_LEN]; + uint8_t a = 0; uint8_t b = 0; uint8_t c = 0; @@ -261,7 +284,6 @@ bool CmndTM1637Raw(void) { uint32_t position = 0; uint32_t length = 4; - switch (ArgC()) { case 6 : @@ -304,17 +326,16 @@ bool CmndTM1637Raw(void) { * Display a given string. If more than 4 characters, will scroll message on display * Text can be placed at arbitrary location on the display using the length and * position parameters without affecting the rest of the display. -* Command: DisplaySevensegText text [, length {1-4} [, position {0-3}]] +* Command: DisplayText text [, length {1-4} [, position {0-3}]] \*********************************************************************************************/ bool CmndTM1637Text(bool clear) { - if(XdrvMailbox.data_len > CMD_MAX_LEN) { - sprintf(msg, PSTR("Text too long. Please limit text command length to %d"), CMD_MAX_LEN); - XdrvMailbox.data = msg; - return true; - } - char sString[CMD_MAX_LEN + 1]; char sLength[5]; char sPos[5]; + + char sString[CMD_MAX_LEN + 1]; + char sLength[CMD_MAX_LEN]; + char sPos[CMD_MAX_LEN]; uint32_t position = 0; uint32_t length = 4; + switch (ArgC()) { case 3 : @@ -336,7 +357,7 @@ bool CmndTM1637Text(bool clear) { AddLog(LOG_LEVEL_DEBUG, PSTR("LOG: TM1637: length=%d"), length); AddLog(LOG_LEVEL_DEBUG, PSTR("LOG: TM1637: pos=%d"), position); - for(uint32_t i; i BRIGHTNESS_MAX)) { - sprintf(msg, PSTR("Brightness is a number in the range [%d, %d]"), BRIGHTNESS_MIN, BRIGHTNESS_MAX); + sprintf(msg, PSTR("Brightness should be a number in the range [%d, %d]"), BRIGHTNESS_MIN, BRIGHTNESS_MAX); XdrvMailbox.data = msg; return false; } @@ -365,9 +388,14 @@ bool CmndTM1637Brightness(void) { return true; } + +/*********************************************************************************************\ +* Sets the scroll frame delay when the display needs to scroll. The setting takes effect +* when a text display command sends an argument with over four characters. +* Command: DisplayScrollDelay delay_in_milliseconds // default = 200 +\*********************************************************************************************/ bool CmndTM1637ScrollDelay(void) { uint16_t val = XdrvMailbox.payload; - if(val == 0) val = 200; display->setScrolldelay(val); return true; } @@ -375,16 +403,21 @@ bool CmndTM1637ScrollDelay(void) { /*********************************************************************************************\ * Displays a clock. -* Command: DisplayClock 1 // for 12-hour format -* DisplayClock 2 // for 24-hour format -* DisplayClock 0 // turn off clock +* Command: DisplayClock 1 // 12-hour format +* DisplayClock 2 // 24-hour format +* DisplayClock 0 // turn off clock and clear \*********************************************************************************************/ bool CmndTM1637Clock(void) { - AddLog(LOG_LEVEL_DEBUG, PSTR("LOG: TM1637: CmndTM1637Clock %d"), XdrvMailbox.payload); showClock = XdrvMailbox.payload; + + if(ArgC() == 0) XdrvMailbox.payload = 1; if(XdrvMailbox.payload > 1) clock24 = true; else if(XdrvMailbox.payload == 1) clock24 = false; + + AddLog(LOG_LEVEL_DEBUG, PSTR("LOG: TM1637: showClock=%d"), showClock); + AddLog(LOG_LEVEL_DEBUG, PSTR("LOG: TM1637: clock24=%d"), clock24); + if(!showClock) { display->clear(); } @@ -393,17 +426,31 @@ bool CmndTM1637Clock(void) { /*********************************************************************************************\ -* refreshes the time on if clock is displayed +* refreshes the time if clock is displayed \*********************************************************************************************/ void showTime() { uint8_t hr = RtcTime.hour; uint8_t mn = RtcTime.minute; - - if(!clock24) { + // uint8_t hr = 1; + // uint8_t mn = 0; + char z = ' '; + if(clock24) { + z = '0'; + } else { if(hr > 12) hr -= 12; + if(hr == 0) hr = 12; } - if((millis() % 1000) > 500) display->showNumber(1.0f * hr + ((float)RtcTime.minute)/100.0f, 2, 4, 0); - else display->showNumber(100 * hr + RtcTime.minute); + + if(hr < 10) { + if(mn < 10) snprintf(tm, sizeof(tm), PSTR("%c%d0%d"), z, hr, mn); + else snprintf(tm, sizeof(tm), PSTR("%c%d%d"), z, hr, mn); + } else { + if(mn < 10) snprintf(tm, sizeof(tm), PSTR("%d0%d"), hr, mn); + else snprintf(tm, sizeof(tm), PSTR("%d%d"), hr, mn); + } + tm[4] = 0; + if((millis() % 1000) > 500) display->showNumberDec(atoi(tm), 64, clock24, 4, 0); + else display->showString_P(tm, 4, 0); } /*********************************************************************************************\ @@ -411,6 +458,12 @@ void showTime() { \*********************************************************************************************/ bool TM1637Cmd(uint8_t fn) { bool result = false; + if(XdrvMailbox.data_len > CMD_MAX_LEN) { + sprintf(msg, PSTR("Command text too long. Please limit it to %d characters"), CMD_MAX_LEN); + XdrvMailbox.data = msg; + return result; + } + switch (fn) { case FUNC_DISPLAY_CLEAR: result = CmndTM1637Clear(); @@ -463,7 +516,6 @@ bool Xdsp15(uint8_t function) bool result = false; if (FUNC_DISPLAY_INIT_DRIVER == function) { - AddLog(LOG_LEVEL_DEBUG, PSTR("LOG: TM1637: FUNC_DISPLAY_INIT_DRIVER")); result = TM1637Init(); // init } else if (XDSP_15 == Settings.display_model) { @@ -476,11 +528,11 @@ bool Xdsp15(uint8_t function) CmndTM1637Clear(); AddLog(LOG_LEVEL_DEBUG, PSTR("LOG: TM1637: FUNC_DISPLAY_INIT")); break; - case FUNC_DISPLAY_DRAW_STRING: - sprintf(msg, PSTR("For TM1637, please use DisplaySevenSegText instead of DisplayText")); - XdrvMailbox.data = msg; - result = true; - break; + // case FUNC_DISPLAY_DRAW_STRING: + // sprintf(msg, PSTR("For TM1637, please use DisplaySevenSegText instead of DisplayText")); + // XdrvMailbox.data = msg; + // result = true; + // break; case FUNC_DISPLAY_SEVENSEG_TEXT: case FUNC_DISPLAY_CLEAR: case FUNC_DISPLAY_NUMBER: