Monday, May 4, 2015

P3 - WIFI Mains Power Dimmer / Switch with CBDBv2


New released MPDMv4 (MAINS Power Dimmer) Driver Board !


WARNING!! You will play with LIVE MAINS!! Deadly zone!! 

If you don't have any experience and are not qualified for working with MAINS power I will not ecourage you to play arround!


   For any new requests please feel free to use as usual: tech at
     If you want to order MAINS POwer Dimmer/Switch bare PCBs only, you can also do it directly at Dirty PCBs, our preferred PCB House:


    For that ones of you that have already read my articles related with MAINS Power Switching
 you remember that the above modules were ON/OFF switching only.

    Now it's about time to talk also about what many of you has asked for: DIMMING!
   It's a total different story, liitle bit complicated but, as you will see, not so hard to understand.

General considerations

    There are several types of dimmers generally available. These are used for resistive, and inductive loads, such as incandescent,cold cathode and low voltage (inductive) lamp sources. Note that not all electronic transformers used for low voltage lamps are suitable for dimming by Triac or Thyristors dimmers. In case of Thyristors you need 2 of them as Thyristor is a Unidirectional device and because AC power flows in both directions! 
   Why using Thyristors? One of the reasons is that they are available in higher power ratings than Triacs and are more robust. A 4-500 A to 1kA ratings is something common for Thyristors. 
Usually you will find this kind of Thyristors in Industrial applications, not exacty a hobbist part.  
 Just look, for example,  at the specifications of ABB 5STP27H2801  and you will understand why :)

  I don't remember a highly available Triac rated more than 40A. BTA40-700B is a good example.

  For resistive loads ON-OFF only jobs (no dimming required) a winning combination is between  MOC304X for  Triac driver (Zero voltage crossing one) and a good quality Triac, decently sized at the power needs. 

   In case of dimming you DON'T want to use a zero crossing voltage one! And this is because of the way the dimming process is going and depending on our own ZCD (zero cross detection) function. In our case zero cross detection is done by the biphase optocoupler as in the schematic below

Zero Cross Detection output example

    Mains power is comprised of an alternating current that flows in one direction and then in the other, along the cable, at the rate of 50 or 60 cycles per second.

   The number of cycles in one second is called the frequency.  The frequency is given in a unit called hertz (symbol Hz) where 1 Hz = 1 cycle per second . 

   The value 50 or 60Hz is dependent on the countries power system. The current alternates back and forth changing direction at the zero point.

    If we will to look at the waveform (yellow) with the Osciloscope it would appear as a sinusoidal shape. Drawing a line through the middle and this is what is called the zero crossing point. At this instant in time no current is flowing in either direction.

MAINS 50Hz and ZCD waveforms

   The Triac is electronically synchronized with the help of the ZCD to turn the power ON or OFF. By chopping the waveform at the zero-crossing point, smooth dimming can be achieved without the lamp flickering. This turning on and off of the power device occurs every time the mains crossing point is reached (half phase), 100 or 120 times per second (50 or 60Hz).

Firing Triac at 50%

   ZCD determines the point in time (Firing delay time) at which they turn ON (conduct). The ON state continues until the next zero-crossing point, at which point the Triac turns itself OFF. The command circuit then provides a delay, which equates to the dimness of the lamp, before turning the control device back on. The slight capacitance of the load, filters the chopped waveform resulting in a smooth light output.

NOTE: If you notice that the 50Hz AC Voltage repesented up (yellow) is not around 240VAC and is nor pure sinusoide as should be, it's a simple explanation: I didn't want to put Osciloscope directly on MAINS. For very simple reasons. But this is not affecting at all the general view of the process.

What we will need:
  • CBDB Board or any other ESP/Arduino /MSP/ARM/Whaterver Board you may like
  • USB adapter (take a look on Part 1 for details about the USB Adapter)
  • Main Power Dimmer/Switch module (MPDMv3 - details below)

Main Power Dimmer/Switch module (MPDMv3)

     This time the MAINS Dimmer switch module was designed as a standalone unit, not including the ESP8266 anymore, as people were asking for a more general usage one that can be used with existing Setup/Environments. 

    Because the MPSMv2 was designed more as a DevBoard for MAINS switching application and the FUSE and MAINS input / output /filtering unit was keept separatelly  has created some confusion and a lot of talks about, Hackaday thread included :).

    So, this time, you have on the same board, fuse and connectors to directly connect de MPDMv3 module to MAINS, Lightbulb/Lamp and your MCU Board. 

