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:
arendst 2018-02-06 10:06:22 +01:00
parent 265e0a03f7
commit 0d6275fe5e
5 changed files with 57 additions and 80 deletions

View File

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

View File

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

View File

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

View File

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

View File

@ -44,6 +44,7 @@ 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];
if (I2cDevice(tsl2561_address)) {
tsl = new TSL2561(tsl2561_address); tsl = new TSL2561(tsl2561_address);
if (tsl->begin()) { if (tsl->begin()) {
tsl->setGain(TSL2561_GAIN_16X); tsl->setGain(TSL2561_GAIN_16X);
@ -55,6 +56,7 @@ void Tsl2561Detect()
} }
} }
} }
}
#ifdef USE_WEBSERVER #ifdef USE_WEBSERVER
const char HTTP_SNS_TSL2561[] PROGMEM = const char HTTP_SNS_TSL2561[] PROGMEM =