Instructables

Arduino controlled light 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. (if you use an 8051 or PIC16F877A microcontroller, there is stuf 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.

The proper way to do it is through phase control with a Triac: the Triac then is fully opened, but only during a part of the sinus AC wave.
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 for a number of microseconds delay starting from the zero crossing therefore gives a predictable level of dimming.

Such a circuit is easy to build: The zero crossing is directly derived from the rectified mains AC lines – via an optocoupler ofcourse- 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.

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 www.inmojo.com, 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 flickrs 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!


Materials
Zerocrossing
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)
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

Other
Piece of PCB 6x3cm
electric wiring

That is about €3  in parts
 
Remove these adsRemove these ads by Signing Up
Scipione7 days ago

Hello,

I'm a filmmaker (in high school I realized the impossible with PICs xD but now I'm a bit rusty with electronics xD ), and for an indie movie I need to control up to six lights using the PC (with Arduino). For an unrgent scene, wich we will shoot in 2 weeks maximum, we need at least to control 2 lights (1KW each...).

Since my future use will be 6 channels, with up to 2.5KW for each channel, I would like to improve this design for high load and modular upgradeability.

For a load up to 2.5 KW (I will use 2 KW maximum, but I want to overbuild for safety), I need to change the optocoupler and TRIAC (and also to oversize the copper traces). What to use?

Carlo

diy_bloke (author)  Scipione7 days ago

For a load of 2.5kW you need 11.4 amps. so that is what yr Triac needs to be able to endure, so BT138-600 with a BT139-600 you would have 16 amperes while it si only a dime more expensive.
Obviously you need some serious cooling on that TRIAC.
No need for a different optocoupler.
You may want to lower the 1k resistor to a 330 ohm resistor and add a gate resistor as well, according to this circuit (only look at the triac circuit, no need for the MOC3041)
If you really want to handle 12 amps. I am not sure what oversized traces you would need, but what I do in cases like that is to either solder a copper core thick enough onto the coppertrace really directly from the component to the connector itself.
Since you will need some adequate cooling of the TRIAC, I can imagine you will mount them directly on a cooling plate and use 12 amp capable wire to connect the terminal leads to Load and Mains and use regular wire to connect to the trigger and zerocrossing.
For 12 amps you would need I guess 2.5 mm diameter wire which is AWG 11

diy_bloke (author)  diy_bloke7 days ago

sorry, part of a sentence got lost:

so a BT138-600 would give you 12 Amperes, but with a BT139-600 you would have 16 amperes while it is only a dime more expensive.

Thank you. For the copper traces there are calculations to do. I don't rememer the formula, however recently I found this useful tool:

http://www.desmith.net/NMdS/Electronics/TraceWidth...

Today after work I will check datasheet and A.N.'s of T138-600 and T139-600.

Then I will do a post aout that with reference to your work and advices on:

http://indiemotionpictures.blogspot.it/

and when the project is finished I will also do an instructales and release every file; everything will e CC-BY-NC . I don't know what kind of license did you choosed for your project, please tell me if that is ok for you.

Thanks!

diy_bloke (author)  Scipione6 days ago

Tnx Scipione. I know the calculations tool but then i always have to figure out how thick the copper is. I rather just solder a piece of wire on top of it. Saves space as well.

reference to my work is always appreciated. I am ok with yr licence. I dont feel i have been doing any trailblazing work on this circuit, other than making a workable project/ibble of it.

Good luck with yr movie

hello Bloke,

tnx again. Today I will go to the electronics spare shop and I hope to find the T139-600; then I will build one zero-crossing circuit and two dimmers. Then I will play. xD I will figure out how to handle the heat on the triacs however, I will choose the appropriate heatsink

diy_bloke (author)  Scipione6 days ago

It is a BT 139. not a T139

yes yes I know, however today I was too late to go to the shop :(

msyazwan37 days ago

Hi

Can I control the intensity of light & then let it flash
Would you guide me or give me some suggestions on how to do it..

thank you

diy_bloke (author)  msyazwan37 days ago

yes of course. You can just set the desired intensity with the variable 'dimmer' and then change it between that intensity and 128 (which is 'off')

john2357 days ago

Thanks for your help

I really2 appreciate it. If i could meet you in person

i would glad to treat you a lunch

my project already went well
thanks again :D

diy_bloke (author)  john2357 days ago

Thanks John, so I presume the connection to the MOC was the problem :-)
I appreciate the offer, but I am sure you are at the other end of the globe somewhere, so I will take a rain check on that one.
Take care

john2359 days ago

I just found out that if i connect the feet 1 & 2 of the triac

the lamp will start to turn on

but it doesn't flash like it suppose to

what do you think about this?
tq

diy_bloke (author)  john2359 days ago

well that is why I advised to put a resistor between pin 4 and 6 of the IC foot.
and of course it doesn’t flash because you give a continuous trigger signal by connecting the gate with one of the terminal leads.
Anyway, it shows your TRIAC is probably functioning OK. So the suspicion falls on your MOC3021.
Please do the following:
double check the connections to that MOC3021. Are you sure you had inserted it the right way around?
If you are convinced the connections are OK, insert a new MOC3021 because yours is most likely broken.
Please check the resistor that gives the MOC its input from the arduino. hard to see which one you used but since you left out the LED I would suggest a 470-560 ohm resistor.
After you replace the MOC (make sure it goes in the right way)
apply a 5 Volt input voltage again (via the resistor) and see what happens

"well that is why I advised to put a resistor between pin 4 and 6 of the IC foot.

and of course it doesn’t flash because you give a continuous trigger signal by connecting the gate with one of the terminal leads."

which IC, both the 4n25 and 3021?
btw, while testing this, i should not connect it with arduino right?

diy_bloke (author)  john2359 days ago

only the MOC. we were only testing the TRIAC function for now. But you no longer need to do it i guess as you connected pin 1 and 2 which is the gate and a terminal. Tht is what I wanted you to test albeit through a resistor.
Anyway, go fortht as I said in my previous message as most likely your MOC is faulty. check all the connections and make sure you inserted the moc the right way

I already did as you suggest

& the lamp is on..so, what do you think?

btw, the optocoupler i'm using is this one

10245432_10202560697353176_7586304768954098155_n.jpg

I also test the optocoupler, if i applied 5v between foot 1 & 3
there exist voltage between them.

How to check whether my optocoupler is still good or damage?

diy_bloke (author)  john2358 days ago

the optocoupler isnt really tested by measuring the voltage on pin 1 and 3. that only makes sure that it is receiving a voltage.
What you need to do to test the optocoupler is to measure if the AC voltage over the secundary site of the optocoupler drops when you apply a 5 Volt signal to the circuit. For this you need to hook up yr meter to pin 4 & 6 and plug in your circuit. then apply 5 volt to the entrance and see if the voltage drops.

Now you mentioned something else that found intriguing. You said you measured a voltage over pin 1 and 3 .

Hmm that gives me an uneasy feeling as the MOC3021 needs a voltage over pin 1 and 2 NOT 1 and 3.
I suggest you check first if you have your MOC3021 connected correctly

moc3021.jpeg
diy_bloke (author)  john2358 days ago

John, I know the lamp is on, that is why i tell you the triac is most likely fine and you need to replace your MOC3021. Is that what you mean by 'I already did as you suggested'?
that sounds a bit odd coz the lamp cant be on just by putting in a new MOC as you also need a trigger signnal for that.
So, can you confirm that you replaced the MOC? are you sure it is the right way around?
The picture doesnt tell me much because I cannot see from the outside if it is working.

But just to reiterate:
there can be 3 things wrong in your circuit:

1-the wiring.. but you checked that several times
2- the triac, but when you connect the gate to 1 of the terminals, yr lamp goes on, so yr triac is probably OK

3. leaves the MOC3021, so i sugegst you replace that, OR, measure the voltage over it on the secundary site when you send a trigger signal

john2359 days ago

My circuit totally fail

The lamp in not even on

Can you please tell me what are may be the cause that it did not work

I did some of your suggestion on step 10

unattached the circuit from arduino

I already test with multimeter that
there are no connection between the arduino part & main 230V part...

when 230V is apply, there exist voltage on the 230V part

but the lamp is still not on

diy_bloke (author)  john2359 days ago

Always a bad feeling when you build something and it just doesnt do anything. However, there are only a few components in the circuit so it shouldnt be too hard to find out. So let's go about this systematically.
First we will check the function of the TRIAC circuit. Please do the following:

1) disconnect from the mains and put the Arduino away, you wont need that for now
2) Check your circuit. Is really everything connected as it should be?
3) take your 5 Volt PSU and connect it to the Ground and to the Plus to the connection 'Dimmer signal in'
4) measure if there is a voltage over Pin 1 and 2 of your MOC3021
5) leave the 5Volt applied and connect your circuit to the mains.
6) check if your lamp is burning and let me know
If it isnt and you are sure the connections are correct and your lamp is ok Then the problem must be with your optocoupler or with the triac.
Let me know and then i can help you further

Yup..i already test step 4

there exist 5v on pin 1 & pin 2

lamp is still not on after i connected it with main

btw,
tq for your response. really appreciate that

i also test for continuity & it seems like there is short circuit

between the lamp output
is it suppose to be that way?

1514624_10202554798525709_8093668262450601085_n.jpg
diy_bloke (author)  john2359 days ago

well no it is not supposed to be that way. if the lamp is shortcircuited ofcourse it will never go on.
Please check if you really wired it right and if there are no shortcircuits between the copper traces on your board.
If it was short circuited, there is a fair chance you destroyed your triac as well.
No thanks necessary, it sucks when something doesnt work and if i can help I gladly do so

I tried unconnect the lamp from the board

& check the continuity again at the board, this time no shortcircuit

then i checked the continuity directly with the lamp & there exist shortcircuit

but if i connect the lamp directly to supply the lamp is on

it's really confusing.

p/s: sorry for asking lots of questions

diy_bloke (author)  john2359 days ago

well are you sure it is a shortcut? lamps have in general a low resistance. a 220 Volt 100 wat lamp is about 490 Ohm.

Well if u are sure the connections are all ok do the following: remove the optocoupler and stick a 470 Ohm (or something close) in the pins 4 and 6 of your circuit. dont add any 5 Volt, just the resistor and plug it into the mains

john23510 days ago

Hi

Can you explain more about the coding please

You said that you used pin 2

but in the coding, you declare pin 3
" In the program pin 2 is chosen

*/

int AC_LOAD = 3; // Output to Opto Triac pin "

..

i'm using arduino uno

can you help me regarding this connection with the software(coding) from arduino to the board. like from pin 2 arduino to num 3 on the board..here i attach the circuit that i build it

1513182_10202550862227304_3206919043635761337_n.jpg
diy_bloke (author)  john23510 days ago

Hi John
there are 2 connections with the arduino: the zerocrossing signal (an input to the arduino) and the Triac triggering signal (an outout from the arduino)
the zerocrossing is fed to pin 2 (i.e. interrupt 0) and the triggering for the Triac is taken from D3

Perhaps this picture can help you a bit:

http://www.pighixxx.com/pgdev/Temp/Arduino_uno_Pin...

As I am not sure what exactly the numbers in your photo are I presume the following
1=Vcc
2=zerocrossing
3-Triactriggering
4=0Volt

so what you do is to connect '1' to any 5Volt pin on yr arduino. You connect '2' (the zerocrossing) with interrupt 0 which is Pin 2 on your Arduino. You connect '3' to 'Pin 3' on your arduino and you connect '4' to any Ground pin.

when i say 'Pin 2' and 'Pin 3' I mean the pins that are literally called pin 2 and 3. They are next to the Rx (pin 0) and the Tx (Pin 1). Logically they are referred to as D2 and D3.
I hope the schematic below will clarify any doubts left

dimmer-ard-connection.jpg

hy i have build this whole setup problem is when i use simple increasing or decreasing loop of dimming in program it works fine but when i set a fix value of dimming level it do not work well, it just starts flickring. i want to control the dimming level with two input buttons please help me.

diy_bloke (author)  deependra.kushwah9512 days ago

hi deependra, sorry to hear that. Can you send me the code you are using?

int AC_LOAD = 4; // Output to Opto Triac pin

int dimming = 128; // Dimming level (0-128) 0 = ON, 128 = OFF

void setup()

{

pinMode(AC_LOAD, OUTPUT); // Set the AC Load as output

attachInterrupt(0, zero_crosss_int, RISING); // Choose the zero cross interrupt # from the table above

}

void zero_crosss_int() // function to be fired at the zero crossing to dim the light

{

// Firing angle calculation :: 50Hz-> 10ms (1/2 Cycle)

// (10000us - 10us) / 128 = 75 (Approx)

int dimtime = (75*dimming);

delayMicroseconds(dimtime); // Off cycle

digitalWrite(AC_LOAD, HIGH); // triac firing

delayMicroseconds(10); // triac On propogation delay

digitalWrite(AC_LOAD, LOW); // triac Off

}

void loop()

{

dimming = 75;

}

diy_bloke (author)  deependra.kushwah9512 days ago

I am a bit surprised that it should flickr. What I would like you to try is to add a slight delay after the 'dimming=75;'

e.g.

{
dimming = 75;
delay(200);

}

and see how that works

It shldnt make much difference theoretically, but one never knows.
I will try a fixed setting myself as well this weekend.

Also. how is your PSU? Sometimes a PSU is a bit 'dirty', leading to extra triggering of your interrupt routine

Once we get this sorted out I will help you with the buttons if you wish

ok i will check this too and post result. and about the power supply i am using sony mobile adopter which provide 5.1v output but if you have doubt on that i will change that too, and then post the result. thanks for the help

diy_bloke (author)  deependra.kushwah9512 days ago

well th esony mobile adaptor is there to charge batteries. That means that the output doesnt really need to be a 'clean' DC and maybe the output smoothing capacitor is a bit small, leaving some peaks that maybe sometimes could trigger the interrupt. Nevertheless, the delay seemed to work for you

yes you were right. i tried 9v battery with 7805 + a 10uf filter capacitor it also worked without providing any delay. but may please check this code for me even if i am using battery its again started flick-ring. please tell me where i am doing wrong.

int dimmer_up = 0;

int dimmer_down = 1;

int AC_LOAD = 4; // Output to Opto Triac pin

int dimming = 128; // Dimming level (0-128) 0 = ON, 128 = OFF

void setup()

{

pinMode(AC_LOAD, OUTPUT);

pinMode(dimmer_up, INPUT);

pinMode(dimmer_down, INPUT); // Set the AC Load as output

attachInterrupt(0, zero_crosss_int, RISING); // Choose the zero cross interrupt # from the table above

}

void zero_crosss_int() // function to be fired at the zero crossing to dim the light

{

// Firing angle calculation :: 50Hz-> 10ms (1/2 Cycle)

// (10000us - 10us) / 128 = 75 (Approx)

int dimtime = (75*dimming);

delayMicroseconds(dimtime); // Off cycle

digitalWrite(AC_LOAD, HIGH); // triac firing

delayMicroseconds(10); // triac On propogation delay

digitalWrite(AC_LOAD, LOW); // triac Off

}

void loop()

{

if(digitalRead(dimmer_up) == HIGH)

{

if(dimming==128)

{

dimming=100;

delay(300);

}

else if(dimming==100)

{

dimming=75;

delay(300);

}

else if(dimming==75)

{

dimming=50;

delay(300);

}

else if(dimming==50)

{

dimming=25;

delay(300);

}

else if(dimming==25)

{

dimming=0;

delay(300);

}

else

{

dimming=0;

delay(300);

}

}

if(digitalRead(dimmer_down) == HIGH)

{

if(dimming==128)

{

dimming=128;

delay(300);

}

else if(dimming==100)

{ dimming=128;

delay(300);

}

else if(dimming==75)

{ dimming=100;

delay(300);

}

else if(dimming==50)

{ dimming=75;

delay(300);

}

else if(dimming==25)

{ dimming=50;

delay(300);

}

else if(dimming==0)

{ dimming=25;

delay(300);

}

}

}

diy_bloke (author)  deependra.kushwah9512 days ago

deependra. your code is rather complicated coz of all the if statements.
could you just for testing purposes use this code:

void loop()
{
if(digitalRead(dimmer_up)==HIGH
{
dimming=dimming-10;
delay(300);
}
if(digitalRead(dimmer_down) == HIGH)
{
dimming=dimming+10;
delay(300);
}
}
I know it is not perfect as it doesnt protect against <0 or >128 but it is just to test the concept.
As 'dimming' starts out as 128, you may want to try the UP button first.

Also, you do not have to use the 'dimming' variable. I only introduced that to have 128 steps to set the light level, but it is actually the product of 'dimming' x 75 that sets the dimtime. You could of course set 'dimtime' directly

i even tried this code its working. but i don't know my circuit has very unstable behavior. when i tried above code it do no flicker but even without touching the input dimming level increases automatically and after crossing 128 it starts flickring. i checked all the possible false inputs which could be triggering microcontroller input but there in no such thing. i designed this whole on a single PCB and my design is very clear i don't understand whats going wrong. i even replaced power supply with a high quality 5 v 1amp adopter. do you have any idea where i am going wrong.

diy_bloke (author)  deependra.kushwah9510 days ago

Well as I said, my code was just for testing and you should not go above 128 because then you get in the new cycle already so then yes it starts to flicker.
As your circuit was working with my original code, the one that was in te article, your circuit is OK
It is just the your software that seemed problematic.
As there was a lot of If statements in your code, I had you replace it with a simpeler code that however does not prevent you from going over 128 or even into negative numbers. It is just to prove concept.
Can you confirm that the up and down code is working as long as you stay between 0 and 128?

Pro

Get More Out of Instructables

Already have an Account?

close

PDF Downloads
As a Pro member, you will gain access to download any Instructable in the PDF format. You also have the ability to customize your PDF download.

Upgrade to Pro today!