MPDMv3 - Schematic

MPDMv3 - MAINS Dimmer/Switch Module

   Both signals, phase detect (PHS) for ZCD and Triac command (CMD) are fully optocoupled and you have a proper galvanic separation between the low side and the MAINS side voltage, but,  as a general practice DO NOT TOUCH any part of the circuit as long as MAINS power it's applied!! The scope of LED1 is just to help you in the testing phase process, it does not have any other sense on dimming.

Proper clearance and creepage distance were also taken in consideration when PCB was designed:

MPDMv3 - PCB - Bottom side

MPDMv3 Software

For programming CBDBv2 Board and uploading the driver and the software we will continue to use the LuaUploader as before. 

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

2. Zero Cross Detector function

   As you have seen above on the Osciloscope, zero crossing is the moment when the sinusoide goes through zero. After each zero crossing there is one full half of the sinuswave available to send through the Triac to the Load.

   So what the software needs to do is to detect the zerocrossing, and then wait for a set amount of time on that sinuswave to switch on the TRIAC.

We have a 50Hz VAC that means is 50 waves per second.
Each sinuswave thus takes 1000ms/50=20ms
They are 2 sinus peaks in a wave.  That means that after every zero crossing detection there is a 10ms period that we can regulate.
If we switch Triac directly at the beginning of that period, the load will receive full power
If we do it at the end of that 10ms period the load will receive none and if we do it halfway, the load will receive half power.

Now, how can we obtain the desired number of dimming steps?

If you look at the above explanation you know already the answer: we will divide the 10ms to the number of the steps we want and that's it. The obtained value can be tweaked a bit, depending on how is really looking your AC MAINS and how clean it is, filtering, delays, etc, but that's the dimming steps value you need to start with.

Let's assume we have:
Dimming steps = 128
Waveform Time= 10 ms
Step = 10000/128 = 78

Total dim time then is calculated as desired dimming steps * step value.

Also what we need to take in consideration after we fire the Triac is the Triac ON Propagation time (the time Triac needs to become fully ON).

      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

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

4. Main code

       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

For testing, just save the code on ESP as 'dimmer.lua', restart ESP and run:   
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

Save the code on ESP as 'init.lua', restart ESP. It should reboot and restart automatically the program.

Testing Zero Cross Detector

First test - Dimming a Lamp


As requested, please find below MPDMv3 BOM:

No Part Value Package Description
1 R1 470 R1206 RESISTOR, European symbol
2 R2 360/1W 0204/7 RESISTOR, European symbol
3 R3 470/1W 0204/7 RESISTOR, European symbol
4 R4 470 R1206 RESISTOR, European symbol
5 R5 39/1W 0207/5V RESISTOR, European symbol
6 R6 47k/1W 0207/10 RESISTOR, European symbol
7 R7 47k/1W 0207/10 RESISTOR, European symbol
8 R8 10k R1206 RESISTOR, European symbol
9 C1 0.01uF/400 X2 C075-032X103 CAPACITOR, European symbol
10 C2 0.05uF/400V C075-032X103 CAPACITOR, European symbol
11 IC1 MOC3021 DIL06B 6-Pin DIP Optoisolators Triac Driver Output
12 IC2 SFH620A DIL04 Optocoupler, Phototransistor Output, AC Input
13 T1 BT137 TO220BV TRIAC
15 PWR_IN DG3XX-02-5.0 DG306-5.0-02P DG350-3.5-02P
16 SW_OUT DG3XX-02-5.0 DG306-5.0-02P DG350-3.5-02P
17 FUSE 5A SHK20Q Fuse
18 U$3 1X4 1X4 2mm Header or 2mm socket

That's all for today, next time we will talk about WEB Interface implementation for our MAINS Power Dimmer / Switch Module!



Kristian Schneider said...

hi. great effort.

could you perhaps list the components for the MPDMv3 as it can be a bit hard to deduct from the schematic alone?

Chris Dobson said...

