AC mains dimmer

Active today
Viewed 21 times

I’m trying to dim a 7W LED with a Raspberry Pi Zero for home automation. However it doesn’t work as expected. I followed this tutorial : https://www.youtube.com/watch?v=wqY4-gHqvZI . I have the exact same connections between my raspberry and my led and I also have the same dimmer. I tried their test code that is supposed to dim the light bulb using the Pigpio hardware_pwm() function (documentation : http://abyz.me.uk/rpi/pigpio/python.html#hardware_PWM).

The Python script used to the test is :

import pigpio


pi = pigpio.pi()

if pi.connected:
    print("Connected to pigpio daemon !\n")

dm = 0
while dm < 860:
    dm = input("Enter Dimmer Value: ")
    dm = int(dm)
    pi.hardware_PWM(GPIO, 5000, dm*1000) # 5000Hz dm*1000% dutycycle

print("\nOut of range. Exiting...")
pi.hardware_PWM(GPIO, 5000, 860000) # 5000Hz 95% dutycycle

For my case, the led is acting strangely. With a 5000Hz frequency, changing the duty cycle from 0% to 70% doesn’t change it’s luminosity, 70% to 86% reduce the luminosity, 86% to 95% increase it and 95% to 100% reduce it again. But the led is always turned On, even if the duty cycle is at 100% the led emits a little light.

Here a graph to better illustrate the situation. Graph illustrating the luminosity of a led depending on the duty cycle

The Python code used is from the youtube tutorial, do someone understand why the max duty cycle used is 86% ?

Why is the dimming not linear ?

And why the led cannot be totally turned Off using a 100% duty cycle ?

  • the video uses an incandescent lamp … try using the same …. also, a 5 kHz refresh rate is not necessary – jsotola 6 hours ago
  • @Milow, Ah, let me see. I woke up this gloomy Sunday morning and found your question sun shining. First thing first, let me introduce myself. I am a smart home learning guy, but never heard of what you are talking about, a Rpi PWM controlled AC mains dimmer. So I am losing face and my bad friends are LOL at me. To save my face, I am going see what is going on and if I can make an answer. To start with, I watched the YT and found it good, but sadly this 2 year old tutorial has collected only 25 thumbs up, … 😦 – tlfong01 5 hours ago    
  • @Milow, “Why dimming nbot linear?” Well, perhaps the stupid human eyes are like the ears, highly non linear, actually exponentially evolved to have become logarithmic! 🙂 – tlfong01 4 hours ago    
  • @Milow, “Why max DC 86%, not 100%?” This has something to do with the characteristics of the AC main voltage which is much complicated than DC. (1) AC voltage is sinusoidally nonlinear, and change polarity every cycle (50Hz or 60Hz). And a traic (sort of bidirectional current switch) is used to cut power. A triac has two current switches, one each to switch on current at a particular point in time of the positive or negative phase. It is rather tricky to detect the cross over point (zero detection) and then use a “stop watch” to cut current according to the stupid human’s wishes, … – tlfong01 3 hours ago   
  • @Milow, I am getting off topic and diverting too far into electronics engineering discipline, which makes a lot of trade off’s to finally decide that it is cost effective and stupid human eyes pleasant (no flickering etc) to decide the max dc to be 86% (just an example). Anyway, I will now go back to the stupid human’s buggy brain’s creation – the buggy python program. Stay tuned to my answer! 🙂 – tlfong01 3 hours ago   
  • @Milow, Can you please give me a link to your code, with reference to the following: (1) PWM Frequency = 5kHz, (2) Max duty cycle = 86%. Question: is your mains power 50Hz or 60Hz? Are you sure the timing calculation in your code matches your mains frequency? Perhaps the Zero Cross function can take care of the mains power frequencies related timing. But I have not looked into the details. – tlfong01 2 hours ago   



I am using Rpi GPIO 18 PWM control to dim a 7W AC LED lamp.

dimmer dip

(A) Why there is a weird dip at duty cycle 85%?

(B) Why dimming not linear?

(C) Why use PWM frequency 5kHz?

(D) Why limit duty cycle to 86%?

(E) Why LED not completely switch off at duty cycle 0%

/ to continue, …


(1) Short Answers

(A) There is no reason for a dip. Your program might be buggy. Try my bug free programs (Refs 5, 6).

(B) Dimming not linear because your eyes are logarithmic, which is non linear.

