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?
