Autor Tema: Error en codigo de dimer  (Leído 3994 veces)

0 Usuarios y 2 Visitantes están viendo este tema.

Desconectado rivale

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1707
Error en codigo de dimer
« en: 21 de Noviembre de 2013, 00:39:47 »
Hola a todos, escribo solicitando ideas para corregir un error que se me ha presentado.
Es algo muy simple pero no he podido solucionarlo, ya le di muchas vueltas y no he logrado encontrar el error.

Tengo un circuito para un dimer conectado a una lampara de leds, detecto el cruce por cero y un tiempo después activo el triac para encender la lámpara.

el problema que tengo es que no logro hacer que funcione con las interrupciones del timer, tengo el siguiente código y funciona como se ve en la primera parte del video

feature=youtu.be[/youtube]

Código: [Seleccionar]
#include <16f819.h>
//#device ADC=8;
#FUSES INTRC_IO, NOCPD, PROTECT, NOMCLR, NOPUT,nowdt,nolvp
#use delay(clock=8000000)//relog para el 12f1822
#define  moc  pin_b3
//#byte apfcon = 0x11D//se define el registro apfcon debido a que ccs no lo tiene configurado
//#include "dimer_16.h"
int1 zero_c=0;
int16 trigger=0;
int1 re_f=0;
void init()
{  
   setup_adc(adc_off);
   setup_adc_ports(no_analogs);
   set_tris_a(0b00000000);
   set_tris_b(0b00000101);
  
   output_low(moc);
   setup_ccp1(ccp_capture_fe);//se configura el modulo ccp1 en modo captura en flanco descendente para leer el sensor
   setup_timer_1(t1_internal|t1_div_by_2);  //se configura el timer uno para que se incremente cada 1us (4*div/osc) (4MHz)
   //setup_timer_0(t0_internal|t0_div_64);//se configura el timer para que se desborde cada 8.192ms(4*div/osc) (4MHz)
   re_f=0;
   ext_int_edge(h_to_l);//interrupcion externa para el cruce por cero  
   enable_interrupts(int_ext);
   set_timer0(0);
  // enable_interrupts(int_ccp1);
   enable_interrupts(global);
}
void  main()
{
   init();
   trigger=6;
   while(true)
   {
      if(zero_c==1)
      {
         zero_c=0;
        
        
      }
   }
}



#int_ext //interrupcion para detectar el cruce por cero de la linea de AC
void cruce_0()
{
   if(re_f)
   {
       ext_int_edge(h_to_l);
       re_f=0;
   }
   else
   {
      ext_int_edge(l_to_h);
      re_f=1;
   }
  
   delay_ms(7);              
   output_high(moc);//si es menor a 10 entonces el triac nunca se prende
   delay_us(150);
   output_low(moc);
                
   zero_c=1;
   clear_interrupt(int_ext);
}







ahora, cuando cambio el código a el que muestro a continuación , hace lo de la segunda parte del video.


Código: [Seleccionar]
#include <16f819.h>
//#device ADC=8;
#FUSES INTRC_IO, NOCPD, PROTECT, NOMCLR, NOPUT,nowdt,nolvp
#use delay(clock=8000000)//relog para el 12f1822
#define  moc  pin_b3
//#byte apfcon = 0x11D//se define el registro apfcon debido a que ccs no lo tiene configurado
//#include "dimer_16.h"
int1 zero_c=0;
int16 trigger=0;
int1 re_f=0;
void init()
{  
   setup_adc(adc_off);
   setup_adc_ports(no_analogs);
   set_tris_a(0b00000000);
   set_tris_b(0b00000101);
  
   output_low(moc);
   setup_ccp1(ccp_capture_fe);//se configura el modulo ccp1 en modo captura en flanco descendente para leer el sensor
   setup_timer_1(t1_internal|t1_div_by_2);  //se configura el timer uno para que se incremente cada 1us (4*div/osc) (4MHz)
   //setup_timer_0(t0_internal|t0_div_64);//se configura el timer para que se desborde cada 8.192ms(4*div/osc) (4MHz)
   re_f=0;
   ext_int_edge(h_to_l);//interrupcion externa para el cruce por cero  
   enable_interrupts(int_ext);
   set_timer0(0);
  // enable_interrupts(int_ccp1);
   enable_interrupts(global);
}
void  main()
{
   init();
   trigger=6;
   while(true)
   {
      if(zero_c==1)
      {
         zero_c=0;
         delay_ms(7);
              
         output_high(moc);//si es menor a 10 entonces el triac nunca se prende
         delay_us(150);
         output_low(moc);
        
      }
   }
}



#int_ext //interrupcion para detectar el cruce por cero de la linea de AC
void cruce_0()
{
   if(re_f)
   {
       ext_int_edge(h_to_l);
       re_f=0;
   }
   else
   {
      ext_int_edge(l_to_h);
      re_f=1;
   }
  
  
                
   zero_c=1;
   clear_interrupt(int_ext);
}




Alguna idea de porque pasa esto, cabe mencionar que ya intente con interrupciones y hace lo mismo que la segunda parte del video, solo logre hacer que funcione poniendo un retardo dentro de la interrupción del cruce por cero
"Nada es imposible, no si puedes imaginarlo"

Desconectado stk500

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 4919
Re: Error en codigo de dimer
« Respuesta #1 en: 21 de Noviembre de 2013, 02:00:43 »
y porque usa el cruce por cero? para dimmer Led basta con un Transistor Mosfet o un CI , o me imagino que esta dimmando la alimentacion del Led. puede poner el circuito como lo hace ?

Saludos

Desconectado jeremylf

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1341
Re: Error en codigo de dimer
« Respuesta #2 en: 21 de Noviembre de 2013, 02:56:37 »
Será que tu circuito para el cruce por cero te esta metiendo pulsos indeseados que hace que la interrupción se ejecute varias veces mientras intenta ejecutar lo que hace en el while.

Ademas, falta la configuración de la frecuencia del oscilador interno a 8Mhz: setup_oscillator.
« Última modificación: 21 de Noviembre de 2013, 03:02:27 por jeremylf »

Desconectado BrunoF

  • Administrador
  • DsPIC30
  • *******
  • Mensajes: 3865
Re: Error en codigo de dimer
« Respuesta #3 en: 21 de Noviembre de 2013, 03:27:14 »
Uy! si habré renegado hace unos años con esto...

Te doy una posible respuesta al problema. Si lo soluciona te explico la teoría que me llevó a pensar que puede ser eso.  :mrgreen:

modificá el segundo código a:

Código: C
  1. if(zero_c==1)
  2.       {
  3.         disable_interrupts(global);
  4.          zero_c=0;
  5.          delay_ms(7);
  6.              
  7.          output_high(moc);//si es menor a 10 entonces el triac nunca se prende
  8.          delay_us(150);
  9.          output_low(moc);
  10.          clear_interrupts(int_ext);
  11.          enable_interrupts(global);        
  12.       }

Aunque puede que te des cuenta en base al código. Los tiempos "muertos" son distintos entre el cambio de flanco de L_TO_H y de H_TO_L. Si marcas en la senoidal los momentos de cambio vas a podés apreciarlo.

"All of the books in the world contain no more information than is broadcast as video in a single large American city in a single year. Not all bits have equal value."  -- Carl Sagan

Sólo responderé a mensajes personales, por asuntos personales. El resto de las consultas DEBEN ser escritas en el foro público. Gracias.

Desconectado PCCM

  • PIC16
  • ***
  • Mensajes: 109
Re: Error en codigo de dimer
« Respuesta #4 en: 21 de Noviembre de 2013, 03:33:13 »
Coloca como configuras el timer porque en el código que colocas.
La interrupción por timer, puede ser que no te este funcionando porque no has activado la interrupción por timer:

enable_interrupts(int_timer0)

ademas de que configuras timer1 y usas el timer0.
En cada interrupción externa por cruce por cero tienes que setear al valor que quieres del timer para que vuelva a contar: set_timer0(...)

y por lo del segundo, seria como dice stk500, que coloques el circuito.

Desconectado BrunoF

  • Administrador
  • DsPIC30
  • *******
  • Mensajes: 3865
Re: Error en codigo de dimer
« Respuesta #5 en: 21 de Noviembre de 2013, 03:40:37 »
Creo que la rutina del Timer va a implementarla luego. En este momento no está logrando siquiera poder encender de forma pareja la carga lo mas cercana al 100% mediante disparos acertados del MOC, que es el primer paso para luego mover el punto de disparo y poder dimmerizar (ahi sí usando un Timer).

Saludos.
"All of the books in the world contain no more information than is broadcast as video in a single large American city in a single year. Not all bits have equal value."  -- Carl Sagan

Sólo responderé a mensajes personales, por asuntos personales. El resto de las consultas DEBEN ser escritas en el foro público. Gracias.

Desconectado rivale

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1707
Re: Error en codigo de dimer
« Respuesta #6 en: 21 de Noviembre de 2013, 11:20:55 »
Gracias a todos por las respuestas.

y porque usa el cruce por cero? para dimmer Led basta con un Transistor Mosfet o un CI , o me imagino que esta dimmando la alimentacion del Led. puede poner el circuito como lo hace ?


en efecto los leds los podríadimear con un pwm, sin embargo, la lampara es comercial y ya esta fabricada, esta se alimenta directamente de la linea de AC, por eso estos haciendo el dimer a la alimentación, para solo poner el circuito entre la linea de AC y la lampara
mas tarde subo el esquematico del circuito que estoy usando

Será que tu circuito para el cruce por cero te esta metiendo pulsos indeseados que hace que la interrupción se ejecute varias veces mientras intenta ejecutar lo que hace en el while.

Ademas, falta la configuración de la frecuencia del oscilador interno a 8Mhz: setup_oscillator.


tambien pensé en eso, pero hice la prueba de poner un led para verificar el cruce por cero, hice que el led parpadeara cada 120 interrupciones, y en efecto se ve que este parpadea cada segundo (la linea de AC tiene una frecuencia de 60 Hz)




Uy! si habré renegado hace unos años con esto...

Te doy una posible respuesta al problema. Si lo soluciona te explico la teoría que me llevó a pensar que puede ser eso.  :mrgreen:

modificá el segundo código a:

Código: C
  1. if(zero_c==1)
  2.       {
  3.         disable_interrupts(global);
  4.          zero_c=0;
  5.          delay_ms(7);
  6.              
  7.          output_high(moc);//si es menor a 10 entonces el triac nunca se prende
  8.          delay_us(150);
  9.          output_low(moc);
  10.          clear_interrupts(int_ext);
  11.          enable_interrupts(global);        
  12.       }

Aunque puede que te des cuenta en base al código. Los tiempos "muertos" son distintos entre el cambio de flanco de L_TO_H y de H_TO_L. Si marcas en la senoidal los momentos de cambio vas a podés apreciarlo.



GRacias por la sugerencia Bruno, no se me ocurrió esto, lo pruebo mas tarde y comento los resultados




Coloca como configuras el timer porque en el código que colocas.
La interrupción por timer, puede ser que no te este funcionando porque no has activado la interrupción por timer:

enable_interrupts(int_timer0)

ademas de que configuras timer1 y usas el timer0.
En cada interrupción externa por cruce por cero tienes que setear al valor que quieres del timer para que vuelva a contar: set_timer0(...)

y por lo del segundo, seria como dice stk500, que coloques el circuito.


Creo que la rutina del Timer va a implementarla luego. En este momento no está logrando siquiera poder encender de forma pareja la carga lo mas cercana al 100% mediante disparos acertados del MOC, que es el primer paso para luego mover el punto de disparo y poder dimmerizar (ahi sí usando un Timer).

Saludos.


En este código no implemente el timer, de hecho el timer fue lo primero que intenté, pero al ver que no funcionaba fui regresando hasta llegar a lo mas básico, para tratar de encontrar el error, que serian los codigos que puse.
Lo curioso es que este circuito ya lo habia hecho funcionar anteriormente para un motor de AC y para un foco, pero en este diseño cambie el modelo del micro y no me funciona, supongo que es algun detalle en la configuracion o algo que no estoy contemplando.

Mas tarde subo los comentarios de las nuevas pruebas
"Nada es imposible, no si puedes imaginarlo"

Desconectado rivale

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1707
Re: Error en codigo de dimer
« Respuesta #7 en: 22 de Noviembre de 2013, 01:17:39 »
Realice unas pruebas con la interrupcion por el timer 0

por lo que veo el dimer se porta bien en algunos valores, pero para otros valores que le cargo al timer, el la lampara empieza a parpadear nuevamente.

Alguna idea de porque hace esto?

uso este codigo

Código: [Seleccionar]
#include <16f819.h>
//#device ADC=8;
#FUSES INTRC_IO, NOCPD, PROTECT, NOMCLR, NOPUT,nowdt,nolvp
#use delay(clock=8000000)//relog para el 12f1822
#define  moc  pin_b3
#define  led  pin_a1
//#byte apfcon = 0x11D//se define el registro apfcon debido a que ccs no lo tiene configurado
//#include "dimer_16.h"
int16 cnt=0;
int1 zero_c=1;
char trigger=0;
int1 re_f=0;
char vals[11]={25,26,27,28,29,30,31,32,33,34,35};
void init()
{  
   setup_adc(adc_off);
   setup_adc_ports(no_analogs);
   set_tris_a(0b00000000);
   set_tris_b(0b00000101);
   setup_oscillator( OSC_8MHZ );

   output_low(moc);
   setup_ccp1(ccp_capture_fe);//se configura el modulo ccp1 en modo captura en flanco descendente para leer el sensor
   setup_timer_1(t1_internal|t1_div_by_2);  //se configura el timer uno para que se incremente cada 1us (4*div/osc) (4MHz)
   setup_timer_0(t0_internal|t0_div_64);//se configura el timer para que se desborde cada 8.192ms(4*div/osc) (4MHz)
   re_f=0;
   ext_int_edge(h_to_l);//interrupcion externa para el cruce por cero  
   enable_interrupts(int_ext);
   set_timer0(0);
  // enable_interrupts(int_ccp1);
   enable_interrupts(global);
}
void  main()
{
   init();
   trigger=0;
  
   while(true)
   {
      
   }
}

int1 on_moc=0;
int cc=0;
#int_ext //interrupcion para detectar el cruce por cero de la linea de AC
void cruce_0()
{                
  
  
   if(zero_c)
   {
      enable_interrupts(int_timer0);
      set_timer0(trigger);
      on_moc=0;
   }
   zero_c=0;
   cnt++;
   if(cnt==240)
   {
       output_toggle(led);
       trigger=vals[cc];
       cc++;
       if(cc==11)cc=0;
       //if(trigger>250)trigger=0;
       cnt=0;
   }
        
   if(re_f)
   {
       ext_int_edge(h_to_l);
       re_f=0;
   }
   else
   {
       ext_int_edge(l_to_h);
       re_f=1;
   }  
   disable_interrupts(int_ext);  
}



#int_timer0
void activar()//interrupcion por timer0, se desborda maximo cada 8.19 ms, si se le da un valor al regitro del timer0 se desbordada antes, y en ese momento se prendera el triac, entre mayor sea el valor del tmr0 el triac estara prendido mayor tiempo
{  
  if(trigger>10)output_high(moc);//si es menor a 10 entonces el triac nunca se prende
  else output_low(moc);
  set_timer0(0);//se reinicia el contador
  delay_us(100);
  output_low(moc);
  clear_interrupt(int_timer0);
  disable_interrupts(int_timer0);
  enable_interrupts(int_ext);
  set_timer0(0);
  zero_c=1;
}

Saludos
"Nada es imposible, no si puedes imaginarlo"

Desconectado BrunoF

  • Administrador
  • DsPIC30
  • *******
  • Mensajes: 3865
Re: Error en codigo de dimer
« Respuesta #8 en: 22 de Noviembre de 2013, 02:41:42 »
Hola,

proba modificando a:
Código: C
  1. //...
  2.  if(zero_c)
  3.    {
  4.       clear_interrupts(int_timer0);
  5.       enable_interrupts(int_timer0);
  6. //...

La lámpara tiene algún regulador electrónico dentro o es directa la carga? Porque por lo que veo no debería comportarse así.
« Última modificación: 22 de Noviembre de 2013, 03:19:02 por BrunoF »
"All of the books in the world contain no more information than is broadcast as video in a single large American city in a single year. Not all bits have equal value."  -- Carl Sagan

Sólo responderé a mensajes personales, por asuntos personales. El resto de las consultas DEBEN ser escritas en el foro público. Gracias.

Desconectado rivale

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1707
Re: Error en codigo de dimer
« Respuesta #9 en: 22 de Noviembre de 2013, 11:14:25 »
mas tarde pruebo lo que comentas Bruno, aunque como dices, creo que no debería comportarse así.

La lampara, solo tiene un integrado que es el que hace la conversión de AC a DC, mas tarde reviso el modelo para ver que es exactamente.

estuve probando con varios valores asignados al timer0, en el video se ve que se comporta bien desde el 25 hasta el 34, pero al incrementar 1(en 35), comienza el comportamiento no deseado, esto para una intensidad baja; posteriormente con valores de 70 aproximadamente, se estabiliza nuevamente con una intensidad mayor, pero se me hace muy extraño el comportamiento que presenta, es como si dejara de medir bien el cruce por cero, o si solo lo detectara en un flanco.

creo que como funciona ahora podría ponerle 3 o 4 valores de intensidad, pero me da mucha curiosidad saber porque no hace lo que debe

 :? :? :?

"Nada es imposible, no si puedes imaginarlo"

Desconectado BrunoF

  • Administrador
  • DsPIC30
  • *******
  • Mensajes: 3865
Re: Error en codigo de dimer
« Respuesta #10 en: 22 de Noviembre de 2013, 14:24:01 »
Es muy raro porque cuando falla, lo hace en un punto de mayor potencial dentro de la senoidal que en el resto de los valores, lo que no debería ser problema alguno para dispararlo correctamente.






« Última modificación: 22 de Noviembre de 2013, 14:44:45 por BrunoF »
"All of the books in the world contain no more information than is broadcast as video in a single large American city in a single year. Not all bits have equal value."  -- Carl Sagan

Sólo responderé a mensajes personales, por asuntos personales. El resto de las consultas DEBEN ser escritas en el foro público. Gracias.

Desconectado rivale

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1707
Re: Error en codigo de dimer
« Respuesta #11 en: 22 de Noviembre de 2013, 14:40:39 »
Es muy raro porque cuando falla, lo hace en un punto de mayor potencia dentro de la senoidal que en el resto de los valores, lo que no debería ser problema alguno para dispararlo correctamente.


Si, se supone que cuando incremento el valor del timer, solo hago que el triac se dispare antes, entonces no debería fallar de esa forma, además, vi que al pasar de 34 a 35 cambia totalmente, siendo que la diferencia en tiempo es de 32[us].

no se si el integrado que tiene la lampara afecte algo, mas tarde pruebo con un foco normal, ahí no debería verse ese problema
"Nada es imposible, no si puedes imaginarlo"

Desconectado BrunoF

  • Administrador
  • DsPIC30
  • *******
  • Mensajes: 3865
Re: Error en codigo de dimer
« Respuesta #12 en: 22 de Noviembre de 2013, 14:44:17 »
Apuntaría hacia la lámpara esa, sí. Seguramente con una lámpara común no se comporte así, excepto se haya dañado algún componente del circuito...
Esperaremos a ver las pruebas.

Saludos
"All of the books in the world contain no more information than is broadcast as video in a single large American city in a single year. Not all bits have equal value."  -- Carl Sagan

Sólo responderé a mensajes personales, por asuntos personales. El resto de las consultas DEBEN ser escritas en el foro público. Gracias.

Desconectado rivale

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1707
Re: Error en codigo de dimer
« Respuesta #13 en: 27 de Enero de 2014, 13:07:53 »
Apuntaría hacia la lámpara esa, sí. Seguramente con una lámpara común no se comporte así, excepto se haya dañado algún componente del circuito...
Esperaremos a ver las pruebas.

Saludos

vuelvo al tema, habia dejado de lado el proyecto por un tiempo, pero ya arme otra placa y resulta que ya tengo todos los niveles de intensidad, al parecer era algún componente dañado.

mas tarde subo un videido
"Nada es imposible, no si puedes imaginarlo"

Desconectado rivale

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1707
Re: Error en codigo de dimer
« Respuesta #14 en: 31 de Enero de 2014, 02:38:54 »
Aca el video de como quedó

Gracias a todos por su ayuda


"Nada es imposible, no si puedes imaginarlo"