ESP8266_new_pwm icon indicating copy to clipboard operation
ESP8266_new_pwm copied to clipboard

flicker at 50% :-(

Open gorec2005 opened this issue 8 years ago • 19 comments

i have flicker at 50% pwm! if range=10000 than pwm from 4998 to 4999 ok but from 4999 to 5000 flicker :-(

gorec2005 avatar Dec 10 '16 22:12 gorec2005

same here

kaeferfreund avatar Dec 11 '16 11:12 kaeferfreund

  • [ ] How many channels do you use?
  • [ ] What are the duty levels of the other channels?
  • [ ] Does it only happen with 5000, or also with 5001, 5002, ... 5017?
  • [ ] Is only the channel at 50% flickering, or also the other channels?

StefanBruens avatar Dec 11 '16 15:12 StefanBruens

  • i use only one channel
  • it's happen with any before 5000 and any after 5000 for example 4980 and 5001 or 4990 and 5017! -it's happen when go accross 50% i.e. from <5000 to >=5000
  • i use only one channel :-(

gorec2005 avatar Dec 11 '16 16:12 gorec2005

Can you please clarify the second answer?

StefanBruens avatar Dec 11 '16 16:12 StefanBruens

i test it again: flicker appear only when pwm intersects 5000 (for 10000 range)! from 4999 to 5000 i don't know how i can clarify... - sorry... 4990..4995...4999.flicker..5000...5005...

gorec2005 avatar Dec 11 '16 16:12 gorec2005

no videos, please.

Just describe, step by step, what you are doing, and what results you have, e.g.:

  1. I set PWM to 4999 -> ~50% output
  2. set to 5000 -> flickering
  3. set to 5001 -> ~50% output, no flickering ...

StefanBruens avatar Dec 11 '16 16:12 StefanBruens

yes! - your's describe is correct i just make slow soft-on and slow soft-off led lamp via table for equal change bright speed in both low and high ends... and when it from full bright (100% = 10000) go to the (0% = 0) at the 50% all time flicker have appear... and from 0 to 10000 also the same

gorec2005 avatar Dec 11 '16 16:12 gorec2005

i think it's because at the 50% pwm you just invert signal... but this inverse have destroy smoth regulation... :-(

gorec2005 avatar Dec 11 '16 17:12 gorec2005

What do you mean by flicker? A single flash? Or constant flickering? Are you using the compat mode? If yes, then lower your PWM period to ~2500, 100 Hz is flickering anyway.

StefanBruens avatar Dec 11 '16 17:12 StefanBruens

sorry - single flash only no - i did not use compat mode: #ifndef SDK_PWM_PERIOD_COMPAT_MODE #define SDK_PWM_PERIOD_COMPAT_MODE 0 #endif #ifndef PWM_MAX_CHANNELS #define PWM_MAX_CHANNELS 4 #endif #define PWM_DEBUG 0 #define PWM_USE_NMI 0

gorec2005 avatar Dec 12 '16 04:12 gorec2005

Hi, I have the problem with a single flash when passing the 50% also. I have 5 PWM channels and use NMI mode. Period ist set to 20000 (should be 250Hz). Each time a channel pass the 50% it generate a single flash. Channels which do not pass the 50% mark at the same time do not flash.

Example with 2 channels: Ch1 9500 / CH2 9991 -> smooth Output of both channels Ch1 9700 / CH2 9993 -> smooth Output of both channels Ch1 9900 / CH2 9995 -> smooth Output of both channels Ch1 10200 / CH2 9997 -> Ch1 have a single flash Ch1 10500 / CH2 9999 -> smooth Output of both channels Ch1 10500 / CH2 10001 -> Ch2 have a single flash Ch1 10700 / CH2 10003 -> smooth Output of both channels Ch1 9950 / CH2 9950 -> CH1 and Ch2 have a single flash (passed both the 50% at same time) Ch1 9940 / CH2 9940 -> smooth Output of both channels

Kind regards, Uwe.

UweHeinritz avatar Mar 27 '17 20:03 UweHeinritz

Do you use a selfbuilt board or something from the shelf? Can you please provide schematics/part numbers of the MOSFETs/board photos?

I can not reproduce it, and am suspecting a hardware specific issue.

StefanBruens avatar Mar 28 '17 17:03 StefanBruens

Hello Stefan, I do not think that this is a hardware issue. Because I also have random flickering when cossfade all channels, I tried 2 things to exclude issues create from my remaining source code (use 3 timers and do some calculation/display stuff). First I disabled pwm_start and let all functions in my source active. There were no flickering -> I have no CPU limitation issue Then I enabled pwm_start, but disabled changes to duty cycles (use fix values for test). There were also no flickering -> The calculation in pwm_start + my functions does also have no CPU limitation issue So the flickering must be generated by the pwm phases calculated in pwm_start. I looked in your source code and also did a simple test with enabled pwm_debug. I found out that the source code force flickering in 2 conditions. Condition 1 - pass the 50% duty cycle value: I let pwm_start calculate the pwm phases for following 2 duty sets (period of 20000). Set 1: 6000/6000/9995/6000/6000, Set 2: 6000/6000/10005/6000/6000 The calculated phases are (duration / on mask / off mask): Set 1: 5999 / 0,1,2,3,4 / - 3994 / - / 0,1,3,4 10004 / - / 2 Set 2: 5999 / 0,1,3,4 / 2 3994 / - / 0,1,3,4 10004 / 2 / -

Both sets are OK and create exact the duty cycles which are defined. But if we have a look at channel 2 when switching pwm sets (finish cylce after pwm_start) we see this (duration/output state): Last set 9995 on 10005 off Switch set 9995 off 10005 on Restart set 9995 off 10005 on.... When switching to the new set, the output of channel 2 is a complete period (nearly 20000 ticks) off. This will create a single flicker. When switching direction (from high to low) this will create a 20000 ticks on signal which is seen as a single flash.

Condition 2 - 2 channels have nearly the same duty cycle which is > 16: I let pwm_start calculate the pwm phases for following 2 duty sets (period of 20000). Set 1: 6000/6000/6500/6480/6000, Set 2: 6000/6000/6500/6485/6000 The calculated phases are (duration / on mask / off mask): Set 1: 5999 / 0,1,2,3,4 / - 479 / - / 0,1,4 19 / - / 3 13499 / - / 2 Set 2: 484 / - / 0,1,4 13499 / - / 2,3 14 / 2 / - 5999 / 0,1,3,4 / -

Both sets are OK and create exact the duty cycles which are defined. But if we have a look at channels 0,1,4 when switching pwm sets we see this: Last set 5999 on 13997 off Switch set 13998 off 5999 on Restart set 13998 off 5999 on When switching to the new set, the outputs of these 3 channels (where we did not change the duty cylce) are longer then a complete period (nearly 28000 ticks) off. This will create a single flicker on these 3 channels. With duty cycles in the upper half we get a single flash.

Following changes are necessary to get rid of these flickering/flashes:

  • do not mirror phases for duty cycles above 50%
  • do not shift left phases (this will also mirror the phase) which have a duty cycle diff < 16
  • do not perform a cyclic shift if last phase is < 16 ticks
  • better handling for short last phases (do delay noop, and use no timer for restart PWM cycle)

Positive effects:

  • no flickering/flashes when cross the 50%
  • no flickering/flash when 2 channels have nearly the same duty cycle
  • no jump in light when fade from duty cycle 15 to duty cycle 16 (currently we invert phases for duty cycle < 16)
  • all on phases start at same time

Unfortunately this will have negative side effects:

  • more "action" in second half of duty cylces. amount of switch operations (phases) should be the same, but now they are spread over the full duty cycle. Because we have no problem with many short timer cycles in first half, we should also have no problem with some more in second half
  • more difficult handling of short last phases

I wonder why you could not reproduce these problems when they are clearly visible in debug outputs and also on the LEDs (also in source code).

Kind regards, Uwe.

UweHeinritz avatar Mar 29 '17 06:03 UweHeinritz

Hi Uwe,

I am completely aware of the calculations, and also the fact that the phase mirroring extends the pulse length when crossing the 50% setting.

At a PWM frequency of 250Hz, the pulse scheme is changed from 2ms low/2ms high/2ms low/2ms high to 2ms low/4ms high/2ms low. From a human vision standpoint, double the luminous flux does not equal double the perceived brightness. There is a tradeoff between the the length of a flash and its intensity to be noticeable.

If you can notice a brightness increase, either the pulse is longer than 4ms, or the brightness increase is more than intended.

Depending on the MOSFET and the driver strength, you may not be switching the MOSFET fully on with a 2ms pulse, but do with a 4ms pulse, increasing the power from e.g. 20% to 100%, instead of the expected 50% to 100%.

None of you proposed changes is applyable in general:

  1. the maximum interrupt rate is limited to about 4us
  2. due to the interrupt rate limiting, fine adjustments have to be done with a busy loop
  3. if you have a busy loop, you have to reserve some time for the busy loop.

The term "inversion" is also not good to describe the effects, you better used "phase shifting". The maximum phase shifting happening for any duty cycle below 50% is 3us, less than 1% of the cycle of a 250Hz PWM, which is completely irrelevant. When crossing 50% duty, there is a one-time phase shift by 2ms between consecutive pulses which might be relevant.

Feel free to come up with a pulse scheme under the following constraints:

  • works for a arbitrary number of channels (at least 5)
  • is adjustable with full resolution (at least 400ns, better 200ns)
  • guaranteed to never require an interrupt cycle below 4us

StefanBruens avatar Mar 29 '17 16:03 StefanBruens

Hi, you say that the maximum Phase shifting für duty cycles below 50% is 3us. But in my example of the second condition I get a 28000tick = 1,4 PWM cycle = 5,6ms pause between 2 pulses (250Hz, 20000 ticks period). The human eye recognize the differences in phases when invert/shift phases (in my examples this generate a 2-4ms longer pause at this time) as short brightness changes. I could not see that the LEDs are full off or full on at this time, but I recognize a slight flicker.

I use IRLML2502 MOSFET which is a very fast switching Ultra low On-Resistance MOSFET. I added a 180Ohm resistor in the signal line to limit the gate current. This Setup should work well.

I removed the 50% Phase switching, the "shift left to align right edge" and the cyclic shift if last phase is short. Then I added the check for restart PWM cycle to the while cycle (only executed if current PWM phase is shorter then 16 ticks). With this modifications a get a smooth Fading between 0 and 100% and also when randomly cross fade all 5 channels (which produced flickering when diff between duty cycles are < 16). The PWM is not affected by my main application (include httpd, oled Display, color calculation).

The execution time of the pwm_intr_handler is only longer (if Statement with 2 expressions) if we have a PWM phase which is shorter than 16 ticks.

Kind regards, Uwe Heinritz.

UweHeinritz avatar Mar 29 '17 18:03 UweHeinritz

Now set your 5 channels to 12, 24, 36, 48, 60 ticks duty, and measure the duty of the fifth channel, it will be well beyond 60 ticks ...

StefanBruens avatar Mar 29 '17 23:03 StefanBruens

As there are no new posts and the problem still exists, @UweHeinritz I would like to try your changes in my project, maybe it'd solve the flickering. Can you fork this repo and publish your changes? That would be awesome.

steveh80 avatar Jan 20 '20 18:01 steveh80

Hello Stephan, I uploaded my source to https://github.com/UweHeinritz/ESP8266_new_pwm

UweHeinritz avatar Jan 21 '20 17:01 UweHeinritz

Thanks Uwe, it works and looks good at first glance. 🥇

steveh80 avatar Jan 21 '20 19:01 steveh80