Home / Circuits / Light Dimmer Circuit with Arduino

Light Dimmer Circuit with Arduino

Light dimmer circuit projects are a good way to learn about thyristors. Thyristors, which include TRIAC, SCR, and Shockley diodes, are four-layer semiconductors that find many applications in AC power control.

This post will show you how to create a light dimmer circuit with a TRIAC. As an additional feature,  dimming controls is through an Arduino microcontroller.

How TRIACs Work

A TRIAC is a three-terminal device that conducts current in both directions. However, it doesn’t readily conduct current across the MT1 and MT2 terminals.

TRIAC schematic symbol

This is unless current through the gate exceeds the gate triggering current IGT. Once this condition is true, the TRIAC keeps conducting, and the main terminal current increases following the curve of the AC sine wave. Removing IGT at this point will have no effect on the main terminal current.

Gate trigger waveform

The main terminal current value at which the TRIAC starts conducting is the latching current. As the AC current across the main terminal goes down and reaches below the holding current, then the TRIAC turns off. Hence, the TRIAC requires another gate voltage to fire again.

TRIAC Power Control Circuit

A typical TRIAC power control circuit is shown below:

TRIAC dimmer circuit

Here, the voltage across the gate is controllable via the variable resistor R1. This effectively varies the current IGT. And by controlling IGT, the latching current point can be moved further or closer to the zero-crossing point. Consequently, the amount of current and voltage across the load varies. Here we see the effect of varying gate voltage. The grey area is the voltage on the load (negative half-cycle not included in the diagram). The larger this area, the greater the power at the load.

TRIAC waveform animation

The capacitor adds more control as it forms a capacitive impedance with the resistor R1 that shifts the phase of the gate voltage between 0 to 90 degrees.

Firing delay angle waveform

The delay from the zero-crossing point to the trigger point is the firing delay angle (alpha). Varying the resistor R1 in the circuit will vary the firing delay angle. The greater the alpha, the less power the load receives. If a light bulb or an LED is a load, then its light will dim as we vary the gate voltage!

Adding an Arduino

The TRIAC circuit above is already a light dimmer. Now, what if instead of a variable resistor, we use an Arduino to control the dimming instead?

This is entirely possible through pulse width modulation (PWM). This is a method of varying the width of a series of pulses in order to vary its average voltage. The average voltage of a PWM is:

The duty cycle is the ratio of the positive cycle width of the PWM signal to its period. Vamp is the amplitude of the PWM signal. Hence by varying the duty cycle, we can have a changing average voltage.

However, an Arduino operates at DC voltage levels while our TRIAC circuit is at mains voltage! To solve this problem, we need an isolation circuit, particularly an optocoupler IC. The MOC3021 optocoupler IC handles DC voltage at its input and AC mains voltage at its output.

MOC3021 optocoupler

Another good reason for using an Arduino is detecting the zero-crossing point. As shown above, the zero-crossing point indicates the start (or end) of the positive or negative half-cycle of the sine wave. Hence, if we know when is this point, then we can adjust the firing delay angle accordingly.

Zero-crossing detection can be achieved by adding a second optocoupler. Here we use an MCT2E IC which has a higher voltage tolerance than the MOC3021.

The AC mains is stepped down to a lower voltage, rectified, and applied to the input of the MCT2E. At the peak value of that voltage, the MCT2E triggers, and at its output is a logic HIGH voltage. Otherwise, the MCT2E’s output is low. The output pin of the MCT2E connects to the Arduino’s interrupt pin (2).

The interval between peak values will be the same as the interval between zero-crossing points. And since the interrupt triggers every peak value, the Arduino now determines when the zero-cross occurs.

With all of the previous discussion in mind, here’s is now our final Arduino light dimmer circuit:

Arduino light dimmer circuit

Here we omit the capacitor because we already have a zero-cross detection circuit for adjusting the firing delay angle. Note that the load can be an incandescent or LED lamp but never a fluorescent lamp as it is not suitable for dimming.

Code for Arduino Dimmer

Here’s the code for the Arduino for our light dimmer circuit. First, you need to install the Dimmable Light and ArduinoSTL libraries.

#include "dimmable_light.h"

const int syncPin = 2;
const int thyristorPin = 5;

DimmableLight light(thyristorPin);

// Delay between a brightness changement in millisecond
int period = 50;

void setup() {
  Serial.println("Dimmable Light for Arduino: first example");
  Serial.print("Init the dimmable light class... ");
  // VERY IMPORTANT: Call this method to start internal light routine

void loop() {
  for(int i=0;i<256;i++){

If you are having errors in compiling the sketch, particularly these kinds:

C:\Users\CxC\Documents\Arduino\libraries\ArduinoSTL-master\src\del_opvs.cpp:25:53: error: 'std::size_t' has not been declared

_UCXXEXPORT void operator delete[](void * ptr, std::size_t) throw(){

Go to C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino and then locate the “new” file (without extension). Rename it to something else. This solves the compile error.

Have any questions about this tutorial? Drop them as comments below!

Check Also

voltage divider circuit

Voltage Divider Calculator

Introduction to Voltage Dividers Resistors are in series when the same current flows through them. …

Leave a Reply

Your email address will not be published. Required fields are marked *