diff --git a/sonoff/_releasenotes.ino b/sonoff/_releasenotes.ino index ffc7219f9..42635ea3a 100644 --- a/sonoff/_releasenotes.ino +++ b/sonoff/_releasenotes.ino @@ -5,8 +5,11 @@ * 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) + * Fix Software Watchdog restart around log roll-over (#1793) * * 5.11.1h * Rewrite webserver argument processing gaining 5k code space (#1705) diff --git a/sonoff/settings.ino b/sonoff/settings.ino index 710598e9c..46f16f688 100644 --- a/sonoff/settings.ino +++ b/sonoff/settings.ino @@ -123,7 +123,7 @@ void RtcSettingsDump() for (row = 0; row < maxrow; row++) { idx = row * CFG_COLS; - snprintf_P(log_data, sizeof(log_data), PSTR("%04X:"), idx); + snprintf_P(log_data, sizeof(log_data), PSTR("%03X:"), idx); for (col = 0; col < CFG_COLS; col++) { if (!(col%4)) { snprintf_P(log_data, sizeof(log_data), PSTR("%s "), log_data); @@ -378,7 +378,7 @@ void SettingsDump(char* parms) for (row = srow; row < maxrow; row++) { idx = row * CFG_COLS; - snprintf_P(log_data, sizeof(log_data), PSTR("%04X:"), idx); + snprintf_P(log_data, sizeof(log_data), PSTR("%03X:"), idx); for (col = 0; col < CFG_COLS; col++) { if (!(col%4)) { snprintf_P(log_data, sizeof(log_data), PSTR("%s "), log_data); diff --git a/sonoff/sonoff.ino b/sonoff/sonoff.ino index a3a211bc6..c21b31a49 100644 --- a/sonoff/sonoff.ino +++ b/sonoff/sonoff.ino @@ -129,7 +129,7 @@ int wifi_state_flag = WIFI_RESTART; // Wifi state flag int uptime = 0; // Current uptime in hours boolean latest_uptime_flag = true; // Signal latest uptime int tele_period = 0; // Tele period timer -byte web_log_index = 0; // Index in Web log buffer +byte web_log_index = 1; // Index in Web log buffer (should never be 0) byte reset_web_log_flag = 0; // Reset web console log byte devices_present = 0; // Max number of devices supported int status_update_timer = 0; // Refresh initial status @@ -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); @@ -1916,129 +1917,130 @@ void ButtonHandler() char scmnd[20]; uint8_t maxdev = (devices_present > MAX_KEYS) ? MAX_KEYS : devices_present; - for (byte i = 0; i < maxdev; i++) { + for (byte button_index = 0; button_index < maxdev; button_index++) { button = NOT_PRESSED; button_present = 0; - if (!i && ((SONOFF_DUAL == Settings.module) || (CH4 == Settings.module))) { + if (!button_index && ((SONOFF_DUAL == Settings.module) || (CH4 == Settings.module))) { button_present = 1; if (dual_button_code) { snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_APPLICATION D_BUTTON " " D_CODE " %04X"), dual_button_code); AddLog(LOG_LEVEL_DEBUG); button = PRESSED; if (0xF500 == dual_button_code) { // Button hold - holdbutton[i] = (Settings.param[P_HOLD_TIME] * (STATES / 10)) -1; + holdbutton[button_index] = (Settings.param[P_HOLD_TIME] * (STATES / 10)) -1; } dual_button_code = 0; } } else { - if ((pin[GPIO_KEY1 +i] < 99) && !blockgpio0) { + if ((pin[GPIO_KEY1 +button_index] < 99) && !blockgpio0) { button_present = 1; - button = digitalRead(pin[GPIO_KEY1 +i]); + button = digitalRead(pin[GPIO_KEY1 +button_index]); } } if (button_present) { if (SONOFF_4CHPRO == Settings.module) { - if (holdbutton[i]) { - holdbutton[i]--; + if (holdbutton[button_index]) { + holdbutton[button_index]--; } + boolean button_pressed = false; - if ((PRESSED == button) && (NOT_PRESSED == lastbutton[i])) { - snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_APPLICATION D_BUTTON " %d " D_LEVEL_10), i +1); + if ((PRESSED == button) && (NOT_PRESSED == lastbutton[button_index])) { + snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_APPLICATION D_BUTTON "%d " D_LEVEL_10), button_index +1); AddLog(LOG_LEVEL_DEBUG); - holdbutton[i] = STATES; + holdbutton[button_index] = STATES; button_pressed = true; } - if ((NOT_PRESSED == button) && (PRESSED == lastbutton[i])) { - snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_APPLICATION D_BUTTON " %d " D_LEVEL_01), i +1); + if ((NOT_PRESSED == button) && (PRESSED == lastbutton[button_index])) { + snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_APPLICATION D_BUTTON "%d " D_LEVEL_01), button_index +1); AddLog(LOG_LEVEL_DEBUG); - if (!holdbutton[i]) { // Do not allow within 1 second + if (!holdbutton[button_index]) { // Do not allow within 1 second button_pressed = true; } } if (button_pressed) { - if (!send_button_power(0, i +1, 2)) { // Execute Toggle command via MQTT if ButtonTopic is set - ExecuteCommandPower(i +1, POWER_TOGGLE); // Execute Toggle command internally + if (!send_button_power(0, button_index +1, POWER_TOGGLE)) { // Execute Toggle command via MQTT if ButtonTopic is set + ExecuteCommandPower(button_index +1, POWER_TOGGLE); // Execute Toggle command internally } } } else { - if ((PRESSED == button) && (NOT_PRESSED == lastbutton[i])) { + if ((PRESSED == button) && (NOT_PRESSED == lastbutton[button_index])) { if (Settings.flag.button_single) { // Allow only single button press for immediate action - snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_APPLICATION D_BUTTON " %d " D_IMMEDIATE), i +1); + snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_APPLICATION D_BUTTON "%d " D_IMMEDIATE), button_index +1); AddLog(LOG_LEVEL_DEBUG); - if (!send_button_power(0, i +1, 2)) { // Execute Toggle command via MQTT if ButtonTopic is set - ExecuteCommandPower(i +1, POWER_TOGGLE); // Execute Toggle command internally + if (!send_button_power(0, button_index +1, POWER_TOGGLE)) { // Execute Toggle command via MQTT if ButtonTopic is set + ExecuteCommandPower(button_index +1, POWER_TOGGLE); // Execute Toggle command internally } } else { - multipress[i] = (multiwindow[i]) ? multipress[i] +1 : 1; - snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_APPLICATION D_BUTTON " %d " D_MULTI_PRESS " %d"), i +1, multipress[i]); + multipress[button_index] = (multiwindow[button_index]) ? multipress[button_index] +1 : 1; + snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_APPLICATION D_BUTTON "%d " D_MULTI_PRESS " %d"), button_index +1, multipress[button_index]); AddLog(LOG_LEVEL_DEBUG); - multiwindow[i] = STATES /2; // 0.5 second multi press window + multiwindow[button_index] = STATES /2; // 0.5 second multi press window } blinks = 201; } if (NOT_PRESSED == button) { - holdbutton[i] = 0; + holdbutton[button_index] = 0; } else { - holdbutton[i]++; + holdbutton[button_index]++; if (Settings.flag.button_single) { // Allow only single button press for immediate action - if (holdbutton[i] == Settings.param[P_HOLD_TIME] * (STATES / 10) * 4) { // Button hold for four times longer + if (holdbutton[button_index] == Settings.param[P_HOLD_TIME] * (STATES / 10) * 4) { // Button hold for four times longer // Settings.flag.button_single = 0; snprintf_P(scmnd, sizeof(scmnd), PSTR(D_CMND_SETOPTION "13 0")); // Disable single press only ExecuteCommand(scmnd); } } else { - if (holdbutton[i] == Settings.param[P_HOLD_TIME] * (STATES / 10)) { // Button hold - multipress[i] = 0; + if (holdbutton[button_index] == Settings.param[P_HOLD_TIME] * (STATES / 10)) { // Button hold + multipress[button_index] = 0; if (!Settings.flag.button_restrict) { // No button restriction snprintf_P(scmnd, sizeof(scmnd), PSTR(D_CMND_RESET " 1")); ExecuteCommand(scmnd); } else { - send_button_power(0, i +1, 3); // Execute Hold command via MQTT if ButtonTopic is set + send_button_power(0, button_index +1, 3); // Execute Hold command via MQTT if ButtonTopic is set } } } } if (!Settings.flag.button_single) { // Allow multi-press - if (multiwindow[i]) { - multiwindow[i]--; + if (multiwindow[button_index]) { + multiwindow[button_index]--; } else { - if (!restart_flag && !holdbutton[i] && (multipress[i] > 0) && (multipress[i] < MAX_BUTTON_COMMANDS +3)) { + if (!restart_flag && !holdbutton[button_index] && (multipress[button_index] > 0) && (multipress[button_index] < MAX_BUTTON_COMMANDS +3)) { boolean single_press = false; - if (multipress[i] < 3) { // Single or Double press + if (multipress[button_index] < 3) { // Single or Double press if ((SONOFF_DUAL_R2 == Settings.module) || (SONOFF_DUAL == Settings.module) || (CH4 == Settings.module)) { single_press = true; } else { - single_press = (Settings.flag.button_swap +1 == multipress[i]); - multipress[i] = 1; + single_press = (Settings.flag.button_swap +1 == multipress[button_index]); + multipress[button_index] = 1; } } - if (single_press && send_button_power(0, i + multipress[i], 2)) { // Execute Toggle command via MQTT if ButtonTopic is set + if (single_press && send_button_power(0, button_index + multipress[button_index], POWER_TOGGLE)) { // Execute Toggle command via MQTT if ButtonTopic is set // Success } else { - if (multipress[i] < 3) { // Single or Double press + if (multipress[button_index] < 3) { // Single or Double press if (WifiState()) { // WPSconfig, Smartconfig or Wifimanager active restart_flag = 1; } else { - ExecuteCommandPower(i + multipress[i], POWER_TOGGLE); // Execute Toggle command internally + ExecuteCommandPower(button_index + multipress[button_index], POWER_TOGGLE); // Execute Toggle command internally } } else { // 3 - 7 press if (!Settings.flag.button_restrict) { - snprintf_P(scmnd, sizeof(scmnd), kCommands[multipress[i] -3]); + snprintf_P(scmnd, sizeof(scmnd), kCommands[multipress[button_index] -3]); ExecuteCommand(scmnd); } } } - multipress[i] = 0; + multipress[button_index] = 0; } } } } } - lastbutton[i] = button; + lastbutton[button_index] = button; } } @@ -2641,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/support.ino b/sonoff/support.ino index 2ece5455a..d3a597d48 100644 --- a/sonoff/support.ino +++ b/sonoff/support.ino @@ -1405,6 +1405,7 @@ void AddLog(byte loglevel) memmove(web_log, it, WEB_LOG_SIZE -(it-web_log)); // Move buffer forward to remove oldest log line } snprintf_P(web_log, sizeof(web_log), PSTR("%s%c%s%s\1"), web_log, web_log_index++, mxtime, log_data); + if (!web_log_index) web_log_index++; // Index 0 is not allowed as it is the end of char string } #endif // USE_WEBSERVER if ((WL_CONNECTED == WiFi.status()) && (loglevel <= syslog_level)) { 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; + } } } }