Hi folks,
A friend and myself are trying to implement the following project:
http://playground.arduino.cc/Main/ACPhaseControl
We've checked the wiring several times - it's exactly like in the schematic. The code is as well - we didn't change it to 50Hz yet (Austria 230V/50Hz) but since that should just affect the timing we thought that shouldn't be relevant right now. At the moment we're working on a prototyping board - yes, I know, it's not terribly safe and we're just using it for testing purposes, we'll improve safety as soon as it works.
For easier viewing I'll add the schematic and code from the above website:
// AC Control V1.1
//
// This Arduino sketch is for use with the heater
// control circuit board which includes a zero
// crossing detect function and an opto-isolated TRIAC.
//
// AC Phase control is accomplished using the internal
// hardware timer1 in the Arduino
//
// Timing Sequence
// * timer is set up but disabled
// * zero crossing detected on pin 2
// * timer starts counting from zero
// * comparator set to "delay to on" value
// * counter reaches comparator value
// * comparator ISR turns on TRIAC gate
// * counter set to overflow - pulse width
// * counter reaches overflow
// * overflow ISR turns off TRIAC gate
// * TRIAC stops conducting at next zero cross
// The hardware timer runs at 16MHz. Using a
// divide by 256 on the counter each count is
// 16 microseconds. 1/2 wave of a 60Hz AC signal
// is about 520 counts (8,333 microseconds).
#include <avr/io.h>
#include <avr/interrupt.h>
#define DETECT 2 //zero cross detect
#define GATE 9 //TRIAC gate
#define PULSE 4 //trigger pulse width (counts)
int i=483;
void setup(){
// set up pins
pinMode(DETECT, INPUT); //zero cross detect
digitalWrite(DETECT, HIGH); //enable pull-up resistor
pinMode(GATE, OUTPUT); //TRIAC gate control
// set up Timer1
//(see ATMEGA 328 data sheet pg 134 for more details)
OCR1A = 100; //initialize the comparator
TIMSK1 = 0x03; //enable comparator A and overflow interrupts
TCCR1A = 0x00; //timer control registers set for
TCCR1B = 0x00; //normal operation, timer disabled
// set up zero crossing interrupt
attachInterrupt(0,zeroCrossingInterrupt, RISING);
//IRQ0 is pin 2. Call zeroCrossingInterrupt
//on rising signal
}
//Interrupt Service Routines
void zeroCrossingInterrupt(){ //zero cross detect
TCCR1B=0x04; //start timer with divide by 256 input
TCNT1 = 0; //reset timer - count from zero
}
ISR(TIMER1_COMPA_vect){ //comparator match
digitalWrite(GATE,HIGH); //set TRIAC gate to high
TCNT1 = 65536-PULSE; //trigger pulse width
}
ISR(TIMER1_OVF_vect){ //timer1 overflow
digitalWrite(GATE,LOW); //turn off TRIAC gate
TCCR1B = 0x00; //disable timer stopd unintended triggers
}
void loop(){ // sample code to exercise the circuit
i--;
OCR1A = i; //set the compare register brightness desired.
if (i<65){i=483;}
delay(15);
}
OUR PROBLEM IS: The Zero Cross detection doesn't work. We've checked the interrupt-routine and it does do what it's supposed to do - when it sees a rising edge it is triggered (5V cable directly to arduino pin-2). To test this we just had an integer counting up inside the interrupt routine as follows:
void zeroCrossingInterrupt(){ //zero cross detect
TCCR1B=0x04;
TCNT1 = 0;
j++; //our integer counter
}
In the main loop we had this integer printed via Serial.print() to check if the value is rising steadily. I realize that the Serial.print is probably too slow to catch all the values, but it should at least prove that the value is changing, e.g. rising. (+50 per second shouldn't overflow it soon). The integer was initialized globally with value 0.
As I understand the circuit, the "usual" state of the DETECT-pin (interrupt pin 2, in code 0 for some reason -- IRQ0 -- but it works anyway) is GND. As soon as the optocoupler sees a phase change the driving voltage is too low to trigger the diodes on the other end - so the internal pull-up of the arduino should pull the DETECT-pin to high. (btw we tried an external 8.2k-pullup as well, same result). The interrupt routine should trigger the timer then AND our variable j++. It doesn't though - j remains at 0 as it was initially. The timer isn't triggered either since there's no ouput (that part of the circuit works).
What's sort of weird is that the value DOES change when we unplug the 230V-cable from the circuit - it jumps to some random value (45 or so) - I guess unplugging means a few on-offs. So some form of detection between no voltage and voltage is there - which means it shouldn't be completely bricked (I hope).
any help would be great, we're out of ideas.
best regards,
wiseman
p.s. the schematic doesn't mention that it is important that the MT2 pin of the triac has to be the one connected to the triac-driving-opto, NOT MT1 - which we didn't know at first and only found out after some research. That part of the circuit works (we can turn a lamp on and off).