Autor Tema: Dimmer con TMR0  (Leído 10763 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado jhozate

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1698
Re: Dimmer con TMR0
« Respuesta #15 en: 14 de Julio de 2009, 19:47:50 »
psss el cruce por cero lo detecto con resistencia de 5M (asi como pone la nota de microchip) pero yo pongo la resistencia en RB4 y no tengo q fijarme por cambiar el flanco si sera ascendente o descendente y el codigo en asm es para poder salir de la interrupcion por cambio de nibble, se debe escribir o leer el portb(cosa q hay q hacerlo por soft) y de la abandera se encarga el ccs.

saludos
Ser Colombiano es un Premio, Saludos desde CALI-COLOMBIA

Desconectado Cryn

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 4169
Re: Dimmer con TMR0
« Respuesta #16 en: 15 de Julio de 2009, 11:15:30 »
muy interesante solución...

y queda muy bien, te ha funcionado el dimmer??

puedes cambiar la instrucción que colocaste en asm por:

output_b(input_b());

solo para mantener la estructura en C, jeje, soy muy aficionado de tener o todo en C o todo en ASM

saludos
.

Desconectado hamiltontodopic

  • PIC10
  • *
  • Mensajes: 3
Re: Dimmer con TMR0
« Respuesta #17 en: 07 de Noviembre de 2009, 03:40:45 »
Amigos me podrian ayudar a adaptar este codigo a mplab para el pic16f88,mil gracias saludos


Desconectado jhozate

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1698
Re: Dimmer con TMR0
« Respuesta #18 en: 07 de Noviembre de 2009, 13:34:02 »
busca el plug-in para vincular ccs con mplab y listo..aqui mismo en el foro esta
« Última modificación: 07 de Noviembre de 2009, 14:03:41 por jhozate »
Ser Colombiano es un Premio, Saludos desde CALI-COLOMBIA

Desconectado hamiltontodopic

  • PIC10
  • *
  • Mensajes: 3
Re: Dimmer con TMR0
« Respuesta #19 en: 07 de Noviembre de 2009, 14:00:39 »
Gracias por responder ahorita lo busco

saludos!!

Desconectado MexaTronko

  • PIC10
  • *
  • Mensajes: 38
Re: Dimmer con TMR0
« Respuesta #20 en: 06 de Enero de 2014, 02:14:36 »
hola vi este tema y tome su idea solo que puse un potenciometro en lugar de botones y el disparo esta dado por la lectura del adc, pero no tengo una sincronia por lo que se dispara el triac en cualquier momento y no puedo regular la intesidad de mi carga (foco), espero que me puedan hechar la mano dejo mi codigo de antemano gracias.

#include <16F886.H>   //LIbreria del PIC Implementado.
#device ADC = 8
#fuses HS, MCLR, NOWDT, PUT, NOIESO, NOFCMEN //Deshabilita el Doggy, Oscilador Externo.
#use delay( clock = 12000000 )   //Crystal de 20MHz.INTRC_IO
#use standard_io( B )
#use standard_io( C )   //Direccion del Puerto B.

#define LCD_E     PIN_C0
#define LCD_CK    PIN_C1   
#define LCD_DAT   PIN_C2

#include <flex_lcd_3pins.c>

int f = 0, Cont0 = 0, leer;

#INT_EXT
void ext( void )
   { 
      if( f == 0 )         //Deteccion de Flanco de Subida.
         {
           set_timer0( 160 );
           f = 1;         //Cambio de Bandera de FLag.
           ext_int_edge( 0, H_TO_L );   //Cambio a Flag de Bajada.
           enable_interrupts( INT_TIMER0 );
         }   
      else         //Deteccion de Flanco de Bajada.
         {
            set_timer0( 160 );
            f = 0;              //Cambio de Bandera de FLag.
            ext_int_edge( 0, L_TO_H );   //Cambio a Flag de Subida.
            disable_interrupts( INT_TIMER0 );
         }
   }

#INT_TIMER0
void timer0 ( void )
   {
      Cont0++;
      set_timer0( 160 );
      if( Cont0 == 255 )
         {
            Cont0 = 0;
         }
      if( Cont0 == leer )
         {
            output_high( PIN_B1 );
         }
       else
         {
            output_low( PIN_B1 );
         }
   }

void main( void )
   { 
      //setup_oscillator( OSC_8MHZ );208
      lcd_init();
      //lcd_setcursor_vb(1,1);
     
      ext_int_edge( 0, L_TO_H );   //Inicia en Flag de Subida.
      enable_interrupts( INT_EXT );   //Habilita la Interrupcion Externa.
     
      setup_adc_ports( SAN0 );   //Seleccion del Canal 0 Analogico.
      setup_adc( ADC_CLOCK_INTERNAL );   //Reloj Interno RC.
      set_adc_channel( 0 );    //Habilita el Canal 0;
     
      //set_timer0( 208 );
      setup_timer_0( RTCC_INTERNAL | RTCC_DIV_1 );  //Prescaler de 1.
      disable_interrupts( INT_TIMER0 );      //Deshabilita la Interrupcion del Timer1.         
      enable_interrupts( GLOBAL );    //Habilita la Interrupcion Global.
     
      while( 1 )
         {     
            leer = read_adc();
            delay_us( 10 );
            printf( lcd_putc, "\fADC =  %4u\n", leer );   //Muestra el Valor del Dato Leido por el ADC.
            printf( lcd_putc, "Cont0 =  %4u", Cont0 );   //Muestra elVoltaje Correspondiente al Dato.
            delay_ms( 500 ); 
         }
   }

Desconectado rivale

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1707
Re: Dimmer con TMR0
« Respuesta #21 en: 06 de Enero de 2014, 14:00:29 »
Veo algunos errores en tu codigo,
-no necesitas apagar la interrupcion del timer0 cuando cambias de flanco, recuerda que el triac tiene que activarse en ambos sentidos de la senoidal, -tambien debes verificar que la frecuencia de tu activacion del timer sea acorde a la frecuancia de tu liena de AC
- el valor que leas directamente de tu pot no necesariamente puedes aplicarlo directamente al tiempo de activacion del triac
-no es necesario que leas continuamente el valor de tu potenciometro, puedes leerlo cada que recibas el cruce por cero, que es cuando utilizaras el valor


Saludos
"Nada es imposible, no si puedes imaginarlo"

Desconectado MexaTronko

  • PIC10
  • *
  • Mensajes: 38
Re: Dimmer con TMR0
« Respuesta #22 en: 06 de Enero de 2014, 20:39:43 »
hola gracias por corregirme, modifique el codigo cambie el cristalexterno por el inerno del micro de 8MHz y ahora tomo elvalor del adc en el flanco de subida, solo que ahora el pulsito de disparo esta dado por un intervalo, hice la simulacion y elpulsito se "mueve solito"y no realiza un buen disparo en el triac no se si sea un error de sincronia o este utilizando mal el timer0 el calculo para cargar el timer0 lo hice asi

x = 256 - 32*10^-6*8*10^6 / 4 * 1
x = 192

el 32*10^-6 sale de dividir 120^-1/256 que seria el periodo del cruce por cero (la frecuencia de la linea es de 60Hz) entre los 256 valores del adc y un prescaler de 1, para que el timer0 realice una interrupcion cada 32usegundos, no se si de esta manera de cargar el timer0 es buena o hay otra forma de ajustarlo, porque yo creo que no hay sincronia.

#include <16F886.H>   //LIbreria del PIC Implementado.
#device ADC = 8
#fuses INTRC_IO, MCLR, NOWDT, PUT, NOIESO, NOFCMEN //Deshabilita el Doggy, Oscilador Interno.
#use delay( clock = 8000000 )
#use standard_io( B )
#use standard_io( C )   //Direccion del Puerto B.

#define LCD_E     PIN_C0
#define LCD_CK    PIN_C1   
#define LCD_DAT   PIN_C2

#include <flex_lcd_3pins.c>

int f = 0, Cont0 = 0, leer;

#INT_EXT
void ext( void )
   { 
      if( f == 0 )         //Deteccion de Flanco de Subida.208
         {
           leer = read_adc();
           set_timer0( 192 ); //carga el timer0
           f = 1;         //Cambio de Bandera de FLag.
           ext_int_edge( 0, H_TO_L );   //Cambio a Flag de Bajada.
         }   
      else         //Deteccion de Flanco de Bajada.
         {
            set_timer0( 192 );
            f = 0;              //Cambio de Bandera de FLag.
            ext_int_edge( 0, L_TO_H );   //Cambio a Flag de Subida.
         }
   }

#INT_TIMER0
void timer0 ( void )
   {
      Cont0++;
      set_timer0( 192 );
      if( Cont0 == 256 )
         {
            Cont0 = 0;
         }
      if( Cont0 < leer )
         {
            output_low( PIN_B1 );
         }
      if( Cont0 >= leer && Cont0 <= leer + 5  )
         {
            output_high( PIN_B1 );
         }
      if( Cont0 > leer + 5 )
         {
            output_low( PIN_B1 );
         }
   }

void main( void )
   {
      setup_oscillator( OSC_8MHZ );
     
      lcd_init();
     
      ext_int_edge( 0, L_TO_H );   //Inicia en Flag de Subida.
      enable_interrupts( INT_EXT );   //Habilita la Interrupcion Externa.
     
      setup_adc_ports( SAN0 );   //Seleccion del Canal 0 Analogico.
      setup_adc( ADC_CLOCK_INTERNAL );   //Reloj Interno RC.
      set_adc_channel( 0 );    //Habilita el Canal 0;
     
      setup_timer_0( RTCC_INTERNAL | RTCC_DIV_1 );  //Prescaler de 1.
      enable_interrupts( INT_TIMER0 );      //habilita la Interrupcion del Timer0.         
      enable_interrupts( GLOBAL );    //Habilita la Interrupcion Global.
     
      while( 1 )
         {     
            printf( lcd_putc, "\fADC =  %4u\n", leer );   //Muestra el Valor del Dato Leido por el ADC.
            printf( lcd_putc, "Cont0 =  %4u", Cont0 );   
            delay_ms( 500 ); 
         }
   }

Desconectado rivale

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1707
Re: Dimmer con TMR0
« Respuesta #23 en: 07 de Enero de 2014, 11:28:38 »
tus cálculos estan bien, el periodo de interrupción es de 8.3 [ms] y tu timer se desborda cada 32 [us], creo que el problema esta en tu condicion dentro del timer0

tu estas esperando que tu variable cont0 llegue a 256, pero como la declaraste como un entero (en CCS los int son de 8 bits) esta no puede pasar de 255 (o de 127 si es signado) y el siguiente numero es 0, entonces nunca se cumple tu condicion

Otra forma para configurar tu timer podria ser con un multiplicador de 64, asi tu timer interrumpe cada 8.19 [ms], que es cercano a tu interrupcion, y de esta forma podrias utilizar tu lectura del ADC para cargarla al registro del timer0 (set_timer0(leer)) y en tu interrupción solo activas el triac, espero te sirva

Saludos
"Nada es imposible, no si puedes imaginarlo"

Desconectado MexaTronko

  • PIC10
  • *
  • Mensajes: 38
Re: Dimmer con TMR0
« Respuesta #24 en: 07 de Enero de 2014, 20:56:44 »
rivale tienes razon la condicion no se cumplira nunca, ya correji la condicion la cambie por 255 y el pulsito se sigue moviendo osea que dispara o no el triac en un tiempo que no le corresponde,  pero no entiedo una cosa lo del multiplicador de 64, entedi que cada valor del adc tomado hara un retardo, dejo una imagen poe si no me explique

Desconectado rivale

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1707
Re: Dimmer con TMR0
« Respuesta #25 en: 08 de Enero de 2014, 11:16:08 »
creo que el problema es que tu timer y tu interrupcion no estan sincronizadas, es decir, cada que detectes un cruce por cero debes reiniciar tu contador "CONT0" para que asi tu timer comience a contar a partir de ese momento.

otra cosa que tienes que considerar es que  en esta condición
 if( Cont0 >= leer && Cont0 <= leer + 5  )

si tu variable de leer vale mas de 250 entonces tu valor (leer+5) excede el maximo de tu variable tipo entero



En cuanto a lo del divisor de 64 me referia a que puedes configurar tu timer0 de la siguiente manera

setup_timer_0( RTCC_INTERNAL | RTCC_DIV_64 ); 

entonces tu tiempo de interrupción será 4/8000000 * 64 * (256-tmr0).

donde tmr0 es el valor de tu registro del timer0, cuando este valga 0, tu interrupcion será cada 8.19 ms, si incrementas el valor entonces tu interrupcion será cada menos tiempo.

y puedes usar el tiempo de tu interrupcion para activar tu triac, cuando quieras que se prenda al maximo le das un valor de set_timer0(255) y cuando quieras un valor medio lo seteas con 120 por ejemplo, entre menor sea el numero que cargues en el registro menos sera la parte de la senoidal que dejarás pasar
« Última modificación: 08 de Enero de 2014, 11:25:41 por rivale »
"Nada es imposible, no si puedes imaginarlo"

Desconectado MexaTronko

  • PIC10
  • *
  • Mensajes: 38
Re: Dimmer con TMR0
« Respuesta #26 en: 08 de Enero de 2014, 16:57:29 »
Gracias rivale ya ha quedado, reinicie el contador del timer0 en cada cruce por cero y agrege dos condiciones para que no se salga de los limetes

leer = read_adc();
if( leer == 0 )
{
  leer = 1; 
}
if( leer == 255 )
{
leer = 254;
}

y en la condicion del timer0 solo le sume uno y con la condicion de arriba no se pasara del limite
if( Cont0 >= leer && Cont0 <= leer + 1  )
{
  output_high( PIN_B1 );
 }

dejo el codigo por si alguien lo quiere utilizar, de nuevo gracias.

#include <16F886.H>   //LIbreria del PIC Implementado.
#device ADC = 8
#fuses INTRC_IO, MCLR, NOWDT, PUT, NOIESO, NOFCMEN //Deshabilita el Doggy, Oscilador Externo.
#use delay( clock = 8000000 )   //Crystal de 20MHz.
#use standard_io( B )
#use standard_io( C )

#define LCD_E     PIN_C0
#define LCD_CK    PIN_C1   
#define LCD_DAT   PIN_C2

#include <flex_lcd_3pins.c>

int f = 0, Cont0 = 0, leer;

#INT_EXT
void ext( void )
   { 
      if( f == 0 )         //Deteccion de Flanco de Subida.208
         {
           leer = read_adc();
           if( leer == 0 )
             {
               leer = 1; 
             }
           if( leer == 255 )
              {
               leer = 254;
              }
           Cont0 = 0;
           set_timer0( 192 );
           f = 1;         //Cambio de Bandera de FLag.
           ext_int_edge( 0, H_TO_L );   //Cambio a Flag de Bajad
         }   
      else         //Deteccion de Flanco de Bajada.
         {
            Cont0 = 0;
            set_timer0( 192 );
            f = 0;              //Cambio de Bandera de FLag.
            ext_int_edge( 0, L_TO_H );   //Cambio a Flag de Subida.
         }
   }

#INT_TIMER0
void timer0 ( void )
   {
      Cont0++;
      set_timer0( 192 );
      if( Cont0 < leer )
         {
            output_low( PIN_B1 );
         }
      if( Cont0 >= leer && Cont0 <= leer + 1  )
         {
            output_high( PIN_B1 );
         }
      if( Cont0 > leer + 1 )
         {
            output_low( PIN_B1 );
         }
   }

void main( void )
   {
      setup_oscillator( OSC_8MHZ );
     
      lcd_init();
     
      ext_int_edge( 0, L_TO_H );   //Inicia en Flag de Subida.
      enable_interrupts( INT_EXT );   //Habilita la Interrupcion Externa.
     
      setup_adc_ports( SAN0 );   //Seleccion del Canal 0 Analogico.
      setup_adc( ADC_CLOCK_INTERNAL );   //Reloj Interno
      set_adc_channel( 0 );    //Habilita el Canal 0;
   
      //set_timer0( 192 );//16 131
      setup_timer_0( RTCC_INTERNAL | RTCC_DIV_1 );  //Prescaler de 1.
      enable_interrupts( INT_TIMER0 );      //habilita la Interrupcion del Timer1.         
      enable_interrupts( GLOBAL );   
     
      while( 1 )
         {     
            printf( lcd_putc, "\fADC =  %4u\n", leer );   //Muestra el Valor del Dato Leido por el ADC.
            printf( lcd_putc, "Cont0 =  %4u", Cont0 );   //Muestra elVoltaje Correspondiente al Dato.
            delay_ms( 300 );   
         }
   }

Desconectado rivale

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1707
Re: Dimmer con TMR0
« Respuesta #27 en: 08 de Enero de 2014, 17:18:01 »
 ((:-)) ((:-))

que bien que ya quedó solucionado

"Nada es imposible, no si puedes imaginarlo"


 

anything