diff --git a/BUILDS.md b/BUILDS.md index 9e4e847d0..f510ee046 100644 --- a/BUILDS.md +++ b/BUILDS.md @@ -172,6 +172,7 @@ | USE_TASMOTA_CLIENT | - | - | - | - | - | - | - | | USE_OPENTHERM | - | - | - | - | - | - | - | | USE_MIEL_HVAC | - | - | - | - | - | - | - | +| USE_PROJECTOR_CTRL | - | - | - | - | - | - | - | | USE_AS608 | - | - | - | - | - | - | - | | USE_TCP_BRIDGE | - | - | - | - | - | - | - | zbbridge | | | | | | | | | diff --git a/CHANGELOG.md b/CHANGELOG.md index 66156b59a..30b7395a0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,22 @@ All notable changes to this project will be documented in this file. ## [Unreleased] - Development ## [9.3.1.1] +### Added +- Allow MCP230xx pinmode from output to input (#11104) +- SML VBUS support (#11125) +- Command ``Sensor80 1 <0..7>`` to control MFRC522 RFID antenna gain from 18dB (0) to 48dB (7) (#11073) +- Support for NEC and OPTOMA LCD/DLP Projector serial power control by Jan Bubík (#11145) + +### Changed +- TuyaMcu dimmer timeout (#11121) + +### Fixed +- Refactor acceleration function for shutter stepper and servo (#11088) +- LM75AD detection on different addresses (#11096) +- Timer loop when console is scrolled up regression from v9.3.0 (#11108) +- Display exception when no file system is present (#11125) +- PN532 on ESP32 Serial flush both Tx and Rx buffers (#10910) +- Light scheme related color changes (#11041) ## [Released] diff --git a/RELEASENOTES.md b/RELEASENOTES.md index fc39668fb..f02d78da4 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -79,3 +79,19 @@ The attached binaries can also be downloaded from http://ota.tasmota.com/tasmota [Complete list](BUILDS.md) of available feature and sensors. ## Changelog v9.3.1.1 +### Added +- Command ``Sensor80 1 <0..7>`` to control MFRC522 RFID antenna gain from 18dB (0) to 48dB (7) [#11073](https://github.com/arendst/Tasmota/issues/11073) +- Support for SML VBUS [#11125](https://github.com/arendst/Tasmota/issues/11125) +- Support for NEC and OPTOMA LCD/DLP Projector serial power control by Jan Bubík [#11145](https://github.com/arendst/Tasmota/issues/11145) +- Allow MCP230xx pinmode from output to input [#11104](https://github.com/arendst/Tasmota/issues/11104) + +### Changed +- TuyaMcu dimmer timeout [#11121](https://github.com/arendst/Tasmota/issues/11121) + +### Fixed +- Refactor acceleration function for shutter stepper and servo [#11088](https://github.com/arendst/Tasmota/issues/11088) +- LM75AD detection on different addresses [#11096](https://github.com/arendst/Tasmota/issues/11096) +- Timer loop when console is scrolled up regression from v9.3.0 [#11108](https://github.com/arendst/Tasmota/issues/11108) +- Display exception when no file system is present [#11125](https://github.com/arendst/Tasmota/issues/11125) +- PN532 on ESP32 Serial flush both Tx and Rx buffers [#10910](https://github.com/arendst/Tasmota/issues/10910) +- Light scheme related color changes [#11041](https://github.com/arendst/Tasmota/issues/11041) diff --git a/lib/default/TasmotaSerial-3.2.0/src/TasmotaSerial.cpp b/lib/default/TasmotaSerial-3.2.0/src/TasmotaSerial.cpp index c3eff150a..d49a5ff2a 100644 --- a/lib/default/TasmotaSerial-3.2.0/src/TasmotaSerial.cpp +++ b/lib/default/TasmotaSerial-3.2.0/src/TasmotaSerial.cpp @@ -173,7 +173,8 @@ void TasmotaSerial::flush(void) { Serial.flush(); #endif // ESP8266 #ifdef ESP32 - TSerial->flush(); + TSerial->flush(); // Flushes Tx only https://github.com/espressif/arduino-esp32/pull/4263 + while (TSerial->available()) { TSerial->read(); } #endif // ESP32 } else { m_in_pos = m_out_pos = 0; diff --git a/lib/lib_display/Adafruit_SSD1351-gemu-1.0/SSD1351.cpp b/lib/lib_display/Adafruit_SSD1351-gemu-1.0/SSD1351.cpp index 891a573d5..274b030b2 100644 --- a/lib/lib_display/Adafruit_SSD1351-gemu-1.0/SSD1351.cpp +++ b/lib/lib_display/Adafruit_SSD1351-gemu-1.0/SSD1351.cpp @@ -22,11 +22,12 @@ const uint16_t ssd1351_colors[]={SSD1351_BLACK,SSD1351_WHITE,SSD1351_RED,SSD1351 SSD1351_LIGHTGREY,SSD1351_DARKGREY,SSD1351_ORANGE,SSD1351_GREENYELLOW,SSD1351_PINK}; // Constructor when using software SPI. All output pins are configurable. -SSD1351::SSD1351(int8_t cs,int8_t mosi,int8_t sclk) : Renderer(SSD1351_WIDTH, SSD1351_HEIGHT) { +SSD1351::SSD1351(int8_t cs,int8_t mosi,int8_t sclk, int8_t dc) : Renderer(SSD1351_WIDTH, SSD1351_HEIGHT) { _cs = cs; _mosi = mosi; _sclk = sclk; _hwspi = 0; + _dc = dc; } #ifndef ESP32 @@ -70,27 +71,30 @@ uint32_t ssd1351_mtdo_prev; void SSD1351::spi_lcd_mode_init(void) { uint32 regvalue; - ssd1351_clock_prev=SPI1CLK; - ssd1351_usr_prev=SPI1U; - ssd1351_usr1_prev=SPI1U1; - ssd1351_usr2_prev=SPI1U2; - ssd1351_spi1c_prev=SPI1C; - ssd1351_spi1p_prev=SPI1P; - //ssd1351_gpmux_prev=GPMUX; - ssd1351_mtdo_prev=READ_PERI_REG(PERIPHS_IO_MUX_MTDO_U); + if (_dc >= 0) { + spis = SPISettings(40000000, MSBFIRST, SPI_MODE0); + } else { + ssd1351_clock_prev=SPI1CLK; + ssd1351_usr_prev=SPI1U; + ssd1351_usr1_prev=SPI1U1; + ssd1351_usr2_prev=SPI1U2; + ssd1351_spi1c_prev=SPI1C; + ssd1351_spi1p_prev=SPI1P; + //ssd1351_gpmux_prev=GPMUX; + ssd1351_mtdo_prev=READ_PERI_REG(PERIPHS_IO_MUX_MTDO_U); - SPI1U = SPIUMOSI | SPIUDUPLEX | SPIUSSE; - SPI1U1=0; - SPI1C = 0; + SPI1U = SPIUMOSI | SPIUDUPLEX | SPIUSSE; + SPI1U1=0; + SPI1C = 0; - //bit9 of PERIPHS_IO_MUX should be cleared when HSPI clock doesn't equal CPU clock - //bit8 of PERIPHS_IO_MUX should be cleared when SPI clock doesn't equal CPU clock + //bit9 of PERIPHS_IO_MUX should be cleared when HSPI clock doesn't equal CPU clock + //bit8 of PERIPHS_IO_MUX should be cleared when SPI clock doesn't equal CPU clock - WRITE_PERI_REG(PERIPHS_IO_MUX, 0x105); //clear bit9 + WRITE_PERI_REG(PERIPHS_IO_MUX, 0x105); //clear bit9 //PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTDI_U, 2);//configure miso to spi mode - PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTCK_U, 2);//configure mosi to spi mode - PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTMS_U, 2);//configure sclk to spi mode - PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTDO_U, 2);//configure cs to spi mode + PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTCK_U, 2);//configure mosi to spi mode + PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTMS_U, 2);//configure sclk to spi mode + PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTDO_U, 2);//configure cs to spi mode // the current implementation leaves about 1 us between transfers ???? // due to lack of documentation i could not find the reason @@ -98,9 +102,9 @@ void SSD1351::spi_lcd_mode_init(void) { //SET_PERI_REG_MASK(SPI_USER(1), SPI_CS_SETUP|SPI_CS_HOLD|SPI_USR_COMMAND); - SET_PERI_REG_MASK(SPI_USER(1), SPI_USR_COMMAND); + SET_PERI_REG_MASK(SPI_USER(1), SPI_USR_COMMAND); - CLEAR_PERI_REG_MASK(SPI_USER(1), SPI_FLASH_MODE); + CLEAR_PERI_REG_MASK(SPI_USER(1), SPI_FLASH_MODE); // SPI clock=CPU clock/8 => 10 Mhz /* WRITE_PERI_REG(SPI_CLOCK(1), @@ -110,47 +114,58 @@ void SSD1351::spi_lcd_mode_init(void) { ((3&SPI_CLKCNT_L)<= 0) { + SPI.beginTransaction(spis); + } else { + while(READ_PERI_REG(SPI_CMD(1))&SPI_USR); + SPI1CLK=ssd1351_clock; + SPI1U=ssd1351_usr; + SPI1U1=ssd1351_usr1; + SPI1U2=ssd1351_usr2; + SPI1C=ssd1351_spi1c; + SPI1P=ssd1351_spi1p; + //GPMUX=ssd1351_gpmux; + WRITE_PERI_REG(PERIPHS_IO_MUX_MTDO_U,ssd1351_mtdo); + } + ssd131_start = 1; } void SSD1351::stop(void) { if (!ssd131_start) return; - //while(SPI1CMD & SPIBUSY) {} - while(READ_PERI_REG(SPI_CMD(1))&SPI_USR); - SPI1CLK=ssd1351_clock_prev; - SPI1U=ssd1351_usr_prev; - SPI1U1=ssd1351_usr1_prev; - SPI1U2=ssd1351_usr2_prev; - SPI1C=ssd1351_spi1c_prev; - SPI1P=ssd1351_spi1p_prev; - //GPMUX=ssd1351_gpmux_prev; - WRITE_PERI_REG(PERIPHS_IO_MUX_MTDO_U,ssd1351_mtdo_prev); - ssd131_start=0; + + if (_dc >= 0) { + SPI.endTransaction(); + } else { + //while(SPI1CMD & SPIBUSY) {} + while(READ_PERI_REG(SPI_CMD(1))&SPI_USR); + SPI1CLK=ssd1351_clock_prev; + SPI1U=ssd1351_usr_prev; + SPI1U1=ssd1351_usr1_prev; + SPI1U2=ssd1351_usr2_prev; + SPI1C=ssd1351_spi1c_prev; + SPI1P=ssd1351_spi1p_prev; + //GPMUX=ssd1351_gpmux_prev; + WRITE_PERI_REG(PERIPHS_IO_MUX_MTDO_U,ssd1351_mtdo_prev); + } + ssd131_start = 0; } // dc = 0 @@ -158,19 +173,23 @@ void SSD1351::writecommand(uint8_t c) { if (_hwspi) { uint32_t regvalue; uint8_t bytetemp; - bytetemp=(c>>1)&0x7f; - start(); - //#define SPI_USR_COMMAND_BITLEN 0x0000000F //#define SPI_USR_COMMAND_BITLEN_S 28 - - regvalue= ((8&SPI_USR_COMMAND_BITLEN)<= 0) { + digitalWrite(_dc, LOW); + SPI.transfer(c); + } else { + bytetemp = (c >> 1) & 0x7f; + regvalue= ((8&SPI_USR_COMMAND_BITLEN)<>1)|0x80; - start(); - regvalue= ((8&SPI_USR_COMMAND_BITLEN)<= 0) { + digitalWrite(_dc, HIGH); + SPI.transfer(d); + } else { + bytetemp = (d >> 1) | 0x80; + regvalue= ((8&SPI_USR_COMMAND_BITLEN)<>= 1) { + if (_dc >= 0) { + digitalWrite(_dc, dc); WRITE_PERI_REG( PIN_OUT_CLEAR, 1<<_sclk); - if(d&bit) WRITE_PERI_REG( PIN_OUT_SET, 1<<_mosi); + for(uint8_t bit = 0x80; bit; bit >>= 1) { + WRITE_PERI_REG( PIN_OUT_CLEAR, 1<<_sclk); + if(d&bit) WRITE_PERI_REG( PIN_OUT_SET, 1<<_mosi); + else WRITE_PERI_REG( PIN_OUT_CLEAR, 1<<_mosi); + WRITE_PERI_REG( PIN_OUT_SET, 1<<_sclk); + } + } else { + WRITE_PERI_REG( PIN_OUT_CLEAR, 1<<_sclk); + if(dc) WRITE_PERI_REG( PIN_OUT_SET, 1<<_mosi); else WRITE_PERI_REG( PIN_OUT_CLEAR, 1<<_mosi); WRITE_PERI_REG( PIN_OUT_SET, 1<<_sclk); + for(uint8_t bit = 0x80; bit; bit >>= 1) { + WRITE_PERI_REG( PIN_OUT_CLEAR, 1<<_sclk); + if(d&bit) WRITE_PERI_REG( PIN_OUT_SET, 1<<_mosi); + else WRITE_PERI_REG( PIN_OUT_CLEAR, 1<<_mosi); + WRITE_PERI_REG( PIN_OUT_SET, 1<<_sclk); + } } - WRITE_PERI_REG( PIN_OUT_SET, 1<<_cs); + WRITE_PERI_REG( PIN_OUT_SET, 1 << _cs); } - #else // ESP32 section uint8_t ssd131_start; void SSD1351::writedata(uint8_t d) { - fastSPIwrite(d,1); + fastSPIwrite(d, 1); } void SSD1351::writecommand(uint8_t c) { - fastSPIwrite(c,0); + fastSPIwrite(c, 0); } #include "soc/spi_reg.h" @@ -227,12 +262,10 @@ void SSD1351::writecommand(uint8_t c) { #include "esp32-hal.h" #include "soc/spi_struct.h" -SPISettings oled_spiSettings; - // diconnect from spi void SSD1351::start(void) { if (ssd131_start) return; - SPI.beginTransaction(oled_spiSettings); + SPI.beginTransaction(spis); ssd131_start = 1; } @@ -245,21 +278,25 @@ void SSD1351::stop(void) { // since ardunio transferBits ia completely disfunctional // we use our own hardware driver for 9 bit spi -void SSD1351::fastSPIwrite(uint8_t d,uint8_t dc) { +void SSD1351::fastSPIwrite(uint8_t d, uint8_t dc) { + digitalWrite( _cs, LOW); + if (_dc >= 0) { + digitalWrite(_dc, dc); + SPI.transfer(d); + } else { + uint32_t regvalue = d >> 1; + if (dc) regvalue |= 0x80; + else regvalue &= 0x7f; + if (d & 1) regvalue |= 0x8000; - uint32_t regvalue=d>>1; - if (dc) regvalue|=0x80; - else regvalue&=0x7f; - if (d&1) regvalue|=0x8000; - - REG_SET_BIT(SPI_USER_REG(3), SPI_USR_MOSI); - REG_WRITE(SPI_MOSI_DLEN_REG(3), 9 - 1); - uint32_t *dp=(uint32_t*)SPI_W0_REG(3); - *dp=regvalue; - REG_SET_BIT(SPI_CMD_REG(3), SPI_USR); - while (REG_GET_FIELD(SPI_CMD_REG(3), SPI_USR)); - + REG_SET_BIT(SPI_USER_REG(3), SPI_USR_MOSI); + REG_WRITE(SPI_MOSI_DLEN_REG(3), 9 - 1); + uint32_t *dp=(uint32_t*)SPI_W0_REG(3); + *dp = regvalue; + REG_SET_BIT(SPI_CMD_REG(3), SPI_USR); + while (REG_GET_FIELD(SPI_CMD_REG(3), SPI_USR)); + } digitalWrite( _cs, HIGH); } @@ -312,21 +349,26 @@ void SSD1351::begin(void) { pinMode(_mosi, OUTPUT); digitalWrite(_mosi, LOW); + if (_dc >= 0) { + pinMode(_dc, OUTPUT); + digitalWrite(_dc, LOW); + } + #ifndef ESP32 - if ((_sclk==14) && (_mosi==13) && (_cs==15)) { + if ((_sclk == 14) && (_mosi == 13) && (_cs == 15)) { // we use hardware spi - _hwspi=1; + _hwspi = 1; SPI.begin(); spi_lcd_mode_init(); } else { // we must use software spi - _hwspi=0; + _hwspi = 0; } #else - _hwspi=1; - SPI.begin(_sclk,-1,_mosi, -1); - oled_spiSettings = SPISettings(4500000, MSBFIRST, SPI_MODE3); + _hwspi = 1; + SPI.begin(_sclk, -1, _mosi, -1); + spis = SPISettings(4500000, MSBFIRST, SPI_MODE3); #endif const uint8_t *addr = (const uint8_t *)initList; diff --git a/lib/lib_display/Adafruit_SSD1351-gemu-1.0/SSD1351.h b/lib/lib_display/Adafruit_SSD1351-gemu-1.0/SSD1351.h index d9b05ad0f..ad81fc240 100644 --- a/lib/lib_display/Adafruit_SSD1351-gemu-1.0/SSD1351.h +++ b/lib/lib_display/Adafruit_SSD1351-gemu-1.0/SSD1351.h @@ -93,7 +93,7 @@ class SSD1351 : public Renderer { public: - SSD1351(int8_t cs,int8_t mosi,int8_t sclk); + SSD1351(int8_t cs,int8_t mosi,int8_t sclk, int8_t dc); void begin(void); void DisplayInit(int8_t p,int8_t size,int8_t rot,int8_t font); @@ -119,10 +119,11 @@ class SSD1351 : public Renderer { private: uint8_t tabcolor; + SPISettings spis; void fastSPIwrite(uint8_t d,uint8_t dc); void start(void); void stop(void); - int8_t _cs, _mosi, _sclk, _hwspi; + int8_t _cs, _mosi, _sclk, _hwspi, _dc; }; diff --git a/tasmota/language/af_AF.h b/tasmota/language/af_AF.h index 07e8a88fa..266486276 100644 --- a/tasmota/language/af_AF.h +++ b/tasmota/language/af_AF.h @@ -769,18 +769,22 @@ #define D_SENSOR_IEM3000_RX "iEM3000 RX" #define D_SENSOR_MIEL_HVAC_TX "MiEl HVAC Tx" #define D_SENSOR_MIEL_HVAC_RX "MiEl HVAC Rx" +#define D_SENSOR_PROJECTOR_CTRL_TX "DLP Tx" +#define D_SENSOR_PROJECTOR_CTRL_RX "DLP Rx" #define D_SENSOR_SHELLY_DIMMER_BOOT0 "SHD Boot 0" #define D_SENSOR_SHELLY_DIMMER_RST_INV "SHD Herstel" #define D_SENSOR_RC522_RST "RC522 Herstel" #define D_SENSOR_RC522_CS "RC522 CS" #define D_SENSOR_NRF24_CS "NRF24 CS" #define D_SENSOR_NRF24_DC "NRF24 DC" +#define D_SENSOR_XPT2046_CS "XPT2046 CS" #define D_SENSOR_ILI9341_CS "ILI9341 CS" #define D_SENSOR_ILI9341_DC "ILI9341 DC" #define D_SENSOR_ILI9488_CS "ILI9488 CS" #define D_SENSOR_EPAPER29_CS "EPaper29 CS" #define D_SENSOR_EPAPER42_CS "EPaper42 CS" #define D_SENSOR_SSD1351_CS "SSD1351 CS" +#define D_SENSOR_SSD1351_DC "SSD1351 DC" #define D_SENSOR_RA8876_CS "RA8876 CS" #define D_SENSOR_ST7789_CS "ST7789 CS" #define D_SENSOR_ST7789_DC "ST7789 DC" diff --git a/tasmota/language/bg_BG.h b/tasmota/language/bg_BG.h index 9f222a84c..6c30d6c9a 100644 --- a/tasmota/language/bg_BG.h +++ b/tasmota/language/bg_BG.h @@ -768,6 +768,8 @@ #define D_SENSOR_IEM3000_RX "iEM3000 RX" #define D_SENSOR_MIEL_HVAC_TX "MiEl HVAC Tx" #define D_SENSOR_MIEL_HVAC_RX "MiEl HVAC Rx" +#define D_SENSOR_PROJECTOR_CTRL_TX "DLP Tx" +#define D_SENSOR_PROJECTOR_CTRL_RX "DLP Rx" #define D_SENSOR_SHELLY_DIMMER_BOOT0 "SHD Boot 0" #define D_SENSOR_SHELLY_DIMMER_RST_INV "SHD Reset" #define D_SENSOR_RC522_RST "RC522 Rst" @@ -775,11 +777,13 @@ #define D_SENSOR_NRF24_CS "NRF24 CS" #define D_SENSOR_NRF24_DC "NRF24 DC" #define D_SENSOR_ILI9341_CS "ILI9341 CS" +#define D_SENSOR_XPT2046_CS "XPT2046 CS" #define D_SENSOR_ILI9341_DC "ILI9341 DC" #define D_SENSOR_ILI9488_CS "ILI9488 CS" #define D_SENSOR_EPAPER29_CS "EPaper29 CS" #define D_SENSOR_EPAPER42_CS "EPaper42 CS" #define D_SENSOR_SSD1351_CS "SSD1351 CS" +#define D_SENSOR_SSD1351_DC "SSD1351 DC" #define D_SENSOR_RA8876_CS "RA8876 CS" #define D_SENSOR_ST7789_CS "ST7789 CS" #define D_SENSOR_ST7789_DC "ST7789 DC" diff --git a/tasmota/language/cs_CZ.h b/tasmota/language/cs_CZ.h index 1e9382216..ef8d3ea40 100644 --- a/tasmota/language/cs_CZ.h +++ b/tasmota/language/cs_CZ.h @@ -769,18 +769,22 @@ #define D_SENSOR_IEM3000_RX "iEM3000 RX" #define D_SENSOR_MIEL_HVAC_TX "MiEl HVAC Tx" #define D_SENSOR_MIEL_HVAC_RX "MiEl HVAC Rx" +#define D_SENSOR_PROJECTOR_CTRL_TX "DLP Tx" +#define D_SENSOR_PROJECTOR_CTRL_RX "DLP Rx" #define D_SENSOR_SHELLY_DIMMER_BOOT0 "SHD Boot 0" #define D_SENSOR_SHELLY_DIMMER_RST_INV "SHD Reset" #define D_SENSOR_RC522_RST "RC522 Rst" #define D_SENSOR_RC522_CS "RC522 CS" #define D_SENSOR_NRF24_CS "NRF24 CS" #define D_SENSOR_NRF24_DC "NRF24 DC" +#define D_SENSOR_XPT2046_CS "XPT2046 CS" #define D_SENSOR_ILI9341_CS "ILI9341 CS" #define D_SENSOR_ILI9341_DC "ILI9341 DC" #define D_SENSOR_ILI9488_CS "ILI9488 CS" #define D_SENSOR_EPAPER29_CS "EPaper29 CS" #define D_SENSOR_EPAPER42_CS "EPaper42 CS" #define D_SENSOR_SSD1351_CS "SSD1351 CS" +#define D_SENSOR_SSD1351_DC "SSD1351 DC" #define D_SENSOR_RA8876_CS "RA8876 CS" #define D_SENSOR_ST7789_CS "ST7789 CS" #define D_SENSOR_ST7789_DC "ST7789 DC" diff --git a/tasmota/language/de_DE.h b/tasmota/language/de_DE.h index cde12947c..2c945ce75 100644 --- a/tasmota/language/de_DE.h +++ b/tasmota/language/de_DE.h @@ -769,18 +769,22 @@ #define D_SENSOR_IEM3000_RX "iEM3000 RX" #define D_SENSOR_MIEL_HVAC_TX "MiEl HVAC Tx" #define D_SENSOR_MIEL_HVAC_RX "MiEl HVAC Rx" +#define D_SENSOR_PROJECTOR_CTRL_TX "DLP Tx" +#define D_SENSOR_PROJECTOR_CTRL_RX "DLP Rx" #define D_SENSOR_SHELLY_DIMMER_BOOT0 "SHD Boot 0" #define D_SENSOR_SHELLY_DIMMER_RST_INV "SHD Reset" #define D_SENSOR_RC522_RST "RC522 Rst" #define D_SENSOR_RC522_CS "RC522 CS" #define D_SENSOR_NRF24_CS "NRF24 CS" #define D_SENSOR_NRF24_DC "NRF24 DC" +#define D_SENSOR_XPT2046_CS "XPT2046 CS" #define D_SENSOR_ILI9341_CS "ILI9341 CS" #define D_SENSOR_ILI9341_DC "ILI9341 DC" #define D_SENSOR_ILI9488_CS "ILI9488 CS" #define D_SENSOR_EPAPER29_CS "EPaper29 CS" #define D_SENSOR_EPAPER42_CS "EPaper42 CS" #define D_SENSOR_SSD1351_CS "SSD1351 CS" +#define D_SENSOR_SSD1351_DC "SSD1351 DC" #define D_SENSOR_RA8876_CS "RA8876 CS" #define D_SENSOR_ST7789_CS "ST7789 CS" #define D_SENSOR_ST7789_DC "ST7789 DC" diff --git a/tasmota/language/el_GR.h b/tasmota/language/el_GR.h index 7ba39fa04..45a104063 100644 --- a/tasmota/language/el_GR.h +++ b/tasmota/language/el_GR.h @@ -769,18 +769,22 @@ #define D_SENSOR_IEM3000_RX "iEM3000 RX" #define D_SENSOR_MIEL_HVAC_TX "MiEl HVAC Tx" #define D_SENSOR_MIEL_HVAC_RX "MiEl HVAC Rx" +#define D_SENSOR_PROJECTOR_CTRL_TX "DLP Tx" +#define D_SENSOR_PROJECTOR_CTRL_RX "DLP Rx" #define D_SENSOR_SHELLY_DIMMER_BOOT0 "SHD Boot 0" #define D_SENSOR_SHELLY_DIMMER_RST_INV "SHD Reset" #define D_SENSOR_RC522_RST "RC522 Rst" #define D_SENSOR_RC522_CS "RC522 CS" #define D_SENSOR_NRF24_CS "NRF24 CS" #define D_SENSOR_NRF24_DC "NRF24 DC" +#define D_SENSOR_XPT2046_CS "XPT2046 CS" #define D_SENSOR_ILI9341_CS "ILI9341 CS" #define D_SENSOR_ILI9341_DC "ILI9341 DC" #define D_SENSOR_ILI9488_CS "ILI9488 CS" #define D_SENSOR_EPAPER29_CS "EPaper29 CS" #define D_SENSOR_EPAPER42_CS "EPaper42 CS" #define D_SENSOR_SSD1351_CS "SSD1351 CS" +#define D_SENSOR_SSD1351_DC "SSD1351 DC" #define D_SENSOR_RA8876_CS "RA8876 CS" #define D_SENSOR_ST7789_CS "ST7789 CS" #define D_SENSOR_ST7789_DC "ST7789 DC" diff --git a/tasmota/language/en_GB.h b/tasmota/language/en_GB.h index dbf52c1aa..9b20a9335 100644 --- a/tasmota/language/en_GB.h +++ b/tasmota/language/en_GB.h @@ -769,6 +769,8 @@ #define D_SENSOR_IEM3000_RX "iEM3000 RX" #define D_SENSOR_MIEL_HVAC_TX "MiEl HVAC Tx" #define D_SENSOR_MIEL_HVAC_RX "MiEl HVAC Rx" +#define D_SENSOR_PROJECTOR_CTRL_TX "DLP Tx" +#define D_SENSOR_PROJECTOR_CTRL_RX "DLP Rx" #define D_SENSOR_SHELLY_DIMMER_BOOT0 "SHD Boot 0" #define D_SENSOR_SHELLY_DIMMER_RST_INV "SHD Reset" #define D_SENSOR_RC522_RST "RC522 Rst" @@ -782,6 +784,7 @@ #define D_SENSOR_EPAPER29_CS "EPaper29 CS" #define D_SENSOR_EPAPER42_CS "EPaper42 CS" #define D_SENSOR_SSD1351_CS "SSD1351 CS" +#define D_SENSOR_SSD1351_DC "SSD1351 DC" #define D_SENSOR_RA8876_CS "RA8876 CS" #define D_SENSOR_ST7789_CS "ST7789 CS" #define D_SENSOR_ST7789_DC "ST7789 DC" diff --git a/tasmota/language/es_ES.h b/tasmota/language/es_ES.h index f5e3e8d2a..93e1de64e 100644 --- a/tasmota/language/es_ES.h +++ b/tasmota/language/es_ES.h @@ -769,18 +769,22 @@ #define D_SENSOR_IEM3000_RX "iEM3000 RX" #define D_SENSOR_MIEL_HVAC_TX "MiEl HVAC Tx" #define D_SENSOR_MIEL_HVAC_RX "MiEl HVAC Rx" +#define D_SENSOR_PROJECTOR_CTRL_TX "DLP Tx" +#define D_SENSOR_PROJECTOR_CTRL_RX "DLP Rx" #define D_SENSOR_SHELLY_DIMMER_BOOT0 "SHD Boot 0" #define D_SENSOR_SHELLY_DIMMER_RST_INV "SHD Reset" #define D_SENSOR_RC522_RST "RC522 Rst" #define D_SENSOR_RC522_CS "RC522 CS" #define D_SENSOR_NRF24_CS "NRF24 CS" #define D_SENSOR_NRF24_DC "NRF24 DC" +#define D_SENSOR_XPT2046_CS "XPT2046 CS" #define D_SENSOR_ILI9341_CS "ILI9341 CS" #define D_SENSOR_ILI9341_DC "ILI9341 DC" #define D_SENSOR_ILI9488_CS "ILI9488 CS" #define D_SENSOR_EPAPER29_CS "EPaper29 CS" #define D_SENSOR_EPAPER42_CS "EPaper42 CS" #define D_SENSOR_SSD1351_CS "SSD1351 CS" +#define D_SENSOR_SSD1351_DC "SSD1351 DC" #define D_SENSOR_RA8876_CS "RA8876 CS" #define D_SENSOR_ST7789_CS "ST7789 CS" #define D_SENSOR_ST7789_DC "ST7789 DC" diff --git a/tasmota/language/fr_FR.h b/tasmota/language/fr_FR.h index 1a8eb94fe..e93b51968 100644 --- a/tasmota/language/fr_FR.h +++ b/tasmota/language/fr_FR.h @@ -765,6 +765,8 @@ #define D_SENSOR_IEM3000_RX "iEM3000 RX" #define D_SENSOR_MIEL_HVAC_TX "MiEl HVAC Tx" #define D_SENSOR_MIEL_HVAC_RX "MiEl HVAC Rx" +#define D_SENSOR_PROJECTOR_CTRL_TX "DLP Tx" +#define D_SENSOR_PROJECTOR_CTRL_RX "DLP Rx" #define D_SENSOR_SHELLY_DIMMER_BOOT0 "SHD Boot 0" #define D_SENSOR_SHELLY_DIMMER_RST_INV "SHD Reset" #define D_SENSOR_RC522_RST "RC522 Rst" @@ -775,8 +777,10 @@ #define D_SENSOR_ILI9341_DC "ILI9341 DC" #define D_SENSOR_ILI9488_CS "ILI9488 CS" #define D_SENSOR_EPAPER29_CS "EPaper29 CS" +#define D_SENSOR_XPT2046_CS "XPT2046 CS" #define D_SENSOR_EPAPER42_CS "EPaper42 CS" #define D_SENSOR_SSD1351_CS "SSD1351 CS" +#define D_SENSOR_SSD1351_DC "SSD1351 DC" #define D_SENSOR_RA8876_CS "RA8876 CS" #define D_SENSOR_ST7789_CS "ST7789 CS" #define D_SENSOR_ST7789_DC "ST7789 DC" diff --git a/tasmota/language/fy_NL.h b/tasmota/language/fy_NL.h index fcb977be1..533c6ee5e 100644 --- a/tasmota/language/fy_NL.h +++ b/tasmota/language/fy_NL.h @@ -769,18 +769,22 @@ #define D_SENSOR_IEM3000_RX "iEM3000 RX" #define D_SENSOR_MIEL_HVAC_TX "MiEl HVAC Tx" #define D_SENSOR_MIEL_HVAC_RX "MiEl HVAC Rx" +#define D_SENSOR_PROJECTOR_CTRL_TX "DLP Tx" +#define D_SENSOR_PROJECTOR_CTRL_RX "DLP Rx" #define D_SENSOR_SHELLY_DIMMER_BOOT0 "SHD Boot 0" #define D_SENSOR_SHELLY_DIMMER_RST_INV "SHD Reset" #define D_SENSOR_RC522_RST "RC522 Rst" #define D_SENSOR_RC522_CS "RC522 CS" #define D_SENSOR_NRF24_CS "NRF24 CS" #define D_SENSOR_NRF24_DC "NRF24 DC" +#define D_SENSOR_XPT2046_CS "XPT2046 CS" #define D_SENSOR_ILI9341_CS "ILI9341 CS" #define D_SENSOR_ILI9341_DC "ILI9341 DC" #define D_SENSOR_ILI9488_CS "ILI9488 CS" #define D_SENSOR_EPAPER29_CS "EPaper29 CS" #define D_SENSOR_EPAPER42_CS "EPaper42 CS" #define D_SENSOR_SSD1351_CS "SSD1351 CS" +#define D_SENSOR_SSD1351_DC "SSD1351 DC" #define D_SENSOR_RA8876_CS "RA8876 CS" #define D_SENSOR_ST7789_CS "ST7789 CS" #define D_SENSOR_ST7789_DC "ST7789 DC" diff --git a/tasmota/language/he_HE.h b/tasmota/language/he_HE.h index 79cc2c3b8..aa64de0e1 100644 --- a/tasmota/language/he_HE.h +++ b/tasmota/language/he_HE.h @@ -769,18 +769,22 @@ #define D_SENSOR_IEM3000_RX "iEM3000 RX" #define D_SENSOR_MIEL_HVAC_TX "MiEl HVAC Tx" #define D_SENSOR_MIEL_HVAC_RX "MiEl HVAC Rx" +#define D_SENSOR_PROJECTOR_CTRL_TX "DLP Tx" +#define D_SENSOR_PROJECTOR_CTRL_RX "DLP Rx" #define D_SENSOR_SHELLY_DIMMER_BOOT0 "SHD Boot 0" #define D_SENSOR_SHELLY_DIMMER_RST_INV "SHD Reset" #define D_SENSOR_RC522_RST "RC522 Rst" #define D_SENSOR_RC522_CS "RC522 CS" #define D_SENSOR_NRF24_CS "NRF24 CS" #define D_SENSOR_NRF24_DC "NRF24 DC" +#define D_SENSOR_XPT2046_CS "XPT2046 CS" #define D_SENSOR_ILI9341_CS "ILI9341 CS" #define D_SENSOR_ILI9341_DC "ILI9341 DC" #define D_SENSOR_ILI9488_CS "ILI9488 CS" #define D_SENSOR_EPAPER29_CS "EPaper29 CS" #define D_SENSOR_EPAPER42_CS "EPaper42 CS" #define D_SENSOR_SSD1351_CS "SSD1351 CS" +#define D_SENSOR_SSD1351_DC "SSD1351 DC" #define D_SENSOR_RA8876_CS "RA8876 CS" #define D_SENSOR_ST7789_CS "ST7789 CS" #define D_SENSOR_ST7789_DC "ST7789 DC" diff --git a/tasmota/language/hu_HU.h b/tasmota/language/hu_HU.h index 360a4c17c..1ab0c850c 100644 --- a/tasmota/language/hu_HU.h +++ b/tasmota/language/hu_HU.h @@ -769,18 +769,22 @@ #define D_SENSOR_IEM3000_RX "iEM3000 RX" #define D_SENSOR_MIEL_HVAC_TX "MiEl HVAC Tx" #define D_SENSOR_MIEL_HVAC_RX "MiEl HVAC Rx" +#define D_SENSOR_PROJECTOR_CTRL_TX "DLP Tx" +#define D_SENSOR_PROJECTOR_CTRL_RX "DLP Rx" #define D_SENSOR_SHELLY_DIMMER_BOOT0 "SHD Boot 0" #define D_SENSOR_SHELLY_DIMMER_RST_INV "SHD Reset" #define D_SENSOR_RC522_RST "RC522 Rst" #define D_SENSOR_RC522_CS "RC522 CS" #define D_SENSOR_NRF24_CS "NRF24 CS" #define D_SENSOR_NRF24_DC "NRF24 DC" +#define D_SENSOR_XPT2046_CS "XPT2046 CS" #define D_SENSOR_ILI9341_CS "ILI9341 CS" #define D_SENSOR_ILI9341_DC "ILI9341 DC" #define D_SENSOR_ILI9488_CS "ILI9488 CS" #define D_SENSOR_EPAPER29_CS "EPaper29 CS" #define D_SENSOR_EPAPER42_CS "EPaper42 CS" #define D_SENSOR_SSD1351_CS "SSD1351 CS" +#define D_SENSOR_SSD1351_DC "SSD1351 DC" #define D_SENSOR_RA8876_CS "RA8876 CS" #define D_SENSOR_ST7789_CS "ST7789 CS" #define D_SENSOR_ST7789_DC "ST7789 DC" diff --git a/tasmota/language/it_IT.h b/tasmota/language/it_IT.h index 20b1957f0..f7b30abfc 100644 --- a/tasmota/language/it_IT.h +++ b/tasmota/language/it_IT.h @@ -769,18 +769,22 @@ #define D_SENSOR_IEM3000_RX "iEM3000 - RX" #define D_SENSOR_MIEL_HVAC_TX "MiEl HVAC - TX" #define D_SENSOR_MIEL_HVAC_RX "MiEl HVAC - RX" +#define D_SENSOR_PROJECTOR_CTRL_TX "DLP - Tx" +#define D_SENSOR_PROJECTOR_CTRL_RX "DLP - Rx" #define D_SENSOR_SHELLY_DIMMER_BOOT0 "SHD - Boot 0" #define D_SENSOR_SHELLY_DIMMER_RST_INV "SHD - Reset" #define D_SENSOR_RC522_RST "RC522 - Reset" #define D_SENSOR_RC522_CS "RC522 - CS" #define D_SENSOR_NRF24_CS "NRF24 - CS" #define D_SENSOR_NRF24_DC "NRF24 - DC" +#define D_SENSOR_XPT2046_CS "XPT2046 CS" #define D_SENSOR_ILI9341_CS "ILI9341 - CS" #define D_SENSOR_ILI9341_DC "ILI9341 - DC" #define D_SENSOR_ILI9488_CS "ILI9488 - CS" #define D_SENSOR_EPAPER29_CS "EPaper29 - CS" #define D_SENSOR_EPAPER42_CS "EPaper42 - CS" #define D_SENSOR_SSD1351_CS "SSD1351 - CS" +#define D_SENSOR_SSD1351_DC "SSD1351 - DC" #define D_SENSOR_RA8876_CS "RA8876 - CS" #define D_SENSOR_ST7789_CS "ST7789 - CS" #define D_SENSOR_ST7789_DC "ST7789 - DC" diff --git a/tasmota/language/ko_KO.h b/tasmota/language/ko_KO.h index 22f98997b..bd1ef471f 100644 --- a/tasmota/language/ko_KO.h +++ b/tasmota/language/ko_KO.h @@ -769,18 +769,22 @@ #define D_SENSOR_IEM3000_RX "iEM3000 RX" #define D_SENSOR_MIEL_HVAC_TX "MiEl HVAC Tx" #define D_SENSOR_MIEL_HVAC_RX "MiEl HVAC Rx" +#define D_SENSOR_PROJECTOR_CTRL_TX "DLP Tx" +#define D_SENSOR_PROJECTOR_CTRL_RX "DLP Rx" #define D_SENSOR_SHELLY_DIMMER_BOOT0 "SHD Boot 0" #define D_SENSOR_SHELLY_DIMMER_RST_INV "SHD Reset" #define D_SENSOR_RC522_RST "RC522 Rst" #define D_SENSOR_RC522_CS "RC522 CS" #define D_SENSOR_NRF24_CS "NRF24 CS" #define D_SENSOR_NRF24_DC "NRF24 DC" +#define D_SENSOR_XPT2046_CS "XPT2046 CS" #define D_SENSOR_ILI9341_CS "ILI9341 CS" #define D_SENSOR_ILI9341_DC "ILI9341 DC" #define D_SENSOR_ILI9488_CS "ILI9488 CS" #define D_SENSOR_EPAPER29_CS "EPaper29 CS" #define D_SENSOR_EPAPER42_CS "EPaper42 CS" #define D_SENSOR_SSD1351_CS "SSD1351 CS" +#define D_SENSOR_SSD1351_DC "SSD1351 DC" #define D_SENSOR_RA8876_CS "RA8876 CS" #define D_SENSOR_ST7789_CS "ST7789 CS" #define D_SENSOR_ST7789_DC "ST7789 DC" diff --git a/tasmota/language/nl_NL.h b/tasmota/language/nl_NL.h index 875f25551..38e3046c9 100644 --- a/tasmota/language/nl_NL.h +++ b/tasmota/language/nl_NL.h @@ -769,18 +769,22 @@ #define D_SENSOR_IEM3000_RX "iEM3000 RX" #define D_SENSOR_MIEL_HVAC_TX "MiEl HVAC Tx" #define D_SENSOR_MIEL_HVAC_RX "MiEl HVAC Rx" +#define D_SENSOR_PROJECTOR_CTRL_TX "DLP Tx" +#define D_SENSOR_PROJECTOR_CTRL_RX "DLP Rx" #define D_SENSOR_SHELLY_DIMMER_BOOT0 "SHD Boot 0" #define D_SENSOR_SHELLY_DIMMER_RST_INV "SHD Reset" #define D_SENSOR_RC522_RST "RC522 Rst" #define D_SENSOR_RC522_CS "RC522 CS" #define D_SENSOR_NRF24_CS "NRF24 CS" #define D_SENSOR_NRF24_DC "NRF24 DC" +#define D_SENSOR_XPT2046_CS "XPT2046 CS" #define D_SENSOR_ILI9341_CS "ILI9341 CS" #define D_SENSOR_ILI9341_DC "ILI9341 DC" #define D_SENSOR_ILI9488_CS "ILI9488 CS" #define D_SENSOR_EPAPER29_CS "EPaper29 CS" #define D_SENSOR_EPAPER42_CS "EPaper42 CS" #define D_SENSOR_SSD1351_CS "SSD1351 CS" +#define D_SENSOR_SSD1351_DC "SSD1351 DC" #define D_SENSOR_RA8876_CS "RA8876 CS" #define D_SENSOR_ST7789_CS "ST7789 CS" #define D_SENSOR_ST7789_DC "ST7789 DC" diff --git a/tasmota/language/pl_PL.h b/tasmota/language/pl_PL.h index 825448a04..4ae81c0cc 100644 --- a/tasmota/language/pl_PL.h +++ b/tasmota/language/pl_PL.h @@ -769,18 +769,22 @@ #define D_SENSOR_IEM3000_RX "iEM3000 RX" #define D_SENSOR_MIEL_HVAC_TX "MiEl HVAC Tx" #define D_SENSOR_MIEL_HVAC_RX "MiEl HVAC Rx" +#define D_SENSOR_PROJECTOR_CTRL_TX "DLP Tx" +#define D_SENSOR_PROJECTOR_CTRL_RX "DLP Rx" #define D_SENSOR_SHELLY_DIMMER_BOOT0 "SHD Boot 0" #define D_SENSOR_SHELLY_DIMMER_RST_INV "SHD Reset" #define D_SENSOR_RC522_RST "RC522 Rst" #define D_SENSOR_RC522_CS "RC522 CS" #define D_SENSOR_NRF24_CS "NRF24 CS" #define D_SENSOR_NRF24_DC "NRF24 DC" +#define D_SENSOR_XPT2046_CS "XPT2046 CS" #define D_SENSOR_ILI9341_CS "ILI9341 CS" #define D_SENSOR_ILI9341_DC "ILI9341 DC" #define D_SENSOR_ILI9488_CS "ILI9488 CS" #define D_SENSOR_EPAPER29_CS "EPaper29 CS" #define D_SENSOR_EPAPER42_CS "EPaper42 CS" #define D_SENSOR_SSD1351_CS "SSD1351 CS" +#define D_SENSOR_SSD1351_DC "SSD1351 DC" #define D_SENSOR_RA8876_CS "RA8876 CS" #define D_SENSOR_ST7789_CS "ST7789 CS" #define D_SENSOR_ST7789_DC "ST7789 DC" diff --git a/tasmota/language/pt_BR.h b/tasmota/language/pt_BR.h index 68e4e4df1..c753d1a8a 100644 --- a/tasmota/language/pt_BR.h +++ b/tasmota/language/pt_BR.h @@ -769,18 +769,22 @@ #define D_SENSOR_IEM3000_RX "iEM3000 RX" #define D_SENSOR_MIEL_HVAC_TX "MiEl HVAC Tx" #define D_SENSOR_MIEL_HVAC_RX "MiEl HVAC Rx" +#define D_SENSOR_PROJECTOR_CTRL_TX "DLP Tx" +#define D_SENSOR_PROJECTOR_CTRL_RX "DLP Rx" #define D_SENSOR_SHELLY_DIMMER_BOOT0 "SHD Boot 0" #define D_SENSOR_SHELLY_DIMMER_RST_INV "SHD Reset" #define D_SENSOR_RC522_RST "RC522 Rst" #define D_SENSOR_RC522_CS "RC522 CS" #define D_SENSOR_NRF24_CS "NRF24 CS" #define D_SENSOR_NRF24_DC "NRF24 DC" +#define D_SENSOR_XPT2046_CS "XPT2046 CS" #define D_SENSOR_ILI9341_CS "ILI9341 CS" #define D_SENSOR_ILI9341_DC "ILI9341 DC" #define D_SENSOR_ILI9488_CS "ILI9488 CS" #define D_SENSOR_EPAPER29_CS "EPaper29 CS" #define D_SENSOR_EPAPER42_CS "EPaper42 CS" #define D_SENSOR_SSD1351_CS "SSD1351 CS" +#define D_SENSOR_SSD1351_DC "SSD1351 DC" #define D_SENSOR_RA8876_CS "RA8876 CS" #define D_SENSOR_ST7789_CS "ST7789 CS" #define D_SENSOR_ST7789_DC "ST7789 DC" diff --git a/tasmota/language/pt_PT.h b/tasmota/language/pt_PT.h index 2f26b2e64..7893bf4ad 100644 --- a/tasmota/language/pt_PT.h +++ b/tasmota/language/pt_PT.h @@ -769,18 +769,22 @@ #define D_SENSOR_IEM3000_RX "iEM3000 RX" #define D_SENSOR_MIEL_HVAC_TX "MiEl HVAC Tx" #define D_SENSOR_MIEL_HVAC_RX "MiEl HVAC Rx" +#define D_SENSOR_PROJECTOR_CTRL_TX "DLP Tx" +#define D_SENSOR_PROJECTOR_CTRL_RX "DLP Rx" #define D_SENSOR_SHELLY_DIMMER_BOOT0 "SHD Boot 0" #define D_SENSOR_SHELLY_DIMMER_RST_INV "SHD Reset" #define D_SENSOR_RC522_RST "RC522 Rst" #define D_SENSOR_RC522_CS "RC522 CS" #define D_SENSOR_NRF24_CS "NRF24 CS" #define D_SENSOR_NRF24_DC "NRF24 DC" +#define D_SENSOR_XPT2046_CS "XPT2046 CS" #define D_SENSOR_ILI9341_CS "ILI9341 CS" #define D_SENSOR_ILI9341_DC "ILI9341 DC" #define D_SENSOR_ILI9488_CS "ILI9488 CS" #define D_SENSOR_EPAPER29_CS "EPaper29 CS" #define D_SENSOR_EPAPER42_CS "EPaper42 CS" #define D_SENSOR_SSD1351_CS "SSD1351 CS" +#define D_SENSOR_SSD1351_DC "SSD1351 DC" #define D_SENSOR_RA8876_CS "RA8876 CS" #define D_SENSOR_ST7789_CS "ST7789 CS" #define D_SENSOR_ST7789_DC "ST7789 DC" diff --git a/tasmota/language/ro_RO.h b/tasmota/language/ro_RO.h index e00935295..09152b026 100644 --- a/tasmota/language/ro_RO.h +++ b/tasmota/language/ro_RO.h @@ -769,18 +769,22 @@ #define D_SENSOR_IEM3000_RX "iEM3000 RX" #define D_SENSOR_MIEL_HVAC_TX "MiEl HVAC Tx" #define D_SENSOR_MIEL_HVAC_RX "MiEl HVAC Rx" +#define D_SENSOR_PROJECTOR_CTRL_TX "DLP Tx" +#define D_SENSOR_PROJECTOR_CTRL_RX "DLP Rx" #define D_SENSOR_SHELLY_DIMMER_BOOT0 "SHD Boot 0" #define D_SENSOR_SHELLY_DIMMER_RST_INV "SHD Reset" #define D_SENSOR_RC522_RST "RC522 Rst" #define D_SENSOR_RC522_CS "RC522 CS" #define D_SENSOR_NRF24_CS "NRF24 CS" #define D_SENSOR_NRF24_DC "NRF24 DC" +#define D_SENSOR_XPT2046_CS "XPT2046 CS" #define D_SENSOR_ILI9341_CS "ILI9341 CS" #define D_SENSOR_ILI9341_DC "ILI9341 DC" #define D_SENSOR_ILI9488_CS "ILI9488 CS" #define D_SENSOR_EPAPER29_CS "EPaper29 CS" #define D_SENSOR_EPAPER42_CS "EPaper42 CS" #define D_SENSOR_SSD1351_CS "SSD1351 CS" +#define D_SENSOR_SSD1351_DC "SSD1351 DC" #define D_SENSOR_RA8876_CS "RA8876 CS" #define D_SENSOR_ST7789_CS "ST7789 CS" #define D_SENSOR_ST7789_DC "ST7789 DC" diff --git a/tasmota/language/ru_RU.h b/tasmota/language/ru_RU.h index c9d8c1166..6f5ccac38 100644 --- a/tasmota/language/ru_RU.h +++ b/tasmota/language/ru_RU.h @@ -769,18 +769,22 @@ #define D_SENSOR_IEM3000_RX "iEM3000 RX" #define D_SENSOR_MIEL_HVAC_TX "MiEl HVAC Tx" #define D_SENSOR_MIEL_HVAC_RX "MiEl HVAC Rx" +#define D_SENSOR_PROJECTOR_CTRL_TX "DLP Tx" +#define D_SENSOR_PROJECTOR_CTRL_RX "DLP Rx" #define D_SENSOR_SHELLY_DIMMER_BOOT0 "SHD Boot 0" #define D_SENSOR_SHELLY_DIMMER_RST_INV "SHD Reset" #define D_SENSOR_RC522_RST "RC522 Rst" #define D_SENSOR_RC522_CS "RC522 CS" #define D_SENSOR_NRF24_CS "NRF24 CS" #define D_SENSOR_NRF24_DC "NRF24 DC" +#define D_SENSOR_XPT2046_CS "XPT2046 CS" #define D_SENSOR_ILI9341_CS "ILI9341 CS" #define D_SENSOR_ILI9341_DC "ILI9341 DC" #define D_SENSOR_ILI9488_CS "ILI9488 CS" #define D_SENSOR_EPAPER29_CS "EPaper29 CS" #define D_SENSOR_EPAPER42_CS "EPaper42 CS" #define D_SENSOR_SSD1351_CS "SSD1351 CS" +#define D_SENSOR_SSD1351_DC "SSD1351 DC" #define D_SENSOR_RA8876_CS "RA8876 CS" #define D_SENSOR_ST7789_CS "ST7789 CS" #define D_SENSOR_ST7789_DC "ST7789 DC" diff --git a/tasmota/language/sk_SK.h b/tasmota/language/sk_SK.h index b752d20fe..393507016 100644 --- a/tasmota/language/sk_SK.h +++ b/tasmota/language/sk_SK.h @@ -769,18 +769,22 @@ #define D_SENSOR_IEM3000_RX "iEM3000 RX" #define D_SENSOR_MIEL_HVAC_TX "MiEl HVAC Tx" #define D_SENSOR_MIEL_HVAC_RX "MiEl HVAC Rx" +#define D_SENSOR_PROJECTOR_CTRL_TX "DLP Tx" +#define D_SENSOR_PROJECTOR_CTRL_RX "DLP Rx" #define D_SENSOR_SHELLY_DIMMER_BOOT0 "SHD Boot 0" #define D_SENSOR_SHELLY_DIMMER_RST_INV "SHD Reset" #define D_SENSOR_RC522_RST "RC522 Rst" #define D_SENSOR_RC522_CS "RC522 CS" #define D_SENSOR_NRF24_CS "NRF24 CS" #define D_SENSOR_NRF24_DC "NRF24 DC" +#define D_SENSOR_XPT2046_CS "XPT2046 CS" #define D_SENSOR_ILI9341_CS "ILI9341 CS" #define D_SENSOR_ILI9341_DC "ILI9341 DC" #define D_SENSOR_ILI9488_CS "ILI9488 CS" #define D_SENSOR_EPAPER29_CS "EPaper29 CS" #define D_SENSOR_EPAPER42_CS "EPaper42 CS" #define D_SENSOR_SSD1351_CS "SSD1351 CS" +#define D_SENSOR_SSD1351_DC "SSD1351 DC" #define D_SENSOR_RA8876_CS "RA8876 CS" #define D_SENSOR_ST7789_CS "ST7789 CS" #define D_SENSOR_ST7789_DC "ST7789 DC" diff --git a/tasmota/language/sv_SE.h b/tasmota/language/sv_SE.h index 7105f64a9..1896d25a2 100644 --- a/tasmota/language/sv_SE.h +++ b/tasmota/language/sv_SE.h @@ -769,18 +769,22 @@ #define D_SENSOR_IEM3000_RX "iEM3000 RX" #define D_SENSOR_MIEL_HVAC_TX "MiEl HVAC Tx" #define D_SENSOR_MIEL_HVAC_RX "MiEl HVAC Rx" +#define D_SENSOR_PROJECTOR_CTRL_TX "DLP Tx" +#define D_SENSOR_PROJECTOR_CTRL_RX "DLP Rx" #define D_SENSOR_SHELLY_DIMMER_BOOT0 "SHD Boot 0" #define D_SENSOR_SHELLY_DIMMER_RST_INV "SHD Reset" #define D_SENSOR_RC522_RST "RC522 Rst" #define D_SENSOR_RC522_CS "RC522 CS" #define D_SENSOR_NRF24_CS "NRF24 CS" #define D_SENSOR_NRF24_DC "NRF24 DC" +#define D_SENSOR_XPT2046_CS "XPT2046 CS" #define D_SENSOR_ILI9341_CS "ILI9341 CS" #define D_SENSOR_ILI9341_DC "ILI9341 DC" #define D_SENSOR_ILI9488_CS "ILI9488 CS" #define D_SENSOR_EPAPER29_CS "EPaper29 CS" #define D_SENSOR_EPAPER42_CS "EPaper42 CS" #define D_SENSOR_SSD1351_CS "SSD1351 CS" +#define D_SENSOR_SSD1351_DC "SSD1351 DC" #define D_SENSOR_RA8876_CS "RA8876 CS" #define D_SENSOR_ST7789_CS "ST7789 CS" #define D_SENSOR_ST7789_DC "ST7789 DC" diff --git a/tasmota/language/tr_TR.h b/tasmota/language/tr_TR.h index a23f686fe..8deecf270 100644 --- a/tasmota/language/tr_TR.h +++ b/tasmota/language/tr_TR.h @@ -769,18 +769,22 @@ #define D_SENSOR_IEM3000_RX "iEM3000 RX" #define D_SENSOR_MIEL_HVAC_TX "MiEl HVAC Tx" #define D_SENSOR_MIEL_HVAC_RX "MiEl HVAC Rx" +#define D_SENSOR_PROJECTOR_CTRL_TX "DLP Tx" +#define D_SENSOR_PROJECTOR_CTRL_RX "DLP Rx" #define D_SENSOR_SHELLY_DIMMER_BOOT0 "SHD Boot 0" #define D_SENSOR_SHELLY_DIMMER_RST_INV "SHD Reset" #define D_SENSOR_RC522_RST "RC522 Rst" #define D_SENSOR_RC522_CS "RC522 CS" #define D_SENSOR_NRF24_CS "NRF24 CS" #define D_SENSOR_NRF24_DC "NRF24 DC" +#define D_SENSOR_XPT2046_CS "XPT2046 CS" #define D_SENSOR_ILI9341_CS "ILI9341 CS" #define D_SENSOR_ILI9341_DC "ILI9341 DC" #define D_SENSOR_ILI9488_CS "ILI9488 CS" #define D_SENSOR_EPAPER29_CS "EPaper29 CS" #define D_SENSOR_EPAPER42_CS "EPaper42 CS" #define D_SENSOR_SSD1351_CS "SSD1351 CS" +#define D_SENSOR_SSD1351_DC "SSD1351 DC" #define D_SENSOR_RA8876_CS "RA8876 CS" #define D_SENSOR_ST7789_CS "ST7789 CS" #define D_SENSOR_ST7789_DC "ST7789 DC" diff --git a/tasmota/language/uk_UA.h b/tasmota/language/uk_UA.h index 83c78b23f..7310f8d0b 100644 --- a/tasmota/language/uk_UA.h +++ b/tasmota/language/uk_UA.h @@ -769,18 +769,22 @@ #define D_SENSOR_IEM3000_RX "iEM3000 RX" #define D_SENSOR_MIEL_HVAC_TX "MiEl HVAC Tx" #define D_SENSOR_MIEL_HVAC_RX "MiEl HVAC Rx" +#define D_SENSOR_PROJECTOR_CTRL_TX "DLP Tx" +#define D_SENSOR_PROJECTOR_CTRL_RX "DLP Rx" #define D_SENSOR_SHELLY_DIMMER_BOOT0 "SHD Boot 0" #define D_SENSOR_SHELLY_DIMMER_RST_INV "SHD Reset" #define D_SENSOR_RC522_RST "RC522 Rst" #define D_SENSOR_RC522_CS "RC522 CS" #define D_SENSOR_NRF24_CS "NRF24 CS" #define D_SENSOR_NRF24_DC "NRF24 DC" +#define D_SENSOR_XPT2046_CS "XPT2046 CS" #define D_SENSOR_ILI9341_CS "ILI9341 CS" #define D_SENSOR_ILI9341_DC "ILI9341 DC" #define D_SENSOR_ILI9488_CS "ILI9488 CS" #define D_SENSOR_EPAPER29_CS "EPaper29 CS" #define D_SENSOR_EPAPER42_CS "EPaper42 CS" #define D_SENSOR_SSD1351_CS "SSD1351 CS" +#define D_SENSOR_SSD1351_DC "SSD1351 DC" #define D_SENSOR_RA8876_CS "RA8876 CS" #define D_SENSOR_ST7789_CS "ST7789 CS" #define D_SENSOR_ST7789_DC "ST7789 DC" diff --git a/tasmota/language/vi_VN.h b/tasmota/language/vi_VN.h index 329f7ebe8..4c3607d07 100644 --- a/tasmota/language/vi_VN.h +++ b/tasmota/language/vi_VN.h @@ -769,18 +769,22 @@ #define D_SENSOR_IEM3000_RX "iEM3000 RX" #define D_SENSOR_MIEL_HVAC_TX "MiEl HVAC Tx" #define D_SENSOR_MIEL_HVAC_RX "MiEl HVAC Rx" +#define D_SENSOR_PROJECTOR_CTRL_TX "DLP Tx" +#define D_SENSOR_PROJECTOR_CTRL_RX "DLP Rx" #define D_SENSOR_SHELLY_DIMMER_BOOT0 "SHD Boot 0" #define D_SENSOR_SHELLY_DIMMER_RST_INV "SHD Reset" #define D_SENSOR_RC522_RST "RC522 Rst" #define D_SENSOR_RC522_CS "RC522 CS" #define D_SENSOR_NRF24_CS "NRF24 CS" #define D_SENSOR_NRF24_DC "NRF24 DC" +#define D_SENSOR_XPT2046_CS "XPT2046 CS" #define D_SENSOR_ILI9341_CS "ILI9341 CS" #define D_SENSOR_ILI9341_DC "ILI9341 DC" #define D_SENSOR_ILI9488_CS "ILI9488 CS" #define D_SENSOR_EPAPER29_CS "EPaper29 CS" #define D_SENSOR_EPAPER42_CS "EPaper42 CS" #define D_SENSOR_SSD1351_CS "SSD1351 CS" +#define D_SENSOR_SSD1351_DC "SSD1351 DC" #define D_SENSOR_RA8876_CS "RA8876 CS" #define D_SENSOR_ST7789_CS "ST7789 CS" #define D_SENSOR_ST7789_DC "ST7789 DC" diff --git a/tasmota/language/xpt.patch b/tasmota/language/xpt.patch new file mode 100644 index 000000000..9fc7c4f3c --- /dev/null +++ b/tasmota/language/xpt.patch @@ -0,0 +1,2 @@ +779a780 +> #define D_SENSOR_XPT2046_CS "XPT2046 CS" diff --git a/tasmota/language/zh_CN.h b/tasmota/language/zh_CN.h index 85e7381c4..8f0e36606 100644 --- a/tasmota/language/zh_CN.h +++ b/tasmota/language/zh_CN.h @@ -769,18 +769,22 @@ #define D_SENSOR_IEM3000_RX "iEM3000 RX" #define D_SENSOR_MIEL_HVAC_TX "MiEl HVAC Tx" #define D_SENSOR_MIEL_HVAC_RX "MiEl HVAC Rx" +#define D_SENSOR_PROJECTOR_CTRL_TX "DLP Tx" +#define D_SENSOR_PROJECTOR_CTRL_RX "DLP Rx" #define D_SENSOR_SHELLY_DIMMER_BOOT0 "SHD Boot 0" #define D_SENSOR_SHELLY_DIMMER_RST_INV "SHD Reset" #define D_SENSOR_RC522_RST "RC522 Rst" #define D_SENSOR_RC522_CS "RC522 CS" #define D_SENSOR_NRF24_CS "NRF24 CS" #define D_SENSOR_NRF24_DC "NRF24 DC" +#define D_SENSOR_XPT2046_CS "XPT2046 CS" #define D_SENSOR_ILI9341_CS "ILI9341 CS" #define D_SENSOR_ILI9341_DC "ILI9341 DC" #define D_SENSOR_ILI9488_CS "ILI9488 CS" #define D_SENSOR_EPAPER29_CS "EPaper29 CS" #define D_SENSOR_EPAPER42_CS "EPaper42 CS" #define D_SENSOR_SSD1351_CS "SSD1351 CS" +#define D_SENSOR_SSD1351_DC "SSD1351 DC" #define D_SENSOR_RA8876_CS "RA8876 CS" #define D_SENSOR_ST7789_CS "ST7789 CS" #define D_SENSOR_ST7789_DC "ST7789 DC" diff --git a/tasmota/language/zh_TW.h b/tasmota/language/zh_TW.h index 34ff54547..5dc1ce00c 100644 --- a/tasmota/language/zh_TW.h +++ b/tasmota/language/zh_TW.h @@ -769,18 +769,22 @@ #define D_SENSOR_IEM3000_RX "iEM3000 RX" #define D_SENSOR_MIEL_HVAC_TX "MiEl HVAC Tx" #define D_SENSOR_MIEL_HVAC_RX "MiEl HVAC Rx" +#define D_SENSOR_PROJECTOR_CTRL_TX "DLP Tx" +#define D_SENSOR_PROJECTOR_CTRL_RX "DLP Rx" #define D_SENSOR_SHELLY_DIMMER_BOOT0 "SHD Boot 0" #define D_SENSOR_SHELLY_DIMMER_RST_INV "SHD Reset" #define D_SENSOR_RC522_RST "RC522 Rst" #define D_SENSOR_RC522_CS "RC522 CS" #define D_SENSOR_NRF24_CS "NRF24 CS" #define D_SENSOR_NRF24_DC "NRF24 DC" +#define D_SENSOR_XPT2046_CS "XPT2046 CS" #define D_SENSOR_ILI9341_CS "ILI9341 CS" #define D_SENSOR_ILI9341_DC "ILI9341 DC" #define D_SENSOR_ILI9488_CS "ILI9488 CS" #define D_SENSOR_EPAPER29_CS "EPaper29 CS" #define D_SENSOR_EPAPER42_CS "EPaper42 CS" #define D_SENSOR_SSD1351_CS "SSD1351 CS" +#define D_SENSOR_SSD1351_DC "SSD1351 DC" #define D_SENSOR_RA8876_CS "RA8876 CS" #define D_SENSOR_ST7789_CS "ST7789 CS" #define D_SENSOR_ST7789_DC "ST7789 DC" diff --git a/tasmota/my_user_config.h b/tasmota/my_user_config.h index b35a1c475..33ced12ed 100644 --- a/tasmota/my_user_config.h +++ b/tasmota/my_user_config.h @@ -677,6 +677,9 @@ #define USE_TASMOTA_CLIENT_SERIAL_SPEED 57600 // Depends on the sketch that is running on the Uno/Pro Mini //#define USE_OPENTHERM // Add support for OpenTherm (+15k code) //#define USE_MIEL_HVAC // Add support for Mitsubishi Electric HVAC serial interface (+5k code) +//#define USE_PROJECTOR_CTRL // Add support for LCD/DLP Projector serial control interface (+2k code) +// #define USE_PROJECTOR_CTRL_NEC // Use codes for NEC +// #define USE_PROJECTOR_CTRL_OPTOMA // Use codes for OPTOMA //#define USE_AS608 // Add support for AS608 optical and R503 capacitive fingerprint sensor (+3k code) // #define USE_AS608_MESSAGES // Add verbose error messages (+0k4 code) diff --git a/tasmota/settings.ino b/tasmota/settings.ino index d4857bb15..fe5316e9f 100644 --- a/tasmota/settings.ino +++ b/tasmota/settings.ino @@ -744,7 +744,7 @@ void SettingsDefaultSet2(void) { Settings.module = MODULE; Settings.fallback_module = FALLBACK_MODULE; ModuleDefault(WEMOS); -// for (uint32_t i = 0; i < ARRAY_SIZE(Settings.my_gp.io); i++) { Settings.my_gp.io[i] = GPIO_NONE; } +// for (uint32_t i = 0; i < nitems(Settings.my_gp.io); i++) { Settings.my_gp.io[i] = GPIO_NONE; } SettingsUpdateText(SET_FRIENDLYNAME1, PSTR(FRIENDLY_NAME)); SettingsUpdateText(SET_FRIENDLYNAME2, PSTR(FRIENDLY_NAME"2")); SettingsUpdateText(SET_FRIENDLYNAME3, PSTR(FRIENDLY_NAME"3")); diff --git a/tasmota/support.ino b/tasmota/support.ino index 0cb0daf5a..d5ba2d914 100644 --- a/tasmota/support.ino +++ b/tasmota/support.ino @@ -1237,7 +1237,7 @@ int ResponseJsonEndEnd(void) #ifdef ESP8266 uint16_t GpioConvert(uint8_t gpio) { - if (gpio >= ARRAY_SIZE(kGpioConvert)) { + if (gpio >= nitems(kGpioConvert)) { return AGPIO(GPIO_USER); } return pgm_read_word(kGpioConvert + gpio); @@ -1285,7 +1285,7 @@ void ConvertGpios(void) { void DumpConvertTable(void) { bool jsflg = false; uint32_t lines = 1; - for (uint32_t i = 0; i < ARRAY_SIZE(kGpioConvert); i++) { + for (uint32_t i = 0; i < nitems(kGpioConvert); i++) { uint32_t data = pgm_read_word(kGpioConvert + i); if (!jsflg) { Response_P(PSTR("{\"GPIOConversion%d\":{"), lines); @@ -1293,14 +1293,14 @@ void DumpConvertTable(void) { ResponseAppend_P(PSTR(",")); } jsflg = true; - if ((ResponseAppend_P(PSTR("\"%d\":\"%d\""), i, data) > (MAX_LOGSZ - TOPSZ)) || (i == ARRAY_SIZE(kGpioConvert) -1)) { + if ((ResponseAppend_P(PSTR("\"%d\":\"%d\""), i, data) > (MAX_LOGSZ - TOPSZ)) || (i == nitems(kGpioConvert) -1)) { ResponseJsonEndEnd(); MqttPublishPrefixTopic_P(RESULT_OR_STAT, XdrvMailbox.command); jsflg = false; lines++; } } - for (uint32_t i = 0; i < ARRAY_SIZE(kAdcNiceList); i++) { + for (uint32_t i = 0; i < nitems(kAdcNiceList); i++) { uint32_t data = pgm_read_word(kAdcNiceList + i); if (!jsflg) { Response_P(PSTR("{\"ADC0Conversion%d\":{"), lines); @@ -1308,7 +1308,7 @@ void DumpConvertTable(void) { ResponseAppend_P(PSTR(",")); } jsflg = true; - if ((ResponseAppend_P(PSTR("\"%d\":\"%d\""), i, data) > (MAX_LOGSZ - TOPSZ)) || (i == ARRAY_SIZE(kAdcNiceList) -1)) { + if ((ResponseAppend_P(PSTR("\"%d\":\"%d\""), i, data) > (MAX_LOGSZ - TOPSZ)) || (i == nitems(kAdcNiceList) -1)) { ResponseJsonEndEnd(); MqttPublishPrefixTopic_P(RESULT_OR_STAT, XdrvMailbox.command); jsflg = false; @@ -1328,7 +1328,7 @@ int ICACHE_RAM_ATTR Pin(uint32_t gpio, uint32_t index) { real_gpio += index; mask = 0xFFFF; } - for (uint32_t i = 0; i < ARRAY_SIZE(TasmotaGlobal.gpio_pin); i++) { + for (uint32_t i = 0; i < nitems(TasmotaGlobal.gpio_pin); i++) { if ((TasmotaGlobal.gpio_pin[i] & mask) == real_gpio) { return i; // Pin number configured for gpio } @@ -1342,7 +1342,7 @@ bool PinUsed(uint32_t gpio, uint32_t index) { } uint32_t GetPin(uint32_t lpin) { - if (lpin < ARRAY_SIZE(TasmotaGlobal.gpio_pin)) { + if (lpin < nitems(TasmotaGlobal.gpio_pin)) { return TasmotaGlobal.gpio_pin[lpin]; } else { return GPIO_NONE; @@ -1466,7 +1466,7 @@ void GetInternalTemplate(void* ptr, uint32_t module, uint32_t option) { void TemplateGpios(myio *gp) { uint16_t *dest = (uint16_t *)gp; - uint16_t src[ARRAY_SIZE(Settings.user_template.gp.io)]; + uint16_t src[nitems(Settings.user_template.gp.io)]; memset(dest, GPIO_NONE, sizeof(myio)); if (USER_MODULE == Settings.module) { @@ -1484,7 +1484,7 @@ void TemplateGpios(myio *gp) // AddLogBuffer(LOG_LEVEL_DEBUG, (uint8_t *)&src, sizeof(mycfgio)); uint32_t j = 0; - for (uint32_t i = 0; i < ARRAY_SIZE(Settings.user_template.gp.io); i++) { + for (uint32_t i = 0; i < nitems(Settings.user_template.gp.io); i++) { if (6 == i) { j = 9; } if (8 == i) { j = 12; } dest[j] = src[i]; @@ -1600,7 +1600,7 @@ bool JsonTemplate(char* dataBuf) uint8_t template8[sizeof(mytmplt8285)] = { GPIO_NONE }; if (13 == arr.size()) { // Possible old template uint32_t gpio = 0; - for (uint32_t i = 0; i < ARRAY_SIZE(template8) -1; i++) { + for (uint32_t i = 0; i < nitems(template8) -1; i++) { gpio = arr[i].getUInt(); if (gpio > 255) { // New templates might have values above 255 break; @@ -1615,13 +1615,13 @@ bool JsonTemplate(char* dataBuf) val = root[PSTR(D_JSON_FLAG)]; if (val) { - template8[ARRAY_SIZE(template8) -1] = val.getUInt() & 0x0F; + template8[nitems(template8) -1] = val.getUInt() & 0x0F; } TemplateConvert(template8, Settings.user_template.gp.io); Settings.user_template.flag.data = 0; } else { #endif - for (uint32_t i = 0; i < ARRAY_SIZE(Settings.user_template.gp.io); i++) { + for (uint32_t i = 0; i < nitems(Settings.user_template.gp.io); i++) { JsonParserToken val = arr[i]; if (!val) { break; } uint16_t gpio = val.getUInt(); @@ -1657,7 +1657,7 @@ void TemplateJson(void) // AddLogBufferSize(LOG_LEVEL_DEBUG, (uint8_t*)&Settings.user_template, sizeof(Settings.user_template) / 2, 2); Response_P(PSTR("{\"" D_JSON_NAME "\":\"%s\",\"" D_JSON_GPIO "\":["), SettingsText(SET_TEMPLATE_NAME)); - for (uint32_t i = 0; i < ARRAY_SIZE(Settings.user_template.gp.io); i++) { + for (uint32_t i = 0; i < nitems(Settings.user_template.gp.io); i++) { uint16_t gpio = Settings.user_template.gp.io[i]; if (gpio == AGPIO(GPIO_USER)) { gpio = AGPIO(GPIO_NONE) +1; diff --git a/tasmota/support_command.ino b/tasmota/support_command.ino index 643327aae..1a16279ad 100644 --- a/tasmota/support_command.ino +++ b/tasmota/support_command.ino @@ -597,20 +597,20 @@ void CmndStatus(void) #ifdef USE_SHUTTER if (Settings.flag3.shutter_mode) { if ((0 == payload) || (13 == payload)) { - Response_P(PSTR("{\"" D_CMND_STATUS D_STATUS13_SHUTTER "\":")); + Response_P(PSTR("{\"" D_CMND_STATUS D_STATUS13_SHUTTER "\":{")); for (uint32_t i = 0; i < MAX_SHUTTERS; i++) { if (0 == Settings.shutter_startrelay[i]) { break; } if (i > 0) { ResponseAppend_P(PSTR(",")); } - ResponseAppend_P(PSTR("{\"" D_STATUS13_SHUTTER "%d\":{\"Relay1\":%d,\"Relay2\":%d,\"Open\":%d,\"Close\":%d," - "\"50perc\":%d,\"Delay\":%d,\"Opt\":\"%s\"," - "\"Calib\":[%d,%d,%d,%d,%d]," - "\"Mode\":\"%d\"}}"), - i, Settings.shutter_startrelay[i], Settings.shutter_startrelay[i] +1, Settings.shutter_opentime[i], Settings.shutter_closetime[i], - Settings.shutter_set50percent[i], Settings.shutter_motordelay[i], GetBinary8(Settings.shutter_options[i], 4).c_str(), - Settings.shuttercoeff[0][i], Settings.shuttercoeff[1][i], Settings.shuttercoeff[2][i], Settings.shuttercoeff[3][i], Settings.shuttercoeff[4][i], - Settings.shutter_mode); + ResponseAppend_P(PSTR("\"" D_STATUS13_SHUTTER "%d\":{\"Relay1\":%d,\"Relay2\":%d,\"Open\":%d,\"Close\":%d," + "\"50perc\":%d,\"Delay\":%d,\"Opt\":\"%s\"," + "\"Calib\":[%d,%d,%d,%d,%d]," + "\"Mode\":\"%d\"}"), + i, Settings.shutter_startrelay[i], Settings.shutter_startrelay[i] +1, Settings.shutter_opentime[i], Settings.shutter_closetime[i], + Settings.shutter_set50percent[i], Settings.shutter_motordelay[i], GetBinary8(Settings.shutter_options[i], 4).c_str(), + Settings.shuttercoeff[0][i], Settings.shuttercoeff[1][i], Settings.shuttercoeff[2][i], Settings.shuttercoeff[3][i], Settings.shuttercoeff[4][i], + Settings.shutter_mode); } - ResponseJsonEnd(); + ResponseJsonEndEnd(); MqttPublishPrefixTopic_P(STAT, PSTR(D_CMND_STATUS "13")); } } @@ -1156,7 +1156,7 @@ void CmndModule(void) Settings.module = XdrvMailbox.payload; SetModuleType(); if (Settings.last_module != XdrvMailbox.payload) { - for (uint32_t i = 0; i < ARRAY_SIZE(Settings.my_gp.io); i++) { + for (uint32_t i = 0; i < nitems(Settings.my_gp.io); i++) { Settings.my_gp.io[i] = GPIO_NONE; } } @@ -1200,12 +1200,12 @@ void CmndModules(void) void CmndGpio(void) { - if (XdrvMailbox.index < ARRAY_SIZE(Settings.my_gp.io)) { + if (XdrvMailbox.index < nitems(Settings.my_gp.io)) { myio template_gp; TemplateGpios(&template_gp); if (ValidGPIO(XdrvMailbox.index, template_gp.io[XdrvMailbox.index]) && (XdrvMailbox.payload >= 0) && (XdrvMailbox.payload < AGPIO(GPIO_SENSOR_END))) { bool present = false; - for (uint32_t i = 0; i < ARRAY_SIZE(kGpioNiceList); i++) { + for (uint32_t i = 0; i < nitems(kGpioNiceList); i++) { uint32_t midx = pgm_read_word(kGpioNiceList + i); uint32_t max_midx = ((midx & 0x001F) > 0) ? midx : midx +1; if ((XdrvMailbox.payload >= (midx & 0xFFE0)) && (XdrvMailbox.payload < max_midx)) { @@ -1214,7 +1214,7 @@ void CmndGpio(void) } } if (present) { - for (uint32_t i = 0; i < ARRAY_SIZE(Settings.my_gp.io); i++) { + for (uint32_t i = 0; i < nitems(Settings.my_gp.io); i++) { if (ValidGPIO(i, template_gp.io[i]) && (Settings.my_gp.io[i] == XdrvMailbox.payload)) { Settings.my_gp.io[i] = GPIO_NONE; } @@ -1225,7 +1225,7 @@ void CmndGpio(void) } bool jsflg = false; bool jsflg2 = false; - for (uint32_t i = 0; i < ARRAY_SIZE(Settings.my_gp.io); i++) { + for (uint32_t i = 0; i < nitems(Settings.my_gp.io); i++) { if (ValidGPIO(i, template_gp.io[i]) || ((255 == XdrvMailbox.payload) && !FlashPin(i))) { if (!jsflg) { Response_P(PSTR("{")); @@ -1243,7 +1243,7 @@ void CmndGpio(void) char sindex[4] = { 0 }; uint32_t sensor_name_idx = BGPIO(sensor_type); uint32_t nice_list_search = sensor_type & 0xFFE0; - for (uint32_t j = 0; j < ARRAY_SIZE(kGpioNiceList); j++) { + for (uint32_t j = 0; j < nitems(kGpioNiceList); j++) { uint32_t nls_idx = pgm_read_word(kGpioNiceList + j); if (((nls_idx & 0xFFE0) == nice_list_search) && ((nls_idx & 0x001F) > 0)) { snprintf_P(sindex, sizeof(sindex), PSTR("%d"), (sensor_type & 0x001F) +1); @@ -1310,10 +1310,10 @@ void CmndGpios(void) // DumpConvertTable(); ShowGpios(nullptr, GPIO_SENSOR_END, 0, lines); } else { - ShowGpios(kGpioNiceList, ARRAY_SIZE(kGpioNiceList), 0, lines); + ShowGpios(kGpioNiceList, nitems(kGpioNiceList), 0, lines); #ifdef ESP8266 #ifndef USE_ADC_VCC - ShowGpios(kAdcNiceList, ARRAY_SIZE(kAdcNiceList), 1, lines); + ShowGpios(kAdcNiceList, nitems(kAdcNiceList), 1, lines); #endif // USE_ADC_VCC #endif // ESP8266 } @@ -1345,7 +1345,7 @@ void CmndTemplate(void) } SettingsUpdateText(SET_TEMPLATE_NAME, PSTR("Merged")); uint32_t j = 0; - for (uint32_t i = 0; i < ARRAY_SIZE(Settings.user_template.gp.io); i++) { + for (uint32_t i = 0; i < nitems(Settings.user_template.gp.io); i++) { if (6 == i) { j = 9; } if (8 == i) { j = 12; } if (TasmotaGlobal.my_module.io[j] > GPIO_NONE) { diff --git a/tasmota/support_features.ino b/tasmota/support_features.ino index 45ec475fc..04acd2e07 100644 --- a/tasmota/support_features.ino +++ b/tasmota/support_features.ino @@ -718,7 +718,9 @@ void ResponseAppendFeatures(void) #if defined(USE_DISPLAY) && defined(USE_DISPLAY_TM1637) feature7 |= 0x40000000; #endif -// feature7 |= 0x80000000; +#ifdef USE_PROJECTOR_CTRL + feature7 |= 0x80000000; // xdrv_53_projector_ctrl.ino +#endif } static uint32_t feature8 = 0x00000000; diff --git a/tasmota/support_tasmota.ino b/tasmota/support_tasmota.ino index 1e57256e6..9556f5aee 100644 --- a/tasmota/support_tasmota.ino +++ b/tasmota/support_tasmota.ino @@ -1556,7 +1556,7 @@ void GpioInit(void) ConvertGpios(); #endif // ESP8266 - for (uint32_t i = 0; i < ARRAY_SIZE(Settings.user_template.gp.io); i++) { + for (uint32_t i = 0; i < nitems(Settings.user_template.gp.io); i++) { if ((Settings.user_template.gp.io[i] >= AGPIO(GPIO_SENSOR_END)) && (Settings.user_template.gp.io[i] < AGPIO(GPIO_USER))) { Settings.user_template.gp.io[i] = AGPIO(GPIO_USER); // Fix not supported sensor ids in template } @@ -1564,7 +1564,7 @@ void GpioInit(void) myio template_gp; TemplateGpios(&template_gp); - for (uint32_t i = 0; i < ARRAY_SIZE(Settings.my_gp.io); i++) { + for (uint32_t i = 0; i < nitems(Settings.my_gp.io); i++) { if ((Settings.my_gp.io[i] >= AGPIO(GPIO_SENSOR_END)) && (Settings.my_gp.io[i] < AGPIO(GPIO_USER))) { Settings.my_gp.io[i] = GPIO_NONE; // Fix not supported sensor ids in module } @@ -1576,7 +1576,7 @@ void GpioInit(void) } } - for (uint32_t i = 0; i < ARRAY_SIZE(TasmotaGlobal.my_module.io); i++) { + for (uint32_t i = 0; i < nitems(TasmotaGlobal.my_module.io); i++) { uint32_t mpin = ValidPin(i, TasmotaGlobal.my_module.io[i]); DEBUG_CORE_LOG(PSTR("INI: gpio pin %d, mpin %d"), i, mpin); @@ -1648,7 +1648,7 @@ void GpioInit(void) if (mpin) { SetPin(i, mpin); } // Anything above GPIO_NONE and below GPIO_SENSOR_END } -// AddLogBufferSize(LOG_LEVEL_DEBUG, (uint8_t*)TasmotaGlobal.gpio_pin, ARRAY_SIZE(TasmotaGlobal.gpio_pin), sizeof(TasmotaGlobal.gpio_pin[0])); +// AddLogBufferSize(LOG_LEVEL_DEBUG, (uint8_t*)TasmotaGlobal.gpio_pin, nitems(TasmotaGlobal.gpio_pin), sizeof(TasmotaGlobal.gpio_pin[0])); analogWriteRange(Settings.pwm_range); // Default is 1023 (Arduino.h) analogWriteFreq(Settings.pwm_frequency); // Default is 1000 (core_esp8266_wiring_pwm.c) @@ -1715,7 +1715,7 @@ void GpioInit(void) AddLogSpi(1, Pin(GPIO_SPI_CLK), Pin(GPIO_SPI_MOSI), Pin(GPIO_SPI_MISO)); #endif // USE_SPI - for (uint32_t i = 0; i < ARRAY_SIZE(TasmotaGlobal.my_module.io); i++) { + for (uint32_t i = 0; i < nitems(TasmotaGlobal.my_module.io); i++) { uint32_t mpin = ValidPin(i, TasmotaGlobal.my_module.io[i]); // AddLog(LOG_LEVEL_DEBUG, PSTR("INI: gpio pin %d, mpin %d"), i, mpin); if (AGPIO(GPIO_OUTPUT_HI) == mpin) { diff --git a/tasmota/tasmota.ino b/tasmota/tasmota.ino index c0b7b4669..637d2b84b 100644 --- a/tasmota/tasmota.ino +++ b/tasmota/tasmota.ino @@ -307,7 +307,7 @@ void setup(void) { TasmotaGlobal.no_autoexec = true; } if (RtcReboot.fast_reboot_count > Settings.param[P_BOOT_LOOP_OFFSET] +3) { // Restarted 5 times - for (uint32_t i = 0; i < ARRAY_SIZE(Settings.my_gp.io); i++) { + for (uint32_t i = 0; i < nitems(Settings.my_gp.io); i++) { Settings.my_gp.io[i] = GPIO_NONE; // Reset user defined GPIO disabling sensors } } diff --git a/tasmota/tasmota_ca.ino b/tasmota/tasmota_ca.ino index 97b79614b..f4982c688 100644 --- a/tasmota/tasmota_ca.ino +++ b/tasmota/tasmota_ca.ino @@ -245,7 +245,7 @@ const br_x509_trust_anchor PROGMEM Tasmota_TA[] = { } }; -const size_t Tasmota_TA_size = ARRAY_SIZE(Tasmota_TA); +const size_t Tasmota_TA_size = nitems(Tasmota_TA); // we add a separate CA for telegram /*********************************************************************************************\ diff --git a/tasmota/tasmota_configurations.h b/tasmota/tasmota_configurations.h index e0bf0100e..c4956bdbd 100644 --- a/tasmota/tasmota_configurations.h +++ b/tasmota/tasmota_configurations.h @@ -178,6 +178,9 @@ //#define USE_TASMOTA_CLIENT // Add support for Arduino Uno/Pro Mini via serial interface including flashing (+2k3 code, 44 mem) //#define USE_OPENTHERM // Add support for OpenTherm (+15k code) //#define USE_MIEL_HVAC // Add support for Mitsubishi Electric HVAC serial interface (+5k code) +//#define USE_PROJECTOR_CTRL // Add support for LCD/DLP Projector serial control interface (+2k code) +// #define USE_PROJECTOR_CTRL_NEC // Use codes for NEC +// #define USE_PROJECTOR_CTRL_OPTOMA // Use codes for OPTOMA //#define USE_AS608 // Add support for AS608 optical and R503 capacitive fingerprint sensor (+3k4 code) #define USE_ENERGY_SENSOR // Add energy sensors (-14k code) @@ -431,6 +434,7 @@ #undef USE_TASMOTA_CLIENT // Disable support for Arduino Uno/Pro Mini via serial interface including flashing (+2k3 code, 44 mem) #undef USE_OPENTHERM // Disable support for OpenTherm (+15k code) #undef USE_MIEL_HVAC // Disable support for Mitsubishi Electric HVAC serial interface (+5k code) +#undef USE_PROJECTOR_CTRL // Disable support for LCD/DLP Projector serial control interface #undef USE_DHT // Disable support for DHT11, AM2301 (DHT21, DHT22, AM2302, AM2321) and SI7021 Temperature and Humidity sensor #undef USE_MAX31855 // Disable MAX31855 K-Type thermocouple sensor using softSPI @@ -560,6 +564,7 @@ #undef USE_TASMOTA_CLIENT // Disable support for Arduino Uno/Pro Mini via serial interface including flashing (+2k3 code, 44 mem) #undef USE_OPENTHERM // Disable support for OpenTherm (+15k code) #undef USE_MIEL_HVAC // Disable support for Mitsubishi Electric HVAC serial interface (+5k code) +#undef USE_PROJECTOR_CTRL // Disable support for LCD/DLP Projector serial control interface #undef USE_ENERGY_SENSOR // Disable energy sensors #undef USE_ADE7953 // Disable ADE7953 Energy monitor as used on Shelly 2.5 (I2C address 0x38) (+1k5) @@ -699,6 +704,7 @@ #undef USE_TASMOTA_CLIENT // Disable support for Arduino Uno/Pro Mini via serial interface including flashing (+2k3 code, 44 mem) #undef USE_OPENTHERM // Disable support for OpenTherm (+15k code) #undef USE_MIEL_HVAC // Disable support for Mitsubishi Electric HVAC serial interface (+5k code) +#undef USE_PROJECTOR_CTRL // Disable support for LCD/DLP Projector serial control interface //#undef USE_ENERGY_SENSOR // Disable energy sensors #undef USE_PZEM004T // Disable PZEM004T energy sensor @@ -840,6 +846,7 @@ #undef USE_TASMOTA_CLIENT // Disable support for Arduino Uno/Pro Mini via serial interface including flashing (+2k3 code, 44 mem) #undef USE_OPENTHERM // Disable support for OpenTherm (+15k code) #undef USE_MIEL_HVAC // Disable support for Mitsubishi Electric HVAC serial interface (+5k code) +#undef USE_PROJECTOR_CTRL // Disable support for LCD/DLP Projector serial control interface #undef USE_AS608 // Disable support for AS608 optical and R503 capacitive fingerprint sensor (+3k4 code) #undef USE_ENERGY_SENSOR // Disable energy sensors diff --git a/tasmota/tasmota_globals.h b/tasmota/tasmota_globals.h index 9c05574d7..52149943c 100644 --- a/tasmota/tasmota_globals.h +++ b/tasmota/tasmota_globals.h @@ -461,15 +461,13 @@ const char kWebColors[] PROGMEM = #define tmin(a,b) ((a)<(b)?(a):(b)) #define tmax(a,b) ((a)>(b)?(a):(b)) +#define nitems(_a) (sizeof((_a)) / sizeof((_a)[0])) + #define STR_HELPER(x) #x #ifndef STR #define STR(x) STR_HELPER(x) #endif -#ifndef ARRAY_SIZE -#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) -#endif - #define AGPIO(x) ((x)<<5) #define BGPIO(x) ((x)>>5) diff --git a/tasmota/tasmota_template.h b/tasmota/tasmota_template.h index 234a9d690..6d7a0ae8b 100644 --- a/tasmota/tasmota_template.h +++ b/tasmota/tasmota_template.h @@ -150,10 +150,11 @@ enum UserSelectablePins { GPIO_NEOPOOL_TX, GPIO_NEOPOOL_RX, // Sugar Valley RS485 interface GPIO_SDM72_TX, GPIO_SDM72_RX, // SDM72 Serial interface GPIO_TM1637CLK, GPIO_TM1637DIO, // TM1637 interface + GPIO_PROJECTOR_CTRL_TX, GPIO_PROJECTOR_CTRL_RX, // LCD/DLP Projector Serial Control + GPIO_SSD1351_DC, #ifdef USE_XPT2046 GPIO_XPT2046_CS, // XPT2046 SPI Chip Select #endif - GPIO_SENSOR_END }; enum ProgramSelectablePins { @@ -324,6 +325,8 @@ const char kSensorNames[] PROGMEM = D_SENSOR_NEOPOOL_TX "|" D_SENSOR_NEOPOOL_RX "|" D_SENSOR_SDM72_TX "|" D_SENSOR_SDM72_RX "|" D_SENSOR_TM1637_CLK "|" D_SENSOR_TM1637_DIO "|" + D_SENSOR_PROJECTOR_CTRL_TX "|" D_SENSOR_PROJECTOR_CTRL_RX "|" + D_SENSOR_SSD1351_DC "|" D_SENSOR_XPT2046_CS "|" ; @@ -430,6 +433,7 @@ const uint16_t kGpioNiceList[] PROGMEM = { #endif // USE_DISPLAY_EPAPER_42 #ifdef USE_DISPLAY_SSD1351 AGPIO(GPIO_SSD1351_CS), + AGPIO(GPIO_SSD1351_DC), #endif // USE_DISPLAY_SSD1351 #ifdef USE_DISPLAY_RA8876 AGPIO(GPIO_RA8876_CS), @@ -769,7 +773,10 @@ const uint16_t kGpioNiceList[] PROGMEM = { AGPIO(GPIO_NEOPOOL_TX), // Sugar Valley RS485 Interface AGPIO(GPIO_NEOPOOL_RX), // Sugar Valley RS485 Interface #endif - +#ifdef USE_PROJECTOR_CTRL + AGPIO(GPIO_PROJECTOR_CTRL_TX), // LCD/DLP Projector Serial Control + AGPIO(GPIO_PROJECTOR_CTRL_RX), // LCD/DLP Projector Serial Control +#endif /*-------------------------------------------------------------------------------------------*\ * ESP32 specifics \*-------------------------------------------------------------------------------------------*/ diff --git a/tasmota/xdrv_01_webserver.ino b/tasmota/xdrv_01_webserver.ino index 4ded970b9..4595f50a2 100644 --- a/tasmota/xdrv_01_webserver.ino +++ b/tasmota/xdrv_01_webserver.ino @@ -453,7 +453,7 @@ void StartWebserver(int type, IPAddress ipweb) if (!Webserver) { Webserver = new ESP8266WebServer((HTTP_MANAGER == type || HTTP_MANAGER_RESET_ONLY == type) ? 80 : WEB_PORT); // call `Webserver->on()` on each entry - for (uint32_t i=0; iNone (0)}3}2'17'>Button1 (17)}3... + for (uint32_t i = 0; i < nitems(kGpioNiceList); i++) { // GPIO: }2'0'>None (0)}3}2'17'>Button1 (17)}3... if (option && (1 == i)) { WSContentSend_P(HTTP_MODULE_TEMPLATE_REPLACE_NO_INDEX, AGPIO(GPIO_USER), PSTR(D_SENSOR_USER)); // }2'255'>User}3 } @@ -1338,7 +1338,7 @@ void WSContentSendNiceLists(uint32_t option) { WSContentSend_P(PSTR("hs=[")); uint32_t midx; bool first_done = false; - for (uint32_t i = 0; i < ARRAY_SIZE(kGpioNiceList); i++) { // hs=[36,68,100,132,168,200,232,264,292,324,356,388,421,453]; + for (uint32_t i = 0; i < nitems(kGpioNiceList); i++) { // hs=[36,68,100,132,168,200,232,264,292,324,356,388,421,453]; midx = pgm_read_word(kGpioNiceList + i); if (midx & 0x001F) { if (first_done) { WSContentSend_P(PSTR(",")); } @@ -1348,7 +1348,7 @@ void WSContentSendNiceLists(uint32_t option) { } #ifdef ESP8266 #ifdef USE_ADC - for (uint32_t i = 0; i < ARRAY_SIZE(kAdcNiceList); i++) { // hs=[36,68,100,132,168,200,232,264,292,324,356,388,421,453]; + for (uint32_t i = 0; i < nitems(kAdcNiceList); i++) { // hs=[36,68,100,132,168,200,232,264,292,324,356,388,421,453]; midx = pgm_read_word(kAdcNiceList + i); if (midx & 0x001F) { if (first_done) { WSContentSend_P(PSTR(",")); } @@ -1366,7 +1366,7 @@ void WSContentSendNiceLists(uint32_t option) { void WSContentSendAdcNiceList(uint32_t option) { char stemp[30]; // Template number and Sensor name WSContentSend_P(PSTR("os=\"")); - for (uint32_t i = 0; i < ARRAY_SIZE(kAdcNiceList); i++) { // GPIO: }2'0'>None}3}2'17'>Analog}3... + for (uint32_t i = 0; i < nitems(kAdcNiceList); i++) { // GPIO: }2'0'>None}3}2'17'>Analog}3... if (option && (1 == i)) { WSContentSend_P(HTTP_MODULE_TEMPLATE_REPLACE_NO_INDEX, AGPIO(GPIO_USER), PSTR(D_SENSOR_USER)); // }2'15'>User}3 } @@ -1404,7 +1404,7 @@ void HandleTemplateConfiguration(void) WSContentBegin(200, CT_PLAIN); WSContentSend_P(PSTR("%s}1"), AnyModuleName(module).c_str()); // NAME: Generic - for (uint32_t i = 0; i < ARRAY_SIZE(template_gp.io); i++) { // 17,148,29,149,7,255,255,255,138,255,139,255,255 + for (uint32_t i = 0; i < nitems(template_gp.io); i++) { // 17,148,29,149,7,255,255,255,138,255,139,255,255 if (!FlashPin(i)) { WSContentSend_P(PSTR("%s%d"), (i>0)?",":"", template_gp.io[i]); } @@ -1490,7 +1490,7 @@ void TemplateSaveSettings(void) snprintf_P(svalue, sizeof(svalue), PSTR(D_CMND_TEMPLATE " {\"" D_JSON_NAME "\":\"%s\",\"" D_JSON_GPIO "\":["), tmp); uint32_t j = 0; - for (uint32_t i = 0; i < ARRAY_SIZE(Settings.user_template.gp.io); i++) { + for (uint32_t i = 0; i < nitems(Settings.user_template.gp.io); i++) { if (6 == i) { j = 9; } if (8 == i) { j = 12; } snprintf_P(svalue, sizeof(svalue), PSTR("%s%s%d"), svalue, (i>0)?",":"", WebGetGpioArg(j)); @@ -1549,7 +1549,7 @@ void HandleModuleConfiguration(void) WSContentSendNiceLists(0); - for (uint32_t i = 0; i < ARRAY_SIZE(template_gp.io); i++) { + for (uint32_t i = 0; i < nitems(template_gp.io); i++) { if (ValidGPIO(i, template_gp.io[i])) { WSContentSend_P(PSTR("sk(%d,%d);"), TasmotaGlobal.my_module.io[i], i); // g0 - g17 } @@ -1566,7 +1566,7 @@ void HandleModuleConfiguration(void) WSContentSendStyle(); WSContentSend_P(HTTP_FORM_MODULE, AnyModuleName(MODULE).c_str()); - for (uint32_t i = 0; i < ARRAY_SIZE(template_gp.io); i++) { + for (uint32_t i = 0; i < nitems(template_gp.io); i++) { if (ValidGPIO(i, template_gp.io[i])) { snprintf_P(stemp, 3, PINS_WEMOS +i*2); WSContentSend_P(PSTR("%s " D_GPIO "%d"), @@ -1592,7 +1592,7 @@ void ModuleSaveSettings(void) myio template_gp; TemplateGpios(&template_gp); String gpios = ""; - for (uint32_t i = 0; i < ARRAY_SIZE(template_gp.io); i++) { + for (uint32_t i = 0; i < nitems(template_gp.io); i++) { if (Settings.last_module != new_module) { Settings.my_gp.io[i] = GPIO_NONE; } else { diff --git a/tasmota/xdrv_02_mqtt.ino b/tasmota/xdrv_02_mqtt.ino index b90007e44..6be10eb70 100644 --- a/tasmota/xdrv_02_mqtt.ino +++ b/tasmota/xdrv_02_mqtt.ino @@ -33,7 +33,7 @@ WiFiClient EspClient; // Wifi Client - non-TLS const char kMqttCommands[] PROGMEM = "|" // No prefix // SetOption synonyms - D_SO_MQTTJSONONLY "|" + D_SO_MQTTJSONONLY "|" #ifdef USE_MQTT_TLS D_SO_MQTTTLS "|" #endif @@ -195,7 +195,7 @@ void MqttInit(void) { #endif #ifdef USE_MQTT_TLS_CA_CERT - tlsClient->setTrustAnchor(Tasmota_TA, ARRAY_SIZE(Tasmota_TA)); + tlsClient->setTrustAnchor(Tasmota_TA, nitems(Tasmota_TA)); #endif // USE_MQTT_TLS_CA_CERT MqttClient.setClient(*tlsClient); diff --git a/tasmota/xdrv_04_light.ino b/tasmota/xdrv_04_light.ino index 1d78df359..70390e67a 100644 --- a/tasmota/xdrv_04_light.ino +++ b/tasmota/xdrv_04_light.ino @@ -1083,6 +1083,13 @@ void LightCalcPWMRange(void) { //AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("LightCalcPWMRange %d %d - %d %d"), Settings.dimmer_hw_min, Settings.dimmer_hw_max, Light.pwm_min, Light.pwm_max); } +void LightSetScheme(uint32_t scheme) { + if (!scheme && Settings.light_scheme) { + Light.update = true; + } + Settings.light_scheme = scheme; +} + void LightInit(void) { // move white blend mode from deprecated `RGBWWTable` to `SetOption105` @@ -1149,7 +1156,7 @@ void LightInit(void) max_scheme = LS_POWER; } if ((LS_WAKEUP == Settings.light_scheme) || (Settings.light_scheme > max_scheme)) { - Settings.light_scheme = LS_POWER; + LightSetScheme(LS_POWER); } Light.power = 0; Light.update = true; @@ -1308,7 +1315,7 @@ void LightSetSignal(uint16_t lo, uint16_t hi, uint16_t value) uint16_t signal = changeUIntScale(value, lo, hi, 0, 255); // 0..255 // AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_DEBUG "Light signal %d"), signal); light_controller.changeRGB(signal, 255 - signal, 0, true); // keep bri - Settings.light_scheme = 0; + LightSetScheme(LS_POWER); if (0 == light_state.getBri()) { light_controller.changeBri(50); } @@ -1668,7 +1675,7 @@ void LightAnimate(void) MqttPublishPrefixTopicRulesProcess_P(RESULT_OR_STAT, PSTR(D_CMND_WAKEUP)); Light.wakeup_active = 0; - Settings.light_scheme = LS_POWER; + LightSetScheme(LS_POWER); } } break; @@ -2288,7 +2295,7 @@ void LightHandleDevGroupItem(void) uint32_t old_bri = light_state.getBri(); light_controller.changeChannels(Light.entry_color); light_controller.changeBri(old_bri); - Settings.light_scheme = 0; + LightSetScheme(LS_POWER); if (!restore_power && !Light.power) { Light.old_power = Light.power; Light.power = 0xff; @@ -2448,7 +2455,7 @@ void CmndSupportColor(void) #ifdef USE_LIGHT_PALETTE } #endif // USE_LIGHT_PALETTE - Settings.light_scheme = 0; + LightSetScheme(LS_POWER); coldim = true; } else { // Color3, 4, 5 and 6 for (uint32_t i = 0; i < LST_RGB; i++) { @@ -2617,7 +2624,7 @@ void CmndScheme(void) Light.wheel--; #endif // USE_LIGHT_PALETTE } - Settings.light_scheme = XdrvMailbox.payload; + LightSetScheme(XdrvMailbox.payload); if (LS_WAKEUP == Settings.light_scheme) { Light.wakeup_active = 3; } @@ -2640,7 +2647,7 @@ void CmndWakeup(void) light_controller.changeDimmer(XdrvMailbox.payload); } Light.wakeup_active = 3; - Settings.light_scheme = LS_WAKEUP; + LightSetScheme(LS_WAKEUP); LightPowerOn(); ResponseCmndChar(PSTR(D_JSON_STARTED)); } diff --git a/tasmota/xdrv_10_scripter.ino b/tasmota/xdrv_10_scripter.ino index 05fb79050..10a7db17f 100755 --- a/tasmota/xdrv_10_scripter.ino +++ b/tasmota/xdrv_10_scripter.ino @@ -37,11 +37,6 @@ no math hierarchy (costs ram and execution time, better group with brackets, an keywords if then else endif, or, and are better readable for beginners (others may use {}) // to doo -remove all filesystem inititialization and gui -adapt 3 options -1. ufilesystem -2. eeprom hardware and emulation -3. compression \*********************************************************************************************/ @@ -2681,7 +2676,7 @@ chknext: } } */ - if ((gpiopin < ARRAY_SIZE(TasmotaGlobal.gpio_pin)) && (TasmotaGlobal.gpio_pin[gpiopin] > 0)) { + if ((gpiopin < nitems(TasmotaGlobal.gpio_pin)) && (TasmotaGlobal.gpio_pin[gpiopin] > 0)) { fvar = TasmotaGlobal.gpio_pin[gpiopin]; // skip ] bracket len++; @@ -5992,22 +5987,22 @@ bool ScriptMqttData(void) value = sres; } #endif // SUPPORT_MQTT_EVENT_MORE - if (json_valid) { - value.trim(); - char sbuffer[128]; + } + if (json_valid) { + value.trim(); + char sbuffer[128]; - if (!strncmp(lkey.c_str(), "Epoch", 5)) { - uint32_t ep = atoi(value.c_str()) - (uint32_t)EPOCH_OFFSET; - snprintf_P(sbuffer, sizeof(sbuffer), PSTR(">%s=%d\n"), event_item.Event.c_str(), ep); - } else { - snprintf_P(sbuffer, sizeof(sbuffer), PSTR(">%s=\"%s\"\n"), event_item.Event.c_str(), value.c_str()); - } -#ifdef DEBUG_MQTT_EVENT - AddLog(LOG_LEVEL_INFO, PSTR("Script: setting script var %s"), sbuffer); -#endif - //toLog(sbuffer); - execute_script(sbuffer); + if (!strncmp(lkey.c_str(), "Epoch", 5)) { + uint32_t ep = atoi(value.c_str()) - (uint32_t)EPOCH_OFFSET; + snprintf_P(sbuffer, sizeof(sbuffer), PSTR(">%s=%d\n"), event_item.Event.c_str(), ep); + } else { + snprintf_P(sbuffer, sizeof(sbuffer), PSTR(">%s=\"%s\"\n"), event_item.Event.c_str(), value.c_str()); } +#ifdef DEBUG_MQTT_EVENT + AddLog(LOG_LEVEL_INFO, PSTR("Script: setting script var %s"), sbuffer); +#endif + //toLog(sbuffer); + execute_script(sbuffer); } } } @@ -7397,6 +7392,7 @@ int32_t http_req(char *host, char *request) { #include #endif //ESP8266 + // get tesla powerwall info page json string uint32_t call2https(const char *host, const char *path) { if (TasmotaGlobal.global_state.wifi_down) return 1; @@ -7409,9 +7405,29 @@ uint32_t call2https(const char *host, const char *path) { httpsClient = new BearSSL::WiFiClientSecure_light(1024, 1024); #endif - httpsClient->setTimeout(1500); + httpsClient->setTimeout(2000); httpsClient->setInsecure(); +#if 0 + File file = ufsp->open("/tesla.cer", FS_FILE_READ); + uint16_t fsize = 0; + char *cert = 0; + if (file) { + fsize = file.size(); + if (fsize) { + cert = (char*)malloc(fsize +2); + if (cert) { + file.read((uint8_t*)cert, fsize); + file.close(); + httpsClient->setCACert(cert); + } + AddLog(LOG_LEVEL_INFO,PSTR(">>> cert %d"),fsize); + } + } else { + httpsClient->setCACert(root_ca); + } +#endif + uint32_t retry = 0; while ((!httpsClient->connect(host, 443)) && (retry < 5)) { delay(100); @@ -7420,11 +7436,43 @@ uint32_t call2https(const char *host, const char *path) { if (retry == 5) { return 2; } - String request = String("GET ") + path + + AddLog(LOG_LEVEL_INFO,PSTR("connected")); + +String request; +#if 0 + + File file = ufsp->open("/login.txt", FS_FILE_READ); + uint16_t fsize = 0; + char *cert = 0; + if (file) { + fsize = file.size(); + if (fsize) { + cert = (char*)calloc(fsize +2, 1); + if (cert) { + file.read((uint8_t*)cert, fsize); + file.close(); + //httpsClient->setCACert(cert); + } + AddLog(LOG_LEVEL_INFO,PSTR(">>> cert %d"),fsize); + } + } + + request = String("POST ") + "/api/login/Basic" + " HTTP/1.1\r\n" + "Host: " + host + "\r\n" + cert + "\r\n" + "Content-Type: application/json" + "\r\n"; + httpsClient->print(request); + AddLog_P(LOG_LEVEL_INFO,PSTR(">>> post request %s"),(char*)request.c_str()); + + String line = httpsClient->readStringUntil('\n'); + AddLog(LOG_LEVEL_INFO,PSTR(">>> post response 1a %s"),(char*)line.c_str()); + line = httpsClient->readStringUntil('\n'); + AddLog(LOG_LEVEL_INFO,PSTR(">>> post response 1b %s"),(char*)line.c_str()); +#endif + + request = String("GET ") + path + " HTTP/1.1\r\n" + "Host: " + host + "\r\n" + "Connection: close\r\n\r\n"; httpsClient->print(request); +// AddLog_P(LOG_LEVEL_INFO,PSTR(">>> get request %s"),(char*)request.c_str()); while (httpsClient->connected()) { String line = httpsClient->readStringUntil('\n'); @@ -7441,6 +7489,7 @@ uint32_t call2https(const char *host, const char *path) { } httpsClient->stop(); delete httpsClient; +// AddLog(LOG_LEVEL_INFO,PSTR(">>> response 2 %s"),(char*)result.c_str()); Run_Scripter(">jp", 3, (char*)result.c_str()); return 0; } diff --git a/tasmota/xdrv_13_display.ino b/tasmota/xdrv_13_display.ino index 02c0e1d0f..c056f3570 100755 --- a/tasmota/xdrv_13_display.ino +++ b/tasmota/xdrv_13_display.ino @@ -2681,6 +2681,8 @@ uint8_t vbutt=0; #endif if (renderer) { + rotconvert(&pLoc.x, &pLoc.y); + #ifdef USE_M5STACK_CORE2 // handle 3 built in touch buttons uint16_t xcenter = 80; @@ -2701,7 +2703,6 @@ uint8_t vbutt=0; } #endif - rotconvert(&pLoc.x, &pLoc.y); // AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("touch after convert %d - %d"), pLoc.x, pLoc.y); // now must compare with defined buttons diff --git a/tasmota/xdrv_16_tuyamcu.ino b/tasmota/xdrv_16_tuyamcu.ino index fc2cd861c..22eba70f2 100644 --- a/tasmota/xdrv_16_tuyamcu.ino +++ b/tasmota/xdrv_16_tuyamcu.ino @@ -330,11 +330,11 @@ float TuyaAdjustedTemperature(int16_t packetValue, uint8_t res) break; case 3: return (float)packetValue / 1000.0; - break; + break; default: return (float)packetValue; break; - } + } } /*********************************************************************************************\ * Internal Functions @@ -622,10 +622,10 @@ void LightSerialDuty(uint16_t duty, char *hex_char, uint8_t TuyaIdx) dpid = TuyaGetDpId(TUYA_MCU_FUNC_CT); } else { dpid = TuyaGetDpId(TUYA_MCU_FUNC_DIMMER2); } } - + if (Tuya.ignore_dim && Tuya.ignore_dimmer_cmd_timeout < millis()) { Tuya.ignore_dim = false; - } + } if (duty > 0 && !Tuya.ignore_dim && TuyaSerial && dpid > 0) { if (TuyaIdx == 2 && CTLight) { @@ -955,7 +955,7 @@ void TuyaNormalPowerModePacketProcess(void) uint8_t key1_gpio = Tuya.buffer[7]; bool key1_set = false; bool led1_set = false; - for (uint32_t i = 0; i < ARRAY_SIZE(Settings.my_gp.io); i++) { + for (uint32_t i = 0; i < nitems(Settings.my_gp.io); i++) { if (Settings.my_gp.io[i] == AGPIO(GPIO_LED1)) led1_set = true; else if (Settings.my_gp.io[i] == AGPIO(GPIO_KEY1)) key1_set = true; } diff --git a/tasmota/xdrv_23_zigbee_2_devices.ino b/tasmota/xdrv_23_zigbee_2_devices.ino index 6a6b60655..e349691c7 100644 --- a/tasmota/xdrv_23_zigbee_2_devices.ino +++ b/tasmota/xdrv_23_zigbee_2_devices.ino @@ -100,7 +100,7 @@ Z_Data_Type Z_Data::CharToDataType(char c) { if (c == '_') { return Z_Data_Type::Z_Device; } else { - for (uint32_t i=0; iname_offset)) { continue; } // avoid strcasecmp_P() from crashing if (0 == strcasecmp_P(command, Z_strings + pgm_read_word(&converter->name_offset))) { @@ -690,7 +690,7 @@ const __FlashStringHelper* zigbeeFindAttributeByName(const char *command, // const __FlashStringHelper* zigbeeFindAttributeById(uint16_t cluster, uint16_t attr_id, uint8_t *attr_type, int8_t *multiplier) { - for (uint32_t i = 0; i < ARRAY_SIZE(Z_PostProcess); i++) { + for (uint32_t i = 0; i < nitems(Z_PostProcess); i++) { const Z_AttributeConverter *converter = &Z_PostProcess[i]; uint16_t conv_cluster = CxToCluster(pgm_read_byte(&converter->cluster_short)); uint16_t conv_attr_id = pgm_read_word(&converter->attribute); @@ -1458,7 +1458,7 @@ void ZCLFrame::parseReadAttributes(Z_attribute_list& attr_list) { read_attr_ids[i/2] = attrid; // find the attribute name - for (uint32_t i = 0; i < ARRAY_SIZE(Z_PostProcess); i++) { + for (uint32_t i = 0; i < nitems(Z_PostProcess); i++) { const Z_AttributeConverter *converter = &Z_PostProcess[i]; uint16_t conv_cluster = CxToCluster(pgm_read_byte(&converter->cluster_short)); uint16_t conv_attribute = pgm_read_word(&converter->attribute); @@ -1527,7 +1527,7 @@ void ZCLFrame::parseReadConfigAttributes(Z_attribute_list& attr_list) { // find the attribute name int8_t multiplier = 1; - for (uint32_t i = 0; i < ARRAY_SIZE(Z_PostProcess); i++) { + for (uint32_t i = 0; i < nitems(Z_PostProcess); i++) { const Z_AttributeConverter *converter = &Z_PostProcess[i]; uint16_t conv_cluster = CxToCluster(pgm_read_byte(&converter->cluster_short)); uint16_t conv_attribute = pgm_read_word(&converter->attribute); @@ -1997,7 +1997,7 @@ void Z_postProcessAttributes(uint16_t shortaddr, uint16_t src_ep, class Z_attrib uint8_t map_offset = 0; uint8_t zigbee_type = Znodata; int8_t conv_multiplier; - for (uint32_t i = 0; i < ARRAY_SIZE(Z_PostProcess); i++) { + for (uint32_t i = 0; i < nitems(Z_PostProcess); i++) { const Z_AttributeConverter *converter = &Z_PostProcess[i]; uint16_t conv_cluster = CxToCluster(pgm_read_byte(&converter->cluster_short)); uint16_t conv_attribute = pgm_read_word(&converter->attribute); @@ -2088,7 +2088,7 @@ void Z_postProcessAttributes(uint16_t shortaddr, uint16_t src_ep, class Z_attrib // Internal search function void Z_parseAttributeKey_inner(class Z_attribute & attr, uint16_t preferred_cluster) { // scan attributes to find by name, and retrieve type - for (uint32_t i = 0; i < ARRAY_SIZE(Z_PostProcess); i++) { + for (uint32_t i = 0; i < nitems(Z_PostProcess); i++) { const Z_AttributeConverter *converter = &Z_PostProcess[i]; uint16_t local_attr_id = pgm_read_word(&converter->attribute); uint16_t local_cluster_id = CxToCluster(pgm_read_byte(&converter->cluster_short)); @@ -2177,7 +2177,7 @@ bool Z_parseAttributeKey(class Z_attribute & attr, uint16_t preferred_cluster) { void Z_Data::toAttributes(Z_attribute_list & attr_list) const { Z_Data_Type type = getType(); // iterate through attributes to see which ones need to be exported - for (uint32_t i = 0; i < ARRAY_SIZE(Z_PostProcess); i++) { + for (uint32_t i = 0; i < nitems(Z_PostProcess); i++) { const Z_AttributeConverter *converter = &Z_PostProcess[i]; uint8_t conv_export = pgm_read_byte(&converter->multiplier_idx) & Z_EXPORT_DATA; uint8_t conv_mapping = pgm_read_byte(&converter->mapping); diff --git a/tasmota/xdrv_23_zigbee_7_0_statemachine.ino b/tasmota/xdrv_23_zigbee_7_0_statemachine.ino index bb50d300c..a9afb9764 100644 --- a/tasmota/xdrv_23_zigbee_7_0_statemachine.ino +++ b/tasmota/xdrv_23_zigbee_7_0_statemachine.ino @@ -438,7 +438,7 @@ static const Zigbee_Instruction zb_prog[] PROGMEM = { ZI_SEND(ZBS_PFGK) // check PFGK on ZB1.2 ZI_WAIT_RECV(1000, ZBR_PFGK) ZI_GOTO(ZIGBEE_LABEL_START_COORD) - + ZI_LABEL(ZIGBEE_LABEL_ZB3_INIT) ZI_SEND(ZBS_PFGK3) // check PFGK on ZB3 ZI_WAIT_RECV(1000, ZBR_PFGK3) @@ -947,7 +947,7 @@ void ZigbeeGotoLabel(uint8_t label) { uint8_t cur_d8 = 0; uint8_t cur_instr_len = 1; // size of current instruction in words - for (uint32_t i = 0; i < ARRAY_SIZE(zb_prog); i += cur_instr_len) { + for (uint32_t i = 0; i < nitems(zb_prog); i += cur_instr_len) { const Zigbee_Instruction *cur_instr_line = &zb_prog[i]; cur_instr = pgm_read_byte(&cur_instr_line->i.i); cur_d8 = pgm_read_byte(&cur_instr_line->i.d8); @@ -1006,7 +1006,7 @@ void ZigbeeStateMachine_Run(void) { zigbee.recv_until = false; zigbee.state_no_timeout = false; // reset the no_timeout for next instruction - if (zigbee.pc > ARRAY_SIZE(zb_prog)) { + if (zigbee.pc > nitems(zb_prog)) { AddLog(LOG_LEVEL_ERROR, PSTR(D_LOG_ZIGBEE "Invalid pc: %d, aborting"), zigbee.pc); zigbee.pc = -1; } diff --git a/tasmota/xdrv_23_zigbee_8_parsers.ino b/tasmota/xdrv_23_zigbee_8_parsers.ino index 04fed0f57..39db75771 100644 --- a/tasmota/xdrv_23_zigbee_8_parsers.ino +++ b/tasmota/xdrv_23_zigbee_8_parsers.ino @@ -207,7 +207,7 @@ void EnergyScanResults(void) { uint32_t bars = changeUIntScale(energy_unsigned, bar_min + 0x80, bar_max + 0x80, 0, bar_count); for (uint32_t j = 0; j < bars; j++) { bar_str[j] = '#'; } bar_str[bars] = 0; - + AddLog(LOG_LEVEL_INFO, PSTR(D_LOG_ZIGBEE "Channel %2d: %s"), i + USE_ZIGBEE_CHANNEL_MIN, bar_str); } ResponseAppend_P(PSTR("]}")); @@ -667,7 +667,7 @@ const uint8_t Z_bindings[] PROGMEM = { int32_t Z_ClusterToCxBinding(uint16_t cluster) { uint8_t cx = ClusterToCx(cluster); - for (uint32_t i=0; i 0xFEFF) ? uxy[i] : 0xFEFF; } diff --git a/tasmota/xdrv_23_zigbee_A_impl.ino b/tasmota/xdrv_23_zigbee_A_impl.ino index 870315055..fc8bfdc3c 100644 --- a/tasmota/xdrv_23_zigbee_A_impl.ino +++ b/tasmota/xdrv_23_zigbee_A_impl.ino @@ -622,7 +622,7 @@ void ZbSendRead(JsonParserToken val_attr, ZCLMessage & zcl) { bool found = false; // scan attributes to find by name, and retrieve type - for (uint32_t i = 0; i < ARRAY_SIZE(Z_PostProcess); i++) { + for (uint32_t i = 0; i < nitems(Z_PostProcess); i++) { const Z_AttributeConverter *converter = &Z_PostProcess[i]; uint16_t local_attr_id = pgm_read_word(&converter->attribute); uint16_t local_cluster_id = CxToCluster(pgm_read_byte(&converter->cluster_short)); @@ -1463,7 +1463,7 @@ void CmndZbPermitJoin(void) { } if (0 == zigbee.permit_end_time) { zigbee.permit_end_time = 1; } // avoid very rare case where timer collides with timestamp equals to zero } - + ResponseCmndDone(); } diff --git a/tasmota/xdrv_41_tcp_bridge.ino b/tasmota/xdrv_41_tcp_bridge.ino index aeadfde61..44a686e77 100644 --- a/tasmota/xdrv_41_tcp_bridge.ino +++ b/tasmota/xdrv_41_tcp_bridge.ino @@ -62,15 +62,15 @@ void TCPLoop(void) if ((server_tcp) && (server_tcp->hasClient())) { // find an empty slot uint32_t i; - for (i=0; iavailable(); break; } } - if (i >= ARRAY_SIZE(client_tcp)) { - i = client_next++ % ARRAY_SIZE(client_tcp); + if (i >= nitems(client_tcp)) { + i = client_next++ % nitems(client_tcp); WiFiClient &client = client_tcp[i]; client.stop(); client = server_tcp->available(); @@ -92,14 +92,14 @@ void TCPLoop(void) if (buf_len > 0) { AddLog_P(LOG_LEVEL_DEBUG, PSTR(D_LOG_TCP "from MCU: %*_H"), buf_len, tcp_buf); - for (uint32_t i=0; i + Written with the gifts I got from Jesus. + + 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 . +*/ + +#ifdef USE_PROJECTOR_CTRL +/*********************************************************************************************\ + * LCD/DLP Projector Control via serial interface + * https://www.sharpnecdisplays.eu/p/download/v/5e14a015e26cacae3ae64a422f7f8af4/cp/Products/Projectors/Shared/CommandLists/PDF-ExternalControlManual-english.pdf#page=5 + * https://www.optoma.co.uk/uploads/manuals/hd36-m-en-gb.pdf#page=56 +\*********************************************************************************************/ + +#define XDRV_53 53 + +#ifndef USE_PROJECTOR_CTRL_NEC +#define USE_PROJECTOR_CTRL_NEC // Use at least one projector +#endif + +#define nitems(_a) (sizeof((_a)) / sizeof((_a)[0])) +#define xxstr(s) xstr(s) +#define xstr(s) #s + +enum projector_ctrl_dev_state_e : uint8_t { + PROJECTOR_CTRL_DEV_UNKNOWN=0, + PROJECTOR_CTRL_DEV_PWR_OFF, + PROJECTOR_CTRL_DEV_PWR_ON +}; + +enum projector_ctrl_serial_state_e : uint8_t { + PROJECTOR_CTRL_S_UNCONNECTED=0, + PROJECTOR_CTRL_S_QRY_PWR, + PROJECTOR_CTRL_S_QRY_TYPE, + PROJECTOR_CTRL_S_IDLE, + PROJECTOR_CTRL_S_PWR_ON, + PROJECTOR_CTRL_S_PWR_OFF +}; + +enum projector_ctrl_serial_result_e : uint8_t { + PROJECTOR_CTRL_R_UNKNOWN=0, + PROJECTOR_CTRL_R_PASS, + PROJECTOR_CTRL_R_FAIL +}; + +struct projector_ctrl_command_info_s { + const enum projector_ctrl_serial_state_e command; + const uint8_t *send_codes; + const uint8_t send_len; + const uint8_t timeout_ticks; + const uint8_t pass_first_byte; + const uint8_t pass_len; + const uint8_t pass_value_offset; + const uint8_t pass_value_bytes; + const uint8_t fail_first_byte; + const uint8_t fail_len; + const uint8_t fail_value_offset; + const uint8_t fail_value_bytes; +} __packed; + +#include "xdrv_53_projector_ctrl.h" + +struct projector_ctrl_softc_s { + TasmotaSerial *sc_serial; + uint8_t sc_device; + uint8_t sc_ticks; + enum projector_ctrl_dev_state_e sc_dev_state; + enum projector_ctrl_serial_state_e sc_ser_state; + enum projector_ctrl_serial_result_e sc_ser_result; + enum projector_ctrl_serial_state_e sc_ser_next_cmd; + const struct projector_ctrl_command_info_s *sc_cmd_info; + uint8_t sc_ser_sum; + uint8_t sc_ser_len; + uint32_t sc_ser_value; +} __packed; + +static struct projector_ctrl_softc_s *projector_ctrl_sc = nullptr; + + + +static void +projector_ctrl_pre_init(void) +{ + struct projector_ctrl_softc_s *sc; + int baudrate = PROJECTOR_CTRL_SERIAL_BAUDRATE; + + if (!PinUsed(GPIO_PROJECTOR_CTRL_TX) || !PinUsed(GPIO_PROJECTOR_CTRL_RX)) + return; + + sc = (struct projector_ctrl_softc_s *)malloc(sizeof(*sc)); + if (sc == NULL) { + AddLog_P(LOG_LEVEL_ERROR, PSTR(PROJECTOR_CTRL_LOGNAME ": unable to allocate state")); + return; + } + + memset(sc, 0, sizeof(*sc)); + + sc->sc_serial = new TasmotaSerial(Pin(GPIO_PROJECTOR_CTRL_RX), + Pin(GPIO_PROJECTOR_CTRL_TX), 2); + + if (!sc->sc_serial->begin(baudrate, 2)) { + AddLog_P(LOG_LEVEL_ERROR, PSTR(PROJECTOR_CTRL_LOGNAME ": unable to begin serial " + "(baudrate %d)"), baudrate); + goto del; + } + + if (sc->sc_serial->hardwareSerial()) { + ClaimSerial(); + SetSerial(baudrate, TS_SERIAL_8N1); + } + + sc->sc_device = ++(TasmotaGlobal.devices_present); /* claim a POWER device slot */ + + AddLog_P(LOG_LEVEL_INFO, PSTR(PROJECTOR_CTRL_LOGNAME ": new RELAY%d, polling serial for Projector status"), sc->sc_device); + + projector_ctrl_sc = sc; + return; +del: + delete sc->sc_serial; +free: + free(sc); +} + + + +static void +projector_ctrl_write(struct projector_ctrl_softc_s *sc, const uint8_t *bytes, const size_t len) +{ + TasmotaSerial *serial; + uint8_t cksum; + size_t i; + + cksum = 0; + serial = sc->sc_serial; + + for (i = 0; i < len; i++) { + uint8_t b = bytes[i]; + serial->write(b); + cksum += b; + } +#ifdef USE_PROJECTOR_CTRL_NEC + serial->write(cksum); +#endif +#ifdef DEBUG_PROJECTOR_CTRL + char hex_b[(len + 1) * 2]; + AddLog_P(LOG_LEVEL_DEBUG,PSTR(PROJECTOR_CTRL_LOGNAME ": RAW bytes %s %02x"), + ToHex_P((uint8_t *)bytes, len, hex_b, sizeof(hex_b)), cksum); +#endif //DEBUG_PROJECTOR_CTRL + + serial->flush(); + return; +} + + + +static void +projector_ctrl_request(struct projector_ctrl_softc_s *sc, const uint8_t command) +{ + const struct projector_ctrl_command_info_s *e; + size_t i; + + if ((sc->sc_dev_state!=PROJECTOR_CTRL_DEV_UNKNOWN)&&(sc->sc_ser_state!=PROJECTOR_CTRL_S_IDLE)) { + if ((command!=PROJECTOR_CTRL_S_QRY_PWR)&&(command!=PROJECTOR_CTRL_S_QRY_TYPE)) { + sc->sc_ser_next_cmd=(projector_ctrl_serial_state_e)command; + AddLog_P(LOG_LEVEL_INFO, PSTR(PROJECTOR_CTRL_LOGNAME + ": Serial CMD %02x already running, enqueueing next (%02x)"), sc->sc_ser_state, command); + }; + return; + }; + + for (i = 0; i < nitems(projector_ctrl_commands); i++) { + e = &projector_ctrl_commands[i]; + if (command == e->command){ + sc->sc_cmd_info=e; + sc->sc_ser_len=0; + sc->sc_ser_result=PROJECTOR_CTRL_R_UNKNOWN; + sc->sc_ser_state=(projector_ctrl_serial_state_e)command; + sc->sc_ser_sum=0; + sc->sc_ser_next_cmd=PROJECTOR_CTRL_S_UNCONNECTED; + sc->sc_ticks=0; +#ifdef DEBUG_PROJECTOR_CTRL + AddLog_P(LOG_LEVEL_DEBUG, PSTR(PROJECTOR_CTRL_LOGNAME + ": Sending CMD %02x"), command); +#endif //DEBUG_PROJECTOR_CTRL + projector_ctrl_write(sc,e->send_codes,e->send_len); + return; + } + }; +#ifdef DEBUG_PROJECTOR_CTRL + AddLog_P(LOG_LEVEL_DEBUG, PSTR(PROJECTOR_CTRL_LOGNAME + ": Undefined serial command %02x"), command); +#endif //DEBUG_PROJECTOR_CTRL + return; +} + + + +static uint8_t +projector_ctrl_parse(struct projector_ctrl_softc_s *sc, const uint8_t byte) +{ + enum projector_ctrl_serial_state_e nstate; + const struct projector_ctrl_command_info_s *cmd; + + nstate = sc->sc_ser_state; + + switch (nstate) { + case PROJECTOR_CTRL_S_IDLE: + case PROJECTOR_CTRL_S_UNCONNECTED: +#ifdef DEBUG_PROJECTOR_CTRL + AddLog_P(LOG_LEVEL_DEBUG, PSTR(PROJECTOR_CTRL_LOGNAME + ": Spurious input in state %02x, got %02x, going UNCONNECTED"), nstate, byte); +#endif //DEBUG_PROJECTOR_CTRL + return(PROJECTOR_CTRL_S_UNCONNECTED); + + default: + cmd=sc->sc_cmd_info; + sc->sc_ser_len++; + if (sc->sc_ser_len==1) { + if (byte==cmd->pass_first_byte){ + sc->sc_ser_result=PROJECTOR_CTRL_R_PASS; +#ifdef DEBUG_PROJECTOR_CTRL + AddLog_P(LOG_LEVEL_DEBUG, PSTR(PROJECTOR_CTRL_LOGNAME + ": CMD %02x PASS, 1st byte %02x"), nstate, byte); +#endif //DEBUG_PROJECTOR_CTRL + }else if (byte==cmd->fail_first_byte){ + sc->sc_ser_result=PROJECTOR_CTRL_R_FAIL; +#ifdef DEBUG_PROJECTOR_CTRL + AddLog_P(LOG_LEVEL_DEBUG, PSTR(PROJECTOR_CTRL_LOGNAME + ": CMD %02x FAIL, 1st byte %02x"), nstate, byte); +#endif //DEBUG_PROJECTOR_CTRL + }else{ +#ifdef DEBUG_PROJECTOR_CTRL + AddLog_P(LOG_LEVEL_DEBUG, PSTR(PROJECTOR_CTRL_LOGNAME + ": CMD %02x UNKNOWN, 1st byte %02x, going UNCONNECTED"), nstate, byte); +#endif //DEBUG_PROJECTOR_CTRL + return(PROJECTOR_CTRL_S_UNCONNECTED); + }; + }; + if (sc->sc_ser_result==PROJECTOR_CTRL_R_PASS){ + if (sc->sc_ser_len==(cmd->pass_value_offset+1)) + sc->sc_ser_value=byte; + if ((sc->sc_ser_len>(cmd->pass_value_offset+1))&&(sc->sc_ser_len<=(cmd->pass_value_offset+cmd->pass_value_bytes))) + sc->sc_ser_value=(sc->sc_ser_value<<8)|byte; + if (sc->sc_ser_len==cmd->pass_len){ +#ifdef USE_PROJECTOR_CTRL_NEC + if(sc->sc_ser_sum!=byte){ +#ifdef DEBUG_PROJECTOR_CTRL + AddLog_P(LOG_LEVEL_DEBUG, PSTR(PROJECTOR_CTRL_LOGNAME + ": Failed cksum for CMD %02x. Got %02x bytes, computed cksum: %02x, recevied cksum: %02x, going UNCONNECTED"), + nstate, sc->sc_ser_len, sc->sc_ser_sum, byte); +#endif //DEBUG_PROJECTOR_CTRL + nstate=PROJECTOR_CTRL_S_UNCONNECTED; + } else +#endif //USE_PROJECTOR_CTRL_NEC + { +#ifdef DEBUG_PROJECTOR_CTRL + AddLog_P(LOG_LEVEL_DEBUG, PSTR(PROJECTOR_CTRL_LOGNAME + ": CMD %02x PASS, got %02x bytes, retval %02x, going IDLE"), nstate, sc->sc_ser_len, sc->sc_ser_value); +#endif //DEBUG_PROJECTOR_CTRL + nstate=PROJECTOR_CTRL_S_IDLE; + }; + }; + }; + + if (sc->sc_ser_result==PROJECTOR_CTRL_R_FAIL) { + if (sc->sc_ser_len==(cmd->fail_value_offset+1)) + sc->sc_ser_value=byte; + if ((sc->sc_ser_len>(cmd->fail_value_offset+1))&&(sc->sc_ser_len<=(cmd->fail_value_offset+cmd->fail_value_bytes))) + sc->sc_ser_value=(sc->sc_ser_value<<8)|byte; + if(sc->sc_ser_len==cmd->fail_len){ +#ifdef USE_PROJECTOR_CTRL_NEC + if(sc->sc_ser_sum!=byte){ +#ifdef DEBUG_PROJECTOR_CTRL + AddLog_P(LOG_LEVEL_DEBUG, PSTR(PROJECTOR_CTRL_LOGNAME + ": Failed cksum for CMD %02x. Got %02x bytes, computed cksum: %02x, receied cksum: %02x, going UNCONNECTED"), + nstate, sc->sc_ser_len, sc->sc_ser_sum, byte); +#endif //DEBUG_PROJECTOR_CTRL + nstate=PROJECTOR_CTRL_S_UNCONNECTED; + } else +#endif //USE_PROJECTOR_CTRL_NEC + { +#ifdef DEBUG_PROJECTOR_CTRL + AddLog_P(LOG_LEVEL_DEBUG, PSTR(PROJECTOR_CTRL_LOGNAME + ": CMD %02x FAIL, got %02x bytes, retval %02x, going idle"), nstate, sc->sc_ser_len, sc->sc_ser_value); +#endif //DEBUG_PROJECTOR_CTRL + nstate=PROJECTOR_CTRL_S_IDLE; + }; + }; + }; + +#ifdef USE_PROJECTOR_CTRL_NEC + sc->sc_ser_sum += byte; +#endif //USE_PROJECTOR_CTRL_NEC + + break; + } + return (nstate); +} + + + +static void +projector_ctrl_loop(struct projector_ctrl_softc_s *sc) +{ + TasmotaSerial *serial; + uint8_t oldstate; + serial = sc->sc_serial; + + while (serial->available()) { + yield(); + oldstate = sc->sc_ser_state; + switch (sc->sc_ser_state = (projector_ctrl_serial_state_e)projector_ctrl_parse(sc, serial->read())) { + case PROJECTOR_CTRL_S_UNCONNECTED: + sc->sc_dev_state=PROJECTOR_CTRL_DEV_UNKNOWN; + break; + case PROJECTOR_CTRL_S_IDLE: + if ((oldstate==PROJECTOR_CTRL_S_QRY_PWR)&&(sc->sc_ser_result==PROJECTOR_CTRL_R_PASS)){ + if(((sc->sc_ser_value==PROJECTOR_CTRL_QRYPWR_ON)||(sc->sc_ser_value==PROJECTOR_CTRL_QRYPWR_COOLING))&&(sc->sc_dev_state!=PROJECTOR_CTRL_DEV_PWR_ON)){ + sc->sc_dev_state=PROJECTOR_CTRL_DEV_PWR_ON; + ExecuteCommandPower(sc->sc_device, POWER_ON, SRC_IGNORE); + }; + if(((sc->sc_ser_value!=PROJECTOR_CTRL_QRYPWR_ON)&&(sc->sc_ser_value!=PROJECTOR_CTRL_QRYPWR_COOLING))&&(sc->sc_dev_state!=PROJECTOR_CTRL_DEV_PWR_OFF)){ + sc->sc_dev_state=PROJECTOR_CTRL_DEV_PWR_OFF; + ExecuteCommandPower(sc->sc_device, POWER_OFF, SRC_IGNORE); + }; + }; + if ((oldstate==PROJECTOR_CTRL_S_PWR_ON)&&(sc->sc_ser_result==PROJECTOR_CTRL_R_PASS)) + sc->sc_dev_state=PROJECTOR_CTRL_DEV_PWR_ON; + if ((oldstate==PROJECTOR_CTRL_S_PWR_OFF)&&(sc->sc_ser_result==PROJECTOR_CTRL_R_PASS)) + sc->sc_dev_state=PROJECTOR_CTRL_DEV_PWR_OFF; + if(sc->sc_ser_next_cmd!=PROJECTOR_CTRL_S_UNCONNECTED){ + oldstate=sc->sc_ser_next_cmd; + sc->sc_ser_next_cmd=PROJECTOR_CTRL_S_UNCONNECTED; + projector_ctrl_request(sc,oldstate); + }; + break; + }; + } +} + + + +static void +projector_ctrl_connect(struct projector_ctrl_softc_s *sc) +{ + projector_ctrl_request(sc,PROJECTOR_CTRL_S_QRY_PWR); +} + + + +static void +projector_ctrl_tick(struct projector_ctrl_softc_s *sc) +{ + if(sc->sc_ser_state==PROJECTOR_CTRL_S_IDLE){ + switch (TasmotaGlobal.uptime&0xf) { + case 0: + projector_ctrl_request(sc,PROJECTOR_CTRL_S_QRY_PWR); + break; + case 8: + projector_ctrl_request(sc,PROJECTOR_CTRL_S_QRY_TYPE); + break; + }; + }else if(sc->sc_ticks > sc->sc_cmd_info->timeout_ticks){ + //current CMD has ran out of time, drop connection + AddLog_P(LOG_LEVEL_INFO,PSTR(PROJECTOR_CTRL_LOGNAME ": DISCONNECTED")); + sc->sc_dev_state=PROJECTOR_CTRL_DEV_UNKNOWN; + sc->sc_ser_state=PROJECTOR_CTRL_S_UNCONNECTED; + }; +} + + + +static bool +projector_ctrl_set_power(struct projector_ctrl_softc_s *sc) +{ + if (TasmotaGlobal.active_device==PROJECTOR_CTRL_PWR_BY_RELAY){ + if ((sc->sc_dev_state == PROJECTOR_CTRL_DEV_PWR_ON) && (0==bitRead(XdrvMailbox.index, PROJECTOR_CTRL_PWR_BY_RELAY -1))) { + TasmotaGlobal.power = bitSet(TasmotaGlobal.power,PROJECTOR_CTRL_PWR_BY_RELAY -1); + AddLog_P(LOG_LEVEL_INFO,PSTR(PROJECTOR_CTRL_LOGNAME ": Keep RELAY" xxstr(PROJECTOR_CTRL_PWR_BY_RELAY) " ON")); + } else { + return(false); + }; + } else if (TasmotaGlobal.active_device==sc->sc_device){ + if (bitRead(XdrvMailbox.index, sc->sc_device -1)) { + switch (sc->sc_dev_state) { + case PROJECTOR_CTRL_DEV_UNKNOWN: + TasmotaGlobal.power = bitClear(TasmotaGlobal.power,sc->sc_device -1); + break; + case PROJECTOR_CTRL_DEV_PWR_OFF: + projector_ctrl_request(sc,PROJECTOR_CTRL_S_PWR_ON); + break; + }; + }else{ + if (sc->sc_dev_state == PROJECTOR_CTRL_DEV_PWR_ON) + projector_ctrl_request(sc,PROJECTOR_CTRL_S_PWR_OFF); + }; + } else { + return(false); + }; + return (true); +} + + +/*********************************************************************************************\ + * Interface +\*********************************************************************************************/ + +bool Xdrv53(uint8_t function) { + bool result; + struct projector_ctrl_softc_s *sc; + + result = false; + sc = projector_ctrl_sc; + + switch (function) { + case FUNC_PRE_INIT: + projector_ctrl_pre_init(); + return (false); + } + + if (sc == NULL) + return (false); + + switch (function) { + case FUNC_LOOP: + projector_ctrl_loop(sc); + break; + + case FUNC_EVERY_SECOND: + sc->sc_ticks++; + if (sc->sc_dev_state!=PROJECTOR_CTRL_DEV_UNKNOWN) + projector_ctrl_tick(sc); + else if ((TasmotaGlobal.uptime&0x7)==0) //each 8 seconds + projector_ctrl_connect(sc); + break; + + case FUNC_SET_DEVICE_POWER: + result = projector_ctrl_set_power(sc); + break; + + } + + return (result); +} + +#endif // USE_PROJECTOR_CTRL \ No newline at end of file diff --git a/tasmota/xdsp_04_ili9341.ino b/tasmota/xdsp_04_ili9341.ino index e8dc5e224..b5c36d1e4 100644 --- a/tasmota/xdsp_04_ili9341.ino +++ b/tasmota/xdsp_04_ili9341.ino @@ -167,7 +167,6 @@ void ili9342_dimm(uint8_t dim) { #endif } -//#ifdef ESP32 #if defined(USE_FT5206) || defined(USE_XPT2046) #ifdef USE_TOUCH_BUTTONS @@ -225,7 +224,7 @@ int16_t temp; *x = renderer->height() - temp; break; } -// AddLog(LOG_LEVEL_DEBUG_MORE, PSTR(" TS: after convert x:%d / y:%d screen r:%d / w:%d / h:%d"), *x, *y,rot,renderer->width(),renderer->height()); + AddLog(LOG_LEVEL_DEBUG_MORE, PSTR(" TS: after convert x:%d / y:%d screen r:%d / w:%d / h:%d"), *x, *y,rot,renderer->width(),renderer->height()); } } #endif @@ -242,7 +241,6 @@ ili9342_ctouch_counter++; } #endif // USE_TOUCH_BUTTONS #endif // USE_FT5206 -//#endif // ESP32 #ifdef USE_DISPLAY_MODES1TO5 diff --git a/tasmota/xdsp_09_SSD1351.ino b/tasmota/xdsp_09_SSD1351.ino index 0a1957e3a..2b6301449 100644 --- a/tasmota/xdsp_09_SSD1351.ino +++ b/tasmota/xdsp_09_SSD1351.ino @@ -61,10 +61,10 @@ void SSD1351_InitDriver() { // init renderer if (TasmotaGlobal.soft_spi_enabled){ - ssd1351 = new SSD1351(Pin(GPIO_SSD1351_CS), Pin(GPIO_SSPI_MOSI), Pin(GPIO_SSPI_SCLK)); + ssd1351 = new SSD1351(Pin(GPIO_SSD1351_CS), Pin(GPIO_SSPI_MOSI), Pin(GPIO_SSPI_SCLK), Pin(GPIO_SSD1351_DC)); } else if (TasmotaGlobal.spi_enabled) { - ssd1351 = new SSD1351(Pin(GPIO_SSD1351_CS), Pin(GPIO_SPI_MOSI), Pin(GPIO_SPI_CLK)); + ssd1351 = new SSD1351(Pin(GPIO_SSD1351_CS), Pin(GPIO_SPI_MOSI), Pin(GPIO_SPI_CLK), Pin(GPIO_SSD1351_DC)); } delay(100); diff --git a/tasmota/xnrg_18_sdm72.ino b/tasmota/xnrg_18_sdm72.ino index 0da11cba3..defcd8f0e 100644 --- a/tasmota/xnrg_18_sdm72.ino +++ b/tasmota/xnrg_18_sdm72.ino @@ -110,7 +110,7 @@ void Sdm72Every250ms(void) #endif // SDM72_IMPEXP } - ++Sdm72.read_state %= ARRAY_SIZE(sdm72_register); + ++Sdm72.read_state %= nitems(sdm72_register); if (0 == Sdm72.read_state && !isnan(Sdm72.total_active)) { EnergyUpdateTotal(Sdm72.total_active, true); } diff --git a/tasmota/xsns_53_sml.ino b/tasmota/xsns_53_sml.ino index 88305d03d..ef7c1ef88 100755 --- a/tasmota/xsns_53_sml.ino +++ b/tasmota/xsns_53_sml.ino @@ -1296,6 +1296,7 @@ void sml_shift_in(uint32_t meters,uint32_t shard) { } } else if (meter_desc_p[meters].type=='v') { if (iob==EBUS_SYNC) { + sb_counter = 0; SML_Decode(meters); smltbuf[meters][0] = iob; meter_spos[meters] = 1; @@ -1322,7 +1323,7 @@ void sml_shift_in(uint32_t meters,uint32_t shard) { //AddLog(LOG_LEVEL_INFO, PSTR("ebus crc error")); } } - meter_spos[meters]=0; + meter_spos[meters] = 0; return; } smltbuf[meters][meter_spos[meters]] = iob; @@ -1383,18 +1384,19 @@ void SML_Decode(uint8_t index) { const char *mp=(const char*)meter_p; int8_t mindex; uint8_t *cp; - uint8_t dindex=0,vindex=0; + uint8_t dindex = 0, vindex = 0; delay(0); + while (mp != NULL) { // check list of defines - if (*mp==0) break; + if (*mp == 0) break; // new section - mindex=((*mp)&7)-1; + mindex = ((*mp) & 7) - 1; - if (mindex<0 || mindex>=meters_used) mindex=0; - mp+=2; - if (*mp=='=' && *(mp+1)=='h') { + if (mindex < 0 || mindex >= meters_used) mindex = 0; + mp += 2; + if (*mp == '=' && *(mp+1) == 'h') { mp = strchr(mp, '|'); if (mp) mp++; continue; @@ -1403,98 +1405,103 @@ void SML_Decode(uint8_t index) { if (index!=mindex) goto nextsect; // start of serial source buffer - cp=&smltbuf[mindex][0]; + cp = &smltbuf[mindex][0]; // compare - if (*mp=='=') { + if (*mp == '=') { // calculated entry, check syntax mp++; // do math m 1+2+3 - if (*mp=='m' && !sb_counter) { + if (*mp == 'm' && !sb_counter) { // only every 256 th byte // else it would be calculated every single serial byte mp++; - while (*mp==' ') mp++; + while (*mp == ' ') mp++; // 1. index double dvar; uint8_t opr; - uint32_t ind; - ind=atoi(mp); - while (*mp>='0' && *mp<='9') mp++; - if (ind<1 || ind>SML_MAX_VARS) ind=1; - dvar=meter_vars[ind-1]; - for (uint8_t p = 0; p < 5; p++) { - if (*mp=='@') { + uint8_t mind; + int32_t ind; + mind = strtol((char*)mp, (char**)&mp, 10); + if (mind < 1 || mind > SML_MAX_VARS) mind = 1; + dvar = meter_vars[mind - 1]; + while (*mp==' ') mp++; + for (uint8_t p = 0; p < 8; p++) { + if (*mp == '@') { // store result - meter_vars[vindex]=dvar; + meter_vars[vindex] = dvar; mp++; - SML_Immediate_MQTT((const char*)mp,vindex,mindex); break; } - opr=*mp; + opr = *mp; mp++; - uint8_t iflg=0; - if (*mp=='#') { - iflg=1; + uint8_t iflg = 0; + if (*mp == '#') { + iflg = 1; mp++; } - ind=atoi(mp); - while (*mp>='0' && *mp<='9') mp++; - if (ind<1 || ind>SML_MAX_VARS) ind=1; + ind = strtol((char*)mp, (char**)&mp, 10); + mind = ind; + if (mind < 1 || mind > SML_MAX_VARS) mind = 1; switch (opr) { case '+': - if (iflg) dvar+=ind; - else dvar+=meter_vars[ind-1]; + if (iflg) dvar += ind; + else dvar += meter_vars[mind - 1]; break; case '-': - if (iflg) dvar-=ind; - else dvar-=meter_vars[ind-1]; + if (iflg) dvar -= ind; + else dvar -= meter_vars[mind - 1]; break; case '*': - if (iflg) dvar*=ind; - else dvar*=meter_vars[ind-1]; + if (iflg) dvar *= ind; + else dvar *= meter_vars[mind - 1]; break; case '/': - if (iflg) dvar/=ind; - else dvar/=meter_vars[ind-1]; + if (iflg) dvar /= ind; + else dvar /= meter_vars[mind - 1]; break; } while (*mp==' ') mp++; - if (*mp=='@') { + if (*mp == '@') { // store result - meter_vars[vindex]=dvar; + meter_vars[vindex] = dvar; mp++; - SML_Immediate_MQTT((const char*)mp,vindex,mindex); break; } } + double fac = CharToDouble((char*)mp); + meter_vars[vindex] /= fac; + SML_Immediate_MQTT((const char*)mp, vindex, mindex); + // get sfac } else if (*mp=='d') { // calc deltas d ind 10 (eg every 10 secs) - if (dindex='0' && *mp<='9') mp++; - if (ind<1 || ind>SML_MAX_VARS) ind=1; - uint32_t delay=atoi(mp)*1000; - uint32_t dtime=millis()-dtimes[dindex]; - if (dtime>delay) { + while (*mp == ' ') mp++; + uint8_t ind = atoi(mp); + while (*mp >= '0' && *mp <= '9') mp++; + if (ind < 1 || ind > SML_MAX_VARS) ind = 1; + uint32_t delay = atoi(mp) * 1000; + uint32_t dtime = millis() - dtimes[dindex]; + if (dtime > delay) { // calc difference - dtimes[dindex]=millis(); - double vdiff = meter_vars[ind-1]-dvalues[dindex]; - dvalues[dindex]=meter_vars[ind-1]; - meter_vars[vindex]=(double)360000.0*vdiff/((double)dtime/10000.0); + dtimes[dindex] = millis(); + double vdiff = meter_vars[ind - 1] - dvalues[dindex]; + dvalues[dindex] = meter_vars[ind - 1]; + meter_vars[vindex] = (double)360000.0 * vdiff / ((double)dtime / 10000.0); mp=strchr(mp,'@'); if (mp) { mp++; - SML_Immediate_MQTT((const char*)mp,vindex,mindex); + double fac = CharToDouble((char*)mp); + meter_vars[vindex] /= fac; + SML_Immediate_MQTT((const char*)mp, vindex, mindex); } } dindex++; } - } else if (*mp=='h') { + } else if (*mp == 'h') { // skip html tag line mp = strchr(mp, '|'); if (mp) mp++; @@ -1502,27 +1509,27 @@ void SML_Decode(uint8_t index) { } } else { // compare value - uint8_t found=1; - double ebus_dval=99; - float mbus_dval=99; - while (*mp!='@') { - if (meter_desc_p[mindex].type=='o' || meter_desc_p[mindex].type=='c') { - if (*mp++!=*cp++) { + uint8_t found = 1; + double ebus_dval = 99; + float mbus_dval = 99; + while (*mp != '@') { + if (meter_desc_p[mindex].type == 'o' || meter_desc_p[mindex].type == 'c') { + if (*mp++ != *cp++) { found=0; } } else { - if (meter_desc_p[mindex].type=='s') { + if (meter_desc_p[mindex].type == 's') { // sml uint8_t val = hexnibble(*mp++) << 4; val |= hexnibble(*mp++); - if (val!=*cp++) { + if (val != *cp++) { found=0; } } else { // ebus mbus pzem vbus or raw // XXHHHHSSUU - if (*mp=='x') { - if (*(mp+1)=='x') { + if (*mp == 'x') { + if (*(mp + 1) == 'x') { //ignore one byte mp += 2; cp++; @@ -1824,11 +1831,11 @@ void SML_Decode(uint8_t index) { meter_vars[vindex]=dval; #endif -//AddLog_P(LOG_LEVEL_INFO, PSTR(">> %s"),mp); + //AddLog_P(LOG_LEVEL_INFO, PSTR(">> %s"),mp); // get scaling factor - double fac=CharToDouble((char*)mp); - meter_vars[vindex]/=fac; - SML_Immediate_MQTT((const char*)mp,vindex,mindex); + double fac = CharToDouble((char*)mp); + meter_vars[vindex] /= fac; + SML_Immediate_MQTT((const char*)mp, vindex, mindex); } } dvalid[vindex] = 1; @@ -1953,8 +1960,14 @@ void SML_Show(boolean json) { } else { mid=0; } + } else if (*cp=='b') { + // bit value +#ifdef SML_BIT_TEXT + sprintf_P(tpowstr, PSTR("\"%s\""), (uint8_t)meter_vars[index]?D_ON:D_OFF); + mid = 2; +#endif } else { - mid=0; + mid = 0; } // skip scaling cp=strchr(cp,','); @@ -2157,7 +2170,7 @@ uint32_t SML_getscriptsize(char *lp) { #endif bool Gpio_used(uint8_t gpiopin) { - if ((gpiopin < ARRAY_SIZE(TasmotaGlobal.gpio_pin)) && (TasmotaGlobal.gpio_pin[gpiopin] > 0)) { + if ((gpiopin < nitems(TasmotaGlobal.gpio_pin)) && (TasmotaGlobal.gpio_pin[gpiopin] > 0)) { return true; } return false; @@ -2300,9 +2313,9 @@ dddef_exit: txbuff[cnt] = *lp++; } if (txlen) { - script_meter_desc[index].txmem = (char*)calloc(txlen+2, 1); + script_meter_desc[index].txmem = (char*)calloc(txlen + 2, 1); if (script_meter_desc[index].txmem) { - strcpy(script_meter_desc[index].txmem,txbuff); + strcpy(script_meter_desc[index].txmem, txbuff); } script_meter_desc[index].index = 0; script_meter_desc[index].max_index = tx_entries; @@ -2721,55 +2734,59 @@ uint8_t sml_hexnibble(char chr) { // send sequence every N Seconds void SML_Send_Seq(uint32_t meter,char *seq) { - uint8_t sbuff[32]; - uint8_t *ucp=sbuff,slen=0; - char *cp=seq; + uint8_t sbuff[48]; + uint8_t *ucp = sbuff, slen = 0; + char *cp = seq; uint8_t rflg = 0; - if (*cp=='r') { + if (*cp == 'r') { rflg = 1; cp++; } while (*cp) { if (!*cp || !*(cp+1)) break; - if (*cp==',') break; - uint8_t iob=(sml_hexnibble(*cp) << 4) | sml_hexnibble(*(cp+1)); - cp+=2; - *ucp++=iob; + if (*cp == ',') break; + uint8_t iob = (sml_hexnibble(*cp) << 4) | sml_hexnibble(*(cp + 1)); + cp += 2; + *ucp++ = iob; slen++; - if (slen>=sizeof(sbuff)) break; + if (slen >= sizeof(sbuff)-6) break; // leave space for checksum } - if (script_meter_desc[meter].type=='m' || script_meter_desc[meter].type=='M') { + if (script_meter_desc[meter].type == 'm' || script_meter_desc[meter].type == 'M') { if (!rflg) { - *ucp++=0; - *ucp++=2; - slen+=2; + *ucp++ = 0; + *ucp++ = 2; + slen += 2; } // append crc - uint16_t crc = MBUS_calculateCRC(sbuff,slen); - *ucp++=lowByte(crc); - *ucp++=highByte(crc); - slen+=2; + uint16_t crc = MBUS_calculateCRC(sbuff, slen); + *ucp++ = lowByte(crc); + *ucp++ = highByte(crc); + slen += 2; } - if (script_meter_desc[meter].type=='o') { - for (uint32_t cnt=0;cntwrite(sbuff,slen); + meter_ss[meter]->write(sbuff, slen); if (dump2log) { +#ifdef SML_DUMP_OUT_ALL + Hexdump(sbuff, slen); +#else uint8_t type = meter_desc_p[(dump2log&7) - 1].type; if (type == 'm' || type == 'M') { Hexdump(sbuff, slen); } +#endif } } diff --git a/tasmota/xsns_80_mfrc522.ino b/tasmota/xsns_80_mfrc522.ino index 29207819c..3ad92f4d9 100644 --- a/tasmota/xsns_80_mfrc522.ino +++ b/tasmota/xsns_80_mfrc522.ino @@ -126,6 +126,36 @@ void RC522Show(void) { } #endif // USE_WEBSERVER +/*********************************************************************************************\ + * Supported commands for Sensor80: + * + * Sensor80 1 - Show antenna gain + * Sensor80 1 - Set antenna gain 0..7 (default 4) +\*********************************************************************************************/ + +bool RC522Command(void) { + bool serviced = true; + char argument[XdrvMailbox.data_len]; + + for (uint32_t ca = 0; ca < XdrvMailbox.data_len; ca++) { + if ((' ' == XdrvMailbox.data[ca]) || ('=' == XdrvMailbox.data[ca])) { XdrvMailbox.data[ca] = ','; } + } + + switch (XdrvMailbox.payload) { + case 1: // Antenna gain + uint8_t gain; + if (strchr(XdrvMailbox.data, ',') != nullptr) { + gain = strtol(ArgV(argument, 2), nullptr, 10) & 0x7; + Mfrc522->PCD_SetAntennaGain(gain << 4); + } + gain = Mfrc522->PCD_GetAntennaGain() >> 4; // 0..7 + Response_P(PSTR("{\"Sensor80\":{\"Gain\":%d}}"), gain); + break; + } + + return serviced; +} + /*********************************************************************************************\ * Interface \*********************************************************************************************/ @@ -145,6 +175,11 @@ bool Xsns80(uint8_t function) { RC522ScanForTag(); } break; + case FUNC_COMMAND_SENSOR: + if (XSNS_80 == XdrvMailbox.index) { + result = RC522Command(); + } + break; #ifdef USE_WEBSERVER case FUNC_WEB_SENSOR: RC522Show(); diff --git a/tasmota/xsns_83_neopool.ino b/tasmota/xsns_83_neopool.ino index eb7ac25d4..22fc9489b 100644 --- a/tasmota/xsns_83_neopool.ino +++ b/tasmota/xsns_83_neopool.ino @@ -767,7 +767,7 @@ void NeoPool250ms(void) // Every 250 mSec } #endif // DEBUG_TASMOTA_SENSOR - ++neopool_read_state %= ARRAY_SIZE(NeoPoolReg); + ++neopool_read_state %= nitems(NeoPoolReg); #ifdef NEOPOOL_OPTIMIZE_READINGS if (0 == neopool_read_state) { neopool_first_read = false; @@ -795,7 +795,7 @@ void NeoPool250ms(void) // Every 250 mSec #ifdef DEBUG_TASMOTA_SENSOR AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("NEO: notify 0x%04X - addr block 0x%04X ignored"), NeoPoolGetData(MBF_NOTIFICATION), NeoPoolReg[neopool_read_state].addr); #endif // DEBUG_TASMOTA_SENSOR - ++neopool_read_state %= ARRAY_SIZE(NeoPoolReg); + ++neopool_read_state %= nitems(NeoPoolReg); } } #endif // NEOPOOL_OPTIMIZE_READINGS @@ -840,7 +840,7 @@ bool NeoPoolInitData(void) bool res = false; neopool_error = true; - for(uint32_t i=0; i= NeoPoolReg[i].addr && addr < NeoPoolReg[i].addr+NeoPoolReg[i].cnt) { return NeoPoolReg[i].data[addr - NeoPoolReg[i].addr]; } @@ -1206,14 +1206,14 @@ void NeoPoolShow(bool json) } // Filtration mode - GetTextIndexed(stemp, sizeof(stemp), NeoPoolGetData(MBF_PAR_FILT_MODE) < MBV_PAR_FILT_INTELLIGENT ? NeoPoolGetData(MBF_PAR_FILT_MODE) : ARRAY_SIZE(kNeoPoolFiltrationMode)-1, kNeoPoolFiltrationMode); + GetTextIndexed(stemp, sizeof(stemp), NeoPoolGetData(MBF_PAR_FILT_MODE) < MBV_PAR_FILT_INTELLIGENT ? NeoPoolGetData(MBF_PAR_FILT_MODE) : nitems(kNeoPoolFiltrationMode)-1, kNeoPoolFiltrationMode); WSContentSend_PD(HTTP_SNS_NEOPOOL_FILT_MODE, neopool_type, stemp); // Relays for(uint32_t i=0; i<8; i++) { char sdesc[24]; - memset(sdesc, 0, ARRAY_SIZE(sdesc)); - memset(stemp, 0, ARRAY_SIZE(stemp)); + memset(sdesc, 0, nitems(sdesc)); + memset(stemp, 0, nitems(stemp)); if (0 != NeoPoolGetData(MBF_PAR_PH_ACID_RELAY_GPIO) && i == NeoPoolGetData(MBF_PAR_PH_ACID_RELAY_GPIO)-1) { strncpy_P(sdesc, PSTR(D_NEOPOOL_RELAY_PH_ACID), sizeof(sdesc)); } @@ -1306,14 +1306,14 @@ void CmndNeopoolReadReg(void) { uint16_t addr, data[30] = { 0 }, cnt=1; uint32_t value[2] = { 0 }; - uint32_t params_cnt = ParseParameters(ARRAY_SIZE(value), value); + uint32_t params_cnt = ParseParameters(nitems(value), value); bool fbits32 = !strcasecmp_P(XdrvMailbox.command, PSTR(D_PRFX_NEOPOOL D_CMND_NP_READL)); cnt = 1; if (2 == params_cnt) { cnt = value[1]; } - if (params_cnt && cnt < (fbits32 ? (ARRAY_SIZE(data)/2) : ARRAY_SIZE(data))) { + if (params_cnt && cnt < (fbits32 ? (nitems(data)/2) : nitems(data))) { addr = value[0]; if (NEOPOOL_OK != NeoPoolReadRegister(addr, data, fbits32 ? (cnt*2) : cnt)) { NeopoolResponseError(); @@ -1326,8 +1326,8 @@ void CmndNeopoolReadReg(void) void CmndNeopoolWriteReg(void) { uint16_t addr, data[20] = { 0 }, cnt; - uint32_t value[(ARRAY_SIZE(data)/2)+1] = { 0 }; - uint32_t params_cnt = ParseParameters(ARRAY_SIZE(value), value); + uint32_t value[(nitems(data)/2)+1] = { 0 }; + uint32_t params_cnt = ParseParameters(nitems(value), value); bool fbits32 = !strcasecmp_P(XdrvMailbox.command, PSTR(D_PRFX_NEOPOOL D_CMND_NP_WRITEL)); if (params_cnt > 1) { @@ -1359,7 +1359,7 @@ void CmndNeopoolBit(void) uint16_t addr, data; int8_t bit; uint32_t value[3] = { 0 }; - uint32_t params_cnt = ParseParameters(ARRAY_SIZE(value), value); + uint32_t params_cnt = ParseParameters(nitems(value), value); bool fbits32 = !strcasecmp_P(XdrvMailbox.command, PSTR(D_PRFX_NEOPOOL D_CMND_NP_BITL)); uint16_t tempdata[2]; @@ -1457,7 +1457,7 @@ void CmndNeopoolFiltrationMode(void) NeopoolResponseError(); return; } - ResponseCmndChar(GetTextIndexed(stemp, sizeof(stemp), data < MBV_PAR_FILT_INTELLIGENT ? data : ARRAY_SIZE(kNeoPoolFiltrationMode)-1, kNeoPoolFiltrationMode)); + ResponseCmndChar(GetTextIndexed(stemp, sizeof(stemp), data < MBV_PAR_FILT_INTELLIGENT ? data : nitems(kNeoPoolFiltrationMode)-1, kNeoPoolFiltrationMode)); } void CmndNeopoolTime(void) @@ -1508,7 +1508,7 @@ void CmndNeopoolLight(void) return; } if (relay >=1 && relay <=8) { - if (XdrvMailbox.data_len && XdrvMailbox.payload >= 0 && XdrvMailbox.payload < ARRAY_SIZE(timer_val)) { + if (XdrvMailbox.data_len && XdrvMailbox.payload >= 0 && XdrvMailbox.payload < nitems(timer_val)) { addr = MBF_PAR_TIMER_BLOCK_LIGHT_INT + MBV_TIMER_OFFMB_TIMER_ENABLE; data = timer_val[XdrvMailbox.payload]; NeoPoolWriteRegister(MBF_PAR_TIMER_BLOCK_LIGHT_INT + MBV_TIMER_OFFMB_TIMER_ENABLE, &data, 1); diff --git a/tools/decode-status.py b/tools/decode-status.py index bd1f959a8..4e12be5d5 100755 --- a/tools/decode-status.py +++ b/tools/decode-status.py @@ -247,7 +247,7 @@ a_features = [[ "USE_DISPLAY_ILI9488","USE_DISPLAY_SSD1351","USE_DISPLAY_RA8876","USE_DISPLAY_ST7789", "USE_DISPLAY_SSD1331","USE_UFILESYS","USE_TIMEPROP","USE_PID", "USE_BS814A2","USE_SEESAW_SOIL","USE_WIEGAND","USE_NEOPOOL", - "USE_TOF10120","USE_SDM72","USE_DISPLAY_TM1637","" + "USE_TOF10120","USE_SDM72","USE_DISPLAY_TM1637","USE_PROJECTOR_CTRL" ],[ "","","","", "","","","",