Step 5: Arduino Controlled Lightdimmer: The Software II

I found another piece of Software that allows controlling the lamp via the serial port.It triggers on the falling edge of the zero-crossing signal, so the timing is a bit different.

I have not tested it myself yet, but I see reasons why it should not work: as far as i can see it doesnt receive the number typed in the serial port but it receives the ascii value of each digit that is typed, so a '0' will be seen as 48

int AC_pin = 3;//Pin to OptoTriac
byte 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 = Serial.read();
    if (dim < 1) {
      //Turn TRIAC completely OFF if dim is 0
      digitalWrite(AC_pin, LOW);

    if (dim > 254) { //Turn TRIAC completely ON if dim is 255
      digitalWrite(AC_pin, HIGH);

  if (dim > 0 && dim < 255) {
    //Dimming part, if dim is not 0 and not 255
    digitalWrite(AC_pin, HIGH);
    digitalWrite(AC_pin, LOW);
void loop() {

Just a note: The above software is not mine. I think it is better to keep the check of the serial port out of the interrupt. Also the 500uS delay before the TRIAC is switched OFF is maybe a bit long.

Even more software here


<p>I cant make it to work.I have done the circuit 5 times now from scratch and it still wont work.I uploaded sketches 1 and 2, and I changed the pins in case my arduino doesnt work properly.The first time i did the circuit my lamp just flickered, now it doesnt even turn on.What could i possibly be doing wrong?I dont have an oscilloscope to see the wave in detail.Also i use a bridge GBU 6K(800 V ,6 A).</p>
<p>alex, that is too bad. I have build it I think 10 times and it worked every time. In fact, there cant be much wrong with it. As the outcome between yr first build and your last build is different, somehow it must be a hardware problem. Are you using the same components at every build?<br>Are you sure you make the right connection, please recheck. How do you build it? on pertinax or breadboard.<br>What happens if you disconnect the arduino and just put 5 Volt on the entrance of the circuit and then plug it into the mains?<br></p>
<p>I made this for five bulbs . but there is a flickering. flicker rate is not constant, flicker rate change with the time and its looks periodic. its increase with time and then decrease. then flickering stop, after about 1 second its start flicker again. can you please tell me the problem. its not the number of bulbs i have used, even with one bulb there is flickering . i changed the resister values from 33k to 16.5k, detect zero cross using a 12v transformer, replace optocouplers. changed the 4n25 pull up resister from 10k to another value. nothing helps. flickering rate and pattern remaining same . can you please help me. thank you for this great instructable .</p>
<p><a href="http://www.instructables.com/member/%E0%B6%85%E0%B6%BA%E0%B6%B1%E0%B7%8A%E0%B6%B8">අයන්ම</a> I am not sure if you saw my 3 channel light dimmer, but that is just for your information.<br>There can be various reasons for flickering: software and hardware, so lets see where the problem is. I presume you have juist built the triac circuit 5 times and the zerocross one time.<br>What happens if you ignore the 4 channels and just use one and use my demo program? What happens then?</p><p>Flickering coz of hardware is usually because of a dirty psu. What happens if you feed your microcontroller from a battery?</p><p>I presume you used the 16.5k to get a smaller pulse, but apparently that was not the solution. Though you can use a transformer to get the pulse off but the quality of the transformer is of importance.</p><p>Do you have flickering over the entire range? Is there also flickering if you write one value to the optocoupler? say, 70.</p><p>Disconnect your microcontroller and put 5 volt on the entrance of your circuit. Do you have flickering too? </p><p>Anyway.. try that and try also feeding the microcontroller with a battery </p>
Thank you verymuch for the responce and yes , i saw your3 bulb example. But i didnt do it that way. I just use your timer interrupt code and copy- paste it 5 times.added 5 variables for zero cross detect ,5 for dim and anothre 5 for i. As you said i added 5 triacs and one zerocrossing detector. That is not the problem. I only used your code and the diagram. But the problem is same. As i said the flickering is periodic. It has a pattern. I powered arduino from the laptop usb.the Flickering can be obsrerved about 70%below the brightness. It depends on the wattage of the bulb. When use 25 w bulb it can obseved from about 70%.when the bulb is 75w there is no flicker obsrved untill about 50%,40%. . When the bulb in full brightness- no flicker.
<p>I am not sure if making 5 copies of the timer interrupt code will work flawlessly.<br>what happens if you just use my demo code with ONE lamp.<br>Also try the code I supplied with the 3 channel circuit and please send me yr code so I can check</p>
I used your sample code from the begining. Result is the same.flickring pattren is same. And i used only one lamp.
<p>did you do the other things I suggested earlier? and if yes what was the outcome</p>
&quot;Disconnect your microcontroller and put 5 volt on the entrance of your circuit. Do you have flickering too?&quot; I didnt understand this. What do you mean by entrance
<p>the entrance is where you would normally put the output of the arduino</p>
<p>When you go to amazon and search ac dimmer arduino. you will find excellent products. save your time.</p>
<p>as said above, sure, everything is for sale. In this case for more than 10 times as expensive. It seems you especially joined instructables to make that remark as this is your only contribution</p>
<p>Dear Diy;</p><p>First full, I totally respect your excellent article. I can not compare your explanations with any value, because you are teaching how to fish. I just wanted to let people know that preexist products exists maybe they do not know how to use any electronic devices.</p><p>Thanks again</p>
<p>understood. I appreciate your candor. I might have been a bit on edge as i sometimes have a stalker here.</p>
<p>When you go to amazon and search ac dimmer arduino. you will find excellent products. save your time.</p>
<p>sure, everything is for sale and you pay 30 dollars plus shipping rather than 2.50 usd. But yes, you are free to do that</p>
<p>hi, very nice tutorial. Have you tried this with dimmable led? and what about triac temperature do you have heatsink for it?</p>
<p>the need for a heatsink depends on the load but ofcourse it won't hurt. I have not tried it with a dimmable led but i know some did. However, not every dimmable led will work. You need to find one hat works with a traditional dimmer</p>
<p>and why you are using diode bridge with triac?</p>
<p>The diode bridge has nothing to do with the triac, it is for the zero cross detection</p>
<p>yes, confused with h11aa1 and 4n25 :) i just made this and works fine with dimmable 16w philips led with no flicker, with incandescent bulb have a little flicker near total dimm, do you have flicker too?</p>
<p>yours looks great. As a result of your earlier questiom i picked up a dimmable LED and that works fine. That is no garantee though that all dimmable leds will work. I have no flicker with lamp or led.Fliicker can be a resul of a dirty psu or a zerecross pulse that is too wide</p>
I have 230 vac and i use 1/4 w 30kohm resistors, this can cause wide pulse? You are using 33kohm 1/2 w if i understand correctly
<p>yes I use 33k.<br>I was speaking in general terms with regard to the wider pulse. Not saying that is the problem in your case. Tolerance aside, your pulse shld be even a bit smaller than mine<br>There are a few things you can try. <br>Try the interrupt on the falling flank<br>See what happens if you battery feed your arduino</p>
<p>Sorry, I have deleted the post by mistake.</p><p>I have put 2 Serial.Print in the code, one is inside &quot;<em>void zero_crosss_int()</em>&quot; function and the other in &quot;<em>for (int i=5; i &lt;= 128; i++)</em>&quot; loop, so when im plugged to 220v 50hz, I only get the Serial.print from zero cross function, and when im unplugged only the one in for loop. I think this is correct because is detecting zero crossing right?. But the bulb is always OFF. </p><p>The only difference in my circuit is that im using KBP210G bridge and BT137600E transistor, I have checked optocoupler pins 4 &amp; 5 and im getting 4.98v also all the juntions &amp; routes are ok. </p><p>Im feeding the circuit with vcc pin from arduino pro mini.</p><p>Any idea of what im messing up?</p><p><br>Thanks for your help!</p>
<p>as you deleted your post, I am not sure anymore what your original problem was.<br>Can I ask why you put the serial print in your interrupt?<br>Should keep the interrupt as short and slim as possible. Your serial print may be screwing up your interrupt, meaning a new interrupt is already generated before it gets out of your interrupt.<br><br>If you then unplug your mains conection, you are not getting any interrupt anymore so the program stays in its loop.<br>Contray to what you say it doesnt stay in its loop because it is detecting zerocross, it stays in its loop because it is NOT detecting zerocross, yoou have unplugged it<br><br></p>
<p>Hi, thanks for you great explanations, sorry for my english but my mother tongue is spanish, I have a question please, I implement the code above and only have two states, ON and OFF although the variables dim, dim2 and dim2 change when i press de buttons, in dim = 128 de lamp is off and and any other value of dim diferentes to 128, turns ON the lamp. Finally when the lamp is OFF whit dim=128, after a while the lamp starts blink, I apreciate a lot youy help, I hope you can answeer me question, thanks.</p>
<p>Seems you are using something else than the demoprogram :-) OK first things first: what happens if you load my demoprogram. Does that work properly? </p>
First, thanks for answer my question, second Yes, when I use the demo program works properly, makes the loop from 0 to 128. Whit the demo program I try to send individual values makes a multiplication between 65 (because in my country works wirh 110V 60Hz) and dimming values but doesn't work, because the lamp turn on totally with each value. Finally I used another program that works with the buttons to up or down the dimming level, which caused my doubt.
<p>ok so the hardware works. That means the problem is in your program. I cant say anything on that without seeing your program</p>
<p>Hi, now the program works, but I did a lot of tests and I have the following results:</p><p>1) With dimming=5; -&gt; the lamp is totalilly ON max poer</p><p>2) from dimming=10 to dimming=109 tthe lamp is lowering its brightness</p><p>3) In dimming=110, the lap starts flashing</p><p>4) from dimming=111 to dimming=118 the lap is on its minimum power</p><p>5) in dimming= 119 the lap increase its power again </p><p>6) in dimming=128 the lamps starts a buccle form max power to low power </p><p>7) in dimming=127, dimming=126, dimming=125 the lamp is on its max power again</p><p>In conclusion:</p><p>1) For values over dimming=110 the performance of the dimmer I don't understand</p><p>2) with dimming= 60 and over the zero cross circuit emits a beep, i think that is normally because i have in my room a normal dimmer that i bought in a store</p><p> Thanks very much, I appreciate your help</p><p>The code I am using:</p><p>int AC_LOAD = 3; // Output to Opto Triac pin</p><p>int dimming = 128; // Dimming level (0-128) 0 = ON, 128 = OFF</p><p>void setup()</p><p>{</p><p> pinMode(AC_LOAD, OUTPUT);// Set AC Load pin as output</p><p> attachInterrupt(0, zero_crosss_int, RISING); // Choose the zero cross interrupt # from the table above</p><p>}</p><p>//the interrupt function must take no parameters and return nothing</p><p>void zero_crosss_int() //function to be fired at the zero crossing to dim the light</p><p>{</p><p> // Firing angle calculation : 1 full 50Hz wave =1/50=20ms </p><p> // Every zerocrossing thus: (50Hz)-&gt; 10ms (1/2 Cycle) </p><p> // For 60Hz =&gt; 8.33ms (10.000/120)</p><p> // 10ms=10000us</p><p> // (10000us - 10us) / 128 = 75 (Approx) For 60Hz =&gt;65</p><p> int dimtime = (65*dimming); // For 60Hz =&gt;65 </p><p> delayMicroseconds(dimtime); // Wait till firing the TRIAC </p><p> digitalWrite(AC_LOAD, HIGH); // Fire the TRIAC</p><p> delayMicroseconds(10); // triac On propogation delay </p><p> // (for 60Hz use 8.33) Some Triacs need a longer period</p><p> digitalWrite(AC_LOAD, LOW); // No longer trigger the TRIAC (the next zero crossing will swith it off) TRIAC</p><p>}</p><p>void loop() {</p><p> dimming=30;</p><p> delay(10);</p><p>}</p>
<p>It all suggest that somewhere your timing is off, but before I go any deeper, explain this to me:<br>&quot;2) with dimming= 60 and over the zero cross circuit emits a beep, i <br>think that is normally because i have in my room a normal dimmer that i<br> bought in a store&quot;<br><br>What element produces the beep and what does a store bought dimmer have to do with your problem?</p>
I'm using the zero cross circuit that you propouse in this blog, the dimmer that I have in my room is analog, of those standing on the wall, I think that the triac emits the beep or the lamp I'm not really shure.
<p>TRIACS dont emit beeps</p><p>Not sure what you mean with analog dimmer, but if you are using a store bought dimmer in this circuit I am ot surprised you have problems. <br>1 how do you control it from yr arduino? (i.e. where do the wires go?)<br>2 how do you need to control it? (the dimtime values may mean nothing to yr dimmer)<br>3 can you control it? (maybe it isnt designed to be controlled from a microcontroller)</p>
<p>Sorry, As I said my English is not very good, forget about the analog dimmers, I'm not using that dimmer in the circuit, I think I caused confusion. I'm using de zero cross circuit and de dimmer circuit propouse of you in this blog, sorry again for the confusion</p>
<p>is ok. I was already wondering what a commercial dimmer had to do with it. So that beep that you brought up... from which circuit is that coming?</p>
The beep comes from the light bulb
<p>that surprises me coz lightbulbs generally dont beep.</p><p>Anyway, I might have become sidetracked from your original problem. Is that solved now?</p>
The problem persists, you told me: &quot;It all suggest that somewhere your timing is off...&quot;. I appreciate your help.
<p>OK. I get many questions so sometimes if iot is a bit prolonged I may lose track what the initial problem was.<br>So we can state that the demo program is working, which means that your hardware is working. However when you send an individual value you run into problems.<br>The program you are using is exactly the same as the demo program that is working for you, except for that you replaced <br></p><p>for (int i=5; i &lt;= 128; i++){<br> dimming=i;<br> delay(10);<br> }</p><p> with </p><p> dimming=30;</p><p> delay(10);<br><br>As you can appreciate that is extremely odd as the value 30 and in fact any of the other values that you tried all come along in the loop that actually IS working for you.<br>Additionally, you have a beeping lamp<br>I must say this is all very unlogical. Must oversee something<br>So here is what I like you to do:<br>Load the original demo program again and make sure that indeed works and that the lamp doesnt beep</p><p>then change </p><p>for (int i=5; i &lt;= 128; i++){<br>into</p><p>for (int i=20; i &lt;= 100; i++){<br>and see what that does.<br>If that works narrow the gap to say 30-40 and tell me what that does</p>
<p>OK, my last question: how do you calculate the 30 Ohm? Motorola's 4n25 takes 60mW / 3V and I have the impression that 47 Ohm is better suited for 230V. Am I wrong?</p>
<p>I am not sure what 30 ohm you are referring to</p>
<p>Sorry. On the mains input you have two 30 *Kilo*Ohm resistors. How do you calculate this value? </p>
<p>pls dont overlook my prior reply to this question, but I just wanted to add a bit more. Ideally the resistor value should be as small as possible so the width of the zerocross signal is as small as possible. However, that would lead to a rather high powerdissipation in the resistors.<br>The 4n25 doesnt have 60mW dissipation as you write but max 120mW. However that number is of secundary relevance as we really dont need 40mA to open the 4n25.<br>the rectified voltage of 230 V AC =207 Volt.<br>divided by 60k that gives abt 3.5mA which is enough. Going to 2x47k (not sure where you got that value) would give 2.2mA. That is pushing it a bit. Plus your zerocrosssignal would get wider, giving you timing problems</p>
<p>I think you made a calculation error here. </p><p>The peak to peak voltage after rectification will be 220*sqrt(2) = 311 Volts (not 207V).</p><p>For the purpose of calculating the current, however, you should use the 220V RMS value (because the resistors are on the AC side of the rectifier), so 220/60k = 3.67 mA which is still close to what you calculated, so in the end it does not matter very much.</p>
<p>Thanks. I always used to calculate with 1.4 and it is well possible that 3-4 years ago I used that value to calculate the resistor value based on 1.4x230V.But since then I was told (rectifieing basics on internet) that it should be the average voltage, which was supposed to be 0.9*230. I am not sure if that is true, but as you correctly state: In the end it doesnt matter very much.</p><p>Thanks :-)</p>
<p>by dividing the voltage by the current I wanted to flow.<br>This is a <br>compromise between wanting a decent current to open the phototransistor<br> and a current that wouldnt be too big with regard to the power <br>dissipation</p>
<p>Thank you all for such great projects. I have developed this project and it works all fine. But when I use a sensor with arduino, it gives no response. I think arduino is too much busy in tackling zero-crossings. Can anyone suggest anything about using multiple things with this power control using same arduino board.</p>
<p>seems like instructables is at it again. I answered yesterday, but I cant see my reply anymore. Also I saw you reacted again but cant find that reaction.<br>Anyway I will try again: you probably used the firts program, which is a demo program. It doesnt do much else but wait in a delay.<br>If you want your CPU to do something else, take the 2nd program that uses a timer interrupt to determine that phase cut and leaves the CPU free to do other things</p>
<p>Yet another question. As you write, the zero-crossing detection consumes ~800mW.</p><p>For a 365 days / 24h device that is a lot (thinking at the coal or uranium burnt for that). </p><p>So lets save energy: for the important dim-position &quot;switched off&quot; it might be reasonable to operate mains input by an optocoupler-driven relais that cuts this down to 0mW. Does this seem reasonable to you?</p>

About This Instructable




Bio: I am a physician by trade. After a career in the pharmeceutical world I decided to take it a bit slower and do things I ... More »
More by diy_bloke:Using the 4 pins of the ESP8266-01 Adding the BMP180 to the ESP8266 Adding an RTC and OLED to ESP8266-01 
Add instructable to: