Go Down

Topic: Control de fase AC (Read 867 times) previous topic - next topic

mxt08

Oct 05, 2018, 07:00 am Last Edit: Oct 05, 2018, 03:44 pm by surbyte Reason: Agregado de etiqueta de enlace y visualización de imágen.
Hola a todos:

Estoy implementando el circuito sugerido por playground.arduino para el control de fase AC (adjunto link al final de la publicación), y he implementado el circuito tal y como la página lo sugiere. He analizado el comportamiento del circuito y este debería funcionar sin problemas, pero al implementarlo me topo con un resultado que no esperaba.

Por un lado, no entiendo exactamente el código, y para ser más preciso, cómo controla el tiempo en el cual el pulso de disparo al TRIAC se dará (esto es t1 en la página de referencia). Veo que lo logra con la variable i inicializada en i=483 al inicio del programa, y en el loop principal disminuyéndola hasta 65 (?) para luego reiniciarla. Puedo ver que trata de un comparador con un registro, pero no logro identificar realmente cómo se relaciona esto con el control del ángulo de disparo, sin mencionar el delay(15) que sigue a ello.

Es un problema en el programa, en la implementación de mi circuitería, o de qué? Solo me falta esta parte para completar mi tesis  :smiley-sweat:

Para mayor facilidad, adjunto el esquemático y el código del programa.

Adjunto también un video de cómo funciona mi carga AC (un foco de 20W en este caso) con el código TAL Y COMO ESTÁ en la página.

Link:

https://playground.arduino.cc/Main/ACPhaseControl

Código:

Code: [Select]


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

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

}




Daniel_Arg

Hola, lo primero que tengo para decir que una lampara ahorradoras CFL no es la adecuadra para hacer un atenuador. Tienes que usar una de filamento.

Lo segundo que seguramente sabes es que un Triac se dispara con un pulso en su puerta y por mas que este sea corto, el Tiac permanece encendido hasta que se suprima la tensión, en AC esto es hasta el cruce por cero.

Para hacer un dimmer en AC y obtener un resultado predecible es necesario detectar el cruce por cero y a partir de allí implementar la demora es disparar el pulso de encendido del Triac. En AC 50hz  tienes 10 milisegundos por cada cruce por cero (1000 milis / 50 hz / 2 semiciclos).

Desde que se detecta la interrupción "en tu código void zeroCrossingInterrupt()" si te demoras 6 milisegundos en disparar el Triac, esté estará encendido por 4 milisegundos hasta el nuevo cruce por cero.
Lo que representará un ciclo de trabajo de 40/60.  Espero que esto te ayude a comprender.

surbyte

Los códigos generados para 60Hz llevan implicitos otros tiempos diferentes a la frecuencia de red de 50hz

Como verás el código dice en su comentario incial

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

O sea la frecuencia de red es de 60hz y espera un semiciclo cada 8.333 y no 10mseg

Es algo corregible pero ahora eso implicará una falla.


mxt08

De acuerdo, cambiaré a una bombilla de filamento. Solo usé esta carga como prueba, pero entiendo.

Por otro lado, en mi país la tensión de línea es a 60Hz, por lo que no me preocupa ello.

Entendí a la perfección a @Daniel_Arg, pero no veo cómo se relaciona ello a la implementacion en código (particularmente en i reduciéndose de 483 a 65 y el delay(15) en el loop principal). Quizá sea obvio, pero no logro ver la luz en ello, realmente.

Disculpen las molestias, y muchas gracias de antemano.

mxt08

Acabo de probar con un foco de filamento pero el resultado es el mismo: El foco enciende 'de poco a mucho', es decir, va incrementando su intensidad luminosa desde 0 hasta el máximo, para luego apagarse y repetir el proceso.

Lo que yo deseo es un control de la luminosidad, esto es, un control de la tensión que le llega a la carga a través del ángulo de disparo. No logro identificar aún si es un tema de software (cosa que me temo) o de hardware.

Gracias nuevamente.

surbyte

eso es lo que el código dice
Que quieres que haga la bombilla?

Por cierto, cuando expliques algo indica donde vives, tenemos paises en gral que usamos 50Hz y algunos pocos 60Hz asi que es importante que no perdamos el tiempo como lo hice yo jajaja.

mxt08

Lo siento, debí indicar eso  :smiley-sad-blue:, pero sí, vivo en Perú y aquí es a 60Hz.

Lo que me gustaría que haga mi circuito es algo como esto:

http://youtu.be/ampFrowXZBE

Solo que en vez de un potenciometro, me gustaría controlarlo a través del programa. En resumen, lo que quiero es controlar el voltaje que le llega a la carga en todo instante de tiempo, no que prenda de a pocos para luego apagarse. Espero me puedan ayudar u.u

mxt08

Es una bombilla estándar, de filamento, y sí, me gustaría controlar el ángulo de disparo desde el serial, de ser posible.

Daniel_Arg

Acabo de probar con un foco de filamento pero el resultado es el mismo: El foco enciende 'de poco a mucho', es decir, va incrementando su intensidad luminosa desde 0 hasta el máximo, para luego apagarse y repetir el proceso.
Pues ahí lo tienes. OCR1A pasa por los distintos pasos desde 483 a 65 cada 15 milisegundos ajustando el tiempo que debe pasar desde que se detecta el cruce por cero hasta el disparo del Triac. Cuanto mas corto es este tiempo, mas largo es el tiempo que la lámpara está encendida durante el semiciclo.

