From 5fdc5e890a62871c57a640d8532929e2f28368c8 Mon Sep 17 00:00:00 2001 From: arendst Date: Sun, 13 Aug 2017 15:31:49 +0200 Subject: [PATCH] Add AiLight and update Sonoff B1 (experimental) --- sonoff/_releasenotes.ino | 4 +-- sonoff/sonoff.ino | 17 +++++---- sonoff/sonoff_template.h | 11 +++--- sonoff/xdrv_snfled.ino | 75 +++++++++++++++++++++++++++++----------- 4 files changed, 71 insertions(+), 36 deletions(-) diff --git a/sonoff/_releasenotes.ino b/sonoff/_releasenotes.ino index 3cdd9e4ec..ac7a5ceb2 100644 --- a/sonoff/_releasenotes.ino +++ b/sonoff/_releasenotes.ino @@ -1,7 +1,7 @@ -/* 5.5.2e +/* 5.5.2f * Fix Sonoff Pow intermittent exception 0 * Change Sonoff Pow sending Domoticz telemetry data only - * Add Sonoff B1 support (experimental) + * Add Ai-Thinker RGBW led (AiLight) and Sonoff B1 support (experimental) * * 5.5.2 20170808 * Extent max number of WS2812 pixels from 256 to 512 (#667) diff --git a/sonoff/sonoff.ino b/sonoff/sonoff.ino index 5ae0e505e..5b559f964 100644 --- a/sonoff/sonoff.ino +++ b/sonoff/sonoff.ino @@ -25,7 +25,7 @@ - Select IDE Tools - Flash Size: "1M (no SPIFFS)" ====================================================*/ -#define VERSION 0x05050205 // 5.5.2e +#define VERSION 0x05050206 // 5.5.2f enum log_t {LOG_LEVEL_NONE, LOG_LEVEL_ERROR, LOG_LEVEL_INFO, LOG_LEVEL_DEBUG, LOG_LEVEL_DEBUG_MORE, LOG_LEVEL_ALL}; enum week_t {Last, First, Second, Third, Fourth}; @@ -2318,7 +2318,7 @@ void stateloop() button_handler(); switch_handler(); - if (sfl_flg) { // Sonoff B1, led or BN-SZ01 + if (sfl_flg) { // Sonoff B1, AiLight, Sonoff led or BN-SZ01 sl_animate(); } @@ -2627,13 +2627,16 @@ void GPIO_init() Maxdevice = 0; Baudrate = 19200; } - else if (SONOFF_BN == sysCfg.module) { + else if (SONOFF_BN == sysCfg.module) { // Single color led (White) sfl_flg = 1; } - else if (SONOFF_LED == sysCfg.module) { + else if (SONOFF_LED == sysCfg.module) { // Dual color led (White warm and cold) sfl_flg = 2; } - else if ((SONOFF_B1 == sysCfg.module) || (SONOFF_B1b == sysCfg.module)) { + else if (AILIGHT == sysCfg.module) { // RGBW led + sfl_flg = 4; + } + else if (SONOFF_B1 == sysCfg.module) { // RGBWC led sfl_flg = 5; } else { @@ -2663,8 +2666,8 @@ void GPIO_init() } } - if (sfl_flg) { // Sonoff B1, Led or BN-SZ01 - if (sfl_flg < 5) { + if (sfl_flg) { // Sonoff B1, AiLight, Sonoff Led or BN-SZ01 + if (sfl_flg < 4) { pwm_idxoffset = sfl_flg; // 1 for BN-SZ01, 2 for Sonoff Led } sl_init(); diff --git a/sonoff/sonoff_template.h b/sonoff/sonoff_template.h index 0c1a1a569..bd7e2cadc 100644 --- a/sonoff/sonoff_template.h +++ b/sonoff/sonoff_template.h @@ -152,7 +152,7 @@ enum module_t { HUAFAN_SS, SONOFF_BRIDGE, SONOFF_B1, - SONOFF_B1b, + AILIGHT, MAXMODULE }; /********************************************************************************************/ @@ -506,10 +506,9 @@ const mytmplt modules[MAXMODULE] PROGMEM = { GPIO_DI, // GPIO12 my9231 DI 0, GPIO_DCKI, // GPIO14 my9231 DCKI - 0, - 0, 0 + 0, 0, 0 }, - { "Sonoff B1 b", // Sonoff B1 (ESP8285 - my9231) + { "AiLight", // Ai-Thinker RGBW led (ESP8266 - my9291) GPIO_KEY1, // GPIO00 Pad GPIO_USER, // GPIO01 Serial RXD and Optional sensor pad GPIO_USER, // GPIO02 Optional sensor SDA pad @@ -519,9 +518,9 @@ const mytmplt modules[MAXMODULE] PROGMEM = { 0, 0, 0, // Flash connection 0, - GPIO_DI, // GPIO13 my9231 DI + GPIO_DI, // GPIO13 my9291 DI 0, - GPIO_DCKI, // GPIO15 my9231 DCKI + GPIO_DCKI, // GPIO15 my9291 DCKI 0, 0 } diff --git a/sonoff/xdrv_snfled.ino b/sonoff/xdrv_snfled.ino index b8d7a74a0..8161a077b 100644 --- a/sonoff/xdrv_snfled.ino +++ b/sonoff/xdrv_snfled.ino @@ -18,7 +18,7 @@ */ /*********************************************************************************************\ - * Sonoff B1, Led and BN-SZ01 + * Sonoff B1, AiLight, Sonoff Led and BN-SZ01 \*********************************************************************************************/ uint8_t ledTable[] = { @@ -50,7 +50,7 @@ uint8_t sl_wakeupDimmer = 0; uint16_t sl_wakeupCntr = 0; /*********************************************************************************************\ - * Sonoff B1 based on OpenLight https://github.com/icamgo/noduino-sdk (my9231 and my9291) + * Sonoff B1 (my9231) and AiLight (my9291) based on OpenLight https://github.com/icamgo/noduino-sdk \*********************************************************************************************/ extern "C" { @@ -76,7 +76,7 @@ void sl_dcki_pulse(uint8_t times) } } -void sl_send_command(uint8_t command) +void sl_my92x1_command(uint8_t chips, uint8_t command) { uint8_t command_data; @@ -85,8 +85,8 @@ void sl_send_command(uint8_t command) // Send 12 DI pulse, after 6 pulse's falling edge store duty data, and 12 // pulse's rising edge convert to command mode. sl_di_pulse(12); - os_delay_us(12); // Delay >12us, begin send CMD data - for (uint8_t n = 0; n < 2; n++) { // Send CMD data + os_delay_us(12); // Delay >12us, begin send CMD data + for (uint8_t n = 0; n < chips; n++) { // Send CMD data command_data = command; for (uint8_t i = 0; i < 4; i++) { // Send byte digitalWrite(sl_pdcki, LOW); @@ -107,7 +107,7 @@ void sl_send_command(uint8_t command) // ets_intr_unlock(); } -void sl_send_duty(uint16_t duty_r, uint16_t duty_g, uint16_t duty_b, uint16_t duty_w, uint16_t duty_c) +void sl_my9231_duty(uint16_t duty_r, uint16_t duty_g, uint16_t duty_b, uint16_t duty_w, uint16_t duty_c) { uint16_t duty_current = 0; @@ -134,12 +134,39 @@ void sl_send_duty(uint16_t duty_r, uint16_t duty_g, uint16_t duty_b, uint16_t du // ets_intr_unlock(); } +void sl_my9291_duty(uint16_t duty_r, uint16_t duty_g, uint16_t duty_b, uint16_t duty_w) +{ + uint16_t duty_current = 0; + + uint16_t duty[4] = { duty_r, duty_g, duty_b, duty_w }; // Definition for RGBW channels + +// ets_intr_lock(); + os_delay_us(12); // TStop > 12us. + for (uint8_t channel = 0; channel < 4; channel++) { // RGBW 4CH + duty_current = duty[channel]; // RGBW Channel + for (uint8_t i = 0; i < 4; i++) { // Send 8bit Data + digitalWrite(sl_pdcki, LOW); + digitalWrite(sl_pdi, (duty_current & 0x80)); + digitalWrite(sl_pdcki, HIGH); + duty_current = duty_current << 1; + digitalWrite(sl_pdi, (duty_current & 0x80)); + digitalWrite(sl_pdcki, LOW); + digitalWrite(sl_pdi, LOW); + duty_current = duty_current << 1; + } + } + os_delay_us(12); // TStart > 12us. Ready for send DI pulse. + sl_di_pulse(8); // Send 8 DI pulse. After 8 pulse falling edge, store old data. + os_delay_us(12); // TStop > 12us. +// ets_intr_unlock(); +} + /********************************************************************************************/ void sl_init(void) { pin[GPIO_WS2812] = 99; // I do not allow both Sonoff Led AND WS2812 led - if (sfl_flg < 5) { + if (sfl_flg < 4) { if (!my_module.gp.io[4]) { pinMode(4, OUTPUT); // Stop floating outputs digitalWrite(4, LOW); @@ -165,12 +192,15 @@ void sl_init(void) digitalWrite(sl_pdi, LOW); digitalWrite(sl_pdcki, LOW); - // Clear all duty register - sl_dcki_pulse(64); - sl_send_command(0x18); // ONE_SHOT_DISABLE, REACTION_FAST, BIT_WIDTH_8, FREQUENCY_DIVIDE_1, SCATTER_APDM - - // Test -// sl_send_duty(16, 0, 0, 0, 0); // Red + if (4 == sfl_flg) { + // Clear all duty register + sl_dcki_pulse(32); // 1 * 32 bits + sl_my92x1_command(1, 0x18); // ONE_SHOT_DISABLE, REACTION_FAST, BIT_WIDTH_8, FREQUENCY_DIVIDE_1, SCATTER_APDM + } else if (5 == sfl_flg) { + // Clear all duty register + sl_dcki_pulse(48); // 2 * 24 bits + sl_my92x1_command(2, 0x18); // ONE_SHOT_DISABLE, REACTION_FAST, BIT_WIDTH_8, FREQUENCY_DIVIDE_1, SCATTER_APDM + } } sl_power = 0; @@ -320,14 +350,17 @@ void sl_animate() for (byte i = 0; i < sfl_flg; i++) { sl_lcolor[i] = sl_tcolor[i]; cur_col[i] = (sysCfg.led_table) ? ledTable[sl_lcolor[i]] : sl_lcolor[i]; - if (sfl_flg < 5) { + if (sfl_flg < 4) { if (pin[GPIO_PWM1 +i] < 99) { analogWrite(pin[GPIO_PWM1 +i], cur_col[i] * (PWM_RANGE / 255)); } } } - if (5 == sfl_flg) { - sl_send_duty(cur_col[0], cur_col[1], cur_col[2], cur_col[3], cur_col[4]); + if (4 == sfl_flg) { + sl_my9291_duty(cur_col[0], cur_col[1], cur_col[2], cur_col[3]); + } + else if (5 == sfl_flg) { + sl_my9231_duty(cur_col[0], cur_col[1], cur_col[2], cur_col[3], cur_col[4]); } } } @@ -417,7 +450,7 @@ void sl_replaceHSB(String *response) float sat; float bri; - if (5 == sfl_flg) { + if (sfl_flg > 2) { sl_rgb2hsb(&hue, &sat, &bri); response->replace("{h}", String((uint16_t)(65535.0f * hue))); response->replace("{s}", String((uint8_t)(254.0f * sat))); @@ -431,7 +464,7 @@ void sl_replaceHSB(String *response) void sl_getHSB(float *hue, float *sat, float *bri) { - if (5 == sfl_flg) { + if (sfl_flg > 2) { sl_rgb2hsb(hue, sat, bri); } else { *hue = 0; @@ -443,7 +476,7 @@ void sl_getHSB(float *hue, float *sat, float *bri) void sl_setHSB(float hue, float sat, float bri) { char svalue[MESSZ]; - +/* char log[LOGSZ]; char stemp1[10]; char stemp2[10]; @@ -453,8 +486,8 @@ void sl_setHSB(float hue, float sat, float bri) dtostrf(bri, 1, 3, stemp3); snprintf_P(log, sizeof(log), PSTR("LED: Hue %s, Sat %s, Bri %s"), stemp1, stemp2, stemp3); addLog(LOG_LEVEL_DEBUG, log); - - if (5 == sfl_flg) { +*/ + if (sfl_flg > 2) { sl_hsb2rgb(hue, sat, bri); sl_prepPower(svalue, sizeof(svalue)); mqtt_publish_topic_P(5, "COLOR", svalue);