In Depth Look at AC Power Control With Arduino
In Depth Look at AC Power Control With Arduino
with Arduino
by Lewis Loflin
Fig. 1
Fig. 1 shows the 5-volt power supply for Arduino but includes blocking diode D2. On
the cathode side we have filtered DC which is regulated to 5-volts through U2. On
the Anode side we have unfiltered raw 120 Hz DC going to the LED in the 4N25
opto-coupler. The output from the photo-transistor collector goes to digital pin 2 of
Arduino to interrupt 0. Potentiometer R3 goes analog pin 0 and is used to calculate
the time delay for the triac firing pulses.
Fig. 2
Fig 2 shows the relationship of the zero-crossing pulse with the AC sine wave. By
detecting the pulse and programming a delay one can control the power output level
to a AC load.
Fig. 3
Fig 3 shows the triac firing circuit. The MOC3011 opto-coupler uses a photo triac as
opposed to a transistor. Pulses synchronized to the AC sinewave half-cycle are
output from Arduino digital pin 5 to the LED in the MOC3011, which also serves to
isolate the high voltage AC from the low-voltage components.
Pressing the power switch will enable trigger pulses to the MOC3011 while the LED
on digital pin 12 is a power on indicator. C1 and R6 form a snubber circuit for
inductive loads. Without a snubber switching noise from inductive loads will cause
miss-firing of the triac.
/*
Purpose: to detect zero crossing pulse at
INT0 digital pin 2, which after delay
switches on a triac.
Power output to triac activated by external switch.
*/
#define triacPulse 5
#define SW 4
#define aconLed 12
int val;
void setup() {
pinMode(2, INPUT);
digitalWrite(2, HIGH); // pull up
pinMode(triacPulse, OUTPUT);
pinMode(SW, INPUT);
digitalWrite(SW, HIGH);
pinMode(aconLed, OUTPUT);
digitalWrite(aconLed, LOW);
}
void loop() {
// check for SW closed
if (!digitalRead(SW)) {
// enable power
attachInterrupt(0, acon, FALLING);
// HV indicator on
digitalWrite(aconLed, HIGH);
} // end if
else if (digitalRead(SW)) {
detachInterrupt(0); // disable power
// HV indicator off
digitalWrite(aconLed, LOW);
} // else
} // end loop