WARNING: Some people try to build this with an optocoupler with zerocrossing coz 'that is better' right? Some are even told in electronics shops it is better to use such an optocoupler. WRONG. This will only work with a random fire optocoupler: NOT igniting at zerocrossing is the principle of this dimmer.

Switching an AC load with an Arduino is rather simpel: either a mechanical relay or a solid state relay with an optically isolated Triac. (I say Arduino, but if you use an 8051 or PIC16F877A microcontroller, there is stuff for you too here.)

It becomes a bit more tricky if one wants to dim a mains AC lamp with an arduino: just limiting the current through e.g. a transistor is not really possible due to the large power the transistor then will need to dissipate, resulting in much heat and it is also not efficient from an energy use point of view.

Phase cutting
One way of doing it is through phase control with a Triac: the Triac then is fully opened, but only during a part of the sinus AC wave. This is called leading edge cutting.
One could let an Arduino just open the Triac for a number of microseconds, but that has the problem that it is unpredictable during what part of the sinus wave the triac opens and therefore the dimming level is unpredictable. One needs a reference point in the sinus wave.
For that a zero crossing detector is necessary. This is a circuit that tells the Arduino (or another micro controller) when the sinus-wave goes through zero and therefore gives a defined point on that sinus wave.
Opening the Triac after a number of microseconds delay starting from the zero crossing therefore gives a predictable level of dimming.

Pulse Skip Modulation
Another way of doing this is by Pulse Skip Modulation. With PSM, one or more full cycles (sinuswaves) are transferred to the load and then one or more cycles are not. Though effective, it is not a good way to dim lights as there is a chance for flickering. Though it might be tempting, in PSM one should always allow a full sinuswave to be passed to the load, not a half sinus as in that case the load will be fed factually from DC which is not a good thing for most AC loads. The difference between leading edge cutting and PSM is mainly in the software: in both cases one will need a circuit that detects the zero crossing and that can control a triac.

A circuit that can do this is easy to build: The zero crossing is directly derived from the rectified mains AC lines – via an optocoupler of course- and gives a signal every time the wave goes through zero. Because the sine wave first goes through double phased rectification, the zero-crossing signal is given regardless whether the sinus wave goes up through zero or down through zero. This signal then can be used to trigger an interrupt in the Arduino.

It goes without saying that there needs to be a galvanic separation between the Arduino side of things and anything connected to the mains. For those who do not understand 'galvanic separation' it means 'no metal connections' thus ---> opto-couplers. BUT, if you do not understand 'galvanic separation', maybe you should not build this.

The circuit pictured here does just that. The mains 220Volt voltage is led through two 30k resistors to a bridge rectifier that gives a double phased rectified signal to a 4N25 opto-coupler. The LED in this opto-coupler thus goes low with a frequency of 100Hz and the signal on the collector is going high with a frequency of 100Hz, in line with the sinusoid wave on the mains net. The signal of the 4N25 is fed to an interrupt pin in the Arduino (or other microprocessor). The interrupt routine feeds a signal of a specific length to one of the I/O pins. The I/O pin signal goes back to our circuit and opens the LED and a MOC3021, that triggers the Opto-Thyristor briefly. The LED in series with the MOC3021 indicates if there is any current going through the MOC3021. Mind you though that in dimming operation that light will not be very visible because it is very short lasting. Should you chose to use the triac switch for continuous use, the LED will light up clearly.

Mind you that only regular incandescent lamps are truly suitable for dimming. It will work with a halogen lamp as well, but it will shorten the life span of the halogen lamp. It will not work with any cfl lamps, unless they are specifically stated to be suited for a dimmer. The same goes for LED lamps

If you are interested in an AC dimmer such as this but you do not want to try building it yourself, there is a somewhat similar dimmer available at, however, that is a 110 Volt 60Hz version (but adaptable for 220 50Hz), that has been out of stock for a while. You will also find a schedule here.

NOTE! It is possible that depending on the LED that is used, the steering signal just does not cut it and you may end up with a lamp that just flickers rather than being smoothly regulated. Replacing the LED with a wire bridge will cure that. The LED is not really necessary. increase the 220 ohm resistor to 470 then

STOP: This circuit is attached to a 110-220 Voltage. Do not build this if you are not confident about what you are doing. Unplug it before coming even close to the PCB. The cooling plate of the Triac is attached to the mains. Do not touch it while in operation. Put it in a proper enclosure/container.

WAIT: Let me just add a stronger warning here: This circuit is safe if it is built and implemented only by people who know what they are doing. If you have no clue or if you are doubting about what you do, chances are you are going to be DEAD!

4N25 €0.25 or H11AA1 or IL250, IL251, IL252, LTV814 (see text in the next step)
Resistor 10k €0.10
bridge rectifier 400 Volt €0.30
2x 30 k resistor 1/2 Watt (resistors will probably dissipate 400mW max each €0.30
1 connector €0.20
5.1 Volt zenerdiode (optional)

Lamp driver
LED (Note: you can replace the LED with a wire bridge as the LED may sometimes cause the lamp to flicker rather than to regulate smoothly)
MOC3021 If you chose another type, make sure it has NO zero-crossing detection, I can't stress this enough DO NOT use e.g. a MOC3042
Resistor 220 Ohm €0.10 (I actually used a 330 Ohm and that worked fine)
Resistor 470 Ohm-1k (I ended up using a 560 Ohm and that worked well)
TRIAC TIC206 €1.20 or BR136 €0.50
1 connector €0.20

Piece of PCB 6x3cm
electric wiring

That is about €3 in parts

Remove these adsRemove these ads by Signing Up
1-40 of 441Next »

Hi DiY_Bloke, I made both the circuits according to your given diagrams. zero-crossing works fine and the dimmer input generated by arduino is totally fine. when i fire triac without any delay the bulb is on. But when we fire triac after 1 ms delay the bulb doesnt get on and the output voltage is dropped to zero and all the voltage appears accross triac. So we are only able to fire triac without delay. But when delay of 1 ms or greater is introduced the circuit doesnt work.
Kindly help us!!
we are using BT136 and Moc3021.
the pulse width to triac for latch is set to 600us.
If u say we can also show you output waveforms.
thank you

diy_bloke (author)  Arslan Waheed20 hours ago

there is something very wrong with instructables as i replied almost immediately and now i cant see my reply. Anyway, it is a very odd problem you describe.
It kinda makes me nervous that you talk about two circuits that you built, coz it is in reality only one circuit, but i presume you mean the zerocrossing section and the trigger section.
the strange thing is that you should be able to ignite yr triac at practically every moment in the cycle, so also at 1mS after the zero cross.
Which software are u using? Have you tried my program that cycles through a number of levels??

What i like you to try is to disrefard tge zerocrossing for a while and just make the input on the optocoupler high and low a few times randomly, to make sure the triac does ignite at random moments.
Please let me know how that goes and make sure you also try the first program i provided

Harry0211 days ago

Hi DiY_Bloke

I have made it work, it is really great I had found this I had made few mod on to the PCB, I add a fuse and separated the two AC input/Output to the PCB sides (so I had to print my PCB using two sides)

I have tested the SW and it also works! :) tested the inmojo sample and also works (I'm based on the UK) but I'm trying to send the dimming value via serial, and I cant make it work, (the Sample III here, did not work either) , do you have any advise as I need to send the dimming value via serial

Thank you

diy_bloke (author)  Harry0211 days ago

Well let me start by saying I am happy you made it :-)
It seems to be one of my most popular designs :-)
I always appreciate hearing about builds and if you like, post a picture with the 'I made it' option :-)
Anyway as your module works, your problem must be in the software. In principe you need to send a number to the Serial port that is then read and used as 'dim value'
You say you used Sample III but I presume you mean Sample II. Anyway, now I look at it more diligently (it isnt my code), I wonder how that could work as the 'light' procedure, that checks the serial port, isnt called anywhere.
You need to call that from your 'loop' or even use it as the 'loop'.
Let me know if that works

yes, I had tested it too, I had added the light() onto the loop, and it just keep flickering and no actual dimming occurs

I'm a bit confused, as I had tested the same without the loop, as this works as the interruption will call the serial and the light() function is executed, but again I try to add a value via serial and its not taken

int AC_pin = 3;//Pin to OptoTriac

int dim = 0; //Initial brightness level from 0 to 255, change as you like!

void setup() {


pinMode(AC_pin, OUTPUT);

attachInterrupt(0, light, FALLING);//When arduino Pin 2 is FALLING from HIGH to LOW, run light procedure!


void light() {

if (Serial.available()) {

dim =;

if (dim < 1) {

//Turn TRIAC completely OFF if dim is 0

digitalWrite(AC_pin, LOW);

Serial.println ("im low");


if (dim > 254) { //Turn TRIAC completely ON if dim is 255

digitalWrite(AC_pin, HIGH);

Serial.println ("im High");



if (dim > 2 && dim < 254) {

//Dimming part, if dim is not 0 and not 255


digitalWrite(AC_pin, HIGH);


digitalWrite(AC_pin, LOW);

Serial.write (dim);




void loop() {


ebjorno17 days ago
Are you able to sell me one for £10?
diy_bloke (author)  ebjorno11 days ago

I haven't really considered that till now, but I have no idea how much it would cost to send it to UK.. Also.. how much in a hurry are you?

I'm going to use it to control some lights for a film production. Can you find a price that you're happy with and email me at I'm not in a hurry, but would appreciate if you could send it within a week or so. Thanks!

Little bit confusing on the PCB printed what was up and what down or which pin is actually connected. But with that solver nice work

diy_bloke (author)  ralf.vandenburg1 month ago

I am glad u like it ralf.
With regard to the pin connections: in Step 1 there is a picture with clear indication what is what:

but maybe it is easy to overlook that one. I am happy though u figured it out.enjoy

oh i forgot to mention that i also liked the detail explaination of the matter you gave well done.

i've encountered a really weird issue only i used the components you descibed and after a few hours of operations time it seems the TRIAC (TIC206 4A ) is leaking current. I've used the diagnostics you're suggested. Also the fritzing file uses a 1Kohm resistor while in the picture 3 (right bellow) on step 1 suggests a 560 Ohms resistor.

(I've build this part 3 times and it happend all 3 times, so I suppose i got something wrong here)

diy_bloke (author)  ralf.vandenburg27 days ago

Hmm With regard to the resistor, I explained that in the text (BOM) one can use a 470Ohm-1k and I ended up using a 560 Ohm.
With regard to your other problem: why you think it is leaking current? Because it will not shut off?
Did you build it on a PCB or on a breadboard?
using for incandescent lamps or other devices?
Did you put any snubbers on it?
I have build it several times and actually never had any problems with it. I have had fresh from the shop faulty Triacs or Thyristors before, but that is really an incident and if it happened with all 3 circuits you built that would be unlikely.
Anyway, let me know and maybe we can find out what the problem is.

I've build it upon a test PCB, used the lamp on the photo attached. The board has the Zero cross detector in the center and the white pieces are the MOC3021. I think the TRIAC is leaking because the octocoupler is still functioning when i put a +5V the lamp is fully on but when off the lamp burns dimmed. Also i've had the demo program working the lamp goes slowly off only after a few hours it wouldn't go off it remains dimmed on.



Hope you could give any suggestions

diy_bloke (author)  ralf.vandenburg26 days ago

interesting. I see you use a halogen lamp. In itself that shldnt be a problem.
For now two suggestions:
Make sure yr Arduino is not attached so there is really no input on the optocoupler. Is the lamp then completely OFF or still glowing?
Briefly try with a regulat incandescent bulb
What exactly is te value of the gate resistor you used? it looks like a 470 Ohm
Als je het makkelijker vind om Nederlands te schrijven is dat ook goed

Dat is idd wel makkelijker, De arduino heb ik er idd helemaal af gehaald - Lamp blijft gloeien. Als ik er nu een 1 op zet zie je dat de lamp vol aangaat en bij een nul blijft ie gloeien. eerst had ik idd 470 ohm gebruikt maar bij de twee volgende schakelingen heb ik er twee van 470 gebruikt in serie. Ik ga is opzoek naar een gloeilamp 's kijken of ik nog ergens zo'n ding heb.

diy_bloke (author)  ralf.vandenburg26 days ago

Wat gebeurd er als je de MOC3021 even verwijderd? TRIAC krijgt dan geen gatestroom meer. dat zou moten uitwijzen of het lekken is of toch nog een kleine Gatestroom

diy_bloke (author)  diy_bloke26 days ago

Als je een halogeen lamp gebruikt is die waarschijnlijk zon 35 wat max?. 'Leakage' wil ook nog wele eens optreden bij aan lage load omdat dan de off state leakage groot genoeg is om de load aan te houden. probeer eens met een 60-100 wat gloei;amp

diy_bloke (author)  ralf.vandenburg27 days ago

oh, and thanks for your compliment. I wasn't quite an expert on the matter when i started this so I just shared what I learned.

Hello my its not working yet..I found the problem..The problem is the triac, current is not passing throught the triac...I am using the BT136... I will try replace the triac with another one...What do you suggest?

with 'no current passing through the triac´ you mean from M1 to M2.
That can have various reasons:
-Triac broken
-wrong connection
-Triac not opened by gate
-Nothing gets any current

So I suggest in case you havent done so:
Check all connections
Check if there is a voltage over the triac
Check the voltage on the gate with and without a signal on the Iotocoupler.

If that is all ok, take out the optocoupler and insert a 220 Ohm resistor between the gate resistor and the gate (so a resistor in place of the secunday site of the optocoupler)
If that makes the Triac ignite (i.e. the lamp goes on) the problem is in your optocoupler or primary circuit.

Did you try the tests I suggested earlier?

Ok I umderstand...the mystery is that when i connected the lamp straight without the triac in the circuit lamp gies on(flickering). Plus the circuit I made it with a very experience person who is working in the research departnent of the University of Cyprus. He told ne tha probably the problem is the triac...

Well I can only say that if there is NO triac, that mans that yr lamp should only be connected to the grid at ONE side so it should not be able to pass any current.
Look at the circuit and then think away the TRIAC there. There then is just NO connection. A lamp that is connected to the grid only at one side cannot burn.
Have a look at the circuit I attach. Blue line would normally go to the lamp through the triac, but if there is no triac, it cannot go to the lamp. Ergo, there must be a mistake in your circuit.
I am not mitigating yr friend who helped u build the circuit, but even experienced people make mistakes. How can it be your triac if there is a problem when you TAKE OUT the triac.

If you take out the triac and your lamp then is ON, that means that it is somehow connected outside of that TRIAC, which it shouldnt be.
Look at it this way: yr TRIAC is a switch. How can yr lamp suddenly go ON if you remove the entire switch.

Sure you can put in another TRIAC but that is not going to solve your problem.
Your best bet is to again realy check all the connections, or just to rebuild your circuit and then test every step, as I just outlined before

I am also confused...i upload a picture before with the circuit ...I cant see any problem to the connections

well from personal experience I know one can be repeatedly blind for ones own mistakes.
Can I suggest the following:
-Start new or take a new breadboard:
-stick in a TRIAC
-Attach the lamp
-connect the gate resistor from the terminal, to the gate
-plug it in
-Lamp should go ON
If that doesnt work, check yr connections and if necessary try a new TRIAC
-Then insert the optocoupler
-connect your gate resistor via the optocoupler
- plug it all in: Lamp should be OFF
- attach 5 Volt via a 560 k resistor to the optocopler
-plug it back in the mains: Lamp should be ON
- remove the 5 Volt from the optocoupler and attach your arduino.
-Let the arduino make the attached pin high and low with say a 1 sec delay: lamp should go on and off
If that all works, you know your output circuit works well
-Then build up yr zerocrossing circuit
If that doesnt work, the problem is in that circuit

I made the tests you mentioned before...Also when I remove the triac the lamp goes on(flickering instead of dimming which is normal). I also use another triac,the same one (BT136) and again the lamp not firing. I will but another type of triac in order to see if it is the model of triac I used the problem... I don't know what alse to do...all seems to work fine instead triac that is not firing...

I am kinda confused. WITH the TRIAC inserted the lamp is OFF, but WITHOUT the TRIAC present the lamp goes ON?? When the TRIAC isnt inserted there shouldnt be any closed circuit to the lamp and it should be off as one side shldnt be in touch with the grid.
Aside from that.
You say you did the tests but what was the outcome?

I am posting a better picture of the circuit. The arduino is not connected .. If you could see a problem please mention to be.. Thanks indeed
15 - 17:43.jpg

looks OK at first sight, please do the tests as i described and let me know the results.
You can also add the following to your setup and see what the lamp does:

void setup()
pinMode(AC_LOAD, OUTPUT); // Set the AC Load as output
for (int i=0; i < 10; i++) {
digitalWrite(AC_LOAD, HIGH); // triac firing
digitalWrite(AC_LOAD, LOW); // triac Off

Ok thanks a lot

working now?

This is the circuit
15 - 12:12.jpg

it is quite a collection of wires and not easy to follow... but as far as I can see your optocoupler, th eone that needs to trigger the TRiac, doesnt get the required input. See that brown wire? that seems to be only connected at one side... as far as I can see

diy_bloke (author)  diy_bloke1 month ago

though it could be it is connected to the LED, difficult to see

Ok thanks a lot ...the problem seams to be the load it safe to measure the voltsge over the "220" vlamps..?

Well if you make sure not to touch anything with yr bare hands, it is safe, The reason I ask you to do this is to make sure that the board is getting 220 Voltage.
But if you think he problem is the load part, please just recheck the connections.
Even if you think it is OK, recheck again. I do not know how many times I was sure I connected something right, only to find several wiring mistakes when I really checked.

I made the circuit. But I have a problem. The LED dim OK but the lamp is always switched off. No flickering no dimming. Can anybody help me with this ?

Well that is odd, but here is what I like you to do:
-check and double check all your connections.
-make sure the lamp you are using works
-measure the voltage over the clamps that say "220V" in the circuit. Is that 220 V?
-remove your Arduino and put 5Volt on the entrance of your circuit.
-- both the LED and the Lamp should be full on. If the lamp is NOT on please check the voltage over the 1k resistor, remove the 5V voltage and check the voltage over the 1k resistor again and let me know if that is different.

I cannot stress enough to be careful when measuring when this circuit is connected to the mains voltage BE CAREFULL. This voltage can kill you.

Yes of course I have connected it to the main...I am in cyprus its 220/240 V ,50 hz

well then the answer to your earlier question should be clear: you apply 5Volt to the entrance of the circuit, the optocoupler opens, the Triac gets triggered, the lamp gets current and burns.

diy_bloke (author)  diy_bloke1 month ago

anyway, please go through the steps as i described and let me know what the result is

1-40 of 441Next »