You are on page 1of 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