mirror of
https://github.com/arendst/Tasmota.git
synced 2025-07-28 05:06:32 +00:00
v5.11.1i - Fixes Energy, PWM and Tsl2561
5.11.1i * Fix some Energy Monitoring related issues (#1677) * Fix TSL2561 device detection (#1644) * Fix command PWM response if no PWM channel is configured (#1783)
This commit is contained in:
parent
265e0a03f7
commit
0d6275fe5e
@ -5,8 +5,10 @@
|
|||||||
* Fix some Energy Monitoring related issues
|
* Fix some Energy Monitoring related issues
|
||||||
* Add command SetOption21 1 to allow Energy Monitoring when power is off on Sonoff Pow and Sonoff S31 (#1420)
|
* Add command SetOption21 1 to allow Energy Monitoring when power is off on Sonoff Pow and Sonoff S31 (#1420)
|
||||||
* Add support for Sonoff S31 Smart Socket with Power Consumption Detection (#1626)
|
* Add support for Sonoff S31 Smart Socket with Power Consumption Detection (#1626)
|
||||||
|
* Fix TSL2561 device detection (#1644)
|
||||||
* Fix IRReceive Data value (#1663)
|
* Fix IRReceive Data value (#1663)
|
||||||
* Fix compiler warnings (#1774)
|
* Fix compiler warnings (#1774)
|
||||||
|
* Fix command PWM response if no PWM channel is configured (#1783)
|
||||||
*
|
*
|
||||||
* 5.11.1h
|
* 5.11.1h
|
||||||
* Rewrite webserver argument processing gaining 5k code space (#1705)
|
* Rewrite webserver argument processing gaining 5k code space (#1705)
|
||||||
|
@ -185,6 +185,7 @@ uint8_t energy_flg = 1; // Energy monitor configured
|
|||||||
uint8_t i2c_flg = 0; // I2C configured
|
uint8_t i2c_flg = 0; // I2C configured
|
||||||
uint8_t spi_flg = 0; // SPI configured
|
uint8_t spi_flg = 0; // SPI configured
|
||||||
uint8_t light_type = 0; // Light types
|
uint8_t light_type = 0; // Light types
|
||||||
|
bool pwm_present = false; // Any PWM channel configured with SetOption15 0
|
||||||
|
|
||||||
boolean mdns_begun = false;
|
boolean mdns_begun = false;
|
||||||
|
|
||||||
@ -1179,7 +1180,7 @@ void MqttDataCallback(char* topic, byte* data, unsigned int data_len)
|
|||||||
}
|
}
|
||||||
mqtt_data[0] = '\0';
|
mqtt_data[0] = '\0';
|
||||||
}
|
}
|
||||||
else if ((CMND_PWM == command_code) && !light_type && (index > 0) && (index <= MAX_PWMS)) {
|
else if ((CMND_PWM == command_code) && pwm_present && (index > 0) && (index <= MAX_PWMS)) {
|
||||||
if ((payload >= 0) && (payload <= Settings.pwm_range) && (pin[GPIO_PWM1 + index -1] < 99)) {
|
if ((payload >= 0) && (payload <= Settings.pwm_range) && (pin[GPIO_PWM1 + index -1] < 99)) {
|
||||||
Settings.pwm_value[index -1] = payload;
|
Settings.pwm_value[index -1] = payload;
|
||||||
analogWrite(pin[GPIO_PWM1 + index -1], bitRead(pwm_inverted, index -1) ? Settings.pwm_range - payload : payload);
|
analogWrite(pin[GPIO_PWM1 + index -1], bitRead(pwm_inverted, index -1) ? Settings.pwm_range - payload : payload);
|
||||||
@ -2642,6 +2643,7 @@ void GpioInit()
|
|||||||
if (!light_type) {
|
if (!light_type) {
|
||||||
for (byte i = 0; i < MAX_PWMS; i++) { // Basic PWM control only
|
for (byte i = 0; i < MAX_PWMS; i++) { // Basic PWM control only
|
||||||
if (pin[GPIO_PWM1 +i] < 99) {
|
if (pin[GPIO_PWM1 +i] < 99) {
|
||||||
|
pwm_present = true;
|
||||||
pinMode(pin[GPIO_PWM1 +i], OUTPUT);
|
pinMode(pin[GPIO_PWM1 +i], OUTPUT);
|
||||||
analogWrite(pin[GPIO_PWM1 +i], bitRead(pwm_inverted, i) ? Settings.pwm_range - Settings.pwm_value[i] : Settings.pwm_value[i]);
|
analogWrite(pin[GPIO_PWM1 +i], bitRead(pwm_inverted, i) ? Settings.pwm_range - Settings.pwm_value[i] : Settings.pwm_value[i]);
|
||||||
}
|
}
|
||||||
|
@ -47,7 +47,7 @@ float energy_power = 0; // 123.1 W
|
|||||||
float energy_power_factor = 0; // 0.12
|
float energy_power_factor = 0; // 0.12
|
||||||
float energy_daily = 0; // 12.123 kWh
|
float energy_daily = 0; // 12.123 kWh
|
||||||
float energy_total = 0; // 12345.12345 kWh
|
float energy_total = 0; // 12345.12345 kWh
|
||||||
float energy_start = 0; // 12345.12345 kWh total from yesterday
|
float energy_start = 0; // 12345.12345 kWh total previous
|
||||||
unsigned long energy_kWhtoday; // 1212312345 Wh * 10^-5 (deca micro Watt hours) - 5763924 = 0.05763924 kWh = 0.058 kWh = energy_daily
|
unsigned long energy_kWhtoday; // 1212312345 Wh * 10^-5 (deca micro Watt hours) - 5763924 = 0.05763924 kWh = 0.058 kWh = energy_daily
|
||||||
unsigned long energy_period = 0; // 1212312345 Wh * 10^-5 (deca micro Watt hours) - 5763924 = 0.05763924 kWh = 0.058 kWh = energy_daily
|
unsigned long energy_period = 0; // 1212312345 Wh * 10^-5 (deca micro Watt hours) - 5763924 = 0.05763924 kWh = 0.058 kWh = energy_daily
|
||||||
|
|
||||||
@ -254,7 +254,7 @@ void HlwInit()
|
|||||||
|
|
||||||
#define CSE_NOT_CALIBRATED 0xAA
|
#define CSE_NOT_CALIBRATED 0xAA
|
||||||
|
|
||||||
#define CSE_PULSES_NOT_INITIALIZED 0x90000
|
#define CSE_PULSES_NOT_INITIALIZED -1
|
||||||
|
|
||||||
#define CSE_PREF 1000
|
#define CSE_PREF 1000
|
||||||
#define CSE_UREF 100
|
#define CSE_UREF 100
|
||||||
@ -314,9 +314,9 @@ void CseReceived()
|
|||||||
power_cycle = serial_in_buffer[17] << 16 | serial_in_buffer[18] << 8 | serial_in_buffer[19];
|
power_cycle = serial_in_buffer[17] << 16 | serial_in_buffer[18] << 8 | serial_in_buffer[19];
|
||||||
cf_pulses = serial_in_buffer[21] << 8 | serial_in_buffer[22];
|
cf_pulses = serial_in_buffer[21] << 8 | serial_in_buffer[22];
|
||||||
|
|
||||||
if (adjustement & 0x80) { // CF overflow
|
// if (adjustement & 0x80) { // CF overflow
|
||||||
cf_pulses = cf_pulses | 0x10000;
|
// cf_pulses += 0x10000;
|
||||||
}
|
// }
|
||||||
if (energy_power_on) { // Powered on
|
if (energy_power_on) { // Powered on
|
||||||
if (adjustement & 0x40) { // Voltage valid
|
if (adjustement & 0x40) { // Voltage valid
|
||||||
energy_voltage = (float)(Settings.energy_voltage_calibration * CSE_UREF) / (float)voltage_cycle;
|
energy_voltage = (float)(Settings.energy_voltage_calibration * CSE_UREF) / (float)voltage_cycle;
|
||||||
@ -367,11 +367,16 @@ bool CseSerialInput()
|
|||||||
|
|
||||||
void CseEverySecond()
|
void CseEverySecond()
|
||||||
{
|
{
|
||||||
|
long cf_frequency = 0;
|
||||||
|
|
||||||
if (CSE_PULSES_NOT_INITIALIZED == cf_pulses_last_time) {
|
if (CSE_PULSES_NOT_INITIALIZED == cf_pulses_last_time) {
|
||||||
cf_pulses_last_time = cf_pulses;
|
cf_pulses_last_time = cf_pulses; // Init after restart
|
||||||
} else {
|
} else {
|
||||||
if (cf_pulses < cf_pulses_last_time) cf_pulses_last_time = 0; // Looses at most one second of data
|
if (cf_pulses < cf_pulses_last_time) { // Rolled over after 65535 pulses
|
||||||
unsigned long cf_frequency = cf_pulses - cf_pulses_last_time;
|
cf_frequency = (65536 - cf_pulses_last_time) + cf_pulses;
|
||||||
|
} else {
|
||||||
|
cf_frequency = cf_pulses - cf_pulses_last_time;
|
||||||
|
}
|
||||||
if (cf_frequency && energy_power) {
|
if (cf_frequency && energy_power) {
|
||||||
cf_pulses_last_time = cf_pulses;
|
cf_pulses_last_time = cf_pulses;
|
||||||
energy_kWhtoday += (cf_frequency * Settings.energy_power_calibration) / 36;
|
energy_kWhtoday += (cf_frequency * Settings.energy_power_calibration) / 36;
|
||||||
@ -424,9 +429,7 @@ IPAddress pzem_ip(192, 168, 1, 1);
|
|||||||
uint8_t PzemCrc(uint8_t *data)
|
uint8_t PzemCrc(uint8_t *data)
|
||||||
{
|
{
|
||||||
uint16_t crc = 0;
|
uint16_t crc = 0;
|
||||||
for (uint8_t i = 0; i < sizeof(PZEMCommand) -1; i++) {
|
for (uint8_t i = 0; i < sizeof(PZEMCommand) -1; i++) crc += *data++;
|
||||||
crc += *data++;
|
|
||||||
}
|
|
||||||
return (uint8_t)(crc & 0xFF);
|
return (uint8_t)(crc & 0xFF);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -435,9 +438,7 @@ void PzemSend(uint8_t cmd)
|
|||||||
PZEMCommand pzem;
|
PZEMCommand pzem;
|
||||||
|
|
||||||
pzem.command = cmd;
|
pzem.command = cmd;
|
||||||
for (uint8_t i = 0; i < sizeof(pzem.addr); i++) {
|
for (uint8_t i = 0; i < sizeof(pzem.addr); i++) pzem.addr[i] = pzem_ip[i];
|
||||||
pzem.addr[i] = pzem_ip[i];
|
|
||||||
}
|
|
||||||
pzem.data = 0;
|
pzem.data = 0;
|
||||||
|
|
||||||
uint8_t *bytes = (uint8_t*)&pzem;
|
uint8_t *bytes = (uint8_t*)&pzem;
|
||||||
@ -514,30 +515,24 @@ void PzemEvery200ms()
|
|||||||
float value = 0;
|
float value = 0;
|
||||||
if (PzemRecieve(pzem_responses[pzem_read_state], &value)) {
|
if (PzemRecieve(pzem_responses[pzem_read_state], &value)) {
|
||||||
switch (pzem_read_state) {
|
switch (pzem_read_state) {
|
||||||
case 1:
|
case 1: // Voltage as 230.2V
|
||||||
energy_voltage = value; // 230.2V
|
energy_voltage = value;
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2: // Current as 17.32A
|
||||||
energy_current = value; // 17.32A
|
energy_current = value;
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3: // Power as 20W
|
||||||
energy_power = value; // 20W
|
energy_power = value;
|
||||||
break;
|
break;
|
||||||
case 4:
|
case 4: // Total energy as 99999Wh
|
||||||
energy_total = value / 1000; // 99999Wh
|
if (!energy_start || (value < energy_start)) energy_start = value; // Init after restart and hanlde roll-over if any
|
||||||
if (energy_total < energy_start) {
|
energy_kWhtoday += (value - energy_start) * 100000;
|
||||||
energy_start = energy_total;
|
energy_start = value;
|
||||||
Settings.energy_power_calibration = energy_start * 1000;
|
EnergyUpdateToday();
|
||||||
}
|
|
||||||
energy_kWhtoday = (energy_total - energy_start) * 100000000;
|
|
||||||
RtcSettings.energy_kWhtoday = energy_kWhtoday;
|
|
||||||
energy_daily = (float)energy_kWhtoday / 100000000;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
pzem_read_state++;
|
pzem_read_state++;
|
||||||
if (5 == pzem_read_state) {
|
if (5 == pzem_read_state) pzem_read_state = 1;
|
||||||
pzem_read_state = 1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -565,13 +560,8 @@ void Energy200ms()
|
|||||||
if (5 == energy_fifth_second) {
|
if (5 == energy_fifth_second) {
|
||||||
energy_fifth_second = 0;
|
energy_fifth_second = 0;
|
||||||
|
|
||||||
if (ENERGY_HLW8012 == energy_flg) {
|
if (ENERGY_HLW8012 == energy_flg) HlwEverySecond();
|
||||||
HlwEverySecond();
|
if (ENERGY_CSE7766 == energy_flg) CseEverySecond();
|
||||||
}
|
|
||||||
|
|
||||||
if (ENERGY_CSE7766 == energy_flg) {
|
|
||||||
CseEverySecond();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (RtcTime.valid) {
|
if (RtcTime.valid) {
|
||||||
if (LocalTime() == Midnight()) {
|
if (LocalTime() == Midnight()) {
|
||||||
@ -580,13 +570,7 @@ void Energy200ms()
|
|||||||
RtcSettings.energy_kWhtotal = Settings.energy_kWhtotal;
|
RtcSettings.energy_kWhtotal = Settings.energy_kWhtotal;
|
||||||
energy_kWhtoday = 0;
|
energy_kWhtoday = 0;
|
||||||
energy_period = energy_kWhtoday;
|
energy_period = energy_kWhtoday;
|
||||||
RtcSettings.energy_kWhtoday = energy_kWhtoday;
|
EnergyUpdateToday();
|
||||||
#ifdef USE_PZEM004T
|
|
||||||
if (ENERGY_PZEM004T == energy_flg) {
|
|
||||||
energy_start = energy_total;
|
|
||||||
Settings.energy_power_calibration = energy_start * 1000;
|
|
||||||
}
|
|
||||||
#endif // USE_PZEM004T
|
|
||||||
energy_max_energy_state = 3;
|
energy_max_energy_state = 3;
|
||||||
}
|
}
|
||||||
if ((RtcTime.hour == Settings.energy_max_energy_start) && (3 == energy_max_energy_state)) {
|
if ((RtcTime.hour == Settings.energy_max_energy_start) && (3 == energy_max_energy_state)) {
|
||||||
@ -597,21 +581,15 @@ void Energy200ms()
|
|||||||
|
|
||||||
energy_power_on = (power &1) | Settings.flag.no_power_on_check;
|
energy_power_on = (power &1) | Settings.flag.no_power_on_check;
|
||||||
|
|
||||||
if (ENERGY_HLW8012 == energy_flg) {
|
if (ENERGY_HLW8012 == energy_flg) HlwEvery200ms();
|
||||||
HlwEvery200ms();
|
|
||||||
#ifdef USE_PZEM004T
|
#ifdef USE_PZEM004T
|
||||||
}
|
if (ENERGY_PZEM004T == energy_flg) PzemEvery200ms();
|
||||||
else if (ENERGY_PZEM004T == energy_flg) {
|
|
||||||
PzemEvery200ms();
|
|
||||||
#endif // USE_PZEM004T
|
#endif // USE_PZEM004T
|
||||||
}
|
|
||||||
|
|
||||||
float power_factor = 0;
|
float power_factor = 0;
|
||||||
if (energy_voltage && energy_current && energy_power) {
|
if (energy_voltage && energy_current && energy_power) {
|
||||||
power_factor = energy_power / (energy_voltage * energy_current);
|
power_factor = energy_power / (energy_voltage * energy_current);
|
||||||
if (power_factor > 1) {
|
if (power_factor > 1) power_factor = 1;
|
||||||
power_factor = 1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
energy_power_factor = power_factor;
|
energy_power_factor = power_factor;
|
||||||
}
|
}
|
||||||
@ -628,9 +606,7 @@ boolean EnergyMargin(byte type, uint16_t margin, uint16_t value, byte &flag, byt
|
|||||||
{
|
{
|
||||||
byte change;
|
byte change;
|
||||||
|
|
||||||
if (!margin) {
|
if (!margin) return false;
|
||||||
return false;
|
|
||||||
}
|
|
||||||
change = save_flag;
|
change = save_flag;
|
||||||
if (type) {
|
if (type) {
|
||||||
flag = (value > margin);
|
flag = (value > margin);
|
||||||
@ -916,7 +892,7 @@ boolean EnergyCommand()
|
|||||||
if ((ENERGY_HLW8012 == energy_flg) && hlw_cf1_current_pulse_length) {
|
if ((ENERGY_HLW8012 == energy_flg) && hlw_cf1_current_pulse_length) {
|
||||||
Settings.energy_current_calibration = (XdrvMailbox.payload * hlw_cf1_current_pulse_length) / HLW_IREF;
|
Settings.energy_current_calibration = (XdrvMailbox.payload * hlw_cf1_current_pulse_length) / HLW_IREF;
|
||||||
}
|
}
|
||||||
if ((ENERGY_CSE7766 == energy_flg) && current_cycle) {
|
else if ((ENERGY_CSE7766 == energy_flg) && current_cycle) {
|
||||||
Settings.energy_current_calibration = (XdrvMailbox.payload * current_cycle) / 1000;
|
Settings.energy_current_calibration = (XdrvMailbox.payload * current_cycle) / 1000;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1019,15 +995,12 @@ void EnergyDrvInit()
|
|||||||
|
|
||||||
void EnergyInit()
|
void EnergyInit()
|
||||||
{
|
{
|
||||||
if (ENERGY_HLW8012 == energy_flg) {
|
if (ENERGY_HLW8012 == energy_flg) HlwInit();
|
||||||
HlwInit();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (energy_flg) {
|
if (energy_flg) {
|
||||||
energy_kWhtoday = (RtcSettingsValid()) ? RtcSettings.energy_kWhtoday : (RtcTime.day_of_year == Settings.energy_kWhdoy) ? Settings.energy_kWhtoday : 0;
|
energy_kWhtoday = (RtcSettingsValid()) ? RtcSettings.energy_kWhtoday : (RtcTime.day_of_year == Settings.energy_kWhdoy) ? Settings.energy_kWhtoday : 0;
|
||||||
energy_period = energy_kWhtoday;
|
energy_period = energy_kWhtoday;
|
||||||
EnergyUpdateToday();
|
EnergyUpdateToday();
|
||||||
energy_start = (float)Settings.energy_power_calibration / 1000; // Used by PZEM004T to store total yesterday
|
|
||||||
ticker_energy.attach_ms(200, Energy200ms);
|
ticker_energy.attach_ms(200, Energy200ms);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1059,9 +1032,7 @@ void EnergyShow(boolean json)
|
|||||||
|
|
||||||
float energy = 0;
|
float energy = 0;
|
||||||
if (show_energy_period) {
|
if (show_energy_period) {
|
||||||
if (energy_period) {
|
if (energy_period) energy = (float)(energy_kWhtoday - energy_period) / 100000;
|
||||||
energy = (float)(energy_kWhtoday - energy_period) / 100000;
|
|
||||||
}
|
|
||||||
energy_period = energy_kWhtoday;
|
energy_period = energy_kWhtoday;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -40,8 +40,8 @@ struct DHTSTRUCT {
|
|||||||
char stype[12];
|
char stype[12];
|
||||||
uint32_t lastreadtime;
|
uint32_t lastreadtime;
|
||||||
uint8_t lastresult;
|
uint8_t lastresult;
|
||||||
float t;
|
float t = NAN;
|
||||||
float h = 0;
|
float h = NAN;
|
||||||
} Dht[DHT_MAX_SENSORS];
|
} Dht[DHT_MAX_SENSORS];
|
||||||
|
|
||||||
void DhtReadPrep()
|
void DhtReadPrep()
|
||||||
@ -141,7 +141,7 @@ void DhtRead(byte sensor)
|
|||||||
|
|
||||||
boolean DhtReadTempHum(byte sensor, float &t, float &h)
|
boolean DhtReadTempHum(byte sensor, float &t, float &h)
|
||||||
{
|
{
|
||||||
if (!Dht[sensor].h) {
|
if (NAN == Dht[sensor].h) {
|
||||||
t = NAN;
|
t = NAN;
|
||||||
h = NAN;
|
h = NAN;
|
||||||
} else {
|
} else {
|
||||||
@ -214,11 +214,11 @@ void DhtShow(boolean json)
|
|||||||
{
|
{
|
||||||
char temperature[10];
|
char temperature[10];
|
||||||
char humidity[10];
|
char humidity[10];
|
||||||
float t;
|
|
||||||
float h;
|
|
||||||
|
|
||||||
byte dsxflg = 0;
|
byte dsxflg = 0;
|
||||||
for (byte i = 0; i < dht_sensors; i++) {
|
for (byte i = 0; i < dht_sensors; i++) {
|
||||||
|
float t = NAN;
|
||||||
|
float h = NAN;
|
||||||
if (DhtReadTempHum(i, t, h)) { // Read temperature
|
if (DhtReadTempHum(i, t, h)) { // Read temperature
|
||||||
dtostrfd(t, Settings.flag2.temperature_resolution, temperature);
|
dtostrfd(t, Settings.flag2.temperature_resolution, temperature);
|
||||||
dtostrfd(h, Settings.flag2.humidity_resolution, humidity);
|
dtostrfd(h, Settings.flag2.humidity_resolution, humidity);
|
||||||
|
@ -44,14 +44,16 @@ void Tsl2561Detect()
|
|||||||
|
|
||||||
for (byte i = 0; i < sizeof(tsl2561_addresses); i++) {
|
for (byte i = 0; i < sizeof(tsl2561_addresses); i++) {
|
||||||
tsl2561_address = tsl2561_addresses[i];
|
tsl2561_address = tsl2561_addresses[i];
|
||||||
tsl = new TSL2561(tsl2561_address);
|
if (I2cDevice(tsl2561_address)) {
|
||||||
if (tsl->begin()) {
|
tsl = new TSL2561(tsl2561_address);
|
||||||
tsl->setGain(TSL2561_GAIN_16X);
|
if (tsl->begin()) {
|
||||||
tsl->setTiming(TSL2561_INTEGRATIONTIME_101MS);
|
tsl->setGain(TSL2561_GAIN_16X);
|
||||||
tsl2561_type = 1;
|
tsl->setTiming(TSL2561_INTEGRATIONTIME_101MS);
|
||||||
snprintf_P(log_data, sizeof(log_data), S_LOG_I2C_FOUND_AT, "TSL2561", tsl2561_address);
|
tsl2561_type = 1;
|
||||||
AddLog(LOG_LEVEL_DEBUG);
|
snprintf_P(log_data, sizeof(log_data), S_LOG_I2C_FOUND_AT, "TSL2561", tsl2561_address);
|
||||||
break;
|
AddLog(LOG_LEVEL_DEBUG);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user