surbyte

Los ejemplos de ArduMyth son mucho mejores que ese ejemplo del Playground, te recomiendo los mires.
Tienen resuelto incluso toda acción desde 0 a 100%

mxt08

Al parecer era un tema de software.

Probé utilizando, con el mismo circuito, el siguiente código:

Code: [Select]


int AC_OUT = 10;  // Output to Opto Triac
int AC_VALUE = 0;    // AC OUT VALUE (0 - 100) *0 = ON BULB; 100 = OFF BULB
int delayTime = (83*AC_VALUE);  // * THESE VALUES ARE UNTESTED, YOU MUST PLAY AROUND WITH THEM) *

/* ##########################################
   ## THIS IS HOW THE VALUES ARE WORKED OUT##
   ##########################################
   
   F = 60Hz
   ((1/F)/2 *10^6) / 100 = 83.33
   *ROUNDED OFF TO 83*
   
   ##########################################
*/
   
int sensorValue = 0;
int value = 0;


void setup()  // run once, when the sketch starts
{
  Serial.begin(9600);
   
  pinMode(AC_OUT, OUTPUT); // Set the light control pin as output
 
  attachInterrupt(0, setAC, RISING);  // Attach an Interupt to pin2 (interupt 0) for Zero Cross Detection
}

void setAC()  // function to be fired at the zero crossing to dim the light
{
  delayMicroseconds(delayTime);  // delay the dim time
  digitalWrite(AC_OUT, HIGH);  // fire the Triac
  delayMicroseconds(10); // pause briefly to ensure the triac turned on
  digitalWrite(AC_OUT, LOW);   // turn off the Triac gate (triac will not turn off until next zero cross)
}

void loop()
{

}


Extraído de: https://forum.arduino.cc/index.php?topic=95732.0

Y funcionó como yo quiero. Si bien es cierto la relación entre la totalidad del semiciclo (0-100%) y el voltaje que le llega a la carga (0-220V) no es lineal, es algo que debo resolver matemáticamente.

Muchas gracias a todos por su ayuda, veo que este foro realmente está para apoyar a quienes nos iniciamos en la electrónica digital (soy más pegado a lo analógico, pero esos tiempos están acabando jeje). Gracias!

surbyte

#11
Oct 05, 2018, 05:41 pm Last Edit: Oct 05, 2018, 05:49 pm by surbyte
Si miras los links de ardumyth lo tienes resuelto, solo corregir el tema de la frecuencia


Quote
Muchas gracias a todos por su ayuda, veo que este foro realmente está para apoyar a quienes nos iniciamos en la electrónica digital (soy más pegado a lo analógico, pero esos tiempos están acabando jeje)
Vale una mención especial a este comentario.
Muchas veces la gente que llega al foro y se molesta rápidamente por que o bien le pedimos respete las normas (mi caso o mi tarea como moderador), o le pedimos ponga información que no ha puesto incluyendo código.
En tu caso, hicisto todo eso, pusiste el código buscado, pusiste el esquema correspondiente, no importa si lo encontaste o no en un mismo sitio. Te esforzaste y eso es lo que se valora.

La mayoría viene y escribe 1 linea y piden todo, asi que una MENCION para tu trabajo de Leer las normas y postear debidamente una consulta. De ese modo obtienes toda la AYUDA de este foro tu y quien te siga conseguirá lo mismo actuando de este modo y si no, solo verá que le vamos a pedir que de mas detalles.

Daniel_Arg

Los dimmer recomendados como si fuera que todo lo que se dice en la red saliera de expertos de la revista Elektor, no son tal. Uno evita detectar el cruce por cero, rectifica la alterna para no usar un Triac y cambiar a control por transistor MosFet. El otro es peor, porque maneja alterna cruzando con la frecuencia PWM. Ya me imagino lo que debe ser mirar la onda con un osciloscopio.

La descalificada propuesta del playground AC Phase Control imita al clásico  circuito donde la demora en disparar el triac se hace con el tiempo que tarda en cargar el capacitor mediante la resistencia variable.

No veo nada que se pueda criticar en el artículo porque esta todo documentado y dice claramente que el código del loop es un ejercicio de muestra y especifica que se debe ajustar para cambiar el brillo (OCR1A).

Está en cada uno hacer su programa como leer un termistor y usarlo para controlar la temperatura de una incubadora, o ajustar digitalmente la potencia para una resistencia de termoformado evitando la falta de precisión del potenciómetro y sus fallas por desgaste y suciedad.

surbyte

Debo admitir que mi recomendación no fue buena y que @Daniel_Arg tiene razón.

Pense al ver el % que el sistema estaba completo y lejos de estarlo esta muy incompleto.
Tal vez sirva como idea para incorporar lo que sirva al primer código.

Me retracto de mi consejo!! Eso pasa por leer superficialmente.

Tengo por ahi un control de fase donde se corregía incluso la potencia para que el brillo fuese lineal en función de la potencia. Lo debo buscar. Tenía control de fase, control con timer y ademas una corrección muy bien lograda del brillo para conseguir una sensación lineal.
A ver si lo encuentro y puedo aportar algo válido.

Go Up