Hi ordered my pcbs for MPDMv3, but while I am waiting for them to come, I am wanting to experiment, to see how well JCC6 dimmable LED down lights will work with these. And also see if it is possible to control several modules with one ESP-12. Could you please post a parts list so I can build a "lethal version" on breadboard to carry out my experiments. When I play around with ac stuff like this, I always try where possible to use an isolation transformer, at least this stops you getting accross live and earth, and also drop it down to about 100 volts or less if possable, that way when you accidently touch the wrong part , it dosn't smart quite as much!

Tracker J said...

Hello Chris, Kristian,
Separate BOM list posted.

It's no problem to drive more than one module with ESP-12. You need to have a good power supply. Only one ZDC input should be used. I have connected 4 on CBDBv2 Evolution Board, no problems to report. And 32 thru a I2C port expander, but that's another story :)

Chris, I really hope you know what are you doing and will be not so lethal as advertised by you :) (I know it was a joke. I hope. lol)

Enjoy & waiting for feedback from you guys!

Chris Dobson said...

Yes just a joke, I am 48 yrs old and started playing around with the mains when I was 3 or 4 years old. I was brought up in a world where I was taught that " electricity can kill you". Unlike today where they teach " electricity WILL kill you!"

Chris Dobson said...

Uploaded Dim server but getting this error
Dim_server.lua:66: unfinished string near ''<LINK href=" '
i am pretty new to lua and web server stuff, but have tried pasting this into google address bar and i get an error 404, i have also tried commenting it out, but this then creates more errors, as i expected. can you help ??

Chris Dobson said...

Fixed above issue. when i copied and pasted code from here to notepad new lines(with tabs)got added to the longer lines in the script!

Tracker J said...

Chris, code is tested and is OK, must be from the Blog HTML formating somehow. Cut and paste from the web might be tricky sometime. I use Notepad++ for cleaning code from the web.

Chris Dobson said...

Hi have sort of got it going. when using google chrome it dosn't recognise the web page, just displays the html text from send page function. i pad displays the slider bar, but will only move 1 pt at a time every couple of seconds, but does dim. IE displays part of web page(button from slider is missing). i have gone through code several times, but can't find any typo's, although i am very tired. can i send my code to you (didn't want to post it here as it is quite long) to see if you can see my mistake? also i have other things using port80 could this cause issues?. i also hangs and does hard restart from time to time.
Thanks Chris.

titi said...

Wow, Your blog is very interesting. Thanks to share your work.

Few month a go I made a dimmer like this on arduino. It works well even if I had a little flicker sometimes (I did not have an oscillo to check timings at this time). I used moc3021, triac, and powered arduino with china ac dc transformer (like in phone charger 85-240V to DC5v). Next I tried to do same things but with only one main (for in wall switch, at home I have only one phase for switching lights). But it didn't work. Maybe due to my flicker problem I don't know I didn't have too much time to investigate, but I had one flash light at starting then arduino reboot, and then again...Do you have an idea why? I thought it was related to flicker problem and 85vac mini transfo, and the resistance of cold incandescent bulb drop voltage. but not sure. Did you try to power on one main your circuit?? I was trying to do something like Fibaro fgd211. Also incredibly small. And don't know how they do to make it so small. What is your board sizing ? Today I ordered lnk306 to see if it was transformer related...

If you have any idea I am very interested. Anyway now I will follow this blog too.
Have a good day and sorry for my poor english!

Tracker J said...

Thank you for your appreciations. One good thing to do first is to add a proper MAINS EMI filter (if you didn't yet). Regarding direct MAINS PSU, it's duable, but you cannot use the clasic resitor/capacitor thing. ESP8266 needs a solid 100-150mA to run properly with WIFI full power. I was using a tiny switchmode PSU. Still experimenting in that direction for the new MPDMv4 :). LNK306 it's one of the possible solutions, didn't have the chance yet to test.

If you want to power the module from only one wire, inside wall...that is a total different story. One way to do it is to "steal" power bypassing Bulb...and probably use a less power hungry thing than ESP8266. Might worth a separate article this one...

titi said...

Thank you for your advice. I agree with you it needs to steal power, and it might be a wonderful article!!! lol.

