arendst / Tasmota

Alternative firmware for ESP8266 and ESP32 based devices with easy configuration using webUI, OTA updates, automation using timers or rules, expandability and entirely local control over MQTT, HTTP, Serial or KNX. Full documentation at
https://tasmota.github.io/docs
GNU General Public License v3.0
22.26k stars 4.81k forks source link

RGBCCT Qualitel (SM2135) convert with ESP-12F and Tasmota won't switch off #16626

Closed hanscomps closed 2 years ago

hanscomps commented 2 years ago

PROBLEM DESCRIPTION

A clear and concise description of what the problem is. Hardware converted a Qualitel RGB LED bulb that uses the SM2135 LED driver IC, with a ESP-12F and latest Tasmota. After adjusting, with SetOption37, for the LED driver output assignments to correct colour channels, everything works as expected.

After power-on the bulb is OFF and changing White value switches on the bulb and the colour temperature can be set as expected. When making White 0 the bulb goes OFF. Setting colour also work as expected; but when setting everything to 0, Dimmer, Color, HBSColor, White etc the bulb says OFF but still have the Blue LEDs on (dimmed to about 20%). No combination of settings will switch it OFF again; except for a power cycle.

Example of settings when setting everything to 0. {"POWER":"OFF","Dimmer":0,"Color":"0000000000","HSBColor":"0,0,0","White":0,"CT":153,"Channel":[0,0,0,0,0]}

REQUESTED INFORMATION

Make sure your have performed every step and checked the applicable boxes before submitting your issue. Thank you!

- [ ] If using rules, provide the output of this command: `Backlog Rule1; Rule2; Rule3`:
```lua
  Rules output here:

19:11:12.585 MQT: stat/tasmota_EE83D1/STATUS = {"Status":{"Module":0,"DeviceName":"Tasmota","FriendlyName":["Tasmota"],"Topic":"tasmota_EE83D1","ButtonTopic":"0","Power":1,"PowerOnState":3,"LedState":1,"LedMask":"FFFF","SaveData":1,"SaveState":1,"SwitchTopic":"0","SwitchMode":[0,0,0,0,0,0,0,0],"ButtonRetain":0,"SwitchRetain":0,"SensorRetain":0,"PowerRetain":0,"InfoRetain":0,"StateRetain":0}} 19:11:12.591 MQT: stat/tasmota_EE83D1/STATUS1 = {"StatusPRM":{"Baudrate":115200,"SerialConfig":"8N1","GroupTopic":"tasmotas","OtaUrl":"http://ota.tasmota.com/tasmota/release/tasmota.bin.gz","RestartReason":"External System","Uptime":"0T00:11:54","StartupUTC":"2022-09-22T17:59:18","Sleep":50,"CfgHolder":4617,"BootCount":27,"BCResetTime":"2022-09-15T19:05:17","SaveCount":992,"SaveAddress":"F4000"}} 19:11:12.595 MQT: stat/tasmota_EE83D1/STATUS2 = {"StatusFWR":{"Version":"12.1.1(tasmota)","BuildDateTime":"2022-08-25T11:33:55","Boot":31,"Core":"2_7_4_9","SDK":"2.2.2-dev(38a443e)","CpuFrequency":80,"Hardware":"ESP8266EX","CR":"371/699"}} 19:11:12.600 MQT: stat/tasmota_EE83D1/STATUS3 = {"StatusLOG":{"SerialLog":2,"WebLog":2,"MqttLog":0,"SysLog":0,"LogHost":"","LogPort":514,"SSId":["xxxxxxxx",""],"TelePeriod":300,"Resolution":"558180C0","SetOption":["00008009","2805C80001360600003C5A0A192800000000","00000080","00006000","00004000","00000000"]}} 19:11:12.611 MQT: stat/tasmota_EE83D1/STATUS4 = {"StatusMEM":{"ProgramSize":624,"Free":376,"Heap":22,"ProgramFlashSize":1024,"FlashSize":4096,"FlashChipId":"164020","FlashFrequency":40,"FlashMode":3,"Features":["00000809","8F9AC787","04368001","000000CF","010013C0","C000F981","00004004","00001000","54000020","00000000"],"Drivers":"1,2,3,4,5,6,7,8,9,10,12,16,18,19,20,21,22,24,26,27,29,30,35,37,45,62","Sensors":"1,2,3,4,5,6"}} 19:11:12.617 MQT: stat/tasmota_EE83D1/STATUS5 = {"StatusNET":{"Hostname":"tasmota-EE83D1-0977","IPAddress":"192.168.10.101","Gateway":"192.168.10.1","Subnetmask":"255.255.255.0","DNSServer1":"192.168.10.1","DNSServer2":"0.0.0.0","Mac":"A8:48:FA:EE:83:D1","Webserver":2,"HTTP_API":1,"WifiConfig":4,"WifiPower":17.0}} 19:11:12.621 MQT: stat/tasmotaEE83D1/STATUS6 = {"StatusMQT":{"MqttHost":"192.168.10.103","MqttPort":1883,"MqttClientMask":"DVES%06X","MqttClient":"DVES_EE83D1","MqttUser":"DVES_USER","MqttCount":1,"MAX_PACKET_SIZE":1200,"KEEPALIVE":30,"SOCKET_TIMEOUT":4}} 19:11:12.627 MQT: stat/tasmota_EE83D1/STATUS7 = {"StatusTIM":{"UTC":"2022-09-22T18:11:12","Local":"2022-09-22T19:11:12","StartDST":"2022-03-27T02:00:00","EndDST":"2022-10-30T03:00:00","Timezone":"+01:00","Sunrise":"06:36","Sunset":"18:48"}} 19:11:12.632 MQT: stat/tasmota_EE83D1/STATUS10 = {"StatusSNS":{"Time":"2022-09-22T19:11:12"}} 19:11:12.642 MQT: stat/tasmota_EE83D1/STATUS11 = {"StatusSTS":{"Time":"2022-09-22T19:11:12","Uptime":"0T00:11:54","UptimeSec":714,"Heap":20,"SleepMode":"Dynamic","Sleep":10,"LoadAvg":99,"MqttCount":1,"POWER":"ON","Dimmer":7,"Color":"1313130000","HSBColor":"0,0,7","White":0,"CT":153,"Channel":[7,7,7,0,0],"Scheme":0,"Fade":"OFF","Speed":1,"LedTable":"ON","Wifi":{"AP":1,"SSId":"xxxxxxxx","BSSId":"64:66:B3:D5:C3:5C","Channel":11,"Mode":"11n","RSSI":8,"Signal":-96,"LinkCount":1,"Downtime":"0T00:00:03"}}}

- [ ] Set `weblog` to 4 and then, when you experience your issue, provide the output of the Console log:
```lua
  Console output here:

TO REPRODUCE

Steps to reproduce the behavior:

EXPECTED BEHAVIOUR

A clear and concise description of what you expected to happen.

SCREENSHOTS

If applicable, add screenshots to help explain your problem.

ADDITIONAL CONTEXT

Add any other context about the problem here.

(Please, remember to close the issue when the problem has been addressed)

s-hadinger commented 2 years ago

Please add the output of Backlog Template; Module; GPIO 255 as requested in the template.

What happens if you do Color 0000FF0000 (it should set the blue channel to max power), the Color 0000000000 ?

hanscomps commented 2 years ago

Color 0000FF0000 goes to what looks like full blue brightness. Then Color 0000000000 does nothing (can see from log the command does go through, but still full brightness). Color 0000010000 brings it down to lowest brightness. Red and green works as expected.

s-hadinger commented 2 years ago

I really need the Template and Module and GPIO 255 information if I want to try to reproduce

hanscomps commented 2 years ago

Sorry, I went back to the original post and edited it in.

s-hadinger commented 2 years ago

Ha sorry I missed it. Indeed SM2135 is not the most common setup. I will try to reproduce without the actual device

hanscomps commented 2 years ago

Ye, don't spend too much time on it, this is more of an experiment for me until the tuya hardware/firmware (forgot the IC that is now replacing most of the low-cost bulbs and switches) gets tasmota support (if ever). [found it, this bulb had a BK7231 module in it]

s-hadinger commented 2 years ago

There is no plan for Tasmota support for BK7231 for many reasons. Don't expect it to happen any soon if ever.

hanscomps commented 2 years ago

Ok, no problem ripping out module and replacing with something that is proven and locally controlled is worth it. I can debug the hardware a bit more, making sure the expected bitstream is getting to the SM2135.

hanscomps commented 2 years ago

Ok, did some measurements.
Color 0101010000 = first capture. Color 0000000000 = second capture. Looks like some timing issue on clocking? [edit: I see this is expected behavior for setting CW]

image

image

hanscomps commented 2 years ago

Looking quickly at the code I see in the section where the model is evaluated and if RGB is all 0s it sets the light_type to 1 (CV), meaning RGB ALL zero is never going to be set.

s-hadinger commented 2 years ago

Good finding, can you provide a patch?

hanscomps commented 2 years ago

I will take a look and get the build going to test. Easiest (crude) is probably to just force the RGB 0,0,0 write at the check: I guess the same is needed for when RGB is set again to some value; CW must go to zero.

  uint32_t light_type = 3;      // RGB and CW
  if (Sm2135.model < 2) {       // Only allow one of two options due to power supply
    if ((0 == cur_col[0]) && (0 == cur_col[1]) && (0 == cur_col[2])) {
      light_type = 1;           // CW only
      // Force RGB to zero
      Sm2135Start(SM2135_ADDR_MC);
      Sm2135Write(Sm2135.current);
      Sm2135Write(SM2135_RGB);
      Sm2135Write(0);  
      Sm2135Write(0);  
      Sm2135Write(0);  
      Sm2135Stop();
    } else {
      light_type = 2;           // RGB only
    }
  }
hanscomps commented 2 years ago

My crude patch for this; tested and works as expected. I changed the check to evaluate CW values for zero; somehow made more sense to me. This can be cleaned up by setting values to zero and only having one Sm2135Write sequence for RGB and CW, but did not want to directly change the in fear it might cause unforeseen issues somewhere else.

---
 tasmota/tasmota_xlgt_light/xlgt_04_sm2135.ino | 78 +++++++++++--------
 1 file changed, 47 insertions(+), 31 deletions(-)

diff --git a/tasmota/tasmota_xlgt_light/xlgt_04_sm2135.ino b/tasmota/tasmota_xlgt_light/xlgt_04_sm2135.ino
index 0b72520a8..009931a8b 100644
--- a/tasmota/tasmota_xlgt_light/xlgt_04_sm2135.ino
+++ b/tasmota/tasmota_xlgt_light/xlgt_04_sm2135.ino
@@ -156,41 +156,57 @@ bool Sm2135SetChannels(void) {
     return true;
   }

-  uint32_t light_type = 3;      // RGB and CW
   if (Sm2135.model < 2) {       // Only allow one of two options due to power supply
-    if ((0 == cur_col[0]) && (0 == cur_col[1]) && (0 == cur_col[2])) {
-      light_type = 1;           // CW only
+    if ((0 == cur_col[3]) && (0 == cur_col[4])) {
+      Sm2135Start(SM2135_ADDR_MC);
+      Sm2135Write(Sm2135.current);
+      Sm2135Write(SM2135_RGB);
+      if (Sm2135.model &1) {      // SM2135_WCBGR
+        Sm2135Write(cur_col[2]);  // Blue
+        Sm2135Write(cur_col[1]);  // Green
+        Sm2135Write(cur_col[0]);  // Red
+      } else {                    // SM2135_WCGRB
+        Sm2135Write(cur_col[1]);  // Green
+        Sm2135Write(cur_col[0]);  // Red
+        Sm2135Write(cur_col[2]);  // Blue
+      }
+      Sm2135Stop();
+      delay(1);
+      Sm2135Start(SM2135_ADDR_MC);
+      Sm2135Write(Sm2135.current);
+      Sm2135Write(SM2135_CW);
+      Sm2135Stop();
+      delay(1);
+      Sm2135Start(SM2135_ADDR_C);
+      Sm2135Write(0);    // Warm
+      Sm2135Write(0);    // Cold
+      Sm2135Stop();
     } else {
-      light_type = 2;           // RGB only
+      Sm2135Start(SM2135_ADDR_MC);
+      Sm2135Write(Sm2135.current);
+      Sm2135Write(SM2135_RGB);
+      if (Sm2135.model &1) {      // SM2135_WCBGR
+        Sm2135Write(0);           // Blue
+        Sm2135Write(0);           // Green
+        Sm2135Write(0);           // Red
+      } else {                    // SM2135_WCGRB
+        Sm2135Write(0);           // Green
+        Sm2135Write(0);           // Red
+        Sm2135Write(0);           // Blue
+      }
+      Sm2135Stop();
+      delay(1);
+      Sm2135Start(SM2135_ADDR_MC);
+      Sm2135Write(Sm2135.current);
+      Sm2135Write(SM2135_CW);
+      Sm2135Stop();
+      delay(1);
+      Sm2135Start(SM2135_ADDR_C);
+      Sm2135Write(cur_col[4]);    // Warm
+      Sm2135Write(cur_col[3]);    // Cold
+      Sm2135Stop();
     }
   }
-  if (light_type &2) {          // Set RGB
-    Sm2135Start(SM2135_ADDR_MC);
-    Sm2135Write(Sm2135.current);
-    Sm2135Write(SM2135_RGB);
-    if (Sm2135.model &1) {      // SM2135_WCBGR
-      Sm2135Write(cur_col[2]);  // Blue
-      Sm2135Write(cur_col[1]);  // Green
-      Sm2135Write(cur_col[0]);  // Red
-    } else {                    // SM2135_WCGRB
-      Sm2135Write(cur_col[1]);  // Green
-      Sm2135Write(cur_col[0]);  // Red
-      Sm2135Write(cur_col[2]);  // Blue
-    }
-    Sm2135Stop();
-  }
-  if (light_type &1) {          // Set CW
-    Sm2135Start(SM2135_ADDR_MC);
-    Sm2135Write(Sm2135.current);
-    Sm2135Write(SM2135_CW);
-    Sm2135Stop();
-    delay(1);
-    Sm2135Start(SM2135_ADDR_C);
-    Sm2135Write(cur_col[4]);    // Warm
-    Sm2135Write(cur_col[3]);    // Cold
-    Sm2135Stop();
-  }
-
   return true;
 }

-- 
2.37.3
s-hadinger commented 2 years ago

Thanks. I'm fine with this, this code is probably not very used. Would you be kind enough to submit a Pull Request?

arendst commented 2 years ago

The code is used in different kind of lamps:

 * SM2135 RGBCW Led bulbs like some Action LSC SmartLed or Polux
 *
 * Action LSC SmartLed (GreenRedBlue)
 * {"NAME":"LSC RGBCW LED","GPIO":[0,0,0,0,0,0,0,0,181,0,180,0,0],"FLAG":0,"BASE":18}
 * {"NAME":"LSC RGBCW LED","GPIO":[0,0,0,0,0,0,0,0,4064,0,4032,0,0,0],"FLAG":0,"BASE":18}
 * Polux E14 (BlueGreenRed) - Notice GPIO00 = 9 (Switch1)
 * {"NAME":"Polux RGBCW E14","GPIO":[9,0,0,0,0,0,0,0,181,0,180,0,0],"FLAG":0,"BASE":18}
 * Polux E14 (BlueGreenRed)
 * {"NAME":"Polux RGBCW E14","GPIO":[0,0,0,0,0,0,0,0,4065,0,4032,0,0,0],"FLAG":0,"BASE":18}
 * LE LampUX 907001-US
 * {"NAME":"LE LampUX 907001-US","GPIO":[0,0,0,0,0,0,0,0,4066,0,4032,0,0,0],"FLAG":0,"BASE":18}
 * Fitop 10W RGBCCT Bulb (BA60H-W0080-RCBW-E7)
 * {"NAME":"Fitop 10W RGBCCT","GPIO":[1,1,1,1,1,4032,1,1,4069,1,1,1,1,1],"FLAG":0,"BASE":18,"CMND":"RGBWWTable 167,102,109,255,255"}

The proposed change breaks current lights. See #16664

arendst commented 2 years ago

Try latest dev release. It contains at least a working version for my bulbs in addition to your suggested changes.

hanscomps commented 2 years ago

Thanks, looks great, will test tonight. I just scanned the code quickly and applied a dirty fix, thought took care of the other bulbs.

hanscomps commented 2 years ago

Works for my bulb, after adding brackets around the light_type conditions.

...
    if (!(light_type &1)) {
...
    if (!(light_type &2)) {
...
arendst commented 2 years ago

Ah thanks. That's what it should have been. Only problem is now my bulb starts blinking at RGB mode as it hates the CW change.

I will rewrite the code and add two new indexes to the Sm2135.model allowing you to select the extra writes by using the new indexes.

Stay tuned.

arendst commented 2 years ago

OK. Now mine works again.

For you to make it work you will need to use a new template:

{"NAME":"Qualitel RGBWC","GPIO":[0,0,0,0,0,0,0,0,4032,4072,0,0,0,0],"FLAG":0,"BASE":18}

Notice the change from 4064 to 4072. This now indicates that both RGB and WC needs to bewritten.

Give it a try and let me know.

hanscomps commented 2 years ago

Will check tonight. Just looking at the changes made, should these instructions not be swapped? Sm2135SetRGB(0, 0, 0); // Clear RGB Sm2135SetCW(0, 0); // Clear CW Setting RGB should zero CW and reverse.

  if (light_type &2) {          // Set RGB
    Sm2135SetRGB(cur_col[0], cur_col[1], cur_col[2]);
  } else {
    if (Sm2135.grbcw) {
      Sm2135SetRGB(0, 0, 0);    // Clear RGB
    }
  }
  if (light_type &1) {          // Set CW
    Sm2135SetCW(cur_col[3], cur_col[4]);
  } else {
    if (Sm2135.grbcw) {
      Sm2135SetCW(0, 0);        // Clear CW
    }
  }
arendst commented 2 years ago

Nope. This should work. If No RGB is set it will clear all colors. Same for CW.

hanscomps commented 2 years ago

Oh, sorry, I missed the else in there /ignore

hanscomps commented 2 years ago

Tested, works great. Thanks.