3 Channel Dimmer/fader for Arduino or Other Microcontroller

Introduction: 3 Channel Dimmer/fader for Arduino or Other Microcontroller

In an earlier instructable I presented a simple AC TRIAC fader/dimmer that could be controlled with an Arduino. In various reactions I got, a number of people expressed their interest in a 3 channel RGB fader. But since I have not seen any results of those yet. I decided to try myself. I was actually triggered (no pun intended by coming across the T1M5F600 TRIAC (LiteOn) that was quite cheap (0.20 eurocents) and was specified as 1A 600V with a 5mA gate current. It is in a TO92 housing and 1A seems quite enough to switch a coloured lamp who usually dont have a high Wattage to begin with.

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!

The circuit is quite standard. It consists of 3 Triac's that are triggered via a MOC3021. One can use other Triac optocouplers as long as they do not have an inbuilt zero-cross network as we want o decide ourselves when to open the triac.

The circuit that does the zero cross detection is kept quite simple: A bidirectional opto-coupler is fed with 220V AC where the two 33k resistors cause current limitation and a voltage drop. To be on the safe side Both resistors should be 1 Watt. It is possible to use highly sensitive optocouplers and thus limit the current needed and with that limit the dissipation in the resistors (e.g. by using a 4N33), but I do not know any of those that are also bidirectional. So if you'd want to use those, you would also need a bridge rectifier. See my other article: Arduino controlled lightdimmer

It is also possible of course to get the zero-crossing signal from the secundary side of a transformer.

Step 1: 3 Channel Dimmer/fader for Arduino or Other Microcontroller: the PCB

The PCB houses the 3 dimming circuits as well as the Zero cross detection. A PCB design is provided for direct toner transfer. The stocking of the PCB is quite straightforward. Note that the Triac, the M5F600 is in a TO92 case and the pin layout is different from most other Triacs in the TO220 casing.

Note that the IL250 should be mounted with its notch pointing down, whereas the other opto-couplers should be mounted with the notch pointing up

As this program is just to illustrate, the loop cycles between 0 and 127..

/*
AC Light Control
Ryan McLaughlin <ryanjmclaughlin@gmail.com>
with slight modifications
*/
#include <TimerOne.h> // http://www.arduino.cc/playground/Code/Timer1
#define PINS 3
volatile int pinCount[PINS]; // make volatile to make available in interrupt
volatile boolean zero_cross=0; // Boolean to store a "switch" to tell us if we have crossed zero
int AC_pins[] = {3,4,5}; // Stup the pin numbers
int AC_dim[PINS]; // Holds Dimming levels (0-128) 0 = on, 128 = 0ff
int freqStep = 78; // Set the delay for the frequency of power (65 for 60Hz, 78 for 50Hz) per step (using 128 steps)
// freqStep may need some adjustment depending on your power the formula
// you need to us is (500000/AC_freq)/NumSteps = freqStep
void setup() {
for(int a=0; a < PINS; a++) { //set the pins to output
pinMode(AC_pins[a],OUTPUT);
pinCount[a] = 0; // keeps track of the time in the cycle
AC_dim[a] = 0; // dimming level set to zero
}
attachInterrupt(0, zero_cross_detect, FALLING); // Attach Interrupt to Pin 2 (interrupt 0) for Zero Cross Detection
Serial.begin(9600);
Timer1.initialize(freqStep); // Initialize TimerOne library for the freq we need
Timer1.attachInterrupt(dim_check, freqStep); // Use the TimerOne Library to attach an interrupt
// to the function we use to check to see if it is
// the right time to fire the triac. This function
// will now run every freqStep in microseconds.
}
void zero_cross_detect() { // function to be fired at the zero crossing
zero_cross = 1; // set flag to tell dimming function zero cross has occured
} // End zero_cross_detect
void dim_check() { // Function will fire the triac at the proper time
if(zero_cross == 1) { // First check to make sure the zero-cross has happened else do nothing
for(int a=0; a < PINS; a++) {
if(pinCount[a] >= AC_dim[a]) { // Check and see if i has reached the dimming value we want
digitalWrite(AC_pins[a], HIGH); // Fire the Triac
delayMicroseconds(5); // Pause briefly to ensure the triac turned on
digitalWrite(AC_pins[a], LOW); // Turn off the Triac gate (Triac will turn off at the next zero cross)
pinCount[a] = 0; // Reset the accumulator
zero_cross = 0; // Reset the zero_cross so it may be turned on again at the next zero_cross_detect
} else {
pinCount[a]++; // If the dimming value has not been reached, incriment the counter
}
}
}
}
void loop() {
// This is simply making all outputs cycle through bright-dark, out of time with each other.
for(int i=0; i<127; i ++) {
for(int a=0; a < PINS; a++) {
int ii = i+42; //this is the bit that puts the blinking lights out of sync with one another
if(ii > 127) ii -= 127;
AC_dim[a] = ii;
}
delay(50);
}
}

Step 3: 3 Channel Dimmer/fader: Tips for Software

though it may seem a bit daunting to develop software for a 3-channel dimmer, it is not so hard as long as you keep focussed on the essentials the software needs to do:-Wait for the zerocross interrupt to happen.-Wait a set time before tiggering the TRIAC-Trigger the TRIAC

For 3 channels that is not much different, you just have to keep track of 3 time variables. You can do that with "delays" but that is rather complicated. You can do that with "micros" and keep checking the 3 time variables against the time passed since the zerocross. Finally, you can do it with a timer interrupt.

The way timer interrupts are normally used if you are dimming one channel, is to set the interrupt for the desired time and when the interrupt occurs to trigger the TRIAC. With 3 channels that is impossible because you do not have 3 timer interrupts.

A better way is to set the timer interrupt to occur for 78uS. That divides the period of a 50Hz grid frequency in 128 steps (remember the re are 2 zerocrossings per 50Hz period, so you have in fact a 100 Hz signal, thus 10mS to do the work in before the next zerocrossing interrupt. 10mS/128=78.125uS). For 60Hz a value of 65 would be good.You then let the timer interrupt service routine set a counter that in fact counts the number of 78uS steps that have passed since the zerocrossing interrupt occurred.Your 3 time variables -each for every channel- are expressed in a level between 0 and 128. In the main loop check those against the counter set by your timer interrupt and when it is at the desired level.... ignite the corresponding TRIAC.

apologies for my late reply. I was indisposed for a few days.I had chosen the M5F600 Triac mainly because small, cheap and a sensitive gate but I am not stuck on it. The BT136 u link to seems to have rather similar specs though I am not entirely sure abut the gate sensitivity, but I am quite sure it will work.Mind you though that a TO92 cant handle really big currents like the TO220.For full current you mey need some form of heatsink, which is always a bit trickier with a TO92

Thanks for the reply. I'll be using it with smaller currents, at least this time, just to have a way to dim a couple table lamps.

Am I right in assuming that I can make this into a two channel if I just leave the blue circuit part off? Or turn it into a 4 channel if I add another one? I'll probably keep it at 3, but I'm curious how modular this could end up being?

I have worked with mains power and relays before but not TRIACS or optocouplers, so I'm going to be doing a lot of studying to make sure I do it right.

I couldn't get any IL251 or EL814 unless I wanted 1000 of them, so I went with the LTV814.

yes you can leave any of the channels off, or add a channel. The max number I tried was 6, that is gonna be a bit tricky to keep delay time, but it is possible.the LTV814 is a fine chip. used it on many occasions. Just remember it is not pin compatible to the il251, but I think it is fully compatibel with the EL814.

I know the excitement :-)But realize that the programming is a bit demanding as you likely have to keep a separate timer (millis() is fine) for each channel, unless you are using steady ligthing patterns

