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

flicker at 50% :-( #9

Open
gorec2005 opened this issue Dec 10, 2016 · 19 comments
Open

flicker at 50% :-( #9

gorec2005 opened this issue Dec 10, 2016 · 19 comments

Comments

@gorec2005
Copy link

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

@kaeferfreund
Copy link

same here

@StefanBruens
Copy link
Owner

  • 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?

@gorec2005
Copy link
Author

gorec2005 commented Dec 11, 2016

  • 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 :-(

@StefanBruens
Copy link
Owner

Can you please clarify the second answer?

@gorec2005
Copy link
Author

gorec2005 commented Dec 11, 2016

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...

@StefanBruens
Copy link
Owner

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
    ...

@gorec2005
Copy link
Author

gorec2005 commented Dec 11, 2016

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
Copy link
Author

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

@StefanBruens
Copy link
Owner

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.

@gorec2005
Copy link
Author

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

@UweHeinritz
Copy link

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.

@StefanBruens
Copy link
Owner

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.

@UweHeinritz
Copy link

UweHeinritz commented Mar 29, 2017

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.

@StefanBruens
Copy link
Owner

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

@UweHeinritz
Copy link

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.

@StefanBruens
Copy link
Owner

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 ...

@steveh80
Copy link

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.

@UweHeinritz
Copy link

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

@steveh80
Copy link

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants