Added support for XPT2046 touch screen

This commit is contained in:
nonix 2021-02-28 18:27:32 +01:00
commit d38c1c415e
66 changed files with 1184 additions and 353 deletions

View File

@ -172,6 +172,7 @@
| USE_TASMOTA_CLIENT | - | - | - | - | - | - | - |
| USE_OPENTHERM | - | - | - | - | - | - | - |
| USE_MIEL_HVAC | - | - | - | - | - | - | - |
| USE_PROJECTOR_CTRL | - | - | - | - | - | - | - |
| USE_AS608 | - | - | - | - | - | - | - |
| USE_TCP_BRIDGE | - | - | - | - | - | - | - | zbbridge
| | | | | | | | |

View File

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

View File

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

View File

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

View File

@ -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)<<SPI_CLKCNT_L_S)); //clear bit 31,set SPI clock div
*/
// will result in 80/18 = 4,4 Mhz
SPI.setFrequency(4500000);
SPI.setFrequency(4500000);
ssd1351_clock=SPI1CLK;
ssd1351_usr=SPI1U;
ssd1351_usr1=SPI1U1;
ssd1351_usr2=SPI1U2;
ssd1351_spi1c=SPI1C;
ssd1351_spi1p=SPI1P;
//ssd1351_gpmux=GPMUX;
ssd1351_mtdo=READ_PERI_REG(PERIPHS_IO_MUX_MTDO_U);
ssd131_start=0;
ssd1351_clock=SPI1CLK;
ssd1351_usr=SPI1U;
ssd1351_usr1=SPI1U1;
ssd1351_usr2=SPI1U2;
ssd1351_spi1c=SPI1C;
ssd1351_spi1p=SPI1P;
//ssd1351_gpmux=GPMUX;
ssd1351_mtdo=READ_PERI_REG(PERIPHS_IO_MUX_MTDO_U);
}
ssd131_start = 0;
}
void SSD1351::start(void) {
if (ssd131_start) return;
//while(SPI1CMD & SPIBUSY) {}
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;
if (_dc >= 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)<<SPI_USR_COMMAND_BITLEN_S)|((uint32)bytetemp); //configure transmission variable,9bit transmission length and first 8 command bit
if(c&0x01) regvalue|=BIT15; //write the 9th bit
while(READ_PERI_REG(SPI_CMD(1))&SPI_USR); //waiting for spi module available
WRITE_PERI_REG(SPI_USER2(1), regvalue); //write command and command length into spi reg
SET_PERI_REG_MASK(SPI_CMD(1), SPI_USR); //transmission start
} else fastSPIwrite(c,0);
if (_dc >= 0) {
digitalWrite(_dc, LOW);
SPI.transfer(c);
} else {
bytetemp = (c >> 1) & 0x7f;
regvalue= ((8&SPI_USR_COMMAND_BITLEN)<<SPI_USR_COMMAND_BITLEN_S)|((uint32)bytetemp); //configure transmission variable,9bit transmission length and first 8 command bit
if (c & 0x01) regvalue |= BIT15; //write the 9th bit
while (READ_PERI_REG(SPI_CMD(1)) & SPI_USR); //waiting for spi module available
WRITE_PERI_REG(SPI_USER2(1), regvalue); //write command and command length into spi reg
SET_PERI_REG_MASK(SPI_CMD(1), SPI_USR); //transmission start
}
} else {
fastSPIwrite(c, 0);
}
}
// dc = 1
@ -178,47 +197,63 @@ void SSD1351::writedata(uint8_t d) {
if (_hwspi) {
uint32_t regvalue;
uint8_t bytetemp;
bytetemp=(d>>1)|0x80;
start();
regvalue= ((8&SPI_USR_COMMAND_BITLEN)<<SPI_USR_COMMAND_BITLEN_S)|((uint32)bytetemp); //configure transmission variable,9bit transmission length and first 8 command bit
if(d&0x01) regvalue|=BIT15; //write the 9th bit
while(READ_PERI_REG(SPI_CMD(1))&SPI_USR); //waiting for spi module available
WRITE_PERI_REG(SPI_USER2(1), regvalue); //write command and command length into spi reg
SET_PERI_REG_MASK(SPI_CMD(1), SPI_USR); //transmission start
} else fastSPIwrite(d,1);
if (_dc >= 0) {
digitalWrite(_dc, HIGH);
SPI.transfer(d);
} else {
bytetemp = (d >> 1) | 0x80;
regvalue= ((8&SPI_USR_COMMAND_BITLEN)<<SPI_USR_COMMAND_BITLEN_S)|((uint32)bytetemp); //configure transmission variable,9bit transmission length and first 8 command bit
if(d&0x01) regvalue|=BIT15; //write the 9th bit
while(READ_PERI_REG(SPI_CMD(1))&SPI_USR); //waiting for spi module available
WRITE_PERI_REG(SPI_USER2(1), regvalue); //write command and command length into spi reg
SET_PERI_REG_MASK(SPI_CMD(1), SPI_USR); //transmission start
}
} else {
fastSPIwrite(d, 1);
}
}
void ICACHE_RAM_ATTR SSD1351::fastSPIwrite(uint8_t d,uint8_t dc) {
void ICACHE_RAM_ATTR SSD1351::fastSPIwrite(uint8_t d, uint8_t dc) {
WRITE_PERI_REG( PIN_OUT_CLEAR, 1<<_cs);
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);
WRITE_PERI_REG( PIN_OUT_CLEAR, 1 << _cs);
for(uint8_t bit = 0x80; bit; bit >>= 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;

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -0,0 +1,2 @@
779a780
> #define D_SENSOR_XPT2046_CS "XPT2046 CS"

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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
/*********************************************************************************************\

View File

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

View File

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

View File

@ -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
\*-------------------------------------------------------------------------------------------*/

View File

@ -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; i<ARRAY_SIZE(WebServerDispatch); i++) {
for (uint32_t i=0; i<nitems(WebServerDispatch); i++) {
const WebServerDispatch_t & line = WebServerDispatch[i];
// copy uri in RAM and prefix with '/'
char uri[4];
@ -1325,7 +1325,7 @@ void HandleConfiguration(void)
void WSContentSendNiceLists(uint32_t option) {
char stemp[30]; // Template number and Sensor name
for (uint32_t i = 0; i < ARRAY_SIZE(kGpioNiceList); i++) { // GPIO: }2'0'>None (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("<tr><td style='width:116px'>%s <b>" D_GPIO "%d</b></td><td style='width:146px'><select id='g%d' onchange='ot(%d,this.value)'></select></td>"),
@ -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 {

View File

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

View File

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

View File

@ -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 <WiFiClientSecure.h>
#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;
}

View File

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

View File

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

View File

@ -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; i<ARRAY_SIZE(Z_Data_Type_char); i++) {
for (uint32_t i=0; i<nitems(Z_Data_Type_char); i++) {
if (pgm_read_byte(&Z_Data_Type_char[i]) == c) {
return (Z_Data_Type) i;
}
@ -115,7 +115,7 @@ char Z_Data::DataTypeToChar(Z_Data_Type t) {
return '_';
} else {
uint8_t tt = (uint8_t) t;
if (tt < ARRAY_SIZE(Z_Data_Type_char)) {
if (tt < nitems(Z_Data_Type_char)) {
return pgm_read_byte(&Z_Data_Type_char[tt]);
}
}
@ -418,7 +418,7 @@ public:
inline void setZoneType(uint16_t _zone_type) { zone_type = _zone_type; }
bool update(void) {
for (uint32_t i=0; i<ARRAY_SIZE(Z_Alarm_Types); i++) {
for (uint32_t i=0; i<nitems(Z_Alarm_Types); i++) {
Z_Alarm_Types_t conv_type;
conv_type.i = pgm_read_word(&Z_Alarm_Types[i].i);
if (zone_type == conv_type.t.zcl_type) {
@ -553,7 +553,7 @@ const uint8_t Z_Data_Type_len[] PROGMEM = {
size_t Z_Data::DataTypeToLength(Z_Data_Type t) {
uint32_t tt = (uint32_t) t;
if (tt < ARRAY_SIZE(Z_Data_Type_len)) {
if (tt < nitems(Z_Data_Type_len)) {
return pgm_read_byte(&Z_Data_Type_len[tt]);
}
return 0;

View File

@ -145,7 +145,7 @@ SBuffer hibernateDevicev2(const struct Z_Device &device) {
char *names[3] = { device.modelId, device.manufacturerId, device.friendlyName };
for (uint32_t i=0; i<ARRAY_SIZE(names); i++) {
for (uint32_t i=0; i<nitems(names); i++) {
char *p = names[i];
if (p) {
size_t len = strlen(p);

View File

@ -140,14 +140,14 @@ const uint16_t Cx_cluster[] PROGMEM = {
};
uint16_t CxToCluster(uint8_t cx) {
if (cx < ARRAY_SIZE(Cx_cluster)) {
if (cx < nitems(Cx_cluster)) {
return pgm_read_word(&Cx_cluster[cx]);
}
return 0xFFFF;
}
uint8_t ClusterToCx(uint16_t cluster) {
for (uint32_t i=0; i<ARRAY_SIZE(Cx_cluster); i++) {
for (uint32_t i=0; i<nitems(Cx_cluster); i++) {
if (pgm_read_word(&Cx_cluster[i]) == cluster) {
return i;
}
@ -170,7 +170,7 @@ const int8_t Cm_multiplier[] PROGMEM = {
int8_t CmToMultiplier(uint8_t cm) {
cm = cm & 0x0F; // get only low nibble
if (cm < ARRAY_SIZE(Cm_multiplier)) {
if (cm < nitems(Cm_multiplier)) {
return pgm_read_byte(&Cm_multiplier[cm]);
}
return 1;
@ -668,7 +668,7 @@ typedef union ZCLHeaderFrameControl_t {
const __FlashStringHelper* zigbeeFindAttributeByName(const char *command,
uint16_t *cluster, uint16_t *attribute, int8_t *multiplier,
uint8_t *zigbee_type = nullptr, Z_Data_Type *data_type = nullptr, uint8_t *map_offset = nullptr) {
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];
if (0 == pgm_read_word(&converter->name_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);

View File

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

View File

@ -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<ARRAY_SIZE(Z_bindings); i++) {
for (uint32_t i=0; i<nitems(Z_bindings); i++) {
if (pgm_read_byte(&Z_bindings[i]) == cx) {
return i;
}
@ -711,7 +711,7 @@ void Z_AutoBindDefer(uint16_t shortaddr, uint8_t endpoint, const SBuffer &buf,
}
// enqueue bind requests
for (uint32_t i=0; i<ARRAY_SIZE(Z_bindings); i++) {
for (uint32_t i=0; i<nitems(Z_bindings); i++) {
if (bitRead(cluster_map, i)) {
uint16_t cluster = CxToCluster(pgm_read_byte(&Z_bindings[i]));
if ((cluster == 0x0001) && (!Z_BatteryReportingDeviceSpecific(shortaddr))) { continue; }
@ -720,7 +720,7 @@ void Z_AutoBindDefer(uint16_t shortaddr, uint8_t endpoint, const SBuffer &buf,
}
// enqueue config attribute requests
for (uint32_t i=0; i<ARRAY_SIZE(Z_bindings); i++) {
for (uint32_t i=0; i<nitems(Z_bindings); i++) {
if (bitRead(cluster_in_map, i)) {
uint16_t cluster = CxToCluster(pgm_read_byte(&Z_bindings[i]));
if ((cluster == 0x0001) && (!Z_BatteryReportingDeviceSpecific(shortaddr))) { continue; }
@ -1534,7 +1534,7 @@ void Z_AutoConfigReportingForCluster(uint16_t shortaddr, uint16_t groupaddr, uin
Response_P(PSTR("ZbSend {\"Device\":\"0x%04X\",\"Config\":{"), shortaddr);
boolean comma = false;
for (uint32_t i=0; i<ARRAY_SIZE(Z_autoAttributeReporting); i++) {
for (uint32_t i=0; i<nitems(Z_autoAttributeReporting); i++) {
uint16_t conv_cluster = pgm_read_word(&(Z_autoAttributeReporting[i].cluster));
uint16_t attr_id = pgm_read_word(&(Z_autoAttributeReporting[i].attr_id));
@ -2000,7 +2000,7 @@ int32_t ZNP_Recv_Default(int32_t res, const SBuffer &buf) {
// if still during initialization phase, ignore any unexpected message
return -1; // ignore message
} else {
for (uint32_t i = 0; i < ARRAY_SIZE(Z_DispatchTable); i++) {
for (uint32_t i = 0; i < nitems(Z_DispatchTable); i++) {
if (Z_ReceiveMatchPrefix(buf, Z_DispatchTable[i].match)) {
(*Z_DispatchTable[i].func)(res, buf);
}
@ -2120,7 +2120,7 @@ void ZCLFrame::autoResponder(const uint16_t *attr_list_ids, size_t attr_len) {
LightGetHSB(&hue, &sat, nullptr);
LightGetXY(&XY[0], &XY[1]);
uint16_t uxy[2];
for (uint32_t i = 0; i < ARRAY_SIZE(XY); i++) {
for (uint32_t i = 0; i < nitems(XY); i++) {
uxy[i] = XY[i] * 65536.0f;
uxy[i] = (uxy[i] > 0xFEFF) ? uxy[i] : 0xFEFF;
}

View File

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

View File

@ -62,15 +62,15 @@ void TCPLoop(void)
if ((server_tcp) && (server_tcp->hasClient())) {
// find an empty slot
uint32_t i;
for (i=0; i<ARRAY_SIZE(client_tcp); i++) {
for (i=0; i<nitems(client_tcp); i++) {
WiFiClient &client = client_tcp[i];
if (!client) {
client = server_tcp->available();
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<ARRAY_SIZE(client_tcp); i++) {
for (uint32_t i=0; i<nitems(client_tcp); i++) {
WiFiClient &client = client_tcp[i];
if (client) { client.write(tcp_buf, buf_len); }
}
}
// handle data received from TCP
for (uint32_t i=0; i<ARRAY_SIZE(client_tcp); i++) {
for (uint32_t i=0; i<nitems(client_tcp); i++) {
WiFiClient &client = client_tcp[i];
buf_len = 0;
while (client && (buf_len < TCP_BRIDGE_BUF_SIZE) && (client.available())) {
@ -152,7 +152,7 @@ void CmndTCPStart(void) {
delete server_tcp;
server_tcp = nullptr;
for (uint32_t i=0; i<ARRAY_SIZE(client_tcp); i++) {
for (uint32_t i=0; i<nitems(client_tcp); i++) {
WiFiClient &client = client_tcp[i];
client.stop();
}

View File

@ -0,0 +1,66 @@
#ifndef _XDRV53_PROJECTOR_CTRL_H_
#define _XDRV53_PROJECTOR_CTRL_H_
//define RELAY that is forced ON while projector is running
#ifndef PROJECTOR_CTRL_PWR_BY_RELAY
#define PROJECTOR_CTRL_PWR_BY_RELAY 1
#endif //PROJECTOR_CTRL_PWR_BY_RELAY
#define PROJECTOR_CTRL_SERIAL_TIMEOUT 10 //up to 254 seconds
#define PROJECTOR_CTRL_SERIAL_BAUDRATE 9600
#ifdef USE_PROJECTOR_CTRL_NEC
/* see the serial codes in
* https://www.sharpnecdisplays.eu/p/download/v/5e14a015e26cacae3ae64a422f7f8af4/cp/Products/Projectors/Shared/CommandLists/PDF-ExternalControlManual-english.pdf#page=5
* tested with NEC V300W
* final cksum byte is appended automatically
*/
#define PROJECTOR_CTRL_LOGNAME "DLP[NEC]"
static const uint8_t projector_ctrl_msg_qry_typ[] = { 0x00, 0xBF, 0x00, 0x00, 0x01, 0x00 }; //page81
static const uint8_t projector_ctrl_msg_qry_pwr[] = { 0x00, 0xBF, 0x00, 0x00, 0x01, 0x02 }; //page83
static const uint8_t projector_ctrl_msg_pwr_on[] = { 0x02, 0x00, 0x00, 0x00, 0x00 }; //page15
static const uint8_t projector_ctrl_msg_pwr_off[] = { 0x02, 0x01, 0x00, 0x00, 0x00 }; //page16
static const struct projector_ctrl_command_info_s projector_ctrl_commands[] = {
{PROJECTOR_CTRL_S_QRY_TYPE, &projector_ctrl_msg_qry_typ[0], sizeof(projector_ctrl_msg_qry_typ),
PROJECTOR_CTRL_SERIAL_TIMEOUT, 0x20, 22, 8, 4, 0xA0, 8, 5, 2},
{PROJECTOR_CTRL_S_QRY_PWR, &projector_ctrl_msg_qry_pwr[0], sizeof(projector_ctrl_msg_qry_pwr),
PROJECTOR_CTRL_SERIAL_TIMEOUT, 0x20, 22, 6, 1, 0xA0, 8, 5, 2},
{PROJECTOR_CTRL_S_PWR_ON, &projector_ctrl_msg_pwr_on[0], sizeof(projector_ctrl_msg_pwr_on),
PROJECTOR_CTRL_SERIAL_TIMEOUT, 0x22, 6, 0, 1, 0xA2, 8, 5, 2},
{PROJECTOR_CTRL_S_PWR_OFF, &projector_ctrl_msg_pwr_off[0], sizeof(projector_ctrl_msg_pwr_off),
PROJECTOR_CTRL_SERIAL_TIMEOUT, 0x22, 6, 0, 1, 0xA2, 8, 5, 2}
};
#define PROJECTOR_CTRL_QRYPWR_ON 0x04
#define PROJECTOR_CTRL_QRYPWR_COOLING 0x05
#elif defined(USE_PROJECTOR_CTRL_OPTOMA)
/* see the serial codes in
* https://www.optoma.co.uk/uploads/manuals/hd36-m-en-gb.pdf#page=56
* not really tested with OPTOMA devices
*/
#define PROJECTOR_CTRL_LOGNAME "DLP[OPTOMA]"
static const uint8_t projector_ctrl_msg_qry_typ[] = { 0x7e, 0x30, 0x30, 0x31, 0x32, 0x32, 0x20, 0x31, 0x0d }; //page59
static const uint8_t projector_ctrl_msg_qry_pwr[] = { 0x7e, 0x30, 0x30, 0x31, 0x32, 0x34, 0x20, 0x31, 0x0d }; //page59
static const uint8_t projector_ctrl_msg_pwr_on[] = { 0x7e, 0x30, 0x30, 0x30, 0x30, 0x20, 0x31, 0x0d }; //page56
static const uint8_t projector_ctrl_msg_pwr_off[] = { 0x7e, 0x30, 0x30, 0x30, 0x30, 0x20, 0x30, 0x0d }; //page56
static const struct projector_ctrl_command_info_s projector_ctrl_commands[] = {
{PROJECTOR_CTRL_S_QRY_TYPE, &projector_ctrl_msg_qry_typ[0], sizeof(projector_ctrl_msg_qry_typ),
PROJECTOR_CTRL_SERIAL_TIMEOUT, 'O', 6, 2, 4, 'I', 5, 4, 1},
{PROJECTOR_CTRL_S_QRY_PWR, &projector_ctrl_msg_qry_pwr[0], sizeof(projector_ctrl_msg_qry_pwr),
PROJECTOR_CTRL_SERIAL_TIMEOUT, 'O', 3, 2, 1, 'I', 5, 4, 1},
{PROJECTOR_CTRL_S_PWR_ON, &projector_ctrl_msg_pwr_on[0], sizeof(projector_ctrl_msg_pwr_on),
PROJECTOR_CTRL_SERIAL_TIMEOUT, 'P', 1, 0, 1, 'F', 1, 0, 1},
{PROJECTOR_CTRL_S_PWR_OFF, &projector_ctrl_msg_pwr_off[0], sizeof(projector_ctrl_msg_pwr_off),
PROJECTOR_CTRL_SERIAL_TIMEOUT, 'P', 1, 0, 1, 'F', 1, 0, 1}
};
#define PROJECTOR_CTRL_QRYPWR_ON 0x31
#define PROJECTOR_CTRL_QRYPWR_COOLING 0x31 //placebo
#else
#error USE_PROJECTOR_CTRL: No projector type defined
#endif
#endif //_XDRV53_PROJECTOR_CTRL_H_

View File

@ -0,0 +1,459 @@
/*
xdrv_53_projector_ctrl.ino - LCD/DLP Projector Serial Control support for Tasmota
Copyright (C) 2021 Jan Bubík <jbubik@centrum.cz>
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 <http://www.gnu.org/licenses/>.
*/
#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

View File

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

View File

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

View File

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

View File

@ -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<MAX_DVARS) {
if (dindex < MAX_DVARS) {
// only n indexes
mp++;
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) {
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;cnt<slen;cnt++) {
sbuff[cnt]|=(CalcEvenParity(sbuff[cnt])<<7);
if (script_meter_desc[meter].type == 'o') {
for (uint32_t cnt = 0; cnt < slen; cnt++) {
sbuff[cnt] |= (CalcEvenParity(sbuff[cnt]) << 7);
}
}
if (script_meter_desc[meter].type=='p') {
*ucp++=0xc0;
*ucp++=0xa8;
*ucp++=1;
*ucp++=1;
*ucp++=0;
*ucp++=SML_PzemCrc(sbuff,6);
slen+=6;
if (script_meter_desc[meter].type == 'p') {
*ucp++ = 0xc0;
*ucp++ = 0xa8;
*ucp++ = 1;
*ucp++ = 1;
*ucp++ = 0;
*ucp++ = SML_PzemCrc(sbuff, 6);
slen += 6;
}
meter_ss[meter]->write(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
}
}

View File

@ -126,6 +126,36 @@ void RC522Show(void) {
}
#endif // USE_WEBSERVER
/*********************************************************************************************\
* Supported commands for Sensor80:
*
* Sensor80 1 - Show antenna gain
* Sensor80 1 <gain> - 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();

View File

@ -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<ARRAY_SIZE(NeoPoolReg); i++) {
for(uint32_t i=0; i<nitems(NeoPoolReg); i++) {
if (nullptr == NeoPoolReg[i].data) {
NeoPoolReg[i].data = (uint16_t *)malloc(sizeof(uint16_t)*NeoPoolReg[i].cnt);
if (nullptr != NeoPoolReg[i].data) {
@ -1001,7 +1001,7 @@ uint8_t NeoPoolWriteRegister(uint16_t addr, uint16_t *data, uint16_t cnt)
uint16_t NeoPoolGetData(uint16_t addr)
{
for(uint32_t i=0; i<ARRAY_SIZE(NeoPoolReg); i++) {
for(uint32_t i=0; i<nitems(NeoPoolReg); i++) {
if (nullptr != NeoPoolReg[i].data && addr >= 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);

View File

@ -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"
],[
"","","","",
"","","","",