Got my components, and built one channel of the circuit. I'm a little curious... does it matter which main terminal on the BT131 I wire the load up to?

I tried wiring it up one way and nothing happened, so I tried it the other way, and nothing happened, and then I figured out I had a wire loose, and once I fixed that it worked fine. I'm just curious if it would have worked the first way or not.

Then I tried a normal incandescent bulb that I happened to still have laying around, and it worked fine with no buzzing. I'm curious if there are any tricks I can try to get the LED bulb to work without buzzing, since it's kind of hard to find incandescent bulbs nowadays.

I'll upload a picture once I get the second channel wired and clean it up a little.

as afar as I know it makes no difference. after all it is in series with the load.I am happy you worked out the problem with the loose wire :-)Dimmable lEDs are not always that easy to dim without special dimmers. At least yours showed some response. Incandescents are still the best companion for TRIACS

The one part of the diagram that I'm a little hazy on ATM is the il251 (or LTV814 in my case). I have the datasheet for the 814, so I think I can figure out a lot of it. On the right side of the wiring diagram where the 33K resisters are pins 1 and 2, and that will be wired to the 110VAC lines to set the timing of the zero points so that the power can be managed to dim the light. But on the left side of the il251 you have three lines, One is +Vcc, one is 0-Xing, and the last is ground. If I'm reading the program correctly, 0-Xing is connected to pin 2 (interrupt 0), and of course ground is connected to the common ground, and I think +Vcc would be connected to the 5v on the ardunino with a 10k resistor?

So on the LTV814 the collector (LTV814 pin 4) would be connected to both 5V(10kR) and pin 2 (interrupt 0), and the emitter (LTV814 pin 3) would be connected to ground. When the AC cycle hits zero, Interrupt 0 will be pulled high, and when the new cycle starts it'll be pulled low again and interrupt the program.

Hopefully I have that all correct, but if not let me know where I'm confused.

Mayurr I am happy you got it working. The supplied program ofcourse is only a demo program. I keep the dimming values in the Array AC_dim[PINS];Whether in your final setup that is the best to do completely depends on your program

sorry sir ,but i can not understand bridge connection or the link that yiu sen .i am 1st year student and i thimk i do this is big think for me .i complte whole cicuit but i do not have IL251 so my project was incopmlate .if you want to help me than tell me thhat insatnt of IL251 hoe to replace EL812 with proper diagram or picture. this is my last try sir......

I am not sure how i can make it clearer: the 3 channel dimmer has 2 resistors coming from the grid, going ro the the IL251. You want to use an EL812 so you need a bridge in between the 2 resistors and the EL812.In the picture you see exactly how to do that.Look at the two resistors, the bridge and the optocoupler, ignore the rest.You see 2 resistors, they go to the AC connectors of the bridge, the + and - of the bridge then go to the optocoupler which in your case is the EL812. The 400V you were asking about is the spec of the bridge. I think the picture I sent is a proper circuit, but as you are a first year student I now have spelled it out on a resend of that picure. As I said before, I start to get really worried about you building this as you sem to have trouble understanding circuits, can I again draw your attention to my warning at the beginning of this instructable. If you are not sure about what you are doing I would strongly advise you not to build this. It is connected to the grid and that carries a lethal voltage

Having said that, I am starting to worry a bit, yuo seem to have very limited knowledge of electronics, seem to have no real knowledge of the arduino. No problem with that, we all have to learn, but this is a project carrying high voltages that could kill you. Are you sure this is a project you want to build?

Hi! Disclaimer: I am a new with arduino and these kind of things. I would like to ask how would I be able to control dimming easier with these? I am working on a project where I will be dimming an incandescent bulb, an AC motor, and a water heater. However, the dimming values will be dictated by the arduino using conditions that I will set (using fuzzy logic) and with the reading of my temperature and humidity sensor. I am already a bit familiar with PWM dimming and I find its codes more understandable than interrupt so I'm hoping to make the codes a bit similar to that. Also, will the interrupt affect the countdown timer I will be using as a background function? How can I make each channel work independently of the others? Sorry for the questions if it seems so much. I just really need help understanding these things. Thank you!

You are partly right. Indeed the software is more complicated than for instance with PWM, but the channels do work independent from eachother (but not independent from the interrupt).If you use this circuit you will have to deal with interrupts.... or you need to frequently poll the zerocross pin, but that is less reliable.

if you want to stick to PWM........ you can use my pwm dimmer. However that is only suitable for DC devices, so it is going to be difficult for an AC motor.in that instructable however I discuss a circuit by Ton Giesberts, that as far as I know can be used for AC, but in my opinion is not as ideal (for DC) as my circuit.So you could decide to build my PWM circuit for your incandescent bulbs and Giesberts circuit for your motor. What your heater needs I am not sure

I think the heater runs with the same concept as the incandescent bulb since the bulb lights up by heating the filament inside.

Can Giesbert's circuit handle the motor if it will be running continuously for 24 hours for several days? Same question for your PWM dimmer. The device I will be building should run 24 hours for 21-30 days straight. Thank you!