Incorprating AC phase control

Hi All,

I am trying to incorporate the AC phase control in my project and there ways to get it done.

Need a sugestion on which one to go forward with. The arduino playground has the link at the bottom to this sketch

/* AC POWER CONTROL WITH PWM AND ZERO CROSS DETECTION */
 /* AUTHOR: Dimitris El. Vassis - 2013 */

 

 #include <ACPWM.h>

 #define ZERO_PIN 2 //Input pin from zero cross detector
 #define PWM_PIN 9 //Output pin to TRIAC / SSR

 int SET_PIN = A0; //Analog pin for setting the dutyCycle value with a pontentiometer

 

 void setup()
 {
    pinMode(ZERO_PIN, INPUT);
    pinMode(PWM_PIN, OUTPUT);
    /*Initialize PWM operation.
    Mains frequency: 50Hz.
    Zero crossing point reached whenever pulse to PIN2 changes
    Duty cycle = 0..255. 
    where 0 = always off. 
    where 255 = always on.
    and 150 is 59% on.*/
    ACpwm.initialize(50,ZERO_PIN,CHANGE,PWM_PIN,255);
    //Latching when voltage is positive: 3 microseconds.
    //Latching when voltage is negative: 5 microseconds.
    ACpwm.setLatch(3,5);
 }

 

 void loop() {
    //Adjust the power with the potentiometer
    //Set the duty cycle equal to the value of the potentiometer.
    ACpwm.setDutyCycle(analogRead(SET_PIN));
 }

The bristol watch sketch

/*
Purpose: to detect zero crossing pulse at 
 INT0 digital pin 2, which after delay 
 switches on  a triac. 
 Power output to triac activated by external switch.
 */

#define triacPulse 5
#define SW 4
#define aconLed 12 

int val;

void setup()  {
  pinMode(2, INPUT);
  digitalWrite(2, HIGH); // pull up
  pinMode(triacPulse, OUTPUT);
  pinMode(SW, INPUT);
  digitalWrite(SW, HIGH);
  pinMode(aconLed, OUTPUT);
  digitalWrite(aconLed, LOW);
}

void loop() {
  // check for SW closed
  if (!digitalRead(SW))   {
    // enable power
    attachInterrupt(0, acon, FALLING); 
    // HV indicator on
    digitalWrite(aconLed, HIGH);
  }  // end if
  else if (digitalRead(SW)) { 
    detachInterrupt(0); // disable power
    // HV indicator off
    digitalWrite(aconLed, LOW);
  }  // else
} // end loop



// begin AC interrupt routine
// delay() will not work!
void acon()  
{
  delayMicroseconds((analogRead(0) * 6) + 1000); // read AD1 
  digitalWrite(triacPulse, HIGH);
  delayMicroseconds(200);  
  // delay 200 uSec on output pulse to turn on triac
  digitalWrite(triacPulse, LOW);
}

in the bristol watch sketch, what does this (analogRead(0) * 6) + 1000) line mean.

Would appreciate if somebody could explain the lines
//Latching when voltage is positive: 3 microseconds.
** //Latching when voltage is negative: 5 microseconds.**
** ACpwm.setLatch(3,5);**
in the Arduino Playground link as well. I do understand how the whole thing works but wanted more clear picture when it comes to the coding.

Thanks in advance.

From what is understand is that the second option is based on a library. I wish to have read value of a pot as dimmer value and store it as a variable.

Both codes apply to different output circuits (PWM/triac). What's your circuit?

I wish to take the reading for the pot as increments starting from 40 to 100. Pretty much like the second illustration but the pot value stored as a variable.

in the bristol watch sketch, what does this (analogRead(0) * 6) + 1000) line mean.

delayMicroseconds((analogRead(0) * 6) + 1000); // read AD1

It is setting a turn on delay from the falling zero cross of from 1 to a bit over 7 ms. It will give you a portion of the sine wave which is passed to the circuit. The timing looks like it is for 60Hz, but I would think that the zero cross interrupt should be CHANGE.

Would appreciate if somebody could explain the lines
//Latching when voltage is positive: 3 microseconds.
//Latching when voltage is negative: 5 microseconds.
ACpwm.setLatch(3,5);

You will need to look at the library to determine what this is doing. It is a library command.

You will need to look at the library to determine what this is doing. It is a library command.

yes it is and it looks like this

