diff --git a/sonoff/_releasenotes.ino b/sonoff/_releasenotes.ino index ffc7219f9..f64d7b244 100644 --- a/sonoff/_releasenotes.ino +++ b/sonoff/_releasenotes.ino @@ -5,8 +5,10 @@ * 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 support for Sonoff S31 Smart Socket with Power Consumption Detection (#1626) + * Fix TSL2561 device detection (#1644) * Fix IRReceive Data value (#1663) * Fix compiler warnings (#1774) + * Fix command PWM response if no PWM channel is configured (#1783) * * 5.11.1h * Rewrite webserver argument processing gaining 5k code space (#1705) diff --git a/sonoff/sonoff.ino b/sonoff/sonoff.ino index 095922eda..ba3ab1fcc 100644 --- a/sonoff/sonoff.ino +++ b/sonoff/sonoff.ino @@ -185,6 +185,7 @@ uint8_t energy_flg = 1; // Energy monitor configured uint8_t i2c_flg = 0; // I2C configured uint8_t spi_flg = 0; // SPI configured uint8_t light_type = 0; // Light types +bool pwm_present = false; // Any PWM channel configured with SetOption15 0 boolean mdns_begun = false; @@ -1179,7 +1180,7 @@ void MqttDataCallback(char* topic, byte* data, unsigned int data_len) } 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)) { Settings.pwm_value[index -1] = 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) { for (byte i = 0; i < MAX_PWMS; i++) { // Basic PWM control only if (pin[GPIO_PWM1 +i] < 99) { + pwm_present = true; 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]); } diff --git a/sonoff/xdrv_03_energy.ino b/sonoff/xdrv_03_energy.ino index a098d91c4..a32eabcb7 100644 --- a/sonoff/xdrv_03_energy.ino +++ b/sonoff/xdrv_03_energy.ino @@ -47,7 +47,7 @@ float energy_power = 0; // 123.1 W float energy_power_factor = 0; // 0.12 float energy_daily = 0; // 12.123 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_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_PULSES_NOT_INITIALIZED 0x90000 +#define CSE_PULSES_NOT_INITIALIZED -1 #define CSE_PREF 1000 #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]; cf_pulses = serial_in_buffer[21] << 8 | serial_in_buffer[22]; - if (adjustement & 0x80) { // CF overflow - cf_pulses = cf_pulses | 0x10000; - } +// if (adjustement & 0x80) { // CF overflow +// cf_pulses += 0x10000; +// } if (energy_power_on) { // Powered on if (adjustement & 0x40) { // Voltage valid energy_voltage = (float)(Settings.energy_voltage_calibration * CSE_UREF) / (float)voltage_cycle; @@ -367,11 +367,16 @@ bool CseSerialInput() void CseEverySecond() { + long cf_frequency = 0; + 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 { - if (cf_pulses < cf_pulses_last_time) cf_pulses_last_time = 0; // Looses at most one second of data - unsigned long cf_frequency = cf_pulses - cf_pulses_last_time; + if (cf_pulses < cf_pulses_last_time) { // Rolled over after 65535 pulses + cf_frequency = (65536 - cf_pulses_last_time) + cf_pulses; + } else { + cf_frequency = cf_pulses - cf_pulses_last_time; + } if (cf_frequency && energy_power) { cf_pulses_last_time = cf_pulses; 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) { uint16_t crc = 0; - for (uint8_t i = 0; i < sizeof(PZEMCommand) -1; i++) { - crc += *data++; - } + for (uint8_t i = 0; i < sizeof(PZEMCommand) -1; i++) crc += *data++; return (uint8_t)(crc & 0xFF); } @@ -435,9 +438,7 @@ void PzemSend(uint8_t cmd) PZEMCommand pzem; pzem.command = cmd; - for (uint8_t i = 0; i < sizeof(pzem.addr); i++) { - pzem.addr[i] = pzem_ip[i]; - } + for (uint8_t i = 0; i < sizeof(pzem.addr); i++) pzem.addr[i] = pzem_ip[i]; pzem.data = 0; uint8_t *bytes = (uint8_t*)&pzem; @@ -514,30 +515,24 @@ void PzemEvery200ms() float value = 0; if (PzemRecieve(pzem_responses[pzem_read_state], &value)) { switch (pzem_read_state) { - case 1: - energy_voltage = value; // 230.2V + case 1: // Voltage as 230.2V + energy_voltage = value; break; - case 2: - energy_current = value; // 17.32A + case 2: // Current as 17.32A + energy_current = value; break; - case 3: - energy_power = value; // 20W + case 3: // Power as 20W + energy_power = value; break; - case 4: - energy_total = value / 1000; // 99999Wh - if (energy_total < energy_start) { - energy_start = energy_total; - Settings.energy_power_calibration = energy_start * 1000; - } - energy_kWhtoday = (energy_total - energy_start) * 100000000; - RtcSettings.energy_kWhtoday = energy_kWhtoday; - energy_daily = (float)energy_kWhtoday / 100000000; + case 4: // Total energy as 99999Wh + if (!energy_start || (value < energy_start)) energy_start = value; // Init after restart and hanlde roll-over if any + energy_kWhtoday += (value - energy_start) * 100000; + energy_start = value; + EnergyUpdateToday(); break; } pzem_read_state++; - if (5 == pzem_read_state) { - pzem_read_state = 1; - } + if (5 == pzem_read_state) pzem_read_state = 1; } } @@ -565,13 +560,8 @@ void Energy200ms() if (5 == energy_fifth_second) { energy_fifth_second = 0; - if (ENERGY_HLW8012 == energy_flg) { - HlwEverySecond(); - } - - if (ENERGY_CSE7766 == energy_flg) { - CseEverySecond(); - } + if (ENERGY_HLW8012 == energy_flg) HlwEverySecond(); + if (ENERGY_CSE7766 == energy_flg) CseEverySecond(); if (RtcTime.valid) { if (LocalTime() == Midnight()) { @@ -580,13 +570,7 @@ void Energy200ms() RtcSettings.energy_kWhtotal = Settings.energy_kWhtotal; energy_kWhtoday = 0; energy_period = energy_kWhtoday; - RtcSettings.energy_kWhtoday = energy_kWhtoday; -#ifdef USE_PZEM004T - if (ENERGY_PZEM004T == energy_flg) { - energy_start = energy_total; - Settings.energy_power_calibration = energy_start * 1000; - } -#endif // USE_PZEM004T + EnergyUpdateToday(); energy_max_energy_state = 3; } 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; - if (ENERGY_HLW8012 == energy_flg) { - HlwEvery200ms(); + if (ENERGY_HLW8012 == energy_flg) HlwEvery200ms(); #ifdef USE_PZEM004T - } - else if (ENERGY_PZEM004T == energy_flg) { - PzemEvery200ms(); + if (ENERGY_PZEM004T == energy_flg) PzemEvery200ms(); #endif // USE_PZEM004T - } float power_factor = 0; if (energy_voltage && energy_current && energy_power) { power_factor = energy_power / (energy_voltage * energy_current); - if (power_factor > 1) { - power_factor = 1; - } + if (power_factor > 1) power_factor = 1; } energy_power_factor = power_factor; } @@ -628,9 +606,7 @@ boolean EnergyMargin(byte type, uint16_t margin, uint16_t value, byte &flag, byt { byte change; - if (!margin) { - return false; - } + if (!margin) return false; change = save_flag; if (type) { flag = (value > margin); @@ -916,7 +892,7 @@ boolean EnergyCommand() if ((ENERGY_HLW8012 == energy_flg) && hlw_cf1_current_pulse_length) { 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; } } @@ -1019,15 +995,12 @@ void EnergyDrvInit() void EnergyInit() { - if (ENERGY_HLW8012 == energy_flg) { - HlwInit(); - } + if (ENERGY_HLW8012 == energy_flg) HlwInit(); if (energy_flg) { energy_kWhtoday = (RtcSettingsValid()) ? RtcSettings.energy_kWhtoday : (RtcTime.day_of_year == Settings.energy_kWhdoy) ? Settings.energy_kWhtoday : 0; energy_period = energy_kWhtoday; EnergyUpdateToday(); - energy_start = (float)Settings.energy_power_calibration / 1000; // Used by PZEM004T to store total yesterday ticker_energy.attach_ms(200, Energy200ms); } } @@ -1059,9 +1032,7 @@ void EnergyShow(boolean json) float energy = 0; if (show_energy_period) { - if (energy_period) { - energy = (float)(energy_kWhtoday - energy_period) / 100000; - } + if (energy_period) energy = (float)(energy_kWhtoday - energy_period) / 100000; energy_period = energy_kWhtoday; } diff --git a/sonoff/xsns_06_dht.ino b/sonoff/xsns_06_dht.ino index ede23e232..e23d1989f 100644 --- a/sonoff/xsns_06_dht.ino +++ b/sonoff/xsns_06_dht.ino @@ -40,8 +40,8 @@ struct DHTSTRUCT { char stype[12]; uint32_t lastreadtime; uint8_t lastresult; - float t; - float h = 0; + float t = NAN; + float h = NAN; } Dht[DHT_MAX_SENSORS]; void DhtReadPrep() @@ -141,7 +141,7 @@ void DhtRead(byte sensor) boolean DhtReadTempHum(byte sensor, float &t, float &h) { - if (!Dht[sensor].h) { + if (NAN == Dht[sensor].h) { t = NAN; h = NAN; } else { @@ -214,11 +214,11 @@ void DhtShow(boolean json) { char temperature[10]; char humidity[10]; - float t; - float h; byte dsxflg = 0; for (byte i = 0; i < dht_sensors; i++) { + float t = NAN; + float h = NAN; if (DhtReadTempHum(i, t, h)) { // Read temperature dtostrfd(t, Settings.flag2.temperature_resolution, temperature); dtostrfd(h, Settings.flag2.humidity_resolution, humidity); diff --git a/sonoff/xsns_16_tsl2561.ino b/sonoff/xsns_16_tsl2561.ino index a50c16804..1c4e3cc98 100644 --- a/sonoff/xsns_16_tsl2561.ino +++ b/sonoff/xsns_16_tsl2561.ino @@ -44,14 +44,16 @@ void Tsl2561Detect() for (byte i = 0; i < sizeof(tsl2561_addresses); i++) { tsl2561_address = tsl2561_addresses[i]; - tsl = new TSL2561(tsl2561_address); - if (tsl->begin()) { - tsl->setGain(TSL2561_GAIN_16X); - tsl->setTiming(TSL2561_INTEGRATIONTIME_101MS); - tsl2561_type = 1; - snprintf_P(log_data, sizeof(log_data), S_LOG_I2C_FOUND_AT, "TSL2561", tsl2561_address); - AddLog(LOG_LEVEL_DEBUG); - break; + if (I2cDevice(tsl2561_address)) { + tsl = new TSL2561(tsl2561_address); + if (tsl->begin()) { + tsl->setGain(TSL2561_GAIN_16X); + tsl->setTiming(TSL2561_INTEGRATIONTIME_101MS); + tsl2561_type = 1; + snprintf_P(log_data, sizeof(log_data), S_LOG_I2C_FOUND_AT, "TSL2561", tsl2561_address); + AddLog(LOG_LEVEL_DEBUG); + break; + } } } }