0% found this document useful (0 votes)
1K views

Phase Control (Dimmer) Using Arduino

This document contains code for controlling a TRIAC phase-angle controller using an Arduino. It defines digital pins and analog inputs for the circuit connections. Interrupt routines are used to detect zero crossings of the AC voltage and trigger the TRIAC at a timed delay after each zero crossing to regulate power to a load. The delay is mapped from an analog sensor input to vary the firing phase angle and control the output voltage.

Uploaded by

yb3hgf
Copyright
© Attribution Non-Commercial (BY-NC)
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
1K views

Phase Control (Dimmer) Using Arduino

This document contains code for controlling a TRIAC phase-angle controller using an Arduino. It defines digital pins and analog inputs for the circuit connections. Interrupt routines are used to detect zero crossings of the AC voltage and trigger the TRIAC at a timed delay after each zero crossing to regulate power to a load. The delay is mapped from an analog sensor input to vary the firing phase angle and control the output voltage.

Uploaded by

yb3hgf
Copyright
© Attribution Non-Commercial (BY-NC)
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 3

digital pin 8 digital pin 9 (PWM) digital pin 10 (PWM) digital pin 11 (PWM) digital pin 12 digital pin 13

14 15 16 17 18 19 9 10 23 24 25 26 27 28 1

PB0/ICP1/CLKO/PCINT0 PB1/OC1A/PCINT1 PB2/SS/OC1B/PCINT2 PB3/MOSI/OC2A/PCINT3 PB4/MISO/PCINT4 PB5/SCK/PCINT5 PB6/TOSC1/XTAL1/PCINT6 PB7/TOSC2/XTAL2/PCINT7 PC0/ADC0/PCINT8 PC1/ADC1/PCINT9 PC2/ADC2/PCINT10 PC3/ADC3/PCINT11 PC4/ADC4/SDA/PCINT12 PC5/ADC5/SCL/PCINT13 PC6/RESET/PCINT14 ATMEGA168P

PD0/RXD/PCINT16 PD1/TXD/PCINT17 PD2/INT0/PCINT18 PD3/INT1/OC2B/PCINT19 PD4/T0/XCK/PCINT20 PD5/T1/OC0B/PCINT21 PD6/AIN0/OC0A/PCINT22 PD7/AIN1/PCINT23 AREF AVCC

2 3 4 5 6 11 12 13 21 20

digital pin 0 digital pin 1 digital pin 2 digital pin 3 (PWM) digital pin 4 digital pin 5 (PWM) digital pin 6 (PWM) digital pin 7

analog input 0 analog input 1 analog input 2 analog input 3 analog input 4 analog input 5

A B C D

VAC digital pin 2 digital pin 12 VLoad

VAC VAC

U1
ZC 6 5 digital pin 2 4
50%

220V 1 30k 1W 2 1N4001 10M 30k 1W

4N25 analog input 0 TRIAC-fire 1 digital pin 4 50

220V

U2

6 390

2 MOC3021

4 VLoad

VLoad

#define TRIAC_Fire PORTD4 int FiringDelay; int PhaseOFFSET; unsigned long Fire; unsigned long Periode; unsigned long LASTtick; unsigned long ZeroCrossTick; volatile boolean ZeroCrossFlag = false; void setup() { pinMode(TRIAC_Fire, OUTPUT); PORTD &= ~_BV(TRIAC_Fire); // DigitalPin 4 LOW // internal Pull-Up on INT0 (digital pin 2) // and connected to ZC circuit pinMode(2, INPUT_PULLUP); // EICRA = External Interrupt Control Register A, // to control bits for interrupt sense control // it's value is set by ICSx1 and ICSx0 // ICSx1 ICSx0 Result // 0 0 the low level generates an interrupt request // 0 1 any logical change generates an interrupt request // 1 0 the falling edge generates an interrupt request // 1 1 the rising edge generates an interrupt request EICRA = 0x02; // INT0 the falling edge on ZC // EIMSK = External Interrupt Mask Register EIMSK = 0x01; // enable INT0 ZeroCrossFlag = false; while (!ZeroCrossFlag); ZeroCrossing(); while (!ZeroCrossFlag); // performed twice to measure the period ZeroCrossing(); } void loop() { byte i; unsigned long To_OverFlow; // anticipation of overflow (go back to zero) of micros() function To_OverFlow = 0xFFFFFFFF-(Periode); while (ZeroCrossTick > To_OverFlow) { if (ZeroCrossFlag) { ZeroCrossing(); if (ZeroCrossTick < To_OverFlow) { while (!ZeroCrossFlag); ZeroCrossing();

} } } Fire = ZeroCrossTick + FiringDelay; for (i=0; i<2; i++) { while (micros() < Fire); PORTD |= _BV(TRIAC_Fire); // TRIAC fire ON delayMicroseconds(10); PORTD &= ~_BV(TRIAC_Fire); // TRIAC fire OFF Fire += PhaseOFFSET; } while(!ZeroCrossFlag); ZeroCrossing(); } // end loop ISR(INT0_vect) { ZeroCrossFlag = true; } void ZeroCrossing() { ZeroCrossTick = micros(); ZeroCrossFlag = false; Periode = ZeroCrossTick-LASTtick; LASTtick = ZeroCrossTick; PhaseOFFSET = Periode/2; FiringDelay = 10 * map(analogRead(0), 0, 1023, 1000, 0); }

You might also like