Triac not switching on negative AC cycle

Hello,

I am having trouble with some triacs that I am using to drive a heater. They seem to be blocking the negative portion of the AC cycle.

I'm following the AC phase control guide Arduino Playground - ACPhaseControl to try and control some Triacs that will power a 3-phase 16 kW heater.

I'm effectively using the below circuit in triplicate.

For testing, I'm just using 24 V single phase and firing simultaneously but obviously will eventually move to 3-phase. I tested my circuit on a breadboard and everything worked fine but now I've moved it onto protoboard and suddenly I'm losing the bottom half of the AC cycle as though the triac is rectifying it.

I'm using a Mega 2560 and timer 3, 4 & 5 to control the pulses. In the code, I'm using a potentiometer to vary the duty cycle.

I have attached oscilloscope screenshots of what I'nm seeing also.

Yellow (TOP) : 24V 50 Hz AC mains
Cyan (SECOND) : Triac output power
Purple (THIRD) : MOC3052 output gate drive signal
Blue (FOURTH) : Zero-cross detection signal from H11AA1

In the second screenshot, it is the exactly same except I am showing the Arduino firing signal going into the MOC3052 as opposed to the output from it.

Triac Datasheet
H11AA1 Datasheet
MOC3052 Datasheet

I will attach code in next comment.

Thanks for any help you can provide,

Barry

Code here:

//                                                                                                 VARIABLE INITIALIZATION 
//---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
int Zero_Cross_Detect1 = 2;                                               //(INPUT) Zero-crossing event detection output coming from H11AA1 IC. This output is being read on pin 2 of the Mega2560 (interrupt 0)
int Zero_Cross_Detect2 = 3;                                               //(INPUT) Zero-crossing event detection output coming from H11AA1 IC. This output is being read on pin 3 of the Mega2560 (interrupt 1)
int Zero_Cross_Detect3 = 21;                                              //(INPUT) Zero-crossing event detection output coming from H11AA1 IC. This output is being read on pin 21 of the Mega2560 (interrupt 2)

int GateFire1 = 9;                                                        //(OUTPUT) Triac #1 gate firing signal is on pin 9
int GateFire2 = 24;                                                       //(OUTPUT) Triac #2 gate firing signal is on pin 10
int GateFire3 = 5;                                                        //(OUTPUT) Triac #3 gate firing signal is on pin 11

int FiringPulseWidth = 8;
int i;

