You are on page 1of 25
-wordpresscom 2012/10) =— Arduino & ESP8266 stuff ated tf incatingstiry Search. Recent Posts Setting up a local MOTT broker on the Raspberry PI [MQTT with the ENC28160 Ethershield Sending dats to Carrots oT platform ‘with SP8266 Reviewing the Wemes Batery Shield Sending mail with an ESP826 Favourites xe Timer interrupts *| Dimmer-Arduino Switching an AC load with an Arduino is rather simpel: either a mechanical Relay ora solid state relay with an optically isolated Triac. Te becomes a bit more tricky if one wants to dim a mains AC lamp with an arduino: just limiting the current through a Triac is not really possible due to the large power the triac 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 itis through phase control: the Triac then is fully opened, but only during a part of the sinoid AC wave. One could an Arduino just let open the Triac for a number of microseconds, but that has the problem that itis unpredictable during what part of the sinuswave 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 microcontroller) 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 after the zero crossing therefore gives a predictable level of dimming. Dimmer-Arduino Serial connection for your ‘Arduino / Aumega Carduino: an arduino-sort (of for your garden Using MOSFETS with TTL levels (5 Volt and 33 Volt) Solar powering an Atay oF ‘Aino with a capacitor, or just use AA? Pare? Power LED drivers 435 Miz system for your Arde Soli State Relay for microcontroller Connect an ENC28160 Ethernet module wo an Arduino Archives February 2017 January 2017 December 2016 November 2016 October 2016 ‘September 2016 July 2016 May 2016 March 2016 February 2016 ‘his re, isan example. Such a circuit 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 (see figure below), 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 steer an interrupt in the Arduino. December 2015 November 2015 October 2015 ‘September 2015 August 2015 July 2015 June 2015 May 2015 Api 2085 March 2015 January 2015 December 2014 September 2014 ‘August 2014 July 2014 June 2014 March 2014 January 2014 November 2013 October 2013 ‘September 2013 April 2013, February 2013 December 2012 November 2012 October 2012 ‘September 2012 May 2012 ‘pit 2012 March 2012 Signal Suengt Opening the Triac is done via a tried and tested opto coupled Triac circuit. For the Triac a TIC206 can be used, but a BT136 (a bit cheaper) would probably work as well. With regard to the ‘MOC3021: that has a forward voltage of about 1.2-1.4 Volts anda trigger current of 8-15 mA. An LED has a forward voltage of about 2Volts. Presuming a 5V digital steering signal that gives a resistor value between (5-3.2)/0.015- 120 Ohm and (5-3.2/0.008=225 Ohm, making 220 a decent choice. In reality an LED may have a slightly lower forward voltage and a 330 Ohm resistor was found to work as well. It is important NOT to chose an opto-Triac here with an inbuilt zero-crossing filter. ‘The MOC3041 or the MOC3061 for that matter therefore is not usable in this circuit. The MOC 3021 is. NOTE: some people have experienced flicker as a result of a weak input signal. As the voltage drop over an LED may vary depending on the color. itis safer to replace the LED by a wire bridge and increase the 220 Ohm resistor to 330 or 470 Ohm With regard to the 30k resistors: The 1/2 Watt should do it as the resistors dissipate some 400mW. If you think that is too much, replace the N25 with a 4N33 and the two 30k resistors with two 100 k resistors. Be careful though in using sensitive optocouplers as the 4N32 as they will easily be fully in (october 2012 nm m ow oH «sep B February 2012 Meta Register Login Entries RSS Comments RSS WordPress.com 2% 7 saturation. ‘Tiss the complete iret of he dimmer All one needs then is the software. Fortunately someone already has done the basic ‘work. I just adapted the code slightly: a AC Voltage dimmer with Zero cross detection ‘Author: Charith Fernanado http://sn.inmojo.com License: Creative Commons Attribution Share-Alike 3.0 License. Attach the Zero cross pin of the module to Arduino External Interrupt pin Select the correct Interrupt # from the below table: (the Pin numbers are é digital pin 2 [1179] sital pins, NOT physical pins: hysical pin & and digital pin 3 [INT1]= physical pin 5) Pin | Intererupt # | Arduino Platform le Ioan Ia | al ws | Arduino Mega Only wp 14 | Arduino Mega Only 2 | 3 | Arduino Mega Only m1 2 | Arduino Mega Only In the program pin 2 is chosen ” int AC LOAD = 3; // Output to Opto Triac pin int dimming = 128; // Dimming level (0-128) = ON, 128 = OFF /* Due to timing problens, the use of ‘0? can sonetines make the circuit Flicker. Tt iz safer to use 2 value lightly higher thon “a” ” void setup() { Pinlode(AC_LOAD, OUTPUT);// Set AC Load pin as output attachinterrupt(@, zero_crosss_int, RISING); UI Chooses "@" as interrupt for the zero-crossing y JJ the interrupt function must take no parameters and return nothing. nt() 11 function to be fired at the zera crossing to dim the light { // Firing angle calculation : 1 full Sez wave =1/50-20ns void rera_crosss 5 1 Every zeracrossing thus: (SOHz)-> 10ns (1/2 Cycle) For 60H2 => 8.330 17 10s=10000u5 17 (20000u2 - 10u2) / 128 = 75 (Approx) For 6OHz =>65. int dimtine = (75*dimming); // Far 6H: =>65 delayticroseconds(dimtime); // OFF cycle digitalWrite(Ac_LonD, HIGH); // triac firing delayticreseconds(10)3 1/ triac On propogation delay 1 for 60H2 use 8.33) digitalwrite(ac Loan, Low); — // triac off y void loop() { for (int i { dimming=i; deley(10) 5 y 3 554i = 128; i++) Code below uses the timer function instead of delays hitps://codebender.cc/embed/sketch:171819 Print design. Mirrorred. vs (On thing to consider is that if you are building a system in which you are not using a ready made PSU but rather supply your own PSU, built from a transformer and a rectifier, you could consider picking up the 0-crossing from the secundary side of the transformer. A possible circuit could look like this: vot SVot E. ten Winkel set: (Wrvter[IFacbioke@ | EAEna | (G= Gm (cue eR Sone ACdimmingwith WM and Sitchinglowrvoliage AC witha ‘réuino ricrcontall In Ardino” With’ comments Single channel Tria ACswitch Single channel Tviac AC switch > 184 thoughts on “Dimmer-Arduino” ws ‘Swell. Iwill try this. 1am on 115V/60H2 ‘You supplied the values for Otiz but what to do with the 30K resistors? Should I double them or half them and what about their Wattage? Sorry, Lam not so skilled “Reply Smee ‘Thanks Half them, Wattage can temain the same. More than enough ® Reply em Greetings, Ihave a few (silly?) questions; I'm a math guy and (s0) T know nothing about hardware; my brother built the thing and it seems to work but I don’t understand why; probably because I don’t know how a triac works... From the code I can see that half a cycle takes up 10000us and the AC_LOAD pinis set to hhigh for 10us somewhere during that cycle. My calculator shows that (10000us-10us)/128 ~~ 78.046875us so wouldn't 78us be a better approximation instead of 75us? Why is the (half cycle divided in 128 parts? Wouldn't 256 parts be more ‘natural’? ‘My other question deals with the processor itself: during that delay can the processor still be interrupted or is it effectively dead during that delay period? (sorry about this, 1 couldn't find an answer from Google anywhere). ‘Thanks for reading and Kind regards, Jos Reply ee Josh, apologies for my late reply. 78 uS may indeed be a better approxi just picked a nice number close by ‘wether 256 would be a more natural process is up to taste, even at 256 the speed of the change is more important than the size of the step. For my purpose steps of 128th ‘seemed satisfying but there is no problem in taking smaller steps ‘Thanks for your interest ® S Reply No problem; in the mean time I took a diferent approach: your solution makes the processor wait until it has to send a pulse to the triac; in my application that’s a waste of time so Tused a timer that interrupts the processor again when the time has come to send ‘pulse. I divide the 0.01s in 256 parts and prescale the timer by 8; that makes 20.000 ticks per 0.01 second and works very well while my processor can do other things; near the ‘edge’ of the zero crossing interrupt I simply leave the triac on or off because the current is too low to property switch it to an on state (this value differs per tric type). Reply Ste ‘That isin fact a good solution Josh. The example I gave was just that, an example. T have given a solution with a timer interrupt as well se Reply ae Can Tuse a arduino to dinim 220v for a still? ‘Thanks for your answer 4 Reply = ‘Tam not sure what you mean with a still Reply wor I mean a distilling apparatus . To control the boiler temp = In principle that is possible but there might be easier solutions for that a” BY seact.2, 15 2t1600 Has anyone else had problems with flicker / bright flashes from the bulb? 1 can't seem to get a smooth transition, even with the ‘imtime’ variable set toa fixed valle I get the same problems where T would expect a steady brightness. Iwi be heading to a local Hackspace on Sunday cwhere they have an oscilloscope) and will post what Ifind out. Reply T've had a look at my SV supply on a scope. The waveform is terrible, No wonder the arduino gets extra rising edges. Made my own SV supply and it works great now. Reply Lam happy you already found out what the problems, yr Volt psu. Thanks for posting it Reply Arduinodiy ‘That is an interesting approach. My program was just a quick way to show the workings Dut if yoy set a timer interrupt that would be more efficient, ‘Would you care to share your code? “Reply @ Jett | found a great deal of trouble with “flicker/bright flashes” at around 40-50% power. The ‘vay to fix this isto ditch the diode bridge as a zero cross detector, Instead drop the mains through 150K resistance (used 5°47K in series) to directly drive the opto input, but (most important) puta diode in parallel with the opto input, reverse direction. So now on the positive swing of the live, the opto input i “lit, and on the negative swing the parallel diode catches the voltage on the opto input from going more than ~. 7volts reverse polarity, and the opto input is “dark”. Now you get a nice square wave on the opto collector or “the zero crossing out”, changing 0-5v and 5v to Ov etc. exactly with mains zero crossing. In the code, change: attachinterrupt(0, zeto_crosss_int, RISING); to: attachinterrupt(0, zero_crosss int, CHANGE); [Now “void zero erosss. int” is called each zero crossing as before. used a 4n33 instead of a 4n25. You may need lower than 150K if you are using a 4n25. Also I found that I needed a 2.2K pull up resistor on the opto collector (LOk is far to high) ‘to get nice sharp rises and falls. Having nice sharp rises and falls on zero crossings is key to avoiding “flicker” or miss-firing, adapted the code to run on interrupt using timer 1, rather than putting in a delay in the zero_crosss int service code. Here is my arduino leonado test code: ‘har inBytey/ character for serial receive volatile int vary ~ 19980; //.this is OFF value..200 ~ 100 us with an 8 prescale, 100°200 om... ut int response takes 10us so use 19980 int AC LOAD ~3;// Output to Opto Triae pin int dimming - 10; // Dimming level (0-100) 0 - off, 100- on, void setup), t pinMode(AC LOAD, OUTPUT)y/ Set AC Load pin as output attachinterrupt(, zero_crosss int, CHANGE); ‘// Chooses change as interrupt for the zero-crossing Serial begin( 115200); b //%he interrupt function must take no parameters and return nothing void zero crosss int) ‘function to be fired at the zero crossing to dim the light { Firing angle setting /snitialize Timer ‘TCCRIA = 0; //set entire TCCRIA register to 0 ‘TCCRIB = 0; //same for TCCRIB ‘set compare match register to desired timer count: OCRIA= vary; y/tam on CTC mode: ‘TCCRIB | (1 << WGM12); // Set CS11 bit for 8 prescaler: ‘TCCRIB | (1 << C811); //enaible timer compare interrupt: TIMSKI [= (1 <0) i getincoming byte: inByte = Serial.eado; switch (inByte) case 'h ‘dimming ~ dimming+5; if @imming > 95){ dimming ~ 95; 1 Serial. print (‘level is“) Serial printin(dimming); break; case’ dimming ~ dimmning-3; if (dimming<10) { dimming = 1 Serial.print(level is); Serial.printin(dimming); vary = 200*(100-dimming)-20; } Reply ‘Thanks for yr suggestion. I have not had the problem you describe, yet Iwill keep it in ‘mind and perhaps it will be of use in the future. If you do not use a bridge obviously the frequency of the signal gets halved Reply on some of the code did not get posted right. a chunk was missing in the middle, Here isthe code again: char inBytey/ character for serial receive volatile int vary ~ 19980; /200 - 100 us with an 8 prescale, 100°200 - 10ms interrupt - off... but int response -10us so 19980 int AC LOAD ~ 3; // Output to Opto Taiae pin int dimming ~ 10; / Dimming level (0-100) 0 - off, 100 - on void setup0 t pinMode(AC LOAD, OUTPUT);// Set AC Load pin as output, attachinterrupt(, zer0_crosss int, CHANGE); ‘1 Chooses ‘1’ as interrupt for the zero-crossing Serial.begin(115200); q {the interrupt function must take no parameters and return nothing void zero crosss int) //fanction to be fired at the zero crossing to dim the light ( 1/ Firing angle setting i/initialize Timer ‘TCCRIA - 0; //set entire TCCRIA register to 0 TCCRIB ~0; //same for TCCRIB //set compare match register to desired timer count: OCRIA- vary; //tum on CTC mode: TCCRIB (1 << WGMI2); // Set CS11 bit for 8 prescaler: TCCRIB (1 << C811); ‘i/enable timer compare interrupt: TIMSKL Ie (1 <0) 1 gekincoming byte: inByte ~ Serial.eadQ; switch (inByte) [ case ‘h’: dimming = dimming+5; if @imming > 95) [ dimming = 95; 1 Serial.print¢level is"); Serial printin(dimmingy; break; case 'T: dimming - dimming if @immings10) { dimming =10; 1 Serial.printC level is Serial.printin(dimming); break; case: Serial print(‘vary is"); Serial printin(vary); break; case dimming = 30; break; case's! «dimming ~ 60; 1 1 vary = 200*(100-dimming)-20; 1 Reply Jeff second attempt at pasting code also seems to have failed. this bit is missing: 1 ISR(TIMER1_COMPA vect) { digitalWrite(AC_LOAD, HIGH); //triac fring delayMicroseconds(10); //triac On propogation delay digitalWrite(AC LOAD, LOW); //triac Off ‘TCCRIA ~ 0; // set entire TCCRIA register to 0 ‘TGCRIB = 0; // same for TCCRIB 1 void loop { if Serial availableg > 0) insert above exact after text TIMSKI |= (1.< 0) se Reply Jef -message to the moderator... [see other bits of code removed from the paste, so even my correction of missing code also has some missing code. I don’t think this posting blog is good for code. There is text in the upload being filtered out and removed by the web app for some reason. Send me an ‘email if you think others would be interested in the timer code. Jeff Reply ‘You might be right. Have had problems with before. Reply 1am on mobile now so can’t contact u by email but I surely will Reply on Sadly I can't send wan email as I don'thave yr address @ Reply om ‘Trying to use a timer instead of the delayMicroseconds but it keeps blinking...Code is like ‘his: ‘volatile int dimming ~ 128; ‘void setup { pinMode(AC LOAD, OUTPUT);//Set AC Load pin as output attachinterrupt(0, zero_cross int, RISING); } void loop, { } void zero_cross_int() { setTimer(65°dimming); } ISR(TIMER1_COMPA, vect) { digitalWrite(AC_LOAD, HIGH); delayMicroseconds(8.33); digitalWrite(AC_LOAD, Low); b void setTimer(int microseconds) C ‘TCCRIA=0; //set entire TCCRIA register to0 ‘TCCRIB =O; / same for TCCRIB ‘TCCRIB I (1 << WOMI2); TCCRIB |= (1 << S11); TCCRIB &= ~(1<< C810); TCCRIB &= ~(1 << C812); OCRIA ~ microseconds"? -1; ‘TIMSKI |- (1 << OCIELA); 1 Anyone has any ideia? ‘Thank you! s Reply Be sso I can’t immediately see a problem with the code. Maybe someone else will Reply blinking may also be causef ifthe LED on the entrance takes away too much of a voltage drop. Replace the LED by a wire bridge and increase the value of the 220 oghm resistor to 350 or470 chm Reply ‘Thank you very much for your grate job. This circuit is what i long search and this post solved my problem (blinking on low power)! Hii, [want to buy this module, is it available in india ? “Reply BE Actaino Lam not selling any module che than. The one I linked to is mailorder Reply Hi, ifitis not available then | will ty to build my own . Could you pls share the complete circuit schematic... ? . [need to build in the india so my AC supply will be 2300 50H... ae Che than, the complete circuit isin this article. In case it wasn't clear, you need the circuit that u will see immediately above the program listing that has the 4n25, the ‘moc3021, the bridge rectifier and the triac. Ad you can see a rally simple circuit. You will find the print design below the program listing and a picture of the components ‘on the PCB directly below that. The values given are for 250 volts. Don’t hesitate to ask if you need to know more not sure what you mean Chethan. what part of the circuit are you missing?

You might also like