diff --git a/README.md b/README.md index 18f93efe4..681caed8f 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ ## Sonoff-Tasmota Provide ESP8266 based Sonoff by [iTead Studio](https://www.itead.cc/) and ElectroDragon IoT Relay with Serial, Web and MQTT control allowing 'Over the Air' or OTA firmware updates using Arduino IDE. -Current version is **3.9.17** - See ```sonoff/_releasenotes.ino``` for change information. +Current version is **3.9.18** - See ```sonoff/_releasenotes.ino``` for change information. - This version provides all (Sonoff) modules in one file and starts up with Sonoff Basic. - Once uploaded select module using the configuration webpage or the commands ```Modules``` and ```Module```. diff --git a/api/arduino/sonoff.ino.bin b/api/arduino/sonoff.ino.bin index 415809a70..cbce9d36f 100644 Binary files a/api/arduino/sonoff.ino.bin and b/api/arduino/sonoff.ino.bin differ diff --git a/sonoff/_releasenotes.ino b/sonoff/_releasenotes.ino index e5288d83c..99e30fbf8 100644 --- a/sonoff/_releasenotes.ino +++ b/sonoff/_releasenotes.ino @@ -1,4 +1,12 @@ -/* 3.9.17 20170217 +/* 3.9.18 20170218 + * Fix ledstate 0 to turn off led + * Fix Sonoff Led dimmer range (#16) + * Change Sonoff Led command Dimmer to act on both cold and warm color + * Add Sonoff Led command Color CCWW where CCWW are hexadecimal values fro 00 - FF + * Reduce Sonoff Led flickering by disabling interrupts during flash save and disabling + * Led during OTA upgrade and Web upload (#16) + * + * 3.9.17 20170217 * Fix possible ArduinoJSON related memory fragmentation * Changed console logging using less memory * Add GPIO04 as user selectable for Sonoff Dual (#75) diff --git a/sonoff/sonoff.ino b/sonoff/sonoff.ino index 53509c819..cb85376b4 100644 --- a/sonoff/sonoff.ino +++ b/sonoff/sonoff.ino @@ -10,7 +10,7 @@ * ==================================================== */ -#define VERSION 0x03091100 // 3.9.17 +#define VERSION 0x03091200 // 3.9.18 //#define BE_MINIMAL // Compile a minimal version if upgrade memory gets tight (still 404k) // To be used as step 1. Next step is compile and use desired version @@ -842,15 +842,15 @@ void setLed(uint8_t state) digitalWrite(pin[GPIO_LED1], (led_inverted[0]) ? !state : state); } +/********************************************************************************************/ + void sl_setDim(uint8_t *my_color) { float newDim, fmyCld, fmyWrm, fmyRed, fmyGrn, fmyBlu; newDim = 100 / (float)sysCfg.led_dimmer[0]; fmyCld = (float)sysCfg.led_color[0] / newDim; - newDim = 100 / (float)sysCfg.led_dimmer[1]; fmyWrm = (float)sysCfg.led_color[1] / newDim; - newDim = 100 / (float)sysCfg.led_dimmer[2]; fmyRed = (float)sysCfg.led_color[2] / newDim; fmyGrn = (float)sysCfg.led_color[3] / newDim; fmyBlu = (float)sysCfg.led_color[4] / newDim; @@ -865,9 +865,8 @@ void sl_setColor(byte type) { // 0 = Off // 1 = On -// 2 = Dim cold -// 3 = Dim Warm -// 4 = Dim color +// 2 = Dim cold/warm +// 3 = Dim color uint8_t my_color[5]; @@ -882,19 +881,30 @@ void sl_setColor(byte type) if (pin[GPIO_PWM0 +i] < 99) analogWrite(pin[GPIO_PWM0 +i], my_color[i]); } } - else if (type == 2) { // Cold - if (pin[GPIO_PWM0] < 99) analogWrite(pin[GPIO_PWM0], my_color[0]); + else if (type == 2) { // Cold/Warm + for (byte i = 0; i < 2; i++) { + if (pin[GPIO_PWM0 +i] < 99) analogWrite(pin[GPIO_PWM0 +i], my_color[i]); + } } - else if (type == 3) { // Warm - if (pin[GPIO_PWM1] < 99) analogWrite(pin[GPIO_PWM1], my_color[1]); - } - else if (type == 4) { // Color + else if (type == 3) { // Color for (byte i = 2; i < 5; i++) { if (pin[GPIO_PWM0 +i] < 99) analogWrite(pin[GPIO_PWM0 +i], my_color[i]); } } } +void sl_blank(byte state) +{ + if (sysCfg.module == SONOFF_LED) { + if (state) { + if (power &1) sl_setColor(1); + } else { + sl_setColor(0); + } + } +} + +/********************************************************************************************/ void json2legacy(char* stopic, char* svalue) { @@ -1254,33 +1264,47 @@ void mqttDataCb(char* topic, byte* data, unsigned int data_len) } /*** Sonoff Led Commands *********************************************************************/ - -/* - else if ((sysCfg.module == SONOFF_LED) && !strcmp(type,"COLOR"))) { - if ((data_len > 0) && (payload >= 0) && (payload <= 255)) { - sysCfg.led_color[index -1] = payload; - sl_setColor(4); - } - snprintf_P(svalue, sizeof(svalue), PSTR("{\"Color\":\"%s\"}"), sysCfg.led_color[index -1]); - } - else if ((sysCfg.module == SONOFF_LED) && !strcmp(type,"CWRGB") && (index > 0) && (index <= 5)) { - if ((data_len > 0) && (payload >= 0) && (payload <= 255)) { - sysCfg.led_color[index -1] = payload; - sl_setColor(1); - } - snprintf_P(svalue, sizeof(svalue), PSTR("{\"CWRGB%d\":%d}"), index, sysCfg.led_color[index -1]); - } -*/ - else if ((sysCfg.module == SONOFF_LED) && !strcmp(type,"DIMMER") && (index > 0) && (index <= 3)) { - if ((data_len > 0) && (payload >= 0) && (payload <= 100)) { - sysCfg.led_dimmer[index -1] = payload; + + else if ((sysCfg.module == SONOFF_LED) && !strcmp(type,"COLOR")) { + uint8_t my_color[5]; + if (data_len == 4) { + char ccold[3], cwarm[3]; + memcpy(ccold, dataBufUc, 2); + ccold[2] = '\0'; + memcpy(cwarm, dataBufUc + 2, 2); + cwarm[2] = '\0'; + my_color[0] = Atoh(ccold); + my_color[1] = Atoh(cwarm); + uint16_t temp = my_color[0]; + if (temp < my_color[1]) temp = my_color[1]; + float mDim = (float)temp / 2.55; + sysCfg.led_dimmer[0] = (uint8_t)mDim; + float newDim = 100 / mDim; + float fmyCold = (float)my_color[0] * newDim; + float fmyWarm = (float)my_color[1] * newDim; + sysCfg.led_color[0] = (uint8_t)fmyCold; + sysCfg.led_color[1] = (uint8_t)fmyWarm; power = 1; #ifdef USE_DOMOTICZ mqtt_publishDomoticzPowerState(index); #endif // USE_DOMOTICZ - sl_setColor(index +1); + sl_setColor(2); } - snprintf_P(svalue, sizeof(svalue), PSTR("{\"Dimmer%d\":%d}"), index, sysCfg.led_dimmer[index -1]); + sl_setDim(my_color); + uint16_t color = (uint16_t)my_color[0] << 8; + color += (uint16_t)my_color[1]; + snprintf_P(svalue, sizeof(svalue), PSTR("{\"Color\":\"%04X\"}"), color); + } + else if ((sysCfg.module == SONOFF_LED) && !strcmp(type,"DIMMER")) { + if ((data_len > 0) && (payload >= 0) && (payload <= 100)) { + sysCfg.led_dimmer[0] = payload; + power = 1; +#ifdef USE_DOMOTICZ + mqtt_publishDomoticzPowerState(index); +#endif // USE_DOMOTICZ + sl_setColor(2); + } + snprintf_P(svalue, sizeof(svalue), PSTR("{\"Dimmer\":%d}"), sysCfg.led_dimmer[0]); } /*********************************************************************************************/ @@ -1599,7 +1623,7 @@ void mqttDataCb(char* topic, byte* data, unsigned int data_len) else if (!strcmp(type,"LEDSTATE")) { if ((data_len > 0) && (payload >= 0) && (payload < MAX_LED_OPTION)) { sysCfg.ledstate = payload; - if (!sysCfg.ledstate) setLed(led_inverted[0]); + if (!sysCfg.ledstate) setLed(0); } snprintf_P(svalue, sizeof(svalue), PSTR("{\"LedState\":%d}"), sysCfg.ledstate); } @@ -2319,6 +2343,7 @@ void stateloop() if (otaflag <= 0) { otaflag = 12; ESPhttpUpdate.rebootOnUpdate(false); + sl_blank(0); // Try multiple times to get the update, in case we have a transient issue. // e.g. Someone issued "cmnd/sonoffs/update 1" and all the devices // are hammering the OTAURL. @@ -2336,6 +2361,7 @@ void stateloop() snprintf_P(svalue, sizeof(svalue), PSTR("Successful. Restarting")); restartflag = 2; } else { + sl_blank(1); snprintf_P(svalue, sizeof(svalue), PSTR("Failed %s"), ESPhttpUpdate.getLastErrorString().c_str()); } mqtt_publish_topic_P(0, PSTR("UPGRADE"), svalue); @@ -2510,6 +2536,8 @@ void GPIO_init() Baudrate = 19200; } else if (sysCfg.module == SONOFF_LED) { + analogWriteRange(255); // Default is 1023 (Arduino.h) + analogWriteFreq(200); // Default is 1000 (core_esp8266_wiring_pwm.c) - Try to lower flicker for (byte i = 0; i < 5; i++) { if (pin[GPIO_PWM0 +i] < 99) pinMode(pin[GPIO_PWM0 +i], OUTPUT); } diff --git a/sonoff/support.ino b/sonoff/support.ino index 454c49647..d8e6ed707 100644 --- a/sonoff/support.ino +++ b/sonoff/support.ino @@ -82,7 +82,7 @@ void CFG_Save() } } else { #endif // USE_SPIFFS - noInterrupts(); + if (sysCfg.module != SONOFF_LED) noInterrupts(); if (sysCfg.saveFlag == 0) { // Handle default and rollover spi_flash_erase_sector(CFG_LOCATION + (sysCfg.saveFlag &1)); spi_flash_write((CFG_LOCATION + (sysCfg.saveFlag &1)) * SPI_FLASH_SEC_SIZE, (uint32*)&sysCfg, sizeof(SYSCFG)); @@ -90,7 +90,7 @@ void CFG_Save() sysCfg.saveFlag++; spi_flash_erase_sector(CFG_LOCATION + (sysCfg.saveFlag &1)); spi_flash_write((CFG_LOCATION + (sysCfg.saveFlag &1)) * SPI_FLASH_SEC_SIZE, (uint32*)&sysCfg, sizeof(SYSCFG)); - interrupts(); + if (sysCfg.module != SONOFF_LED) interrupts(); snprintf_P(log, sizeof(log), PSTR("Config: Saved configuration (%d bytes) to flash at %X and count %d"), sizeof(SYSCFG), CFG_LOCATION + (sysCfg.saveFlag &1), sysCfg.saveFlag); addLog(LOG_LEVEL_DEBUG, log); } diff --git a/sonoff/webserver.ino b/sonoff/webserver.ino index 80679698e..f70f59891 100644 --- a/sonoff/webserver.ino +++ b/sonoff/webserver.ino @@ -1054,6 +1054,7 @@ void handleUploadDone() } snprintf_P(log, sizeof(log), PSTR("Upload: Error - %s"), error.c_str()); addLog(LOG_LEVEL_DEBUG, log); + sl_blank(1); } else { page += F("successful

Device will restart in a few seconds"); restartflag = 2; @@ -1098,6 +1099,7 @@ void handleUploadLoop() return; } } + sl_blank(0); _colcount = 0; } else if (!_uploaderror && (upload.status == UPLOAD_FILE_WRITE)) { if (upload.totalSize == 0)