120V Zero-Crossing Triac IC

Go To Last Post
11 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I have a moc3042 hooked up like figure 14

I realize its just an opto-isolator and in order to do phase control I need to know when the zero cross is so I trigger at the same time always. Problem is how???

I would prefer to use a 555timer if possible but I do have a ATTiny on hand with an ADC I could hook up with a pot if I needed to.

How do I sync with the AC wave to do proper phase control??

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You want phase control... this is not the right choice of opto triac.
You want block control... go with this device.

This device isintended to be used in block control mode and incorporates zero crossover detcting circuitry to allow for simplified logic level firing.

Use something like MOC3021 to implement phase control.
You could achive phase control within the 555 timer but however you do do it.. you will have to extract a zero crossing marker.

The solution to that will depend on what you want to do. Can You tell us abit more about the intent of the control?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I plan on this being a heater control for my reflow oven as well as a variac for general use. If it works well I have a small watchmakers lathe I would like to speed control the DC motor on as well.

I am using 22A SCR's with a heatsync so I have no worries about loads. Currently with the MOC3042 the way I have it now I am using it as a solid state relay, which works well as a switch but thats all its good for.

I compared the two datasheets, the MOC3021 talks about a varied pulse width to the emitter but mechanically they appear the be exactly the same driver.

I was thinking I could setup a voltage divider(470k & 10k) and when the output is zero that means I'm at the zero point and to wait x time before triggering the triac. Only problem is I can't hook that voltage divider to the avr without frying it.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

OK.. we are making some progress.

While the two appear mechanically identical functionaly they are like auto and stick shifts ( forgive my assumption You are an american ).

The component You wanted to use incorporates a zero crossoverdetector which when enabled via inbuilt LED will switch the triac ONLY when zero cross over detected. This is not phase control. This is BLOCK control. By BLOCK i mean a block or a chunk of power starting at zero cross over voltage and finishing at zero crossover current. The implication of this is that the switching on and off ( comutation of ) the triac creates minimum switching noise (transients) on the line.

Phase control is being able to trigger the triac at any point in the waveform and THEN waiting for triac to commutate off as the current through the triac drops to zero.
To achieve phase control you need to arrange for a sample of the mains voltage ( to detect zero cross over ) and then reference the triggering after the zero voltage cross over has been detected but before the next zero cross over instance.The sooner the triggering occurs after a zero cross over takes place the more power will be delivered to the load.

You can derive the zero cross over signal either by using a resistive divider as You have indicated.
You can use a stepdown transformer.
You could use a reactive ( capacitive/inductive/resistive combination) voltage divider.

Make sure You account for phase shift in which ever way You derive zero cross over point.

A circuit schematic showing a hardware approach attached.

Attachment(s): 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hello again.

I have made a zero crossing setup with my Tiny25 and it triggers the INT0 interrupt on the falling edge of AC. Its 100% reliable and is bang on the zero point. I had to add an offset to fire the triac a bit later as you cannot turn it on at precisely 0v

My main loop is a for loop with a nop so it does nothing, everything is done in ISR:

ISR(INT0_vect) {
	trigger();
}

ISR(ADC_vect) { 
	z_off = ADCH;
}

void trigger() {
	uint16_t i;
	_delay_us(25); // Initial Conduction Offset (25 = 0deg)

	for(i=0; i<(z_off * 2); i++) // Fireing Delay
		_delay_us(1);

	PORTB |= (1<<4); // Neg Phase Fire
	_delay_us(50);
	PORTB &= ~(1<<4);

	_delay_us(980); // Delay 1/2 Cycle

	PORTB |= (1<<4); // Pos Phase Fire
	_delay_us(50);
	PORTB &= ~(1<<4);
}

The ADC value does not exactly reach to cutoff as z_off * 2.5 would be perfect but I'm just testing and don't care at the moment.

The issue I am having is as you see in the picture the triac is being fired at the peak of the sine wave but my output voltage is 110V at this location. Firing at 1deg = 21V, 90deg = 110V, 170deg = 35V. This is strange as the output voltage should do down as the firing angle goes up!

Anybody know whats up?

NOTE:
I put my scope across the AC load I am controlling and it is not a pretty ac wave with a bite out of it. Its quite swoopy like their a LC filter in place even though its actually a 5W ceramic resistor.

Attachment(s): 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Use two off X10 probes in a differential configuration across the load just to make sure You are measuring the correct waveform.

Please show the schematic of the INT0 interface to the mains voltage.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I don't have a schematic but I will explain what I have done.

CCT:
- 120V to a 1VA 6V transformer (from a clock radio)
- Single 1N4004 into regulator and 330uF cap give me 4.88V and very clean.
- 4.88V to micro Gnd as return to transformer

- 6VAC (before diode) is fed to the center point of two clamping diodes (one cathode to 4.88V and one anode to Gnd) through a 1Meg ohm resistor. this is the input to INT0

I got the setup from an application note using the avr's esd protection diodes to clamp the voltage but decided to use external diodes instead.

Here is a video of the gate input and then the AC load:
http://www.box.net/shared/8xgp1z1crb

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Your zerocrossover circuit will not give You each and every instance of zero cross over unless ( and here You need o determine if this is so since I am not familiar witht he micro You are using ) INT0 is edge sensitive both rising and falling edge.
If INT0 is not edge sensitive to both edges You need to alter your circuit.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I chose INT0 instead of PCINT as INT0 has selectable edge triggering. In software I calculated the offset to the other half of the phase and then shift that whole unit by my firing angle.

I originally used PCINT but the triggering has not as stable and one offset was ~6deg into the phase and never less.

With either method I get the same strange results with having peak voltage at a 90deg phase angle.

The video shows what I have setup. First half you see the triggering alignment, zero pulse then the varied firing angle to 100% on. Active on both the pos and neg parts of the cycle.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Once the edge occurs You need to set Your CONDUCTION ANGLE.
Conduction angle is that part of half sinusoidal waveform from the angle during which the SCR/TRIAC conducts. Conduction angle commences some time after the zero cross over point when the trigger signal is issued to the end of the half sine period.

What is the calculated delay( in clock cycles ) between zero cross over being detected and trigger signal being generated?

Since You do not detect each and every zerocrossover how weel does Your estimate of the next zero cross over match up with reality?

What is the duration of Your trigger pulse to trigger the SCR/TRIAC?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I do not know my clocked delays as I tuned my cct with my scope and just added us delays where needed. And for some reason my delay routines are nowhere near what they are set to in the program in reality. For example my 1/2 phase offset is 980us in code but in reality its 8.33ms. To get on with the project I just divide my wanted delay by 8 and use that instead of finding the problem.

Measuring the delay from zero cross to my trigger pulse I can very it from 0 to 7ms and the pulse is 100us. I tried longer and shorter trigger pulses and any more than 100us changes nothing on the AC load output.

My math with the second zero cross over is perfect on my scope, with zero offset I can trigger a pulse at precisely zero on both crosses without measurable jitter.

I originally started this project only controlling one half the the sine wave (trigger at x point in pos cycle and then hold trigger high for all of neg cycle) but the same voltage characteristics are on the setup. at 90deg I get maximum voltage and less on either side.

// ATTINY25V
// ########## SYSTEM INCLUDES ##########
#ifndef F_CPU
	#define F_CPU 8000000UL
#endif
#include "util/delay.h"
#include 
#include 
#include 
#include "stdint.h"
#include "stdbool.h"
#include "stdio.h"
#include  

uint16_t z_off;
uint8_t pwr;
#define ON		1
#define OFF		0

void trigger();

void ioinit(void) { 
	DDRB  = 0x00;
	PORTB = 0x00;

	/* INT Setup */ 
	MCUCR |= (1<<ISC01); // ISR On Falling Edge Of INT0 (PB2)
	GIFR  |= (1<<INTF0); // Clear ISR Flag
	GIMSK |= (1<<INT0);  // Enable INT0

	/* ADC Setup */ 
  ADCSRA |= (1<<ADPS2) | (1<<ADPS1) | (1<<ADPS0); // Set ADC prescalar to 128 
  ADMUX  |= (1<<ADLAR); // Left adjust ADC result to allow easy 8 bit reading 
	ADMUX  |= (1<<MUX0) | (1<<MUX1);  // ADC3 (PB3)
  ADCSRA |= (1<<ADATE); // Set ADC to Free-Running Mode 
  ADCSRA |= (1<<ADIE);  // enable interrupt 
  ADCSRA |= (1<<ADEN);  // Enable ADC 
  ADCSRA |= (1<<ADSC);  // Start A2D Conversions 

  sei(); 
} 

int main(void) {
	ioinit(); 

  for (;;) 
		sleep_enable();

	return 0; 
} 

ISR(INT0_vect) {
	trigger();
}

ISR(ADC_vect) { 
	z_off = ADCH;
}

void trigger() {
	uint8_t i;
	_delay_us(25); // Initial Conduction Offset (25 = 0deg)

	for(i=0; i<(z_off); i++) // Fireing Delay
		_delay_us(2);

	if((z_off >= 20) & (z_off <= 250)) {
		PORTB |= (1<<4);  // Neg Phase Fire
		_delay_us(50);
		PORTB &= ~(1<<4);
		_delay_us(980);   // Delay 1/2 Cycle
		PORTB |= (1<<4);  // Pos Phase Fire
		_delay_us(50);
		PORTB &= ~(1<<4);
	}
	if(z_off < 20)
		PORTB |= (1<<4);  // Keep ON
	if(z_off > 250)
		PORTB &= ~(1<<4); // Keep OFF
}