//---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
//                                                                                                         SETUP
//---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
void setup() 
{
Serial.begin(9600);                                                       //Start serial communication at 9600 baud
  
pinMode(Zero_Cross_Detect1,INPUT);                                        //Zero_Cross_Detect1 (Pin 2) is an input
pinMode(Zero_Cross_Detect2,INPUT);                                        //Zero_Cross_Detect2 (Pin 3) is an input
pinMode(Zero_Cross_Detect3,INPUT);                                        //Zero_Cross_Detect3 (Pin 21) is an input
digitalWrite(Zero_Cross_Detect1,HIGH);                                    //Pull Pin 2 high using internall pull-up
digitalWrite(Zero_Cross_Detect2,HIGH);                                    //Pull Pin 3 high using internall pull-up
digitalWrite(Zero_Cross_Detect3,HIGH);                                    //Pull Pin 21 high using internall pull-up
pinMode(GateFire1,OUTPUT);                                                //GateFire1 (Pin 9) in an output
pinMode(GateFire2,OUTPUT);                                                //GateFire2 (Pin 10) in an output
pinMode(GateFire3,OUTPUT);                                                //GateFire3 (Pin 11) in an output


attachInterrupt(0,ZeroCrossingInterrupt1,RISING);                         //Attach zero-crossing event on pin 2 to interrupt 0
attachInterrupt(1,ZeroCrossingInterrupt2,RISING);                         //Attach zero-crossing event on pin 3 to interrupt 1
attachInterrupt(2,ZeroCrossingInterrupt3,RISING);                         //Attach zero-crossing event on pin 21 to interrupt 2

//                                                                         TIMER 3,4,5 SETUP  (REF: http://playground.arduino.cc/Main/ACPhaseControl )
//---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

OCR3A = 100;                                                              //Initialize the comparator
TIMSK3 = 0x03;                                                            //Enable comparator A and overflow interrupts
TCCR3A = 0x00;                                                            //Timer control registers set for
TCCR3B = 0x00;                                                            //Normal operation, timer disabled

OCR4A = 100;                                                              //Initialize the comparator
TIMSK4 = 0x03;                                                            //Enable comparator A and overflow interrupts
TCCR4A = 0x00;                                                            //Timer control registers set for
TCCR4B = 0x00;                                                            //Normal operation, timer disabled

OCR5A = 100;                                                              //Initialize the comparator
TIMSK5 = 0x03;                                                            //Enable comparator A and overflow interrupts
TCCR5A = 0x00;                                                            //Timer control registers set for
TCCR5B = 0x00;                                                            //Normal operation, timer disabled
  
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
//                                                                                              INTERRUPT SERVICE ROUTINES
//---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------


void ZeroCrossingInterrupt1()
{
TCCR3B=0x04;                                                               //Start timer with divide by 256 input
TCNT3 = 0;                                                                 //Reset timer - count from zero
}


void ZeroCrossingInterrupt2()
{
TCCR4B=0x04;                                                               //Start timer with divide by 256 input
TCNT4 = 0;                                                                 //Reset timer - count from zero
}


void ZeroCrossingInterrupt3()
{
TCCR5B=0x04;                                                               //Start timer with divide by 256 input
TCNT5 = 0;                                                                 //Reset timer - count from zero
}

Remaining code:

//---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
//                                                                                         TIMER 3,4,5 INTERRUPT SERVICE ROUTINES
//---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------


//TIMER 3 (Triac 1)
//----------------------------------------------------------------------
ISR(TIMER3_COMPA_vect)                                                     //Comparator match
{ 
digitalWrite(GateFire1,HIGH);                                              //Set triac gate to high
TCNT3 = 65536-FiringPulseWidth;                                            //Trigger pulse width
}

ISR(TIMER3_OVF_vect)
{                                                                          //Timer3 overflow
  digitalWrite(GateFire1,LOW);                                             //Turn off triac gate
  TCCR3B = 0x00;                                                           //Disable timer to stop unintended triggers
}
//----------------------------------------------------------------------


//TIMER 4 (Triac 2)
//----------------------------------------------------------------------
ISR(TIMER4_COMPA_vect)                                                    //Comparator match
{                                                                         
digitalWrite(GateFire2,HIGH);                                             //Set triac gate to high
TCNT4 = 65536-FiringPulseWidth;                                           //Trigger pulse width
}

ISR(TIMER4_OVF_vect)
{                                                                         //Timer4 overflow
  digitalWrite(GateFire2,LOW);                                            //Turn off triac gate
  TCCR4B = 0x00;                                                          //Disable timer to stop unintended triggers
}
//----------------------------------------------------------------------


//TIMER 5 (Triac 3)
//----------------------------------------------------------------------
ISR(TIMER5_COMPA_vect)                                                    //Comparator match
{                                                                       
digitalWrite(GateFire3,HIGH);                                             //Set triac gate to high
TCNT5 = 65536-FiringPulseWidth;                                           //Trigger pulse width
}

ISR(TIMER5_OVF_vect)
{                                                                         //Timer5 overflow
  digitalWrite(GateFire3,LOW);                                            //Turn off triac gate
  TCCR5B = 0x00;                                                          //Disable timer to stop unintended triggers
}


//----------------------------------------------------------------------


//---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
//                                                                                                         MAIN LOOP
//---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
void loop() 
{

int val = analogRead(A0);
val = constrain(val, 20, 1000);
val = map(val,0,1023, 0, 615);
Serial.println(val);  
  
i--;
OCR3A = val;                                                               //Set the compare register for the desired power output
if (i<10){i=615;}                      

OCR4A = val;                                                               //Set the compare register for the desired power output
if (i<10){i=615;}                      

OCR5A = val;                                                               //Set the compare register for the desired power output


if (i<10){i=615;}                      
delay(3);

  
}

Hi all,

I solved the problem.

In the above schematic, I scaled down the resistors except for the MOC3052 drive resistor (as I'm using 24V and not 240V). Reducing the gate resistance to ~190 ohms greatly improved my waveform and also fixed the bottom half of the AC cycle problem.

Barry

I am having trouble understanding why the signal from the zero crossing detector is the digital output and the signal to the triac controller is the digital input.

michinyon:
I am having trouble understanding why the signal from the zero crossing detector is the digital output and the signal to the triac controller is the digital input.

One board's input is another board's output...

I am using same circuit but facing some problem in zero cross detection, its constantly giving me 2.5 V at output and does 15 k resistors used have to of higher wattage rating than 2W?? coz they got black when connected but still working.

Triacs are often fairly assymetrical in the minimum gate current needed to trigger
the device - the moral is ensure the device gets above the minimum required current
on both half cycles - ie read the datasheet and do the calculations....