Relationship between linear power and phase angle in AC dimmer

Hello, years ago I found a code on the Internet, and it is working, using uC Atmega328.

The thing is that at the time, I found a time table that shows the "linearization of power", but I don't remember how to calculate this table (These values ​​work, I tested them with 220V at 60Hz, but I would like to understand how these values ​​were obtained, I no longer remember where this data was posted, or if it was calculated manually):

const int OCR2A_array[] = {
  515, 445, 426, 413, 402, 392, 384, 377, 370, 363,
  357, 352, 346, 341, 336, 332, 327, 323, 318, 314,
  310, 306, 302, 298, 295, 291, 287, 284, 280, 277,
  274, 270, 267, 264, 261, 257, 254, 251, 248, 245,
  242, 239, 236, 233, 230, 227, 224, 221, 218, 216,
  213, 210, 207, 204, 201, 199, 196, 193, 190, 187,
  184, 182, 179, 176, 173, 170, 168, 165, 162, 159,
  156, 153, 150, 147, 144, 141, 138, 135, 132, 129,
  126, 123, 120, 117, 113, 110, 107, 103, 100, 96,
  92,  89,  85,  81,  76,  72,  67,  62,  56, 49,
  37
};
  • The table value allows a selection from 0 to 100%
    OCR2Abuff = OCR2A_array[valOutputElet];

  • Then the timer is set to the value when it passes through zero

  TCCR1B = 0x00; //stop timer
  OCR1A = OCR2Abuff;
  TCNT1 = 0;     //reset timer - count from zero

  if (GATE_en == true) {
    TCCR1B = 0x04; //start timer with divide by 256 input
  }

The base code for the dimmer, I found in this link:

// 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

  TCCR1B = 0x00; //stop timer
  OCR1A = OCR2Abuff;
  TCNT1 = 0;     //reset timer - count from zero

  if (GATE_en == true) {
    TCCR1B = 0x04; //start timer with divide by 256 input
  }
}

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);

Has anyone done this type of calculation of converting phase angle to effective power?

Except the formatting doesn't carry over this time.

It's essentially using integration of a sinusoid to effect a linear relationship between phase angle and power.

Think area under the curve for resistive loads.

Yes, there is a direct mathematical relation between the values in your table and the integral of the square of a sine wave — which is how RMS power is calculated in phase angle control.

a7

I THINK it's even more complicated...

Power is proportional to the square of the RMS voltage and RMS for a chopped wave is complicated. (Perhaps easy if up-to-speed on your calculus. :stuck_out_tongue: )

Incandescent light bulbs aren't linear. They put-out a higher percentage of heat compared to light at low power. They are more efficient (at putting-out light) at higher power.

Their resistance isn't constant either. The resistance is higher at higher temperature.

Dimmable LED bulbs vary a lot and are unpredictable.

Our eyes aren't linear either...

1 Like

I think the RMS gets took care of, but my calculus is way better than anything else that goes into it.

I stuck with a resistive load, perhaps I should have qualified that with "linear".

Instantaneously we are integrating V x I, so Imma say you integrate directly, root in RMS cancels square. The yield is accumulated watts.

Those other factors, the changing int nature of the light if we are talking about regular light bulbs and the human eye enter into it.

I have not done the work… it is possible the table has those built in and it may have a significant effect on what would be right for a simple power resistor.

I'm afraid I'll have time to spend on this. :expressionless:

a7

I was scratching my head few years ago with this subject.
There is mathematic formula from phase angle to voltage (and so for power).
But there is not formula from voltage to phase angle (if anyone disagrees please comment).

So in my case I needed to control triac timing based on power X and the only way was through mapping the reverse.

Interesting. How do you know the power when the voltage and current are not sine waves? Or is that what you are trying to figure out? I guess I would find a bunch of resistors and power them up and measure how hot they get.

I'm quite far from my daily math practice but if I remember right, I got pretty perfect results for purely resistive load with:

With power ratio I mean here phase cut power / full "non trimmed" power.

1 Like

This is mapping I used with few kW heating element and I got few watts precision.
But these timings are for 50hz mains, so the half cycle is 10000us.

int input[] = {20, 50, 100, 150, 200, 250, 300, 350, 400, 450, 500, 550, 600, 650, 700, 750, 800, 850, 900, 950, 980};//per-mille (1/1000) of max power
int output[] = {8530, 7981, 7411, 6990, 6637, 6324, 6035, 5765, 5505, 5250, 5000, 4750, 4495, 4235, 3965, 3676, 3363, 3010, 2589, 2019, 1470};//Firing delay time in us

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.