Project

Ambient Light Monitor: Using a Triac to Adjust Lamp Brightness

September 01, 2015 by Robert Keim

Part 5 in the “How to Make an Ambient Light Monitor” series.

Part 5 in the “How to Make an Ambient Light Monitor” series.

Recommended Level

Intermediate

Previous Articles in This Series

Required Hardware/Software

Description Quantity Digi-Key p/n
Breadboard 1 377-2094-ND
Receptacle-to-plug jumper wires 6 1471-1231-ND
Ambient light detector 1 425-2778-ND
4.7 kΩ resistor 1 4.7KQBK-ND
General purpose op-amp 1 LT1638CN8#PBF-ND
0.1 µF capacitors 4 399-4266-ND
Comparator 1 LTC1440CN8#PBF-ND
1 MΩ resistor 1 1.0MQBK-ND
10 kΩ resistors 2 10KQBK-ND
2.2 kΩ resistor 1 2.2KQBK-ND
12 V AC/AC wall-mount power supply 1 T1007-ND
5 V AC/DC wall-mount power supply  1 1470-2771-ND
12 V incandescent bulbs 2 CM7371-ND
Low-power triac 1 497-7699-ND
330 Ω resistor 1 330QBK-ND

Project Overview

In this project we will complete our optical sensor–based automatic light dimmer. In the previous article we explored the zero-cross detector circuit, and in this article we will use the zero-cross detection signal to synchronize a triac control pulse generated by the EFM8. The delay between the zero-cross signal and the rising edge of the triac control pulse is adjusted by firmware based on the current ambient light level detected by the GA1A2S100 optical sensor, and this delay in turn determines how much average power is delivered to the lamp. The triac is not a particularly common component in low-voltage mixed-signal designs, so first we will review the nature of this device. Note: this dimmer implementation is intended for incandescent bulbs—standard compact fluorescent bulbs are not compatible with this circuit.

The Triac

A triac is a bidirectional extension of a thyristor, so first let’s consider the electrical characteristics of the latter device. A thyristor is like a diode that does not conduct until a small triggering current passes from the gate terminal to the cathode terminal. This behavior is indicated by the thyristor’s circuit symbol:

Furthermore, the device continues to conduct current from anode to cathode even after the trigger current is removed, as follows: (1) a voltage pulse that exceeds the thyristor’s threshold voltage is applied to the gate; (2) the resulting gate-to-cathode current triggers the device, such that it conducts current from anode to cathode; (3) if this anode-to-cathode current exceeds the device’s specified “latching current,” it will continue to conduct after the gate voltage (and hence the gate current) returns to zero; (4) conduction ceases when the anode-to-cathode current falls below the device’s specified “holding current.”

A triac is essentially a bidirectional thyristor. It operates according to the same principles but can conduct current flowing from MT2 to MT1 or from MT1 to MT2:

The configuration used in this project has MT1 connected to ground, with the triggering current flowing from the gate to MT1.

The foregoing discussion demonstrates why the triac is such a handy component for controlling alternating current flowing through a load (in this case, an incandescent lamp). A short trigger pulse, driven directly by a GPIO pin, turns on the triac at some point during the first half cycle of the AC waveform. The triac continues to conduct until the load current is less than the holding current. Then another trigger pulse, with the same delay relative to zero cross as the first pulse, causes the triac to conduct during the second half cycle. (Refer to the scope traces later in the article if you are having troubling visualizing this.) The delay between zero cross and trigger pulse determines the portion of the AC waveform during which the triac is conducting, and this in turn determines the average power delivered to the load. With a microcontroller this delay can be controlled with high precision. By the way, if you are wondering why this on-off switching behavior does not lead to undesirable flickering, remember that an incandescent bulb generates light because the filament is hot—the temperature does not change as rapidly as the current, and thus the lamp effectively “smooths out” the relatively high-frequency variations in the current flowing through the filament.

The triac used in this project is part number Z00607 from STMicroelectronics. This device is intended for low-power applications. It can be triggered with gate current as low as 5 mA, and its latching and holding current are 10 mA and 5 mA, respectively.   

Circuit

Here is the schematic for the lamp-control portion of this project:

R1 is a current-limiting resistor; it is sized to ensure that the GPIO pin sources well over the minimum gate triggering current (i.e., 5 mA). The voltage drop from gate to MT1 was measured at 360 mV, so (3.3 V - 0.36 V)/330 Ω = 8.9 mA. 

And here is the breadboard implementation:

There are two bulbs instead of one because the particular AC transformer used for this project is limited to 500 mA output current, and the additional resistance provided by the second bulb ensures that the current stays well below this maximum. The piece of black plastic prevents the lamps from illuminating the optical sensor and thereby distorting the ambient light measurements.

Firmware

The new firmware must perform two additional tasks: compute the proper delay from zero cross to trigger pulse based on the ambient light measurement, and output the delayed trigger pulse. The first task is accomplished with the following code:

Code


//convert the ADC conversion result to a current measurement
//the actual value of the resistor in the test circuit is 4.6 kOhms
ADCMeasurement = (RawADCResult*ADCFactor)/4.6;

if(ADCMeasurement >= OPTSENS_CURRENT_MAX)
	TriacGateEnableorDisable = TRIAC_GATE_DISABLE;	//lamp is off

else if(ADCMeasurement <= OPTSENS_CURRENT_MIN)
{
	TriacGateEnableorDisable = TRIAC_GATE_ENABLE;
	TriacGateDelay = TRIAC_GATE_DELAY_MIN;		//maximum lamp brightness
}