void ACPWM::setDutyCycle(int dCycle){
	if(dCycle<0) dutyCycle=0;
	else if(dCycle>100) dutyCycle=100;
	else dutyCycle=dCycle;
	offTime = (long) period*(scale-dutyCycle)/(long)scale*2; //[PERIOD*10^-6*(scale-dutyCycle)/scale]*16*10^6/8
                            //[PERIOD*10^-6*(scale-dutyCycle)/scale-latch]: off time. 16*10^6: Clock rate. 8: Prescaler, set below. See ATMega specs
	onTime = (long)period*dutyCycle/(long)scale*2;
}

so i guess the first one would be more feasible to my project. The line delayMicroseconds((analogRead(0) * 6) + 1000) is what that reads the pot and that could be stored as a variable. Am i correct on that ?

is what that reads the pot and that could be stored as a variable. Am i correct on that ?

Yes. You will map the pot value into a delay time from zero cross. There are many AC dimmer codes found on the internet which use a pot to control the brightness.

What are you trying to do here? From your previous threads you have been using a fixed delay to turn on the triac at max voltage because of highly inductive load?

Why do you now want a variable delay over such a wide range?

What are you trying to do here? From your previous threads you have been using a fixed delay to turn on the triac at max voltage because of highly inductive load?

Am using a second pot control the power of the MOT there eliminating to switch on the TRIAC at the peak. The first pot would control how long the mot will be switched on that is 100ms to 450ms in steps of 50.

Why do you now want a variable delay over such a wide range?

When i tried spot welding a few cells i noticed the cells got a little warm and during the process. So i could reduce the time here to 50ms but i wanted control over the power as well. I will be using the phase control in percentages from like 40, 60, 80, 100.

will try the phase control and see how it goes.

You have no loop() and your code does not compile. I think there are other issues as well.

If I focus on the revised triac triggering for the preweld and weld I see problems.

I think your whole approach is flawed. You are turning the triac on for several cycles determined by the pre weld time or the weld step time. Both of which look to be greater than 10ms. Because your program was developed around the inductive load and the need to set the turn on at max voltage, it does not condition every cycle, only the initial one.

I understand that you are trying to reduce the power of the welds independent of the weld time periods. There are AC control schemes which can chop every cycle, but you will need to recraft the program significantly to do that. How you can chop every cycle, and deal with the inductive load problem is not clear to me.

You may need to modify the transformer or the voltage feed to the transformer. Your project is based on the modification of a microwave oven transformer. I know that 230v goes in, but I don't remember what comes out. Its not clear to me how you can best make it supply variable power to the weld. Why can't you make the preweld and weld times short enough to handle the transformer power as it is now?

A final small point.
Why is the return value of the Weld() function typed as a const int ? I don't see anything returned. I guess the compiler doesn't complain but it seems pretty useless.

Hmmm i had this idea from the dimmer circuit as it controlled the wave so was taking the same principle and using it for my inductive load. I had doubts if it really be a good idea to do as these inductive loads are to switched on at the peak. but then How are the Sunko 778H working ? Did not learn that or have to see how it worked. i assumed it was with phase control that the power was controlled.

The transformer secondary when shorted is 3v. Now to control the power of the transformer, i guess the best and easier way would be to add a power resistor of 27Ohm 50W in series with primary of the transformer.

The Weld() function has the set of conditions to check and return if true.

int WeldStep()          // Map POT value from A5 to increments of 50 from 100 to 500
{
  int WeldStep;
  PotValue = analogRead(Pot);
  WeldStepValue = map(PotValue, 0, 1023, 100, 600);
  if (WeldStepValue >= 100 && WeldStepValue < 150)
    WeldStepValue = 100;
  if (WeldStepValue >= 150 && WeldStepValue < 200)
    WeldStepValue = 150;
  if (WeldStepValue >= 200 && WeldStepValue < 250)
    WeldStepValue = 200;
  if (WeldStepValue >= 250 && WeldStepValue < 300)
    WeldStepValue = 250;
  if (WeldStepValue >= 300 && WeldStepValue < 350)
    WeldStepValue = 300;
  if (WeldStepValue >= 350 && WeldStepValue < 400)
    WeldStepValue = 350;
  if (WeldStepValue >= 400 && WeldStepValue < 450)
    WeldStepValue = 400;
  if (WeldStepValue >= 450 && WeldStepValue < 500)
    WeldStepValue = 450;
  if (WeldStepValue > 450)
    WeldStepValue = 500;
  [b]return WeldStepValue;[/b]
}

I understand the return from int WeldStep().

It’s the return from const int Weld(int pre, int pause) that looks strange.

It's the return from const int Weld(int pre, int pause) that looks strange.

that was initially set to adjust the weld time when i used test the welding time and moreover others could also change it in the code latter.