This is how I'm fading some LEDs using a logarithmic function. But with that the LEDs are flickering somehow. I don't understand why...

import time
import math
import RPi.GPIO as GPIO


# set up GPIO pin for output
GPIOPin = 22
# initialize PWM variable
# set number of fading steps
steps = 50

# start LED fading
    while 1:
        for step in reversed(range(1, steps + 1)):
            RPWM.ChangeDutyCycle((1 - math.log(step, steps)) * 100)
        for step in range(1, steps + 1):
            RPWM.ChangeDutyCycle((1 - math.log(step, steps)) * 100)
except KeyboardInterrupt:

In this code the LEDs are faded in and out in a infinite loop. But how could I prevent the LEDs from flickering?


The RPi.GPIO Python module uses software timing for PWM. Occasionally the software will be delayed leaving the LED on or off for longer than expected. This will be seen as flickering.

You could port the code to my pigpio Python module which times the PWM with hardware and should not suffer from visible flicker.

  • how would leaving the LED on for longer than expected be seen as flickering? Oct 3 '18 at 3:19
  • please review how PWM works to set brightness levels
    – jsotola
    Oct 3 '18 at 4:46
  • Say you want half brightness, you set PWM at 50% duty cycle and switch 100 times a second so the eye sees half on, half off, The brain is fooled and sees half brightness. That means on for 0.005 seconds, off for 0.005 seconds. If it is on or off for 0.02 seconds instead the eye will see a spike of full on or full off, the time is too long for the brain to be fooled. That is flicker. Try it and see.
    – joan
    Oct 3 '18 at 5:09

I came here because I had the same issue. @joan's answer and package fixes the issue but @joans answer doesn't give some specifics on how to get it working (without looking at the page and/or documentation).

On my installation (Rasbian buster), pigpio comes pre-installed, you just have to enable it:

systemctl enable pigpio
systemctl start pigpio

Here is a minimal example that works on BCM pin 18 (slightly modified from @joan's answer on another forum):

import time, sys
import pigpio
pi = pigpio.pi() # connect to local Pi
start_time = time.time()
while (time.time()-start_time) < 60: 
  for p in range(0, 255):
    pi.set_PWM_dutycycle(18, p)
  for p in range(255,0,-1):
    pi.set_PWM_dutycycle(18, p)

Thanks @joan for creating an awesome library!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.