Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RGB PWM Dimmer Steps - improvement in softness for lowlight situations #6942

Closed
Waldmensch1 opened this issue Nov 16, 2019 · 48 comments · Fixed by #7007
Closed

RGB PWM Dimmer Steps - improvement in softness for lowlight situations #6942

Waldmensch1 opened this issue Nov 16, 2019 · 48 comments · Fixed by #7007
Labels
enhancement Type - Enhancement that will be worked on

Comments

@Waldmensch1
Copy link

Waldmensch1 commented Nov 16, 2019

Please take a few minutes to complete the requested information below. Our ability to provide assistance is greatly hampered without it. The details requested potentially affect which options to pursue. The small amount of time you spend completing the template will also help the volunteers providing the assistance to you to reduce the time required to help you.

Have you looked for this feature in other issues and in the wiki?
yes

Is your feature request related to a problem? Please describe.
A clear and concise description of what the problem is.
If you dim an RGB device e.g. from 20 to 0 the single PWM steps are hardly visible which doesn't look soft at all.

Describe the solution you'd like
A clear and concise description of what you want to happen.

I know that we have a limited number of PWM steps to cover the 0-100%. My observation is, if you dim e.g. from 80 to 90 it is very soft but if you dim from 0 to 10 you see each single PWM step. I assume that the number of PWM steps per percent value is static (same number of steps from 0 to 10 as from 80 to 90). I counted 2-3 steps per percent value in the low region.
So the Idea is to use more PWM steps in the low region (0-20), maybe 10 PWM steps, and less steps in the higher region. Finally in the region 80-100 one PWM step per percent would be enough without seeing any flicker. I have no clue whether a logarithmic function or a linear function is better there to calculate the PWM steps from percent value. This have to be tested but I assume a logarithmic decreasing of PWM steps per percent value should have the most benefit to get as much as possible PWM steps in the low dimming region.

Describe alternatives you've considered
A clear and concise description of any alternative solutions or features you've considered.

I found an explanation and a sample code here. (German language) https://www.mikrocontroller.net/articles/LED-Fading

Additional context
Add any other context or screenshots about the feature request here.

I tested the behavior on a MagicHome and H801 and also on a sonoff B1 with single white channel. They show exactly the same behavior. So I assume the steppy lowlight dimming onnly can be fixed on the PWM step calculation.

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

@s-hadinger
Copy link
Collaborator

Tasmota is already doing Gamma correction with a 10 bits resolution which is more or less the maximum possible with Esp8266.

You can try disabling Gamma correction with LedTable 0 to see the difference.

@Waldmensch1
Copy link
Author

Waldmensch1 commented Nov 16, 2019

This Ledtable setting doesn't work properly.

assumed color 00000000FF (only white channel)

  1. the maximum brightness is never reached
  • set ledtable to 1
  • dimmer 100
  • set ledtable to 0
    = youll see an increasing of brigthness by 20% with ledtable 0
  1. the dimmer downwards is much faster (factor 10 or so) than dimmer upwards

@s-hadinger
Copy link
Collaborator

s-hadinger commented Nov 16, 2019

This is indeed not normal. I will have a look. What device was that? Sonoff B1?

What Tasmota version?

@Waldmensch1
Copy link
Author

I tested it right now with a MagicHome single channel (Profile Arilux LC11 Modul) on color 00000000FF

13:57:09 MQT: stat/stadtweg/og/leddimmer1/STATUS2 = {"StatusFWR":{"Version":"6.6.0(release-sonoff)","BuildDateTime":"2019.07.06 13:17:19","Boot":7,"Core":"2_3_0","SDK":"1.5.3(aec24ac9)"}}

@s-hadinger
Copy link
Collaborator

This is an old version and core 2.3.0 had pwm issues preventing from full power. This is solved in latest release. Please use the latest stable release 6.7.1

@Waldmensch1
Copy link
Author

Waldmensch1 commented Nov 16, 2019

Ohh, flashed a week ago, wasn't aware of a new version in the meantime.

Tested on MagicHome with single channel 00000000FF looks indeed better. But on a sonoff B1 it looks crazy. If you want to have full brightness on a B1 you use FFFFFFFFFF so RGB is on max white as well as WW and CW. Set color FFFFFFFFFF, speed 10, ledtable 1 and dimmer 0. Then set dimmer 100 and look at the lamp. It dims up until a certain point. then it witches down to maybe 50% and dim up again to 100%. This cannot be correct.

Edit: this behavior on B1 is only with Ledtable 1. On Ledtable 0 the dimmer proceeds normal.

Also the dimmer 100 to 0 is much faster than dimmer 0 to 100. I would further say factor 10 or more.

Edit: this behavior on B1 is only with Ledtable 1. On Ledtable 0 the dimmer proceeds normal speed up and down.

14:35:02 MQT: stat/stadtweg/sonoff/b1/wohnzimmer/STATUS2 = {"StatusFWR":{"Version":"6.7.1(sonoff)","BuildDateTime":"2019.10.26 13:25:04","Boot":6,"Core":"STAGE","SDK":"2.2.2-dev(38a443e)"}}

@s-hadinger
Copy link
Collaborator

Will try later with my Sonoff B1. Please note that Sonoff B1 uses hardware PMW with only 8 bits resolution.

Can you please send the output of module and template commands. Also add status 0 to be sure

@Waldmensch1
Copy link
Author

Below all requested:

16:32:23 MQT: tele/stadtweg/sonoff/b1/wohnzimmer/STATE = {"Time":"2019-11-16T16:32:23","Uptime":"0T02:20:16","UptimeSec":8416,"Heap":28,"SleepMode":"Dynamic","Sleep":0,"LoadAvg":999,"MqttCount":1,"POWER":"ON","Dimmer":100,"Color":"FFFFFFFFFF","HSBColor":"0,0,100","Channel":[100,100,100,100,100],"CT":327,"Scheme":0,"Fade":"ON","Speed":10,"LedTable":"OFF","Wifi":{"AP":1,"SSId":"iot24","BSSId":"02:9F:C2:DD:2E:79","Channel":1,"RSSI":58,"LinkCount":1,"Downtime":"0T00:00:05"}} 16:37:23 MQT: tele/stadtweg/sonoff/b1/wohnzimmer/STATE = {"Time":"2019-11-16T16:37:23","Uptime":"0T02:25:16","UptimeSec":8716,"Heap":28,"SleepMode":"Dynamic","Sleep":0,"LoadAvg":999,"MqttCount":1,"POWER":"ON","Dimmer":100,"Color":"FFFFFFFFFF","HSBColor":"0,0,100","Channel":[100,100,100,100,100],"CT":327,"Scheme":0,"Fade":"ON","Speed":10,"LedTable":"OFF","Wifi":{"AP":1,"SSId":"iot24","BSSId":"02:9F:C2:DD:2E:79","Channel":1,"RSSI":56,"LinkCount":1,"Downtime":"0T00:00:05"}} 16:42:23 MQT: tele/stadtweg/sonoff/b1/wohnzimmer/STATE = {"Time":"2019-11-16T16:42:23","Uptime":"0T02:30:16","UptimeSec":9016,"Heap":28,"SleepMode":"Dynamic","Sleep":0,"LoadAvg":999,"MqttCount":1,"POWER":"ON","Dimmer":100,"Color":"FFFFFFFFFF","HSBColor":"0,0,100","Channel":[100,100,100,100,100],"CT":327,"Scheme":0,"Fade":"ON","Speed":10,"LedTable":"OFF","Wifi":{"AP":1,"SSId":"iot24","BSSId":"02:9F:C2:DD:2E:79","Channel":1,"RSSI":60,"LinkCount":1,"Downtime":"0T00:00:05"}} 16:47:23 MQT: tele/stadtweg/sonoff/b1/wohnzimmer/STATE = {"Time":"2019-11-16T16:47:23","Uptime":"0T02:35:16","UptimeSec":9316,"Heap":28,"SleepMode":"Dynamic","Sleep":0,"LoadAvg":999,"MqttCount":1,"POWER":"ON","Dimmer":100,"Color":"FFFFFFFFFF","HSBColor":"0,0,100","Channel":[100,100,100,100,100],"CT":327,"Scheme":0,"Fade":"ON","Speed":10,"LedTable":"OFF","Wifi":{"AP":1,"SSId":"iot24","BSSId":"02:9F:C2:DD:2E:79","Channel":1,"RSSI":58,"LinkCount":1,"Downtime":"0T00:00:05"}} 16:49:11 CMD: ledtable 1 16:49:11 MQT: stat/stadtweg/sonoff/b1/wohnzimmer/RESULT = {"LedTable":"ON"} 16:49:23 CMD: dimmer 0 16:49:23 MQT: stat/stadtweg/sonoff/b1/wohnzimmer/RESULT = {"POWER":"OFF","Dimmer":0,"Color":"0000000000","HSBColor":"0,0,0","Channel":[0,0,0,0,0],"CT":327} 16:49:41 CMD: dimmer 100 16:49:41 MQT: stat/stadtweg/sonoff/b1/wohnzimmer/RESULT = {"POWER":"ON","Dimmer":100,"Color":"FFFFFFFFFF","HSBColor":"0,0,100","Channel":[100,100,100,100,100],"CT":327} 16:50:30 CMD: ledtable 0 16:50:30 MQT: stat/stadtweg/sonoff/b1/wohnzimmer/RESULT = {"LedTable":"OFF"} 16:50:39 CMD: dimmer 0 16:50:39 MQT: stat/stadtweg/sonoff/b1/wohnzimmer/RESULT = {"POWER":"OFF","Dimmer":0,"Color":"0000000000","HSBColor":"0,0,0","Channel":[0,0,0,0,0],"CT":327} 16:50:53 CMD: dimmer 100 16:50:53 MQT: stat/stadtweg/sonoff/b1/wohnzimmer/RESULT = {"POWER":"ON","Dimmer":100,"Color":"FFFFFFFFFF","HSBColor":"0,0,100","Channel":[100,100,100,100,100],"CT":327} 16:52:10 CMD: module 16:52:10 MQT: stat/stadtweg/sonoff/b1/wohnzimmer/RESULT = {"Module":{"26":"Sonoff B1"}} 16:52:23 MQT: tele/stadtweg/sonoff/b1/wohnzimmer/STATE = {"Time":"2019-11-16T16:52:23","Uptime":"0T02:40:16","UptimeSec":9616,"Heap":28,"SleepMode":"Dynamic","Sleep":0,"LoadAvg":247,"MqttCount":1,"POWER":"ON","Dimmer":100,"Color":"FFFFFFFFFF","HSBColor":"0,0,100","Channel":[100,100,100,100,100],"CT":327,"Scheme":0,"Fade":"ON","Speed":10,"LedTable":"OFF","Wifi":{"AP":1,"SSId":"iot24","BSSId":"02:9F:C2:DD:2E:79","Channel":1,"RSSI":60,"LinkCount":1,"Downtime":"0T00:00:05"}} 16:52:55 CMD: template 16:52:55 MQT: stat/stadtweg/sonoff/b1/wohnzimmer/RESULT = {"NAME":"Generic","GPIO":[255,255,255,255,255,255,255,255,255,255,255,255,255],"FLAG":1,"BASE":18} 16:53:13 CMD: status 0 16:53:13 MQT: stat/stadtweg/sonoff/b1/wohnzimmer/STATUS = {"Status":{"Module":26,"FriendlyName":["RGB Wohnzimmer 0"],"Topic":"stadtweg/sonoff/b1/wohnzimmer","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}} 16:53:13 MQT: stat/stadtweg/sonoff/b1/wohnzimmer/STATUS1 = {"StatusPRM":{"Baudrate":115200,"GroupTopic":"sonoffs","OtaUrl":"http://thehackbox.org/tasmota/release/sonoff-DE.bin","RestartReason":"Software/System restart","Uptime":"0T02:41:06","StartupUTC":"2019-11-16T13:12:07","Sleep":50,"CfgHolder":4617,"BootCount":19,"SaveCount":1457,"SaveAddress":"F8000"}} 16:53:13 MQT: stat/stadtweg/sonoff/b1/wohnzimmer/STATUS2 = {"StatusFWR":{"Version":"6.7.1(sonoff)","BuildDateTime":"2019.10.26 13:25:04","Boot":6,"Core":"STAGE","SDK":"2.2.2-dev(38a443e)"}} 16:53:13 MQT: stat/stadtweg/sonoff/b1/wohnzimmer/STATUS3 = {"StatusLOG":{"SerialLog":2,"WebLog":2,"MqttLog":0,"SysLog":0,"LogHost":"","LogPort":514,"SSId":["iot24",""],"TelePeriod":300,"Resolution":"558180C0","SetOption":["00008009","2805C8000100060000005AFF000000000000","00000000"]}} 16:53:13 MQT: stat/stadtweg/sonoff/b1/wohnzimmer/STATUS4 = {"StatusMEM":{"ProgramSize":564,"Free":436,"Heap":24,"ProgramFlashSize":1024,"FlashSize":1024,"FlashChipId":"144051","FlashMode":3,"Features":["00000407","8FDAE397","043683A0","22B617CD","01001BC0","0000F081"],"Drivers":"1,2,3,4,5,6,7,8,9,10,12,16,18,19,20,21,22,24,26,30","Sensors":"1,2,3,4,5,6,7,8,9,10,14,15,17,18,20,22,26,34"}} 16:53:13 MQT: stat/stadtweg/sonoff/b1/wohnzimmer/STATUS5 = {"StatusNET":{"Hostname":"stadtweg/sonoff/b1/wohnzimmer-0","IPAddress":"192.168.178.36","Gateway":"192.168.178.1","Subnetmask":"255.255.255.0","DNSServer":"192.168.178.74","Mac":"60:01:94:AA:E1:9F","Webserver":2,"WifiConfig":5}} 16:53:13 MQT: stat/stadtweg/sonoff/b1/wohnzimmer/STATUS6 = {"StatusMQT":{"MqttHost":"192.168.178.46","MqttPort":1883,"MqttClientMask":"DVES_%06X","MqttClient":"DVES_AAE19F","MqttUser":"DVES_USER","MqttCount":1,"MAX_PACKET_SIZE":1000,"KEEPALIVE":30}} 16:53:13 MQT: stat/stadtweg/sonoff/b1/wohnzimmer/STATUS7 = {"StatusTIM":{"UTC":"Sat Nov 16 15:53:13 2019","Local":"Sat Nov 16 16:53:13 2019","StartDST":"Sun Mar 31 02:00:00 2019","EndDST":"Sun Oct 27 03:00:00 2019","Timezone":99,"Sunrise":"07:30","Sunset":"16:19"}} 16:53:13 MQT: stat/stadtweg/sonoff/b1/wohnzimmer/STATUS10 = {"StatusSNS":{"Time":"2019-11-16T16:53:13"}} 16:53:13 MQT: stat/stadtweg/sonoff/b1/wohnzimmer/STATUS11 = {"StatusSTS":{"Time":"2019-11-16T16:53:13","Uptime":"0T02:41:06","UptimeSec":9666,"Heap":24,"SleepMode":"Dynamic","Sleep":0,"LoadAvg":368,"MqttCount":1,"POWER":"ON","Dimmer":100,"Color":"FFFFFFFFFF","HSBColor":"0,0,100","Channel":[100,100,100,100,100],"CT":327,"Scheme":0,"Fade":"ON","Speed":10,"LedTable":"OFF","Wifi":{"AP":1,"SSId":"iot24","BSSId":"02:9F:C2:DD:2E:79","Channel":1,"RSSI":60,"LinkCount":1,"Downtime":"0T00:00:05"}}}

@Waldmensch1
Copy link
Author

Waldmensch1 commented Nov 16, 2019

Below the details for MagicHome 1ch dimmer. With this device the down/up period seems to be the same length, also with ledtable 1 if the values are larger. dimmer 10 is further longer than dimmer 0 (from 10). I have a 12V 5m LED Stripe single color on this controller. The dimming is smoother but I see folowing behavior by fire commands after eachother

dimmer 0 - off
dimmer 1 - on
dimmer 2 - no visible change
dimmer 3 - no visible change
dimmer 4 - no visible change
dimmer 5 - no visible change
dimmer 6 - no visible change
dimmer 7 - no visible change
dimmer 8 - change in brightness
dimmer 9 - no visible change
dimmer 10 - no visible change
dimmer 11 - change in brightness
dimmer 12 - change in brightness
dimmer 13 - no visible change
dimmer 14 - change in brightness

Here the details for this device. I'll try to make some measures with my pocket scope tomorrow to check whether the PWM changes between dimmer 2 and dimmer 7

16:58:43 MQT: tele/stadtweg/og/leddimmer1/STATE = {"Time":"2019-11-16T16:58:43","Uptime":"0T02:50:16","UptimeSec":10216,"Heap":28,"SleepMode":"Dynamic","Sleep":0,"LoadAvg":999,"MqttCount":1,"POWER":"ON","Dimmer":1,"Color":"0000000003","HSBColor":"0,0,0","Channel":[0,0,0,0,1],"CT":500,"Scheme":0,"Fade":"ON","Speed":20,"LedTable":"ON","Wifi":{"AP":1,"SSId":"iot24","BSSId":"02:9F:C2:DD:2E:79","Channel":1,"RSSI":64,"LinkCount":1,"Downtime":"0T00:00:05"}} 16:58:50 CMD: module 16:58:50 MQT: stat/stadtweg/og/leddimmer1/RESULT = {"Module":{"38":"Arilux LC11"}} 16:58:55 CMD: template 16:58:55 MQT: stat/stadtweg/og/leddimmer1/RESULT = {"NAME":"Magic Home Dim","GPIO":[17,255,0,255,38,0,0,0,41,40,0,0,0],"FLAG":0,"BASE":38} 16:59:02 CMD: status 0 16:58:43 MQT: tele/stadtweg/og/leddimmer1/STATE = {"Time":"2019-11-16T16:58:43","Uptime":"0T02:50:16","UptimeSec":10216,"Heap":28,"SleepMode":"Dynamic","Sleep":0,"LoadAvg":999,"MqttCount":1,"POWER":"ON","Dimmer":1,"Color":"0000000003","HSBColor":"0,0,0","Channel":[0,0,0,0,1],"CT":500,"Scheme":0,"Fade":"ON","Speed":20,"LedTable":"ON","Wifi":{"AP":1,"SSId":"iot24","BSSId":"02:9F:C2:DD:2E:79","Channel":1,"RSSI":64,"LinkCount":1,"Downtime":"0T00:00:05"}} 16:58:50 CMD: module 16:58:50 MQT: stat/stadtweg/og/leddimmer1/RESULT = {"Module":{"38":"Arilux LC11"}} 16:58:55 CMD: template 16:58:55 MQT: stat/stadtweg/og/leddimmer1/RESULT = {"NAME":"Magic Home Dim","GPIO":[17,255,0,255,38,0,0,0,41,40,0,0,0],"FLAG":0,"BASE":38} 16:59:02 CMD: status 0 16:59:02 MQT: stat/stadtweg/og/leddimmer1/STATUS = {"Status":{"Module":38,"FriendlyName":["stadtweg/og/leddimmer1"],"Topic":"stadtweg/og/leddimmer1","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}} 16:59:02 MQT: stat/stadtweg/og/leddimmer1/STATUS1 = {"StatusPRM":{"Baudrate":115200,"GroupTopic":"sonoffs","OtaUrl":"http://thehackbox.org/tasmota/release/sonoff-DE.bin","RestartReason":"Software/System restart","Uptime":"0T02:50:35","StartupUTC":"2019-11-16T13:08:27","Sleep":0,"CfgHolder":4617,"BootCount":30,"SaveCount":227,"SaveAddress":"F6000"}} 16:59:02 MQT: stat/stadtweg/og/leddimmer1/STATUS2 = {"StatusFWR":{"Version":"6.7.1(sonoff)","BuildDateTime":"2019.10.26 13:25:04","Boot":7,"Core":"STAGE","SDK":"2.2.2-dev(38a443e)"}} 16:59:02 MQT: stat/stadtweg/og/leddimmer1/STATUS3 = {"StatusLOG":{"SerialLog":2,"WebLog":2,"MqttLog":0,"SysLog":0,"LogHost":"","LogPort":514,"SSId":["iot24","FRITZ!Box Turbo Cable"],"TelePeriod":300,"Resolution":"558180C0","SetOption":["00008009","2805C8000100060000005AFF000000000000","00000000"]}} 16:59:02 MQT: stat/stadtweg/og/leddimmer1/STATUS4 = {"StatusMEM":{"ProgramSize":564,"Free":436,"Heap":24,"ProgramFlashSize":1024,"FlashSize":1024,"FlashChipId":"144051","FlashMode":3,"Features":["00000407","8FDAE397","043683A0","22B617CD","01001BC0","0000F081"],"Drivers":"1,2,3,4,5,6,7,8,9,10,12,16,18,19,20,21,22,24,26,30","Sensors":"1,2,3,4,5,6,7,8,9,10,14,15,17,18,20,22,26,34"}} 16:59:02 MQT: stat/stadtweg/og/leddimmer1/STATUS5 = {"StatusNET":{"Hostname":"stadtweg/og/leddimmer1-6053","IPAddress":"192.168.178.170","Gateway":"192.168.178.1","Subnetmask":"255.255.255.0","DNSServer":"192.168.178.74","Mac":"DC:4F:22:A2:F7:A5","Webserver":2,"WifiConfig":4}} 16:59:02 MQT: stat/stadtweg/og/leddimmer1/STATUS6 = {"StatusMQT":{"MqttHost":"192.168.178.46","MqttPort":1883,"MqttClientMask":"DVES_%06X","MqttClient":"DVES_A2F7A5","MqttUser":"DVES_USER","MqttCount":1,"MAX_PACKET_SIZE":1000,"KEEPALIVE":30}} 16:59:02 MQT: stat/stadtweg/og/leddimmer1/STATUS7 = {"StatusTIM":{"UTC":"Sat Nov 16 15:59:02 2019","Local":"Sat Nov 16 16:59:02 2019","StartDST":"Sun Mar 31 02:00:00 2019","EndDST":"Sun Oct 27 03:00:00 2019","Timezone":99,"Sunrise":"08:00","Sunset":"17:09"}} 16:59:02 MQT: stat/stadtweg/og/leddimmer1/STATUS10 = {"StatusSNS":{"Time":"2019-11-16T16:59:02"}} 16:59:02 MQT: stat/stadtweg/og/leddimmer1/STATUS11 = {"StatusSTS":{"Time":"2019-11-16T16:59:02","Uptime":"0T02:50:35","UptimeSec":10235,"Heap":24,"SleepMode":"Dynamic","Sleep":0,"LoadAvg":999,"MqttCount":1,"POWER":"ON","Dimmer":1,"Color":"0000000003","HSBColor":"0,0,0","Channel":[0,0,0,0,1],"CT":500,"Scheme":0,"Fade":"ON","Speed":20,"LedTable":"ON","Wifi":{"AP":1,"SSId":"iot24","BSSId":"02:9F:C2:DD:2E:79","Channel":1,"RSSI":62,"LinkCount":1,"Downtime":"0T00:00:05"}}}

@Waldmensch1
Copy link
Author

Waldmensch1 commented Nov 16, 2019

I've made a test with my cheap scope. There is indeed no change in PWM from dimmer 1 to dimmer 7. Dimmer 8 to dimmer 10 are on the same PWM and dimmer 11 is a change again. I added a few shoots from scope. Measured on 12V output of MagicHome

dimmer 1 to dimmer 7
dimmer_1_to_7

dimmer 8 to dimmer 10
dimmer_8_to_10

dimmer 11
dimmer_11

@s-hadinger
Copy link
Collaborator

What you are seeing with MagicHome is normal. The human eye is VERY sensitive at low brightness, and there is not enough resolution with 10 bits to accurately represent every Dimmer value. Note also that Dimmer is of range 0..100 while the internal value is actually 0..255.

The Gamma table used internally is as follows:

//  0,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
//  1,  1,  1,  1,  2,  2,  2,  2,  2,  2,  2,  3,  3,  3,  3,  4,
//  4,  4,  4,  5,  5,  5,  6,  6,  6,  7,  7,  8,  8,  9,  9, 10,
// 10, 11, 11, 12, 13, 13, 14, 15, 15, 16, 17, 18, 19, 19, 20, 21,
// 22, 23, 24, 25, 26, 27, 28, 30, 31, 32, 33, 34, 36, 37, 38, 39,
// 41, 42, 44, 45, 47, 48, 50, 51, 53, 55, 56, 58, 60, 62, 64, 65,
// 67, 69, 71, 73, 75, 78, 80, 82, 84, 86, 89, 91, 93, 96, 98,101,
//103,106,108,111,114,116,119,122,125,128,131,134,137,140,143,146,
//151,155,157,161,165,169,171,175,179,183,187,189,193,197,201,205,
//209,213,217,221,225,231,235,239,243,247,251,257,261,265,271,275,
//281,285,289,295,299,305,311,315,321,327,331,337,343,347,353,359,
//365,371,377,383,389,395,401,407,413,419,425,431,439,445,451,459,
//467,475,483,487,495,503,511,515,523,531,539,547,555,559,567,575,
//583,591,599,607,615,623,631,639,647,655,663,675,683,691,699,707,
//715,727,735,743,751,763,771,779,791,799,807,819,827,839,847,859,
//867,879,887,899,907,919,931,939,951,963,971,983,995,1003,1015,1023

We could force to have a change in brightness as every step but it would corrupt the perceived linearity of the light at low brightness. As said previously that's the best we can do with 10 bits resolution.

I will look at the Sonoff B1 issue which looks to be something different.

@Waldmensch1
Copy link
Author

You are totally right, the human eye is very sensitive at low brightness. That's why stuttering in low level dimming is more anoying than stuttering between 80-100%. That's why I mean in the low level dimming there should be more steps per percent and in the higher level of dimming can be less steps per percent.

With ledtable 0 it looks like we have a change on each percent. I don't know whether it is an inaccuracy of my scope but the step in dimmer 5 looks out of order (step is to large). I assume that we see a flicker between dimmer 4 and dimmer 6. I doesn't know the formula behind but also if 100% dealed into 255 steps a linear increasing should be possible

Below the PWM with ledtable 0 - dimmer 1 to dimmer 6
dimmer1
dimmer2
dimmer3
dimmer4
dimmer5
dimmer6

@s-hadinger
Copy link
Collaborator

s-hadinger commented Nov 16, 2019

I just don't see how this would be possible with 10 bits resolution and keeping a perceived linearity.

We could tweak the Gamma table to force different values for Dimmer values, but that would also be artificial, since Dimmer is of range 0..100 while internally channels are of values 0..255. For example, if you want different PWM values for Dimmer 0..20, that would mean that Dimmer 20 has the PWM value 20, which would be equivalent to 25% of perceived brightness instead of 20%.

Put differently, 10 bits PMW is not capable to accurately distinguish between 1%-4%.

Why is it a problem if Dimmer 1 and Dimmer 2 have the same brightness?

@s-hadinger
Copy link
Collaborator

s-hadinger commented Nov 16, 2019

I just tested Sonoff B1. It uses My92x1 hardware PWM drivers, and they appear to have hardware Gamma correction. You should definitely use LedTable 0 with Sonoff B1.

I'm updating the template repository accordingly.

@Waldmensch1
Copy link
Author

Why is it a problem if Dimmer 1 and Dimmer 2 have the same brightness?

This is maybe not a problem at fade 0 or fade 1 && speed 0 (you only see no different on command dimmer 1 to dimmer 7, what a user doesn't expect but it can be explained)

But it is a problem if you use fade 1 and e.g. speed 10. The time runs linear. Let's assume 100 seconds for easy calculation. This is the same as if you execute dimmer 1 to dimmer 100 with a second delay each. You set dimmer 50 and the cycle starts. Now you see LED turns on (dimmer 1). next you see nothing happen for 6 seconds (dimmer 2 to dimmer 7), next you see an increase of brightness (dimmer 8), next 2 seconds you see nothing happen and so on......

I don't know why this so hard to explain. You just have to take a PWM device of your choice, set ledtable 1, fade 1 and speed 10. Then start dimmer 100 look at the LED's and you see the effect I mean. You will see a anoying times of "nothing happen" between 1 and 20 and then a smooth increasing of brightness from 20-100

@Waldmensch1
Copy link
Author

Related to the linear dimming (ledtable 0):
If we have 1024 steps avail on PWM and we have 255 steps (you said 100% equals 255 internally), then a linear increase by 4 per percent should be done but in steps of 1 depending of speed value set.
Actually it seems, on linear dimming, that this 4 steps are done but only once per percent step. The speed value only seems to have an influence how fast the dimmer values are fired after eachother. I can be wrong on this but it is what the scope shows to me: 4 PWM step at once on one percent step

@Waldmensch1
Copy link
Author

Could you make this table accessable from outside via JSON array? The users could play around to define own gama correction?!

The Gamma table used internally is as follows:

// 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,

@Waldmensch1
Copy link
Author

For linear dimmer (I have no clue how it is done actually in tasmota but it looks to me that it is done in 255 steps instead of 1024 steps) I would do it somehow this way
(Javascript)

            var actual_value, target_value, speed;
            const max_dimmerstep = 255;
            const max_pwmstep = 1024;
            var actual_pwm = parseInt(actual_value * max_pwmstep / max_dimmerstep);
            var target_pwm;
             
            if(actual_value >  target_value){
                target_pwm = parseInt((actual_value - target_value) * max_pwmstep / max_dimmerstep);
                for(var i = actual_pwm; i > target_pwm; i--){
                    // set PWM to i
                    // delay (speed)
                }
            } else {
                target_pwm = parseInt((actual_value + target_value) * max_pwmstep / max_dimmerstep);
                for(var i = actual_pwm; i < target_pwm; i++){
                    // set PWM to i
                    // delay (speed)
                }
            }

@s-hadinger
Copy link
Collaborator

s-hadinger commented Nov 17, 2019

In understand now your issue, I never use Fade.

The Gamma tables are defined at compile time and it would take too much Flash and Ram to have them dynamically changed. Can you self-compile and try different values? You can do this locally or via GitPod.

The Gamma table is defined in xdrv_04_light.ino lines 173-193:


#ifdef XFUNC_PTR_IN_ROM
const uint8_t _ledTable[] PROGMEM = {
#else
const uint8_t _ledTable[] = {
#endif
  // 11 bits resolution
    0,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  2,  2,  // 11 bits, 0..2047
    2,  2,  2,  2,  3,  3,  3,  3,  4,  4,  4,  5,  5,  6,  6,  7,  // 11 bits, 0..2047
    7,  8,  8,  9, 10, 10, 11, 12, 12, 13, 14, 15, 16, 17, 18, 19,  // 11 bits, 0..2047
   20, 21, 22, 24, 25, 26, 28, 29, 30, 32, 33, 35, 37, 38, 40, 42,  // 11 bits, 0..2047
  // 10 bits resolution
   22, 23, 24, 25, 26, 27, 28, 30, 31, 32, 33, 34, 36, 37, 38, 39,  // 10 bits, 0..1023
   41, 42, 44, 45, 47, 48, 50, 51, 53, 55, 56, 58, 60, 62, 64, 65,  // 10 bits, 0..1023
   67, 69, 71, 73, 75, 78, 80, 82, 84, 86, 89, 91, 93, 96, 98,101,  // 10 bits, 0..1023
  103,106,108,111,114,116,119,122,125,128,131,134,137,140,143,146,  // 10 bits, 0..1023
  // 9 bits resolution
   75, 77, 78, 80, 82, 84, 85, 87, 89, 91, 93, 94, 96, 98,100,102,  //  9 bits, 0..511
  104,106,108,110,112,115,117,119,121,123,125,128,130,132,135,137,  //  9 bits, 0..511
  140,142,144,147,149,152,155,157,160,163,165,168,171,173,176,179,  //  9 bits, 0..511
  182,185,188,191,194,197,200,203,206,209,212,215,219,222,225,229,  //  9 bits, 0..511
  // 8 bits resolution
  116,118,120,121,123,125,127,128,130,132,134,136,138,139,141,143,  //  8 bits, 0..255
  145,147,149,151,153,155,157,159,161,163,165,168,170,172,174,176,  //  8 bits, 0..255
  178,181,183,185,187,190,192,194,197,199,201,204,206,209,211,214,  //  8 bits, 0..255
  216,219,221,224,226,229,232,234,237,240,242,245,248,250,253,255   //  8 bits, 0..255
};

To keep the whole table into 256 bytes, it uses adaptative resolution in each 64 bytes blocks, starting from 11 bits to 8 bits. PWM uses 10 bits and rounds value to the nearest integer, and forces 1 if the value is lower than 1 but non-zero.

@joba-1
Copy link
Contributor

joba-1 commented Nov 17, 2019

@Waldmensch1 : danke fürs kümmern :)

@s-hadinger : if you never use fade, I understand your priorities, but I think I am not alone as fade user hating visible steps more than not having linearity.
I aim at doing a pwm change at each step (the user requested a change so he should get it) and do linearity with the rest of the range where steps are >= 1.0

@s-hadinger
Copy link
Collaborator

I am reluctant to change the Gamma correction tables and break the perceived linearity of brightness.

So it's actually the Fade algorithm that needs to be changed, and there is little reason fading should follow a linear rule. @joba-1 are you working on a PR?

@Waldmensch1
Copy link
Author

The question is why "fade " is used. The reason is simple. If you use a hardware dimmer with a wheel, you have the efect of a smooth increasing/decreasing of brightness. Same you have on touch Hardware dimmers. A dimmer makes no real sense without fading because without fading it is "jump to a brightness". For "jumping to a brightness" a gamma correction doesn't make sense, because the eye see this jump anyway. The magic is to reach a soft increasing of brightness from 0 to 100% without seeing the steps in between. This is hard because an analog control behavior have to be done by a limitted number of digital steps.

I had a look into code void LightFade(void), Without knowlede of the rest of the lights code I would say the fading is done in 255 steps (related to 100%) instead of 1024 possible PWM steps. This would go conform with my observations with scope on linear fade (see screenshots) a few comments above.

I think, using 1024 PWM steps on fading would result in a quite smoother dimming

@s-hadinger
Copy link
Collaborator

s-hadinger commented Nov 17, 2019

Indeed, but it will need a refactoring of the the way Fade works. Today Fade is done before any Gamma correction or 8 to 10 bits conversion.

I agree with your approach, but this means that the Fading algorithm should take place after the begin and end PWM 10 bits values are calculated (after Gamma correction).

These are significant changes but worth the effort. Let me take a closer look.

@s-hadinger
Copy link
Collaborator

After all it may not be such a big change :)

@Waldmensch1
Copy link
Author

After all it may not be such a big change :)

I have an unused H801 (RGBWW) for testing beside of MagicHome (W) and have re-installed the PlatformIO environment right now. So if you need somebody for testing - just ask and provide me with a link to your branch. (or send the 04-lights.ino to copy over locally)

@s-hadinger
Copy link
Collaborator

Thanks, will do.

@s-hadinger
Copy link
Collaborator

Actually I'm not convinced by the way Fade works today. Speed specifies a speed of change of the light, which means the time of fading depends on the distance from the start to end colors.

In Zigbee you just specify the time it takes from the start to the end state, whatever the colors. Would it be ok to change Speed to a constant time? I feel it would make smoother transitions.

@Waldmensch1
Copy link
Author

Not sure if I understand correct. I my opinion the speed should be always set to cover the time fading from 0% to 100%. If I am at 50% right now I would expect that dimming to 100% would take half time of dimming 0 to 100. Or I'm wrong?

@s-hadinger
Copy link
Collaborator

That's a design choice. Currently the fading algorithm takes the distance between current and target color, and divides the distance by 2^speed at each step. Which is roughly a log function, and not linear at all.

I will try to have a constant speed algorithm, meaning that indeed moving from 50% to 100% takes half the time than moving from 0% to 100%.

@Waldmensch1
Copy link
Author

cool! I did the initial flash for H801 right now. I see that it seems to be that there is also an additional IC hc245 between the ESP and MOSFET. Just the MagicHome seems to not have this. No clue which effect this have for testing. I hope not, because the MagicHome is the hell for FTDI flashing ;)

@s-hadinger
Copy link
Collaborator

Can you please try this branch: https://github.com/s-hadinger/Tasmota/tree/fade_dev
I can provide pre-compiled firmwares if you prefer.

It not polished but gives you a good idea of the result.

There is still a Hue issue I need to fix. For example if you do Color FF8000 then Power Off, it will change from yellow to red. I will fix that later.

@Waldmensch1
Copy link
Author

Waldmensch1 commented Nov 17, 2019

checked out your repo and swiched to fade-dev branch without problems. I'm able to build this with PlatformIO but the .bin is not flashable OTA. Not tasmota and also not tasmota-DE if I build this. sonoff-DE (actual release) is flashed actually. The Error says "Upload Buffer compare differs". Is there any flag to set while compile to get that flashed OTA over the actual sonoff-DE release? Only thing I changed is to include my user_config_override.h
If that not work at all, no problem to flash with serial but OTA would make that a lot easier ;)

Test_OTA

@s-hadinger
Copy link
Collaborator

You need to flash a tasmota-minimal first, then the target firmware. This is because they are bigger than 512KB and you need to fit 2 firmwares in 1MB flash.

@s-hadinger
Copy link
Collaborator

s-hadinger commented Nov 17, 2019

Here is a compact firmware of the fade_dev branch that work for lights.
https://file.hadinger.fr/tejpou

@Waldmensch1
Copy link
Author

got it already :)
00:00:00 CFG: aus Flash geladen am FB, zählen 31 00:00:00 Projekt sonoff Sonoff Version 7.0.0.4(tasmota)-2_6_1 00:00:00 WIF: verbinden mit AP1 iot24 in Modus 11N als stadtweg/og/H801-4629... 00:00:05 WIF: verbunden 00:00:05 HTP: Web-Server aktiv bei stadtweg/og/H801-4629 mit IP-Adresse 192.168.178.173

Do yo have a special test-scenario where I should look at?

@s-hadinger
Copy link
Collaborator

Nothing fancy.

Fade 1
Speed 5
Color FF0000
Power Off
Power On
Color FFFFFF
Power Off

And so on...

@Waldmensch1
Copy link
Author

Waldmensch1 commented Nov 17, 2019

WOW!!!! That works AWESOME!!!

Edit: Tested on H801

  • linear fading nearly no steps visible

  • gamma corrected the usual time related steps are visible but subjectiv impression better than before

  • speed setting seems to be half value from before. Feeling is speed 20 is what speed 10 was before. So please increase the delay a bit or allow larger values in speed. Maybe corosponding with seconds. E.g. speed 60 - 0 to 100% in 60 seconds. This would be good understandable by users. These long intervals are normally used for soft waking up in sleeping room in the morning ;) So "very" slow should be possible.

  • color changes are very smooth. E.g. color ff0000 to color 00ff00

  • colorchange from color 0000ff0000 to color ff0000ff00: the white channel is much faster on 100% than the color change is completed

  • color 000000000 to color 00ff00ff00 RGB and W reach 100% at the same time

  • color 000000000 to color ffffffffff RGB and W reach 100% at the same time

At all you are very close to perfect!

@s-hadinger
Copy link
Collaborator

Thanks. Does it feel natural that moving from FF0000 to 000000 takes twice as long as moving from 800000 to 000000?

@Waldmensch1
Copy link
Author

For me this is okay. I would expect that behavior.

@s-hadinger
Copy link
Collaborator

Currently Speed is the number of half-seconds to go from 0% to 100%, assuming you are using Sleep 50 and not higher.

So Speed 2 means 1 second, Speed 20 means 10 seconds. I would like to keep that resolution, instead of pure seconds. I can extend to allow Speed 40 if 20 seconds makes sense.

@s-hadinger
Copy link
Collaborator

I think I will leave it that way. Maintaining Hue values when scaling will add a lot of code - maybe too much.

@Waldmensch1
Copy link
Author

I never changed sleep, a check shows 50

I never measured the time 0-100 so I don't know how large the different is to your version. By the way, it's hard to measure, because the changes in the higher region are not really detectable for human eye. So I'm not able to see when dimming is at 100%
I assume 20 Secs are okay, but I'm only one of thousends Tasmota users ;)
40 makes more sense then 20 multiplied by 2 in code. 40 makes the setting more individual for users.

@ascillato2 ascillato2 added the enhancement Type - Enhancement that will be worked on label Nov 17, 2019
@Waldmensch1
Copy link
Author

There is maybe something wrong. I found the command WakeupDuration and Wakeup. I never used that before. By reading documentation I would assume:

  • WakeupDuration = time in seconds to reach value
  • Wakeup = start wakeup with percent dimmer as target value

If I set WakeupDuration 1000 and wakeup 100 after eachother nothing happens.

To reproduce:

  • color FFFFFFFFFF
  • dimmer 0
  • WakeupDuration 1000
  • wakeup 100

@s-hadinger
Copy link
Collaborator

I think that Wakeup call is independent from Dimmer. Did it work in the standard Tasmota version? Or did I just break it?

@Waldmensch1
Copy link
Author

I tested the same on MagicHome single Channel 00000000FF (actual sonoff release) right now - it shows the same behavior. It's more strange than thougt before. If you have do

  • color FFFFFFFFFF
  • dimmer 1
  • WakeupDuration 1000
  • wakeup 100
    it seems to work. If you do then
  • dimmer 0
  • dimmer 1
    you get RESULT = {"POWER":"ON","Dimmer":1,"Color":"0000000003","HSBColor":"0,0,0","Channel":[0,0,0,0,1],"CT":500} which is correct but nothing is happen. All other dimmer values seem to be ignored too. To get "a light" again you have to set color FFFFFFFFFF or color 00000000FF

Good news, you made nothing worse, the bug is in actual release too ;)

@Waldmensch1
Copy link
Author

I rebooted the magicHome and switching dimmer 1 and dimmer 0 back and force works like a charm. So I asume that fire the wakeup "destroys" something

@s-hadinger
Copy link
Collaborator

I think it's a very old bug and it looks that nobody is using this feature lol

@Waldmensch1
Copy link
Author

I think too. Maybe "wakeup" was introduced before "Fade" which does nearly the same. I don't know what wakeup does internally but I would assume that it is a loop which fires dimmer commands every (WakeupDuration/ wakeup value) seconds until wakeup value is reached. So it could be used for long duration sunrise scenarios. Max value for wakeup is 3600, so 1hr. Could be a nice gimmick to illuminate a large translucent wall-filling image in your room with a few LED stripes behind.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement Type - Enhancement that will be worked on
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants