-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 51 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:171819Print 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
SVotE. ten Winkelset:
(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 ReplyNo 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 stillReply
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.
ReplyT'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 paralleldiode 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
Replyon
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 ReplyJef
-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
Replyon
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
Replyblinking 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 ?
“ReplyBE 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?