Cambiar delay por micros()

Buenos días.

Mi proyecto consiste en el control de una bombilla de 220V.
Hice este programa y funciona perfectamente

int AC_LOAD = 3;    // Output to Opto Triac pin


void setup()
{
  pinMode(AC_LOAD, OUTPUT);// 
  attachInterrupt(0, zero_crosss_int, RISING); 
}

void zero_crosss_int()
{
  
  // 10ms (1/2 periodo 25Hz) 
 
  // (10000us - 10us) / 128 = 75 Elijo 128 divisiones

  int dimtime = (75*dimming);     
  delayMicroseconds(dimtime);    // Tiempo de espera para activar la puerta del TRIAC  	
  digitalWrite(AC_LOAD, HIGH);   
  delayMicroseconds(10);         // Tiempo de espera para desactivar la puerta 
				 
  digitalWrite(AC_LOAD, LOW);  
}

void loop()  {
 {
    dimming=100; //Valor de 0 a 128 para determinar el tiempo de espera de activación de puerta
    
   }
}

Mi duda es, cómo puedo cambiar los "delays" por la función micros()/millis(), ya que quiero añadir más componentes al programa.
He probado a hacerlo de esta manera pero no funciona correctamente:

int AC_LOAD = 8;    
 unsigned long apagar;

void setup()
{
  pinMode(AC_LOAD, OUTPUT);
  attachInterrupt(0, zero_crosss_int, RISING);  
  
}


void zero_crosss_int()  
{

  digitalWrite(AC_LOAD, LOW); 
  unsigned long encender = micros();
  int dimtime = (98*dimming);        
 if(micros() - encender >= dimtime)   
 {  
  digitalWrite(AC_LOAD, HIGH);  
  unsigned long apagar = micros();
  unsigned long encender = micros();
    if(micros() - apagar > 1)
 {        
  digitalWrite(AC_LOAD, LOW);   
  apagar = micros();
 }
 }

}

void loop()  {
  
  
    dimming=3;
  
   
}

He ido paso a paso, de manera que dejando el delayMicroseconds(dimtime) si me funciona correctamente:

void zero_crosss_int()  
{
  
  digitalWrite(AC_LOAD, LOW); 
  unsigned long encender=micros();
  int dimtime = (98*dimming);      
  delayMicroseconds(dimtime);       
  digitalWrite(AC_LOAD, HIGH);   
  unsigned long apagar = micros();
  if(micros() - apagar > 1)
 {        
  digitalWrite(AC_LOAD, LOW);   
  apagar = micros();
 }
}

Gracias, un saludo.

Explica que hace el programa? Controla el disparo del triac?
Bueno la idea es entonces que uses un TIMER y nada de millis() o micros()
Si tienes que hacer otras cosas que no afecten el timming, lo mejor es un TIMER.

guezro:
Mi duda es, cómo puedo cambiar los "delays" por la función micros()/millis(), ya que quiero añadir más componentes al programa.

¿Qué componentes?
Saludos

Según tus comentarios tu triac se activa con HIGH. Dime en tu código que funciono perfectamente como lograste ver un pulso de 10 microsegundos ?

En tu ultimo código quieres encender el triac solo 1 microsegundo ?

Prueba esto:

const byte PULSADOR = 2
const byte AC_LOAD = 3 //Triac
unsigned long encender = 0;
void setup(){
	pinMode(PULSADOR, INPUT_PULLUP);
	pinMode(AC_LOAD, OUTPUT);
	attachInterrupt(0, zero_crosss_int, RISING);
}

void zero_crosss_int(){  
	digitalWrite(AC_LOAD, HIGH);   
	encender = millis();
}

void loop(){
  if (millis() - encender > 10000) {        
	digitalWrite(AC_LOAD, LOW);   
  }
}

surbyte:
Explica que hace el programa? Controla el disparo del triac?
Bueno la idea es entonces que uses un TIMER y nada de millis() o micros()
Si tienes que hacer otras cosas que no afecten el timming, lo mejor es un TIMER.

Si , pero no consigo usar el timer para controlar dos TRIACs independientes, por eso busqué como hacerlo con millis() o micros()

vffgaston:
¿Qué componentes?
Saludos

Quiero controlar dos TRIACs, 1 luz RGBW y un relé, por eso no quiero utilizar delays

Si, pero me gustaría establecer el tiempo de espera para encender el TRIAC, ya que dependiendo de la duración de ese tiempo, obtendré una Tensión mayor o menor.

guezro:
Quiero controlar dos TRIACs, 1 luz RGBW y un relé, por eso no quiero utilizar delays

A ver, ¿dos triacs para dos bombillas, Y un RGBW (que no sé lo que es, aunque me lo imagino) Y un relé (o sea, cuatro cosas en total)?.

Saludos.

guezro:
Si, pero me gustaría establecer el tiempo de espera para encender el TRIAC, ya que dependiendo de la duración de ese tiempo, obtendré una Tensión mayor o menor.

No es necesario ya que el Triac normalmente esta apagado y en reposo esperando tu pulso.

vffgaston:
A ver, ¿dos triacs para dos bombillas, Y un RGBW (que no sé lo que es, aunque me lo imagino) Y un relé (o sea, cuatro cosas en total)?.

Saludos.

Si, pero esto no es relevante, ya que la programación que he puesto en este post es solo de los triacs.
La cosa es que al usar mas componentes , no puedo utilizar delays para la programación de los triacs, y ahí está mi duda, como controlar los triacs , independientemente uno de otro, sin utilizar los delays.

Un saludo.

guezro:
La cosa es que al usar mas componentes , no puedo utilizar delays para la programación de los triacs, y ahí está mi duda, como controlar los triacs , independientemente uno de otro, sin utilizar los delays.

Ni siquiera solamente con dos triacs …
Tendrás que detectar el paso por cero de la señal de corriente alterna, poner un contador a “0” en ese momento, y después disparar los triacs cuando corresponda cada uno con su timer (¿o eso era con los tiristores?; no me acuerdo si el triac había que dispararlo con un pulso o mantener la puerta a “1” durante todo el tiempo que está encendido, de todas formas, desde el punto de vista del programa tienes que hacer lo que te digo).
¿Sabes detectar el paso por “0”?
Saludos.

vffgaston:
Ni siquiera solamente con dos triacs ...
Tendrás que detectar el paso por cero de la señal de corriente alterna, poner un contador a "0" en ese momento, y después disparar los triacs cuando corresponda cada uno con su timer (¿o eso era con los tiristores?; no me acuerdo si el triac había que dispararlo con un pulso o mantener la puerta a "1" durante todo el tiempo que está encendido, de todas formas, desde el punto de vista del programa tienes que hacer lo que te digo).
¿Sabes detectar el paso por "0"?
Saludos.

Si, la puerta del triac la disparas tras pasar un tiempo que tu establezcas (en mi caso lo determinas con dimming), que lo tengo puesto con un delay que es lo que no consigo cambiar por un timer. Y despues desactivo la puerta cuando pasa un segundo ( pero el triac no deja de conducir hasta que vuelve a pasar por cero la señal de corriente alterna)
Y el paso por cero lo tengo con un attachinterrupt.
un saludo.

int AC_LOAD = 8;   
int dimming;  

void setup()
{
  pinMode(AC_LOAD, OUTPUT);
  attachInterrupt(0, zero_crosss_int, RISING);
}


void zero_crosss_int()  
{
  
  digitalWrite(AC_LOAD, LOW); 
  unsigned long encender=micros();
  int dimtime = (90*dimming);        
  delayMicroseconds(dimtime);       
  digitalWrite(AC_LOAD, HIGH);  
  unsigned long apagar = micros();
  if(micros() - apagar > 1)
 {        
  digitalWrite(AC_LOAD, LOW);  
  apagar = micros();
 }
}

void loop()  {
  
  
    dimming=i; //desde 3 (máximo) hasta 100 (mínimo)
  
   
}

guezro:
Y el paso por cero lo tengo con un attachinterrupt.

¿Qué arduino usas?. ¿Cómo tienes cableado el asunto para detectar el paso por cero?
Saludos

vffgaston:
¿Qué arduino usas?. ¿Cómo tienes cableado el asunto para detectar el paso por cero?
Saludos

Las pruebas las hago con arduino UNO.
El paso por cero lo hago a traves de un H11AA1 al pin 2. (Adjunto la imagen)
Pero el problema lo tengo en la programación.

  • En la imagen el H11AA1 entre el anodo (A) y catodo (K) el dibujo está mal, no hay solo 1 led, si no que hay dos leds en antiparalelo

OK. Tiene muy buena pinta.
A ver, es relativamente sencillo: tienes que crear tres variables, por ejemplo:
pasoPorCero
tiempoTriac1
tiempoTriac2

cuando pasas por cero, en la rutina de la interrupción, cargas millis() en pasoPorCero.

Y después, en el loop, comparas con millis() los tiempoTriac y, si ha pasado el tiempo, le mandas el pulso al triac y listo. (Si el pulso tiene que tener una cierta duración mayor que la que el propio microcontrolador deje entre las instrucciones digitalWrite .... HIGH y digitalWrite .... LOW, tendrías que usar otra variable para la duración del pulso "deltaPulso")

Saludos

(No me detengo en la sintaxsis porque tengo una memoria pésima y metería la pata seguro ...)

He probado y si que varía la tension pero parpadea mucho la bombilla

Moderador: No repitas lo que se lee arriba.

Mira este código AC Phase control. Pruebalo para un triac y luego discutimos como hacerlo con dos

guezro:
He probado y si que varía la tension pero parpadea mucho la bombilla

Hola,

Por favor, manda el código.

Saludos

vffgaston:
Hola,

Por favor, manda el código.

Saludos

Aquí te dejo el código:

int AC_LOAD = 8;    
 unsigned long apagar;
 int dimming;
  unsigned long encender;

void setup()
{
  pinMode(AC_LOAD, OUTPUT);
  attachInterrupt(0, zero_crosss_int, RISING);  
 
}


void zero_crosss_int()  
{

  digitalWrite(AC_LOAD, LOW); 
 encender = millis(); // Encender es el momento que la onda senoidal pasa por cero
 
 

}

void loop()  {
  
  
 dimming=200; //(desde 0 a 255)
  int dimtime = (0.035*dimming); //1000us - 10us /255 = 35us
       do
       {
 if(millis() - encender >= dimtime)   // tiempo de espera para activar la puerta del triac
 {  
  digitalWrite(AC_LOAD, HIGH);  
    if(millis() - encender > 1+dimtime) //1 milisegundo de duracion de pulso para desactivar la puerta
 {        
  digitalWrite(AC_LOAD, LOW);   

 }
 }
       } while(millis()-encender < 10); //lo que dura un semiperiodo 25Hz
   
}

Un saludo

surbyte:
Mira este código AC Phase control. Pruebalo para un triac y luego discutimos como hacerlo con dos

Si, lo he probado y funciona perfectamente, pero no comprendo bien los timers internos y me surgen las dudas a la hora de colocar el segundo Triac.