In same way like stealing power, I did not mention that I tried another circuit. Still with arduino+china transformer (not the best idea maybe), but this time I tried with mosfet+pwm (thinking i did a bad zdc). But not very good too. This time it started right, but dimming was on a little range. I don't remember exactly but when pwm goes up to 200 (of 255pitch 8bits pwm) it rebooted. I think it was arduino reset brownout due to transformer. On these there is a little ic which reset transfo when voltage drop too much. I used arduino mini+nrf24 on Rxmode only, so it was not consuming too much power. I will try again soon with triac. But note sure if I will success. Like you said it's a different story.
See you soon.

krant said...

Can you please post the place where you sourced the 2 capacitors?
I am in europe, but i can not find the 0.05uf v400 cap anywhere.
Will 0.047 also work?

Tracker J said...

you can use 0.047 or even 0.033 ones. Just be sure they are the neede type for that snubber circuit. Reading BT/MOC datasheets might help you to refine both snubber caps for your own needs.

QuasaR said...
This comment has been removed by the author.
QuasaR said...

@krant, I also live in Europe (NL) and can't find those capacitors either. Can you let me know where you got them. I also have trouble finding the SFH620A (also which type do I need, SFH620A-1, SFH620A-2 or SFH620A-3) ?
@Tracker J, the BOM lists a 360/1W resistor but that is not a normal value right ? (I can't seem to find it), if I look at the assembled board, you used the 470/1W resistor, is this correct ?

Tracker J said...

You can use there a 430/460/470 ohm resistor.
I was using SFH620A-2x because it was the one available but cannot see any reason to not work with 1x or 3x.
For capacitors, use Metallized Polyester or Polypropylene film ones with a proper voltage rating. If they are X2, even better. An example found at a quick search:

QuasaR said...

@Tracker J, thanx, for the answers. For the caps, are these 2 good enough then ?

C1 (0.01uF/400 X2) :
C2 (0.05uF/400V) :

Tracker J said...

QuasaR, they should do the job OK. Snubber circuit should be fine tuned based on your load, resistive/capacitive and obtain the right mix together with your input EMI Filter. Take a look also in the Triac / MOC Datasheet.

Project PCB's are still available here if interested in build one:

Also the CBDBv2 Evo Dev Board:

Kabluk said...

Hi Tracker!

He use the same scheme as you but PC814/FOD814 optocouper instead of SFH620A

Our ESP resets periodically and the lamb flashes...

Can this problem exist due to wrong optocouper or we should fing a problem in another part of scheme?

Tracker J said...

As PC814/FOD814 are AC optocouplers should work. As long as you have a proper ZCD signal back to ESP Board should work OK. Be careful with CTR Ratio and signal level out.

Yura Pylypyuck said...

Hi Tracker,
My scheme is exactly the same as yours, except, I'm using EL814 optocoupler.
It is really strange, but I'm getting 200 ZCD per second (frequency = 50Hz) and could not find, where the problem lies.
Do you, maybe, have some suggestions, where should I look for that problem?

Tracker J said...

for f=50Hz is should be exactly 100Hz as in a AC optocupler you have 2 LED connected inverse parallel, 2x50Hz = 100. For testing, just remove everything, connect the ZCD detector pnly to AC line and measure directly the output of the optocupler. The wave format should look as the first picture above. I suppose that the AC ZCD Opto is connected properly to the MAINS live line, between a PHASE and a NEUTRAL wire.

User said...

Is this similar:

Tracker J said...

No, that Ebay ones are MAINS Switches only, No dimming, like the one from the MPSM : and here : As they ude a Zero Crossing Triac not suitable for dimming, even if you add your own one. The above one has the ZCD.

Unknown said...

Hi Tracker,

Thanks for the project, it look amazing I’ve built a DC dimmer but needed an AC one, I’ll try yours.
By the way, to directly power it directly from AC I’ve successfully used this tiny switching power supply HLK-PM01.
You can source them from here:

Also you can find a tear down on this URL:

Tracker J said...

Thank you. yes, I know that PSU, used already in some projects. For more intensive applications I still prefer yet the ones built by MeanWell. More expensive but quality must have a price.

Nolan Ebertsohn said...

Are these MPDMv3 available in kit form?

Tracker J said...

Hi Nolan,
Yes. For more details please send your enquiries to tech at

Ahmed Adel said...


Thanks a lot for the great blog. I need your help please in understanding some concepts regarding choosing the passive components.

Can you please guide me, what values do I need to get from the datasheet to select R2, R3, R5, C1 and C2 ? I need to understand how you did the math as I am keen to design a "safe" circuit.
Thanks a lot

Roque Strongo said...
This comment has been removed by the author.
Roque Strongo said...

Thanks for sharing your design, I stumbeled accross your project as i am also planing to deploy some esp8266 for switching ligths around the house. Till now my layout used some relay (Songle srd-03vdc-sl-c) with 3V coil voltage switched over a transistor to protect the esp GPIOs and a Hilink HLK-PM03 print mount power supply that directly provides 3.3V and can power the ESP and relay directly. So till now my setup only needs a few components and no seperate DC/DC converter. As i would like to try your dimmer design, i would like to ask you if your dimmer will work with my 3V setup or if its possible to adjust the ciruit for 3V supply voltage. Greetz Roque

Roque Strongo said...
This comment has been removed by the author.
Tracker J said...

It will work without any problems with 3.3V

debi prasad Mandhata said...

can you provide dimmer code using sdk for esp8266..

Aaron Nobel said...

It is very informative post.

Paul Hasy said...

I like this article and all information on this blog this information is very helpful specially the pictures which are very neat and clear and easy to understand but the most important and attractive thing in this post is your videos which describe each and every thing very clearly. Thanks for sharing this helpful knowledge.

v1ck said...

What is the correct R6 and R7 value then ? is it 33K or 47K ?

Tracker J said...

Hi v1ck,
You can use 47k, will work OK.

v1ck said...

Thanks Tracker
I can assume that 68K ( that what i got at the moment ) will not work ? i dont have access to the osciloscope to see peaks..

Tracker J said...

Hi v1ck,
Where are you located? Are we talking about EU 245VAC/50Hz MAINS or US 120VAC/60Hz one? It's a bit to high even in case of EU MAINS but give tit a try. Eventually you can put 2x68K in parallel.

v1ck said...

Its UE 230VA/50hz

Tracker J said...

Then try 2x68k in parallel. also please be sure that teh resistor used have the proper voltage rating.

v1ck said...

will try, thanks i have 2w resistors so it should be fine.

by the way - did you ever tried to use timers on ESP for interrupts ?
it seems that arduino library does not work for ESP.. :(

Tracker J said...

yes, and yes.
this might help you -

v1ck said...

looks good, thanks ;)

v1ck said...

is there any restriction for interrupt pins ? im using ESP GPIO5 (10k pullup), but it doesnt seem to work. I have used 34k ( 2x68k in parallel ) but with no success..

I have already tested dimming using arduino and buil-in timers function which worked very well for 33k 5v PullUP on zerocross detector and 68K resistors on mains but cant get ESP to work :(

Tracker J said...

On the ESP8266 nEXT EVO Board that I am using for my experiments the GPIO 4 and 5 are used for the nEXT Extension BUS (I2C) so I am using GPIO 12 and 13 for it.

v1ck said...

well, i have checked and with 10k pullup resistor i was not getting anny interruptions ( i have put counter on intterupt function and printed in main loop ) when i replaced pullup resistor with 33k it started to count, but still the light bulb is off.

Tracker J said...

Your phase detection is on GPIO5 or 12? A Osciloscope or a even a simple LA might help you to to see exactly what's the signal level and quality there...are you using LUA, Arduino IDE or something else for your coding?

v1ck said...

im using GPIO5 on ESP - with 33k pullup i can see its working but not as expected - no dimming. i have no access to any osciloscop..

Im using arduino IDE. Can you try below code and take a look what value you get?

#define SECONDS 2.0

int count = 0;

void setup()
Serial.println("Zero Cross Test");

attachInterrupt(5, cross, RISING);

void loop()
delay(SECONDS * 1000);

float hz = count / SECONDS / 2;
count = 0;


void cross() {

v1ck said...

im getting values from 20Hz to 50Hz with 33k Pullup and 47k on mains.

Tracker J said...

I don't have any Arduino around these days but that huge fluctuation from 20 to 50Hz is showing clearly that something is not right. Probably it's missing pulses.

Unknown said...

I am planning to use this circuit for a 12 VAC halogen lamp (a couple of them, about 60 Watt in total). Do you have any suggestions for the needed resistor values?

Post a Comment