I want to build a 8 channel, independently controlled AC dimmer using Arduino. I have successfully tested a single channel dimmer but i am stuck in expanding it to 8 channels. The circuit I am referring is as below single channel dimmer circuit

The arduino code i am using is as below

AC Voltage dimmer with Zero cross detection
Author: Charith Fernanado http://www.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 pins, NOT physical pins:
digital pin 2 [INT0]=physical pin 4 
and digital pin 3 [INT1]= physical pin 5)

 Pin    |  Interrrupt # | Arduino Platform
 2      |  0            |  All
 3      |  1            |  All
 18     |  5            |  Arduino Mega Only
 19     |  4            |  Arduino Mega Only
 20     |  3            |  Arduino Mega Only
 21     |  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)  0 = ON, 128 = OFF
/* Due to timing problems, the use of ‘0’ can sometimes make the circuit 
flicker. It is safer to use a value slightly higher than ‘0’
void setup()
  pinMode(AC_LOAD, OUTPUT);// Set AC Load pin as output
  attachInterrupt(0, zero_crosss_int, RISING);  
// Chooses '0' as interrupt for the zero-crossing
// the 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 calculation : 1 full 50Hz wave =1/50=20ms  
  // Every zerocrossing thus: (50Hz)-> 10ms (1/2 Cycle) For 60Hz => 8.33ms

  // 10ms=10000us
  // (10000us - 10us) / 128 = 75 (Approx) For 60Hz =>65
  int dimtime = (75*dimming);    // For 60Hz =>65     
  delayMicroseconds(dimtime);    // Off cycle
  digitalWrite(AC_LOAD, HIGH);   // triac firing
  delayMicroseconds(10);         // triac On propogation delay
                                 //(for 60Hz use 8.33)
  digitalWrite(AC_LOAD, LOW);    // triac Off
void loop()  {
 for (int i=5; i <= 128; i++)

Any ideas about how can i expand the code and circuit to work with 8 channels that can be INDEPENDENTLY controlled ?

  • \$\begingroup\$ Your diagram and code snippet for only one channel, if you ask your problem exactly then answer will be more closure to solution ! \$\endgroup\$ – Photon001 Jul 7 '16 at 13:32

Without doing an in-depth code review the problem is likely to be here:

delayMicroseconds(dimtime);    // Off cycle
digitalWrite(AC_LOAD, HIGH);   // triac firing
delayMicroseconds(10);         // triac On propogation delay

The delay functions cause the CPU to loop and no other processing can be done.

A better way would be to create a timer routine and call it for each channel. This would need a variable assigned for

  • the preset value (the value at which the timer output turns on),
  • the actual value (the current time value) and
  • the output state (timer done or not).

An easier method might be:

  • Divide your half-cycle into a discrete number of steps of, say, 50 μs.
  • In your main loop add a counter which is reset at zero-cross and increments every 50 μs.
  • In the loop compare the dimmer level for each channel with the timer and turn on that channel if dimmer level exceeded.

enter image description here

Figure 1. Relationship between current and trigger angle.

Note that the current produced does not vary linearly with the trigger angle due to the sinusoidal mains voltage waveform. Small changes around the peak voltage will have more significant effect than closer to the zero-cross. You may want to address this in your code if the visual effect does not match your dimmer setting.

  • \$\begingroup\$ thank you for your reply. I will consider your suggestions and try to work further on my code for multiple channel \$\endgroup\$ – gaurav bhand Jul 7 '16 at 14:29
  • \$\begingroup\$ You're welcome. Try to avoid using delays in your code. Use timers instead. That way your micro can do other stuff in the meantime. Delays are very tempting but they are bad practice and I think all the tutorials that use them get the users off to a bad start. \$\endgroup\$ – Transistor Jul 7 '16 at 14:49

If you want to use a board already tested and ready use this. Each Channel is independently controlled. 8 ch Arduino AC dimmer

  • 1
    \$\begingroup\$ That board is a hardware module. It still leaves the original question of how to program for eight channels. If you check the code samples they give you might find a solution that avoids the pause instruction which is the cause of the original problem. Put that into your post with some explanation and you might have a good answer. \$\endgroup\$ – Transistor Jun 19 '17 at 6:33

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.