Merge pull request #4 from arendst/development

update tasmota
This commit is contained in:
Mike 2018-10-01 18:04:03 +02:00 committed by GitHub
commit 81439e834a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 1212 additions and 731 deletions

View File

@ -93,8 +93,8 @@ The following devices are supported:
- [BlitzWolf BW-SHP2 Smart Socket with Energy Monitoring](https://www.banggood.com/BlitzWolf-BW-SHP2-Smart-WIFI-Socket-EU-Plug-220V-16A-Work-with-Amazon-Alexa-Google-Assistant-p-1292899.html)<img src="https://github.com/arendst/arendst.github.io/blob/master/media/shelly2_small_250a.png" width="250" align="right" /> - [BlitzWolf BW-SHP2 Smart Socket with Energy Monitoring](https://www.banggood.com/BlitzWolf-BW-SHP2-Smart-WIFI-Socket-EU-Plug-220V-16A-Work-with-Amazon-Alexa-Google-Assistant-p-1292899.html)<img src="https://github.com/arendst/arendst.github.io/blob/master/media/shelly2_small_250a.png" width="250" align="right" />
- [Luani HVIO board](https://luani.de/projekte/esp8266-hvio/) - [Luani HVIO board](https://luani.de/projekte/esp8266-hvio/)
- [Wemos D1 mini](https://wiki.wemos.cc/products:d1:d1_mini) - [Wemos D1 mini](https://wiki.wemos.cc/products:d1:d1_mini)
- [HuaFan Smart Socket](HuaFan-Smart-Socket) - [HuaFan Smart Socket](https://github.com/arendst/Sonoff-Tasmota/wiki/HuaFan-Smart-Socket)
- [Hyleton-313 Smart Plug](Hyleton-313-Smart-Plug) - [Hyleton-313 Smart Plug](https://github.com/arendst/Sonoff-Tasmota/wiki/Hyleton-313-Smart-Plug)
- [Allterco Shelly 1](https://shelly.cloud/shelly1-open-source/) - [Allterco Shelly 1](https://shelly.cloud/shelly1-open-source/)
- [Allterco Shelly 2 with Energy Monitoring](https://shelly.cloud/shelly2/) - [Allterco Shelly 2 with Energy Monitoring](https://shelly.cloud/shelly2/)
- NodeMcu and Ledunia - NodeMcu and Ledunia

View File

@ -1,5 +1,16 @@
/* 6.2.1.9 20180928 /* 6.2.1.10 20180930
* Add command RGBWWTable to support color calibration (#3933)
* Add support for Michael Haustein ESP Switch
* Add support for EXS Relay V5.0 (#3810)
* Fix timer offset -00:00 causing 12:00 hour offset (#3923)
* Add support for OBI Power Socket (#1988, #3944)
* Add support for Teckin Power Socket with Energy Monitoring (#3950)
*
* 6.2.1.9 20180928
* Add Apparent Power and Reactive Power to Energy Monitoring devices (#251) * Add Apparent Power and Reactive Power to Energy Monitoring devices (#251)
* Add RF Receiver control to module MagicHome to be used on Arilux LC10 (#3792)
* Fix I2CScan invalid JSON error message (#3925)
* Fix invalid configuration restores and decode_config.py crc error when savedata = 0 (#3918)
* *
* 6.2.1.8 20180926 * 6.2.1.8 20180926
* Change status JSON message providing more switch and retain information * Change status JSON message providing more switch and retain information

View File

@ -317,6 +317,7 @@
#define D_CMND_LEDTABLE "LedTable" #define D_CMND_LEDTABLE "LedTable"
#define D_CMND_FADE "Fade" #define D_CMND_FADE "Fade"
#define D_CMND_PIXELS "Pixels" #define D_CMND_PIXELS "Pixels"
#define D_CMND_RGBWWTABLE "RGBWWTable"
#define D_CMND_ROTATION "Rotation" #define D_CMND_ROTATION "Rotation"
#define D_CMND_SCHEME "Scheme" #define D_CMND_SCHEME "Scheme"
#define D_CMND_SPEED "Speed" #define D_CMND_SPEED "Speed"

View File

@ -322,7 +322,9 @@ struct SYSCFG {
uint16_t mcp230xx_int_timer; // 718 uint16_t mcp230xx_int_timer; // 718
byte free_71A[174]; // 71A uint8_t rgbwwTable[5]; // 71A
byte free_71F[169]; // 71F
unsigned long energy_frequency_calibration; // 7C8 unsigned long energy_frequency_calibration; // 7C8

View File

@ -624,6 +624,10 @@ void SettingsDefaultSet2()
Settings.button_debounce = KEY_DEBOUNCE_TIME; Settings.button_debounce = KEY_DEBOUNCE_TIME;
Settings.switch_debounce = SWITCH_DEBOUNCE_TIME; Settings.switch_debounce = SWITCH_DEBOUNCE_TIME;
for (byte j = 0; j < 5; j++) {
Settings.rgbwwTable[j] = 255;
}
} }
/********************************************************************************************/ /********************************************************************************************/
@ -827,6 +831,11 @@ void SettingsDelta()
Settings.button_debounce = KEY_DEBOUNCE_TIME; Settings.button_debounce = KEY_DEBOUNCE_TIME;
Settings.switch_debounce = SWITCH_DEBOUNCE_TIME; Settings.switch_debounce = SWITCH_DEBOUNCE_TIME;
} }
if (Settings.version < 0x0602010A) {
for (byte j = 0; j < 5; j++) {
Settings.rgbwwTable[j] = 255;
}
}
Settings.version = VERSION; Settings.version = VERSION;
SettingsSave(1); SettingsSave(1);

View File

@ -296,20 +296,23 @@ char* GetStateText(byte state)
/********************************************************************************************/ /********************************************************************************************/
void SetLatchingRelay(power_t power, uint8_t state) void SetLatchingRelay(power_t lpower, uint8_t state)
{ {
power &= 1; // power xx00 - toggle REL1 (Off) and REL3 (Off) - device 1 Off, device 2 Off
if (2 == state) { // Reset relay // power xx01 - toggle REL2 (On) and REL3 (Off) - device 1 On, device 2 Off
state = 0; // power xx10 - toggle REL1 (Off) and REL4 (On) - device 1 Off, device 2 On
latching_power = power; // power xx11 - toggle REL2 (On) and REL4 (On) - device 1 On, device 2 On
latching_relay_pulse = 0;
if (state && !latching_relay_pulse) { // Set latching relay to power if previous pulse has finished
latching_power = lpower;
latching_relay_pulse = 2; // max 200mS (initiated by stateloop())
} }
else if (state && !latching_relay_pulse) { // Set port power to On
latching_power = power; for (byte i = 0; i < devices_present; i++) {
latching_relay_pulse = 2; // max 200mS (initiated by stateloop()) uint8_t port = (i << 1) + ((latching_power >> i) &1);
} if (pin[GPIO_REL1 +port] < 99) {
if (pin[GPIO_REL1 +latching_power] < 99) { digitalWrite(pin[GPIO_REL1 +port], bitRead(rel_inverted, port) ? !state : state);
digitalWrite(pin[GPIO_REL1 +latching_power], bitRead(rel_inverted, latching_power) ? !state : state); }
} }
} }
@ -2453,6 +2456,10 @@ void GpioInit()
if (pin[GPIO_REL1 +i] < 99) { if (pin[GPIO_REL1 +i] < 99) {
pinMode(pin[GPIO_REL1 +i], OUTPUT); pinMode(pin[GPIO_REL1 +i], OUTPUT);
devices_present++; devices_present++;
if (EXS_RELAY == Settings.module) {
digitalWrite(pin[GPIO_REL1 +i], bitRead(rel_inverted, i) ? 1 : 0);
if (i &1) { devices_present--; }
}
} }
} }
} }
@ -2493,10 +2500,6 @@ void GpioInit()
} }
} }
if (EXS_RELAY == Settings.module) {
SetLatchingRelay(0,2);
SetLatchingRelay(1,2);
}
SetLedPower(Settings.ledstate &8); SetLedPower(Settings.ledstate &8);
XdrvCall(FUNC_PRE_INIT); XdrvCall(FUNC_PRE_INIT);

View File

@ -232,6 +232,9 @@ enum SupportedModules {
SHELLY2, SHELLY2,
PHILIPS, PHILIPS,
NEO_COOLCAM, NEO_COOLCAM,
ESP_SWITCH,
OBI,
TECKIN,
MAXMODULE }; MAXMODULE };
/********************************************************************************************/ /********************************************************************************************/
@ -355,31 +358,31 @@ const uint8_t kGpioNiceList[GPIO_SENSOR_END] PROGMEM = {
}; };
const uint8_t kModuleNiceList[MAXMODULE] PROGMEM = { const uint8_t kModuleNiceList[MAXMODULE] PROGMEM = {
SONOFF_BASIC, SONOFF_BASIC, // Sonoff Relay Devices
SONOFF_RF, SONOFF_RF,
SONOFF_TH, SONOFF_TH,
SONOFF_DUAL, SONOFF_DUAL,
SONOFF_DUAL_R2, SONOFF_DUAL_R2,
SONOFF_POW, SONOFF_POW,
SONOFF_POW_R2, SONOFF_POW_R2,
SONOFF_S31,
SONOFF_4CH, SONOFF_4CH,
SONOFF_4CHPRO, SONOFF_4CHPRO,
SONOFF_SV, SONOFF_S31, // Sonoff Socket Relay Devices with Energy Monitoring
SONOFF_DEV, SONOFF_S2X, // Sonoff Socket Relay Devices
SONOFF_S2X, SONOFF_TOUCH, // Sonoff Switch Devices
SLAMPHER,
SONOFF_TOUCH,
SONOFF_T11, SONOFF_T11,
SONOFF_T12, SONOFF_T12,
SONOFF_T13, SONOFF_T13,
SONOFF_SC, SONOFF_LED, // Sonoff Light Devices
SONOFF_B1,
SONOFF_LED,
SONOFF_BN, SONOFF_BN,
SONOFF_IFAN02, SONOFF_B1, // Sonoff Light Bulbs
SONOFF_BRIDGE, SLAMPHER,
CH1, SONOFF_SC, // Sonoff Environmemtal Sensor
SONOFF_IFAN02, // Sonoff Fan
SONOFF_BRIDGE, // Sonoff Bridge
SONOFF_SV, // Sonoff Development Devices
SONOFF_DEV,
CH1, // Relay Devices
CH4, CH4,
MOTOR, MOTOR,
ELECTRODRAGON, ELECTRODRAGON,
@ -390,9 +393,12 @@ const uint8_t kModuleNiceList[MAXMODULE] PROGMEM = {
WION, WION,
SHELLY1, SHELLY1,
SHELLY2, SHELLY2,
BLITZWOLF_BWSHP2, BLITZWOLF_BWSHP2, // Socket Relay Devices with Energy Monitoring
NEO_COOLCAM, TECKIN,
H801, NEO_COOLCAM, // Socket Relay Devices
OBI,
ESP_SWITCH, // Switch Devices
H801, // Light Devices
MAGICHOME, MAGICHOME,
ARILUX_LC01, ARILUX_LC01,
ARILUX_LC06, ARILUX_LC06,
@ -400,9 +406,9 @@ const uint8_t kModuleNiceList[MAXMODULE] PROGMEM = {
ZENGGE_ZF_WF017, ZENGGE_ZF_WF017,
HUAFAN_SS, HUAFAN_SS,
KMC_70011, KMC_70011,
AILIGHT, AILIGHT, // Light Bulbs
PHILIPS, PHILIPS,
WITTY, WITTY, // Development Devices
WEMOS WEMOS
}; };
@ -598,21 +604,22 @@ const mytmplt kModules[MAXMODULE] PROGMEM = {
GPIO_LED1, // GPIO16 Green/Blue Led (1 = On, 0 = Off) GPIO_LED1, // GPIO16 Green/Blue Led (1 = On, 0 = Off)
GPIO_ADC0 // ADC0 A0 Analog input GPIO_ADC0 // ADC0 A0 Analog input
}, },
{ "EXS Relay", // Latching relay (ESP8266) { "EXS Relay(s)", // ES-Store Latching relay(s) (ESP8266)
// https://ex-store.de/ESP8266-WiFi-Relay-V31 // https://ex-store.de/ESP8266-WiFi-Relay-V31
// Module Pin 1 VCC 3V3, Module Pin 6 GND // V3.1 Module Pin 1 VCC 3V3, Module Pin 6 GND
GPIO_KEY1, // GPIO00 Module Pin 8 - Button (firmware flash) // https://ex-store.de/2-Kanal-WiFi-WLan-Relay-V5-Blackline-fuer-Unterputzmontage
GPIO_USER, // GPIO01 Module Pin 2 = UART0_TXD GPIO_USER, // GPIO00 V3.1 Module Pin 8 - V5.0 Module Pin 4
GPIO_USER, // GPIO02 Module Pin 7 GPIO_USER, // GPIO01 UART0_TXD V3.1 Module Pin 2 - V5.0 Module Pin 3
GPIO_USER, // GPIO03 Module Pin 3 = UART0_RXD GPIO_USER, // GPIO02 V3.1 Module Pin 7
GPIO_USER, // GPIO04 Module Pin 10 GPIO_USER, // GPIO03 UART0_RXD V3.1 Module Pin 3
GPIO_USER, // GPIO05 Module Pin 9 GPIO_USER, // GPIO04 V3.1 Module Pin 10 - V5.0 Module Pin 2
GPIO_USER, // GPIO05 V3.1 Module Pin 9 - V5.0 Module Pin 1
0, 0, 0, 0, 0, 0, // Flash connection 0, 0, 0, 0, 0, 0, // Flash connection
GPIO_REL1, // GPIO12 Relay1 ( 1 = Off) GPIO_REL1, // GPIO12 Relay1 ( 1 = Off)
GPIO_REL2, // GPIO13 Relay1 ( 1 = On) GPIO_REL2, // GPIO13 Relay1 ( 1 = On)
GPIO_USER, // GPIO14 Module Pin 5 GPIO_USER, // GPIO14 V3.1 Module Pin 5 - V5.0 GPIO_REL3_INV Relay2 ( 1 = Off)
0, GPIO_LED1, // GPIO15 V5.0 LED1
GPIO_USER, // GPIO16 Module Pin 4 GPIO_USER, // GPIO16 V3.1 Module Pin 4 - V5.0 GPIO_REL4_INV Relay2 ( 1 = On)
0 0
}, },
{ "WiOn", // Indoor Tap (ESP8266) { "WiOn", // Indoor Tap (ESP8266)
@ -855,19 +862,20 @@ const mytmplt kModules[MAXMODULE] PROGMEM = {
0, 0, 0, 0, 0, 0, // Flash connection 0, 0, 0, 0, 0, 0, // Flash connection
0, 0, 0, 0, 0 0, 0, 0, 0, 0
}, },
{ "MagicHome", // Magic Home (aka Flux-light) (ESP8266) { "MagicHome", // Magic Home (aka Flux-light) (ESP8266) and Arilux LC10 (ESP8285)
// https://www.aliexpress.com/item/Magic-Home-Mini-RGB-RGBW-Wifi-Controller-For-Led-Strip-Panel-light-Timing-Function-16million-colors/32686853650.html // https://www.aliexpress.com/item/Magic-Home-Mini-RGB-RGBW-Wifi-Controller-For-Led-Strip-Panel-light-Timing-Function-16million-colors/32686853650.html
0, 0,
GPIO_USER, // GPIO01 Serial RXD and Optional sensor GPIO_USER, // GPIO01 Serial RXD and Optional sensor
GPIO_LED1_INV, // GPIO02 Blue onboard LED GPIO_LED1_INV, // GPIO02 Blue onboard LED
GPIO_USER, // GPIO03 Serial TXD and Optional sensor GPIO_USER, // GPIO03 Serial TXD and Optional sensor
GPIO_USER, // GPIO04 IR receiver (optional) GPIO_ARIRFRCV, // GPIO04 IR or RF receiver (optional) (Arilux LC10)
GPIO_PWM2, // GPIO05 RGB LED Green GPIO_PWM2, // GPIO05 RGB LED Green
0, 0, 0, 0, 0, 0, // Flash connection 0, 0, 0, 0, 0, 0, // Flash connection
GPIO_PWM3, // GPIO12 RGB LED Blue GPIO_PWM3, // GPIO12 RGB LED Blue
GPIO_USER, // GPIO13 RGBW LED White (optional - set to PWM4 for Cold White or Warm White) GPIO_USER, // GPIO13 RGBW LED White (optional - set to PWM4 for Cold White or Warm White as used on Arilux LC10)
GPIO_PWM1, // GPIO14 RGB LED Red GPIO_PWM1, // GPIO14 RGB LED Red
0, 0, 0 GPIO_LED2_INV, // GPIO15 RF receiver control (Arilux LC10)
0, 0
}, },
{ "Luani HVIO", // ESP8266_HVIO { "Luani HVIO", // ESP8266_HVIO
// https://luani.de/projekte/esp8266-hvio/ // https://luani.de/projekte/esp8266-hvio/
@ -1060,18 +1068,70 @@ const mytmplt kModules[MAXMODULE] PROGMEM = {
{ "Neo Coolcam", // Neo Coolcam (ESP8266) { "Neo Coolcam", // Neo Coolcam (ESP8266)
// https://www.banggood.com/NEO-COOLCAM-WiFi-Mini-Smart-Plug-APP-Remote-Control-Timing-Smart-Socket-EU-Plug-p-1288562.html?cur_warehouse=CN // https://www.banggood.com/NEO-COOLCAM-WiFi-Mini-Smart-Plug-APP-Remote-Control-Timing-Smart-Socket-EU-Plug-p-1288562.html?cur_warehouse=CN
0, 0, 0, 0, 0, 0, 0, 0,
GPIO_LED1_INV, // GPIO13 Red Led (0 = On, 1 = Off) GPIO_LED1_INV, // GPIO04 Red Led (0 = On, 1 = Off)
0, 0,
0, 0, 0, 0, 0, 0, // Flash connection 0, 0, 0, 0, 0, 0, // Flash connection
GPIO_REL1, // GPIO12 Red Led and Relay (0 = Off, 1 = On) GPIO_REL1, // GPIO12 Red Led and Relay (0 = Off, 1 = On)
GPIO_KEY1, // GPIO13 Button GPIO_KEY1, // GPIO13 Button
0, 0, 0, 0 0, 0, 0, 0
},
{ "ESP Switch", // Michael Haustein 4 channel wall switch (ESP07 = ESP8266)
// Use rules for further actions like - rule on power1#state do publish cmnd/other_device/power %value% endon
GPIO_KEY2, // GPIO00 Button 2
GPIO_USER, // GPIO01 Serial RXD and Optional sensor
GPIO_REL3_INV, // GPIO02 Yellow Led 3 (0 = On, 1 = Off)
GPIO_USER, // GPIO03 Serial TXD and Optional sensor
GPIO_KEY1, // GPIO04 Button 1
GPIO_REL2_INV, // GPIO05 Red Led 2 (0 = On, 1 = Off)
0, 0, 0, 0, 0, 0, // Flash connection
GPIO_REL4_INV, // GPIO12 Blue Led 4 (0 = On, 1 = Off)
GPIO_KEY4, // GPIO13 Button 4
GPIO_KEY3, // GPIO14 Button 3
GPIO_LED1, // GPIO15 Optional sensor
GPIO_REL1_INV, // GPIO16 Green Led 1 (0 = On, 1 = Off)
},
{ "OBI Socket", // OBI socket (ESP8266) - https://www.obi.de/hausfunksteuerung/wifi-stecker-schuko/p/2291706
0, 0, 0, 0,
GPIO_LED1, // GPIO04 LED on top and in switch button
GPIO_REL1, // GPIO05 Relay 1 (0 = Off, 1 = On)
0, 0, 0, 0, 0, 0, // Flash connection
GPIO_LED2, // GPIO12
0, // GPIO13
GPIO_KEY1, // GPIO14 switch button
0, 0, 0
},
{ "Teckin", // https://www.amazon.de/gp/product/B07D5V139R
0,
GPIO_KEY1, // GPIO01 Serial TXD and Button
0,
GPIO_LED2_INV, // GPIO03 Serial RXD and Red Led (0 = On, 1 = Off)
GPIO_HLW_CF, // GPIO04 BL0937 or HJL-01 CF power
GPIO_HLW_CF1, // GPIO05 BL0937 or HJL-01 CF1 voltage / current
0, 0, 0, 0, 0, 0, // Flash connection
GPIO_HLW_SEL, // GPIO12 BL0937 or HJL-01 Sel output
GPIO_LED1_INV, // GPIO13 Blue Led (0 = On, 1 = Off)
GPIO_REL1, // GPIO14 Relay (0 = Off, 1 = On)
0, 0, 0
} }
}; };
/* /*
Optionals Optionals
{ "MagicHome", // Magic Home (aka Flux-light) (ESP8266)
// https://www.aliexpress.com/item/Magic-Home-Mini-RGB-RGBW-Wifi-Controller-For-Led-Strip-Panel-light-Timing-Function-16million-colors/32686853650.html
0,
GPIO_USER, // GPIO01 Serial RXD and Optional sensor
GPIO_LED1_INV, // GPIO02 Blue onboard LED
GPIO_USER, // GPIO03 Serial TXD and Optional sensor
GPIO_USER, // GPIO04 IR receiver (optional)
GPIO_PWM2, // GPIO05 RGB LED Green
0, 0, 0, 0, 0, 0, // Flash connection
GPIO_PWM3, // GPIO12 RGB LED Blue
GPIO_USER, // GPIO13 RGBW LED White (optional - set to PWM4 for Cold White or Warm White)
GPIO_PWM1, // GPIO14 RGB LED Red
0, 0, 0
},
{ "Arilux LC10", // Arilux LC10 (ESP8285), RGBW + RF { "Arilux LC10", // Arilux LC10 (ESP8285), RGBW + RF
// https://github.com/arendst/Sonoff-Tasmota/wiki/MagicHome-with-ESP8285 // https://github.com/arendst/Sonoff-Tasmota/wiki/MagicHome-with-ESP8285
// https://www.aliexpress.com/item/DC5-24V-Wireless-WIFI-LED-RGB-Controller-RGBW-Controller-IR-RF-Remote-Control-IOS-Android-for/32827253255.html // https://www.aliexpress.com/item/DC5-24V-Wireless-WIFI-LED-RGB-Controller-RGBW-Controller-IR-RF-Remote-Control-IOS-Android-for/32827253255.html

View File

@ -20,7 +20,7 @@
#ifndef _SONOFF_VERSION_H_ #ifndef _SONOFF_VERSION_H_
#define _SONOFF_VERSION_H_ #define _SONOFF_VERSION_H_
#define VERSION 0x06020109 #define VERSION 0x0602010A
#define D_PROGRAMNAME "Sonoff-Tasmota" #define D_PROGRAMNAME "Sonoff-Tasmota"
#define D_AUTHOR "Theo Arends" #define D_AUTHOR "Theo Arends"

View File

@ -1775,27 +1775,35 @@ int8_t I2cWriteBuffer(uint8_t addr, uint8_t reg, uint8_t *reg_data, uint16_t len
void I2cScan(char *devs, unsigned int devs_len) void I2cScan(char *devs, unsigned int devs_len)
{ {
byte error; // Return error codes defined in twi.h and core_esp8266_si2c.c
byte address; // I2C_OK 0
// I2C_SCL_HELD_LOW 1 = SCL held low by another device, no procedure available to recover
// I2C_SCL_HELD_LOW_AFTER_READ 2 = I2C bus error. SCL held low beyond slave clock stretch time
// I2C_SDA_HELD_LOW 3 = I2C bus error. SDA line held low by slave/another_master after n bits
// I2C_SDA_HELD_LOW_AFTER_INIT 4 = line busy. SDA again held low by another device. 2nd master?
byte error = 0;
byte address = 0;
byte any = 0; byte any = 0;
char tstr[10];
snprintf_P(devs, devs_len, PSTR("{\"" D_CMND_I2CSCAN "\":\"" D_JSON_I2CSCAN_DEVICES_FOUND_AT)); snprintf_P(devs, devs_len, PSTR("{\"" D_CMND_I2CSCAN "\":\"" D_JSON_I2CSCAN_DEVICES_FOUND_AT));
for (address = 1; address <= 127; address++) { for (address = 1; address <= 127; address++) {
Wire.beginTransmission(address); Wire.beginTransmission(address);
error = Wire.endTransmission(); error = Wire.endTransmission();
if (0 == error) { if (0 == error) {
snprintf_P(tstr, sizeof(tstr), PSTR(" 0x%2x"), address);
strncat(devs, tstr, devs_len);
any = 1; any = 1;
snprintf_P(devs, devs_len, PSTR("%s 0x%02x"), devs, address);
} }
else if (4 == error) { else if (error != 2) { // Seems to happen anyway using this scan
snprintf_P(devs, devs_len, PSTR("{\"" D_CMND_I2CSCAN "\":\"" D_JSON_I2CSCAN_UNKNOWN_ERROR_AT " 0x%2x\"}"), address); any = 2;
snprintf_P(devs, devs_len, PSTR("{\"" D_CMND_I2CSCAN "\":\"Error %d at 0x%02x"), error, address);
break;
} }
} }
if (any) { if (any) {
strncat(devs, "\"}", devs_len); strncat(devs, "\"}", devs_len);
} else { }
else {
snprintf_P(devs, devs_len, PSTR("{\"" D_CMND_I2CSCAN "\":\"" D_JSON_I2CSCAN_NO_DEVICES_FOUND "\"}")); snprintf_P(devs, devs_len, PSTR("{\"" D_CMND_I2CSCAN "\":\"" D_JSON_I2CSCAN_NO_DEVICES_FOUND "\"}"));
} }
} }

View File

@ -302,6 +302,7 @@
// #define USE_MCP230xx_DISPLAYOUTPUT // Enable MCP23008/MCP23017 to display state of OUTPUT pins on Web UI (+0k2 code) // #define USE_MCP230xx_DISPLAYOUTPUT // Enable MCP23008/MCP23017 to display state of OUTPUT pins on Web UI (+0k2 code)
// #define USE_PCA9685 // Enable PCA9685 I2C HW PWM Driver - Must define I2C Address in #define USE_PCA9685_ADDR below - range 0x40 - 0x47 (+1k4 code) // #define USE_PCA9685 // Enable PCA9685 I2C HW PWM Driver - Must define I2C Address in #define USE_PCA9685_ADDR below - range 0x40 - 0x47 (+1k4 code)
// #define USE_PCA9685_ADDR 0x40 // Enable PCA9685 I2C Address to use (Must be within range 0x40 through 0x47 - set according to your wired setup) // #define USE_PCA9685_ADDR 0x40 // Enable PCA9685 I2C Address to use (Must be within range 0x40 through 0x47 - set according to your wired setup)
// #define USE_PCA9685_FREQ 50 // Define default PWM frequency in Hz to be used (must be within 24 to 1526) - If other value is used, it will rever to 50Hz
// #define USE_MPR121 // Enable MPR121 controller (I2C addresses 0x5A, 0x5B, 0x5C and 0x5D) in input mode for touch buttons (+1k3 code) // #define USE_MPR121 // Enable MPR121 controller (I2C addresses 0x5A, 0x5B, 0x5C and 0x5D) in input mode for touch buttons (+1k3 code)
// #define USE_CCS811 // Enable CCS811 sensor (I2C address 0x5A) (+2k2 code) // #define USE_CCS811 // Enable CCS811 sensor (I2C address 0x5A) (+2k2 code)
// #define USE_MPU6050 // Enable MPU6050 sensor (I2C address 0x68 AD0 low or 0x69 AD0 high) (+2k6 code) // #define USE_MPU6050 // Enable MPU6050 sensor (I2C address 0x68 AD0 low or 0x69 AD0 high) (+2k6 code)

View File

@ -1013,6 +1013,10 @@ void HandleBackupConfiguration()
WebServer->sendHeader(F("Content-Disposition"), attachment); WebServer->sendHeader(F("Content-Disposition"), attachment);
WebServer->send(200, FPSTR(HDR_CTYPE_STREAM), ""); WebServer->send(200, FPSTR(HDR_CTYPE_STREAM), "");
uint16_t cfg_crc = Settings.cfg_crc;
Settings.cfg_crc = GetSettingsCrc(); // Calculate crc (again) as it might be wrong when savedata = 0 (#3918)
memcpy(settings_buffer, &Settings, sizeof(Settings)); memcpy(settings_buffer, &Settings, sizeof(Settings));
if (config_xor_on_set) { if (config_xor_on_set) {
for (uint16_t i = 2; i < sizeof(Settings); i++) { for (uint16_t i = 2; i < sizeof(Settings); i++) {
@ -1030,6 +1034,8 @@ void HandleBackupConfiguration()
#endif #endif
SettingsBufferFree(); SettingsBufferFree();
Settings.cfg_crc = cfg_crc; // Restore crc in case savedata = 0 to make sure settings will be noted as changed
} }
void HandleSaveSettings() void HandleSaveSettings()

View File

@ -55,11 +55,11 @@
enum LightCommands { enum LightCommands {
CMND_COLOR, CMND_COLORTEMPERATURE, CMND_DIMMER, CMND_LED, CMND_LEDTABLE, CMND_FADE, CMND_COLOR, CMND_COLORTEMPERATURE, CMND_DIMMER, CMND_LED, CMND_LEDTABLE, CMND_FADE,
CMND_PIXELS, CMND_ROTATION, CMND_SCHEME, CMND_SPEED, CMND_WAKEUP, CMND_WAKEUPDURATION, CMND_PIXELS, CMND_RGBWWTABLE, CMND_ROTATION, CMND_SCHEME, CMND_SPEED, CMND_WAKEUP, CMND_WAKEUPDURATION,
CMND_WIDTH, CMND_CHANNEL, CMND_HSBCOLOR, CMND_UNDOCA }; CMND_WIDTH, CMND_CHANNEL, CMND_HSBCOLOR, CMND_UNDOCA };
const char kLightCommands[] PROGMEM = const char kLightCommands[] PROGMEM =
D_CMND_COLOR "|" D_CMND_COLORTEMPERATURE "|" D_CMND_DIMMER "|" D_CMND_LED "|" D_CMND_LEDTABLE "|" D_CMND_FADE "|" D_CMND_COLOR "|" D_CMND_COLORTEMPERATURE "|" D_CMND_DIMMER "|" D_CMND_LED "|" D_CMND_LEDTABLE "|" D_CMND_FADE "|"
D_CMND_PIXELS "|" D_CMND_ROTATION "|" D_CMND_SCHEME "|" D_CMND_SPEED "|" D_CMND_WAKEUP "|" D_CMND_WAKEUPDURATION "|" D_CMND_PIXELS "|" D_CMND_RGBWWTABLE "|" D_CMND_ROTATION "|" D_CMND_SCHEME "|" D_CMND_SPEED "|" D_CMND_WAKEUP "|" D_CMND_WAKEUPDURATION "|"
D_CMND_WIDTH "|" D_CMND_CHANNEL "|" D_CMND_HSBCOLOR "|UNDOCA" ; D_CMND_WIDTH "|" D_CMND_CHANNEL "|" D_CMND_HSBCOLOR "|UNDOCA" ;
struct LRgbColor { struct LRgbColor {
@ -799,7 +799,8 @@ void LightAnimate()
light_update = 0; light_update = 0;
for (byte i = 0; i < light_subtype; i++) { for (byte i = 0; i < light_subtype; i++) {
light_last_color[i] = light_new_color[i]; light_last_color[i] = light_new_color[i];
cur_col[i] = (Settings.light_correction) ? ledTable[light_last_color[i]] : light_last_color[i]; cur_col[i] = light_last_color[i]*Settings.rgbwwTable[i]/255;
cur_col[i] = (Settings.light_correction) ? ledTable[cur_col[i]] : cur_col[i];
if (light_type < LT_PWM6) { if (light_type < LT_PWM6) {
if (pin[GPIO_PWM1 +i] < 99) { if (pin[GPIO_PWM1 +i] < 99) {
if (cur_col[i] > 0xFC) { if (cur_col[i] > 0xFC) {
@ -1279,6 +1280,33 @@ boolean LightCommand()
} }
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_SVALUE, command, GetStateText(Settings.light_correction)); snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_SVALUE, command, GetStateText(Settings.light_correction));
} }
else if (CMND_RGBWWTABLE == command_code) {
bool validtable = (XdrvMailbox.data_len > 0);
char scolor[25];
if (validtable) {
uint16_t HSB[3];
if (strstr(XdrvMailbox.data, ",")) { // Command with up to 5 comma separated parameters
for (int i = 0; i < LST_RGBWC; i++) {
char *substr;
if (0 == i) {
substr = strtok(XdrvMailbox.data, ",");
} else {
substr = strtok(NULL, ",");
}
if (substr != NULL) {
Settings.rgbwwTable[i] = atoi(substr);
}
}
}
light_update = 1;
}
scolor[0] = '\0';
for (byte i = 0; i < LST_RGBWC; i++) {
snprintf_P(scolor, 25, PSTR("%s%s%d"), scolor, (i > 0) ? "," : "", Settings.rgbwwTable[i]);
}
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_INDEX_SVALUE, command, XdrvMailbox.index, scolor);
}
else if (CMND_FADE == command_code) { else if (CMND_FADE == command_code) {
switch (XdrvMailbox.payload) { switch (XdrvMailbox.payload) {
case 0: // Off case 0: // Off

View File

@ -194,7 +194,7 @@ void ApplyTimerOffsets(Timer *duskdawn)
// apply offsets, check for over- and underflows // apply offsets, check for over- and underflows
uint16_t timeBuffer; uint16_t timeBuffer;
if ((uint16_t)stored.time > 720) { if ((uint16_t)stored.time > 719) {
// negative offset, time after 12:00 // negative offset, time after 12:00
timeBuffer = (uint16_t)stored.time - 720; timeBuffer = (uint16_t)stored.time - 720;
// check for underflow // check for underflow

View File

@ -50,7 +50,7 @@ const char HASS_DISCOVER_LIGHT_DIMMER[] PROGMEM =
"\"brightness_value_template\":\"{{value_json." D_CMND_DIMMER "}}\""; "\"brightness_value_template\":\"{{value_json." D_CMND_DIMMER "}}\"";
const char HASS_DISCOVER_LIGHT_COLOR[] PROGMEM = const char HASS_DISCOVER_LIGHT_COLOR[] PROGMEM =
"%s,\"rgb_command_topic\":\"%s\"," // cmnd/led2/Color "%s,\"rgb_command_topic\":\"%s2\"," // cmnd/led2/Color2
"\"rgb_state_topic\":\"%s\"," // stat/led2/RESULT "\"rgb_state_topic\":\"%s\"," // stat/led2/RESULT
"\"rgb_value_template\":\"{{value_json." D_CMND_COLOR "}}\""; "\"rgb_value_template\":\"{{value_json." D_CMND_COLOR "}}\"";
// "\"rgb_value_template\":\"{{value_json." D_CMND_COLOR " | join(',')}}\""; // "\"rgb_value_template\":\"{{value_json." D_CMND_COLOR " | join(',')}}\"";

View File

@ -26,8 +26,13 @@
#define PCA9685_REG_LED0_ON_L 0x06 #define PCA9685_REG_LED0_ON_L 0x06
#define PCA9685_REG_PRE_SCALE 0xFE #define PCA9685_REG_PRE_SCALE 0xFE
#ifndef USE_PCA9685_FREQ
#define USE_PCA9685_FREQ 50
#endif
uint8_t pca9685_detected = 0; uint8_t pca9685_detected = 0;
uint16_t pca9685_freq = 50; uint16_t pca9685_freq = USE_PCA9685_FREQ;
uint16_t pca9685_pin_pwm_value[16];
void PCA9685_Detect(void) void PCA9685_Detect(void)
{ {
@ -51,9 +56,10 @@ void PCA9685_Detect(void)
void PCA9685_Reset(void) void PCA9685_Reset(void)
{ {
I2cWrite8(USE_PCA9685_ADDR, PCA9685_REG_MODE1, 0x80); I2cWrite8(USE_PCA9685_ADDR, PCA9685_REG_MODE1, 0x80);
PCA9685_SetPWMfreq(50); PCA9685_SetPWMfreq(USE_PCA9685_FREQ);
for (uint8_t pin=0;pin<16;pin++) { for (uint8_t pin=0;pin<16;pin++) {
PCA9685_SetPWM(pin,0,false); PCA9685_SetPWM(pin,0,false);
pca9685_pin_pwm_value[pin] = 0;
} }
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"PCA9685\":{\"RESET\":\"OK\"}}")); snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"PCA9685\":{\"RESET\":\"OK\"}}"));
} }
@ -63,9 +69,13 @@ void PCA9685_SetPWMfreq(double freq) {
7.3.5 from datasheet 7.3.5 from datasheet
prescale value = round(25000000/(4096*freq))-1; prescale value = round(25000000/(4096*freq))-1;
*/ */
pca9685_freq=freq; if (freq > 23 && freq < 1527) {
uint8_t pre_scale_osc = round(25000000/(4096*freq))-1; pca9685_freq=freq;
if (1526 == freq) pre_scale_osc=0xFF; // force setting for 24hz because rounding causes 1526 to be 254 } else {
pca9685_freq=50;
}
uint8_t pre_scale_osc = round(25000000/(4096*pca9685_freq))-1;
if (1526 == pca9685_freq) pre_scale_osc=0xFF; // force setting for 24hz because rounding causes 1526 to be 254
uint8_t current_mode1 = I2cRead8(USE_PCA9685_ADDR, PCA9685_REG_MODE1); // read current value of MODE1 register uint8_t current_mode1 = I2cRead8(USE_PCA9685_ADDR, PCA9685_REG_MODE1); // read current value of MODE1 register
uint8_t sleep_mode1 = (current_mode1&0x7F) | 0x10; // Determine register value to put PCA to sleep uint8_t sleep_mode1 = (current_mode1&0x7F) | 0x10; // Determine register value to put PCA to sleep
I2cWrite8(USE_PCA9685_ADDR, PCA9685_REG_MODE1, sleep_mode1); // Let's sleep a little I2cWrite8(USE_PCA9685_ADDR, PCA9685_REG_MODE1, sleep_mode1); // Let's sleep a little
@ -107,6 +117,7 @@ bool PCA9685_Command(void)
if (',' == XdrvMailbox.data[ca]) { paramcount++; } if (',' == XdrvMailbox.data[ca]) { paramcount++; }
} }
UpperCase(XdrvMailbox.data,XdrvMailbox.data); UpperCase(XdrvMailbox.data,XdrvMailbox.data);
if (!strcmp(subStr(sub_string, XdrvMailbox.data, ",", 1),"RESET")) { PCA9685_Reset(); return serviced; } if (!strcmp(subStr(sub_string, XdrvMailbox.data, ",", 1),"RESET")) { PCA9685_Reset(); return serviced; }
if (!strcmp(subStr(sub_string, XdrvMailbox.data, ",", 1),"PWMF")) { if (!strcmp(subStr(sub_string, XdrvMailbox.data, ",", 1),"PWMF")) {
@ -114,7 +125,7 @@ bool PCA9685_Command(void)
uint16_t new_freq = atoi(subStr(sub_string, XdrvMailbox.data, ",", 2)); uint16_t new_freq = atoi(subStr(sub_string, XdrvMailbox.data, ",", 2));
if ((new_freq >= 24) && (new_freq <= 1526)) { if ((new_freq >= 24) && (new_freq <= 1526)) {
PCA9685_SetPWMfreq(new_freq); PCA9685_SetPWMfreq(new_freq);
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"PCA9685\":{\"PWMF\":%i, \"Result\":\"OK\"}}")); snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"PCA9685\":{\"PWMF\":%i, \"Result\":\"OK\"}}"),new_freq);
return serviced; return serviced;
} }
} else { // No parameter was given for setfreq, so we return current setting } else { // No parameter was given for setfreq, so we return current setting
@ -151,28 +162,34 @@ bool PCA9685_Command(void)
return serviced; return serviced;
} }
void PCA9685_OutputTelemetry(void) {
if (0 == pca9685_detected) { return; } // We do not do this if the PCA9685 has not been detected
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_JSON_TIME "\":\"%s\",\"PCA9685\": {"), GetDateAndTime(DT_LOCAL).c_str());
snprintf_P(mqtt_data,sizeof(mqtt_data), PSTR("%s\"PWM_FREQ\":%i,"),mqtt_data,pca9685_freq);
for (uint8_t pin=0;pin<16;pin++) {
snprintf_P(mqtt_data,sizeof(mqtt_data), PSTR("%s\"PWM%i\":%i,"),mqtt_data,pin,pca9685_pin_pwm_value[pin]);
}
snprintf_P(mqtt_data,sizeof(mqtt_data),PSTR("%s\"END\":1}}"),mqtt_data);
MqttPublishPrefixTopic_P(TELE, PSTR(D_RSLT_SENSOR), Settings.flag.mqtt_sensor_retain);
}
boolean Xdrv15(byte function) boolean Xdrv15(byte function)
{ {
boolean result = false; boolean result = false;
if (i2c_flg) { if (i2c_flg) {
switch (function) { switch (function) {
case FUNC_MQTT_DATA:
break;
case FUNC_EVERY_SECOND: case FUNC_EVERY_SECOND:
PCA9685_Detect(); PCA9685_Detect();
break; if (tele_period == 0) {
case FUNC_EVERY_50_MSECOND: PCA9685_OutputTelemetry();
break; }
case FUNC_JSON_APPEND:
break; break;
case FUNC_COMMAND: case FUNC_COMMAND:
if (XDRV_15 == XdrvMailbox.index) { if (XDRV_15 == XdrvMailbox.index) {
PCA9685_Command(); PCA9685_Command();
} }
break; break;
case FUNC_WEB_APPEND:
break;
default: default:
break; break;
} }

File diff suppressed because it is too large Load Diff