else
{
	TriacGateEnableorDisable = TRIAC_GATE_ENABLE;
	//trigger pulse delay is based on the ratio of current illuminance to maximum illuminance
	TriacGateDelay = TRIAC_GATE_DELAY_MAX * (float)ADCMeasurement/OPTSENS_CURRENT_MAX;
}

LIGHT.zip

First we need to select a maximum and minimum ambient light level: If the optical sensor indicates that the illuminance is greater than or equal to the maximum ambient light level, the triac trigger pulse is disabled and the lamp is off. If the illuminance is less than or equal to the minimum ambient light level, the room is considered to be dark and the trigger pulse delay is set to deliver maximum power to the lamp. If the illuminance is between these two values, the delay is adjusted ratiometrically—in other words, the ratio between the current illuminance and the maximum illuminance is the same as the ratio between the chosen delay and the maximum delay. A successful real-world application would require careful selection of maximum and minimum ambient light levels to ensure that the lamp is dimmed according to the needs of the occupant, and it would be beneficial to fine-tune the mathematical relationship between measured illuminance and trigger delay based on empirical observations of how a particular lighting arrangement responds to the dimming algorithm.

Keep in mind that even when the ambient light level is less than or equal to the minimum, the trigger pulse delay is not set to zero. If the pulse is generated immediately after the AC waveform crosses 0 V, the load current might not exceed the triac’s latching current while the gate triggering current is flowing. Maintaining a minimum trigger pulse delay ensures proper triac latching behavior. 

To accomplish the second task (generating the delayed trigger pulse), we configure Timer2 for a clock period of approximately 500 ns and enable the Timer2 interrupt.

Code


//-----------------------------------------------------------------------------
// INT0_ISR
//-----------------------------------------------------------------------------
SI_INTERRUPT (INT0_ISR, INT0_IRQn)
{
	//the interrupt flag is cleared by hardware
	FallingEdgeCount++;

	SFRPAGE = TIMER2_PAGE;
	TMR2 = 0xFFFF - TriacGateDelay;		//Timer2 will overflow at the end of the delay period
	TMR2CN0_TR2 = TriacGateEnableorDisable;		//start Timer2, if lamp illumination is needed
}


//-----------------------------------------------------------------------------
// INT1_ISR
//-----------------------------------------------------------------------------
SI_INTERRUPT (INT1_ISR, INT1_IRQn)
{
	//the interrupt flag is cleared by hardware
	RisingEdgeCount++;

	SFRPAGE = TIMER2_PAGE;
	TMR2 = 0xFFFF - TriacGateDelay;		//Timer2 will overflow at the end of the delay period
	TMR2CN0_TR2 = TriacGateEnableorDisable;		//start Timer2, if lamp illumination is needed
}


//-----------------------------------------------------------------------------
// TIMER2_ISR
//-----------------------------------------------------------------------------
//
// TIMER2 ISR Content goes here. Remember to clear flag bits:
// TMR2CN0::TF2H (Timer # High Byte Overflow Flag)
// TMR2CN0::TF2L (Timer # Low Byte Overflow Flag)
//-----------------------------------------------------------------------------
SI_INTERRUPT (TIMER2_ISR, TIMER2_IRQn)
{
	SFRPAGE = TIMER2_PAGE;
	TMR2CN0_TF2H = 0;	//clear the interrupt flag

	TMR2CN0_TR2 = 0;	//stop Timer2

	//here we output the trigger pulse (width is approximately 50 us)
	TRIAC_GATE = HIGH;
	SFRPAGE = TIMER4_PAGE; TMR4L = 0; while(TMR4L < 100);
	TRIAC_GATE = LOW;
}

AmbientLightMonitor_Part5.zip

Every time the external interrupts detect a rising or falling edge from the zero-cross detection circuit, Timer2 is loaded with (65535 - the currently chosen trigger delay). The result is that the timer overflows (causing an interrupt) at the end of the delay period, and then the trigger pulse is generated in the Timer2 ISR.

The overall functionality of the firmware is the following: An ADC conversion occurs approximately once every 31 ms (i.e., 32 samples per second). Every conversion result is interpreted as the amount of output current from the optical sensor, and then this current measurement is processed by the if-else routine shown above to determine whether the trigger pulse is needed and, if so, what the delay should be. The trigger delay is adjusted at this same rate (32 times per second); this provides a nice smooth response for demonstration purposes, but of course such rapid and oversensitive changes in lamp brightness would be undesirable in a real-world application. The LCD is updated once per second with the most recent value of the optical sensor output current so you can see how the measured illuminance affects the brightness of the lamp.

In the two following images, the blue trace is the trigger pulse and the yellow trace is the voltage across the triac. Before the trigger pulse, the full AC voltage is present across the triac—it is not yet conducting, and thus it is effectively an open circuit. After the trigger pulse until the end of the half cycle, the triac is conducting and thus has only a small conduction-state voltage drop (about 1 V).

Here the triac is conducting for approximately 40% of the AC half cycle, so this corresponds to moderate ambient light level (and consequently moderate lamp brightness).

 

Now the triac is conducting for most of the AC half cycle, which means that a low ambient light level has caused the firmware to increase the brightness of the lamp.

Video

This video shows the lamp brightness reacting to varying illuminance as an LED flashlight is directed closer to and farther from the optical sensor.

Video

This video demonstrates how the position of the trigger pulse (relative to AC zero cross) varies as an LED flashlight is directed closer to and farther from the optical sensor.

 

Give this project a try for yourself! Get the BOM.