Single channel Triac AC switch

smallTriacSwitch .

In order to switch some floodlights by my Arduino, the small switch circuits I built around a 39mf22 were just not man enough to handle the current needed, so I decided to build a switch with discrete components around a TRIAC. Now these circuits are very easy and come a dime a dozen on the internet: just google for TIC206 or MOC3041 and you have lots of choice. The reason I make an instructable for such a simple circuit is to also provide a print design for those people to lazy or unable to make a design themselves 🙂

But let me start with a disclaimer/warning: This circuit is connected to a mains voltage that can kill you. If you do not know what you are doing then do not build this circuit.. Do not touch it when it is connected to the mains. The metal plate of the Triac is connected to it’s Terminal 2 and thus to the mains voltage. When in use, do not touch that plate to feel how warm it gets. Put this circuit in a proper container.

Materials List
Triac TIC206  €1.20
MOC3041 €0.65
DIL 6 IC foot €0.15
LED €0.15
Resistor 220 Ohm 1/4 Watt €0.10
Resistor 470 Ohm 1/4 Watt €0.10
Connector €0.20
Piece of scrap PCB 23×43 mm
That is a total of €2.55

The links are just there to illustrate what I mean and to give a price indication. I have no links to that webshop other than that i use it and am satisfied with it.
It is also possible to use the considerably cheaper BT136-600, that like the TIC206 can deliver 4Amps, but it’s gate current is a hefty 35-70mA as compared to the TIC206’s 5mA. If a BT136 is used, the 470Ohm resistor may need to be a bit smaller (150 Ohm)

additionally you may need:
capacitor 10-100nF 400V
resistor 39-100 Ohm
resistor 330 Ohm
The PCB is here.
and mirorred here.

The circuit
The main components in this circuit are the MOC3041 optocoupler and the TIC206 TRIAC (M or D version). I have chosen for a MOC3041 because it has a zero crossover circuit in the chip, ensuring smooth switching. The TIC 206  is a triac that has a relatively sensitive gate.
The output from an Arduino or other uP  is led to the MOC3041 via a 22o Ohm resistor and an LED. This way one can see for sure if there is current flowing through the optocoupler. 
The gate of the thyristor is fed  from a 470 Ohm resistor that connects through the MOC3041 optocoupler
On the printed circuit board there is room for a 330 Ohm resistor (labelled with a ‘*’). If one uses the TIC206 TRiac this resistor is not necessary. Some other thyristors however may need that resistor in order to start.
As I am switching a lamp, I have no use for a snubber circuit (formed by the 100R resistor and C1). However, if you switch inductive loads you will need one. The values of the resistor and capacitor may vary depending on your situation but a proper way to start would be a 100 Ohm resistor and a 100nF capacitor. The PCB offers holes at various distances, suitable for different sizes of capacitors.


Download the PCB design(s) above and use your favorite method to etch your PCB. With regard to the design: the pcb picture in this ibble is seen from the component side: The copper traces thus are actually seen as if you are looking through the board. That is why the writing is in reverse. This design is suitable for a direct toner transfer
If you use the mirrorred design, the writing  is in fact not mirrorred. 
I have used the non mirrorred design for a direct toner transfer (printing it on glossy paper and ironing it on a copperplate)  and that works well. Etching in Hydrochloric acid and Hydroyperoxide.

There is only a two pole connector on this PCB that can be thought of as a switch, interrupting the ‘Live’ line of a connection, just like a regular switch. The figure shows the proper way to connect it according to EU codes: Blue is neutral, brown is live black is switched and yellow green is earth. Outside the EU there are different colour codes.




here. Mirrored here.

E. ten Winkel



Switching an AC load with an Arduino is rather simple: either a mechanical Relay or a solid state relay with an optically isolated Triac.
It 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 it is 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 it is 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.

An example of  a zero cross detection circuit

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. sine
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 and a 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. it is 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 4N25 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 saturation.

This is the complete circuit of the dimmer

All one needs then is the software. Below a piece of demo software. Due to use of ‘delay()’ it does not work efficiently meaning that the microcontroller can’t do much else, but if you just want to dim a light that is fine.

AC Voltage dimmer with Zero cross detection
Author: Charith Fernanado
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++)

Code below uses the timer function instead of delays


For an MQTT version see here


Print design.

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 secondary side of the transformer.

A possible circuit could look like this:


Using the dimmer with a fan
A question I often get is if this circuit can be used with a (ceiling)fan. Well a Triac is not particularly good at regulating inductive loads and the speed of many AC-motors in fact set by the frequency of the grid and the number of poles.  (rmp=120*f/p). However, the Shaded-pole motor can be regulated with a Triac and the shaded pole motor is often (but not always as the PSC motor is common too) found in fans. Check here.

A tachometer


int val;
long last=0;
int stat=LOW;
int stat2;
int count=0;
int sens=75;    // indicates the limit reading between dark and light,              // it has to be tested as it may change
                // acording on the              
                // distance the leds are placed.
int nBlades=2;  // the number of blades of the propeller
int miliseconds=500; // the time it takes each reading

void setup() 

void loop() 
{   val=analogRead(0);
   digitalWrite(13,stat); // the led on pin 13 shows
                          // the state of the circuit.
   if(stat2!=stat){       // counts when the state changes, 
                          // thats from (dark to light) or 
                          // from (light to dark).  
     double rps=((double)count/nBlades)/2.0*1000.0/miliseconds;  
     double rpm=((double)count/nBlades)/2.0*60000.0/(miliseconds);
     Serial.print("  RPS ");
     Serial.print(" RPM");
     Serial.print("  VAL ");

See also “Reading RPM

On old Buzzer for the Arduino

pcb-speakerFor a project –that I will publish in the future- I needed some form of audio indication, a warning signal if you please.

I had a small 8 Ohm 0.7 Watt speaker, but that needs a resistor to be connected to the arduino pins to prevent too much current being drawn. Even if  a max current of 40 mA would flow through the speaker (with a 242 ohm serial resistor) that would produce a sound at a 128mW level. Not really loud. Add to that that ideally also a capacitor needs to be used to protect the speaker from DC, that will seriously limit its use as a warning signal.

cmb-06Of course I could use an amplifier, such as an LM386 (that conveniently can deliver 0.7Watt)  or just a 1 transistor amplifier, but I figured a buzzer might be the best solution. Piezzo buzzers are quite commonplace, but I remembered that I still had an unused buzzer that I bought perhaps 30 years ago and never used. That buzzer turned out to be better than I could have hoped for.

I would be hesitant to attach a buzzer directly to a pin of the arduino, so I considered ofcourse using a transistor. s it turned out, I did not need one.

The old buzzer that I had for some reason that I did not understand when I bought it,  needed two pins to be tied to ‘+’ and one to the ‘–’.

The buzzer was a CBM-06 from Star industries and a quick search showed that it was only recently discontinued. Out of curiosity I started to look for a datasheet and luckily found some info hidden in another buzzer datasheet.

The CBM-06 seemed to operate on 3-8 volts and its average current draw is 23 mA. However, it needs at least 2-3 times that amount to be available for peak draw and 70mA is just too much for the arduino pins, so I already saw me use a transistor again. Luckily however, I caught a small applicationsheet that proved to be quite helpful. It is pretty loud as it has an output of 76 decibel at 10 cm.


The applicationsheet (if one may call it that way), finally explained to me why I had to connect 2 legs of the buzzer to ‘+’. One of the legs turned out to e a ‘control’ pin. Foratunately, some 30 years ago I had scratched the pins to use in the casing, so I still could see what the function of the pins was.
The middle figure (no 10) in the above picture caught my interest as I figured the ‘control’ pin needed a lot less current to activate the buzzer than the 23-70mA current draw for producing the sound.
So I made a quick setup: + and – connected to the proper supply lines and then 5 Volts fed into the C pin. That worked as I had expected ofcourse because that is how I always had used it.

However, connecting the C pin via a 330 ohm resistor worked as well, proving that a much smaller current suffices to trigger the Buzzer than the 23-70 mA to produce the sound, as only a maximum of 3 mA will flow from the Arduino pin, while the main current is taken directly from the supply line.