(C) There is no reason to use PWM frequency. AC mains frequency is 50/60Hz. So a “sampling” frequency 10 times of that should be flickering free. Try 1 kHz and try and error a pleasant frequency for your eyes only.

(D) There is no reason for a 86% duty cycle limit. Try and error higher. Nothing will explode.

(E) Perhaps there is sort of a “dead band” at AC mains voltage cross over. As soon as zero cross is detected, it take a little bit of time to tell the triac to cut off off current (just guessing, not very sure).

(2) Setup Mains AC Current Dimmer for Testing and Calibration

I would suggest to test and calibrate the dimmer in two steps:

(A) Use a type A (logarithmic) potentiometer.

(B) Use a python program to setup Rpi GPIO in PWM mode to control the dimmer.


Actually you can by hand use a jumper wire to connect Vcnt terminal to 3V3, Ground to see if dimmer is completely on and off. You can also use a cheaper square wave generator such as NE555 to control the dimmer. Using a digital pot is better than GPIO PWM because digital pot memorizes its setting.

setup 1

/ to continue, …


(1) MPDM V4.1 Documentation

(2) Universal AC MAINS Dimmer MPDMv4.1 Catalog- US$17

(3) Universal AC MAINS Dimmer MPDMv4.1 Operation

(4) MPDM Triac Operation

(5) Rpi PWM GPIO pin #18 python program Example 1- tlfong01

(6) Rpi PWM GPIO pin #18 python program Example 2 – tlfong01

/ to continue, …


Appendix A – WARNING!! You will play with LIVE MAINS!! Deadly zone!! – NetEvo

WARNING !!! If you don’t have any experience and are not qualified for working with MAINS power I will not encourage you to play around!.

The author takes no responsibility for any injury or death resulting, directly or indirectly, from your inability to appreciate the hazards of household mains voltages.

The circuit diagrams are as accurately as possible, but are offered with no guarantees whatsoever.

There is no guarantee that this design meets any Rules which may be in force in your country so please check before your local rules/regulations.

Appendix B – MPDM v4.1 Universal AC Current Dimmer

mdpm v4

Appendix C – Zero detection and triac switching schematics

triac schematics

Appendix D – MPDM Traic Operation Explained – NetEvo

Triac operation

*Appendix E – Dimmer Testing Program (Version 3 ESP8266 LUA Version)*





-- *** Define used GPIO pin ***

outpin=7                                          -- Select Triac Command pin - GPIO13 


gpio.write(outpin,gpio.LOW)                       -- Triac OFF

inpin=6                                           -- Zero crossing detector input - GPIO12  

gpio.mode(inpin, gpio.INT, gpio.PULLUP)           -- attach interrupt to ZCD

-- *** Zero Cross ***

function zero_cross()
  dt = 76*dim
  --print("Zero cross detected!") 
  stat = "ON" 
  tmr.delay(dt)                    -- Firing delay time calculated above 
  gpio.write(outpin,gpio.HIGH)     -- Triac ON - Zero cross detected
  tmr.delay(100)                   -- Triac ON - Propagation time  
  gpio.write(outpin,gpio.LOW)      -- Triac OFF - let's be sure it's OFF before next cycle 
  return stat

-- *** Fading function for testing mode ***

function fading()
  if(dim_up==1) then dim=dim+1 
     else dim=dim-1

   if(dim < 10) then dim_up=1 dim=10
      else if (dim > 120 ) then dim_up=0 dim=120

    print("Dimmer level : " .. dim)
    print("Fading mode  : " .. dim_up)

-- *** Main ***

dim = 120                                         -- Dimmer level - smaller value is brighter

dim_up=0                                          -- Fading direction - for test  run

gpio.trig(inpin, "up", zero_cross)                  -- ZCD interrupt attached - trigger on falling edge

tmr.alarm(0, 100, 1, function() fading() end)     -- timer for testing mode

-- *** Setup/Testing Notes ***

-- For testing, just save the code on ESP as ‘dimmer.lua‘, restart ESP and run:   

--  dofile("dimmer.lua")  -- Start the Dimmer Testing  mode

-- If you want the MPDMv3 software to start automatically when your CBDB module starts or reboots, then you neet to create and add some lines in your ‘init.lua‘ file:

--   dofile("dimmer.lua")  -- Start the Dimmer Testing mode

End of Answer

Categories: Uncategorized

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: