Dimmer pic,iIniciar el timer0 cuando se genere la interrupción externa ?

Hola,

Estoy realizando un dimmer para controlar la potencia entregada a una bombilla de 100W.

Dependiendo de la entrada analógica que enviará el controlador (0%5V) se entregará a la carga entre el 0 y el 100% de Potencia a través de la variación del ángulo de disparo de un triac.

Lo he realizado de una manera que ya se ha comentado en este foro, es decir, una vez se detecta el cruce por cero, se genera una interrupción y en ese momento se temporiza con un timer el tiempo necesario con RA1 en estado bajo y al finalizar la temporización se eleva RA1 a estado alto.

Bien pues le he dado vueltas y vueltas al programa y al probar el microcontrolador (PIC18F252) después de haberlo programado, no consigo aplicar más del 71 o 72% de potencia, es decir, el máximo ángulo de disparo que puedo obtener es de unos 8 ms y pico.

Os dejo el código y haber si alguien me puede echar una mano por favor:

PHP:
#include <pic18.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>

unsigned int vdig;
unsigned char potencia;
const float lsb=(float)5/1024;
float vanalog,potenciafloat;

const unsigned int tempo[]={55535,56695,57004,57225,57403,57555,57689,57811,57923,58027,58124,58216,58304,58388,58468,58545,58620,58693,58763,58831,58898,58963,59027,59090,59151,59211,59271,59271,59386,59443,59499,59555,59609,59664,59717,59770,59823,59876,59928,59979,60031,60082,60133,60184,60234,60284,60335,60385,60435,60485,60535,60585,60635,60685,60735,60786,60836,60886,60937,60988,61039,61091,61142,61194,61247,61300,61353,61406,61461,61515,61571,61627,61684,61741,61799,61859,61919,61980,62043,62107,62172,62239,62307,62377,62450,62525,62602,62682,62766,62854,62946,63043,63147,63259,63381,63515,63667,63845,64066,64375,65535};

void main()
{
	/* CONFIG. PUERTOS */
	/* PUERTO_A:  RA0(AnalogIN)  RA1(DigitalOUT)-ANG.DISP */
	LATA=0;
	TRISA=0x01;
	RA1=0;
	/* PUERTO_B:  RB0(DigitalIN) interrupción externa 0 (paso por cero) */
	LATB=0;
	TRISB=0x01;
	/* CONFIG. A/D */
	/* Canal: AN0, Fconv: Fosc/32, Referencia Vdd y Vss (5V), Encendido del Modulo A/D, Result. just. drcha */
	ADCON0=0X41;  
	ADCON1=0x8E;
	/* CONFIG. TIMER1, Borro Flag */
	T1CON=0x00;
	TMR1IF=0;
	/* CONFIG. INT.EXT.0 */
	/* Flanco bajada, Habilito int.ext.0, Borro Flag */
	INTEDG0=0;   
	INT0IE=1;
	INT0IF=0;
	/* Habilitador global de interrupts. */
	PEIE=1;
	GIE=1;
		
	while(1);

}

void interrupt angulo_disparo()
{
		if(INT0IF==1)
		{
			RA1=0;
			INT0IF=0;
			TMR1ON=0;
			TMR1=0;
			INTEDG0=!INTEDG0;
			GODONE=1;
			while(GODONE==1);
			vdig=((int)ADRESH<<8)+ADRESL;
			ADIF=0;
			vanalog=((float)lsb)*vdig;
			if((vanalog>=0)&&(vanalog<=5))
			{
				potenciafloat=vanalog*20;
				potencia=(char)potenciafloat;
				TMR1IE=1;
				GIE=1;
				PEIE=1;
				//TMR1=tempo[potencia];
				TMR1H=tempo[potencia]>>8;
				TMR1L=(tempo[potencia])&0x00FF;
				TMR1ON=1;	
			}
		}
		if(TMR1IF==1)
		{
			RA1=1;
			TMR1IF=0;
			TMR1ON=0;
			TMR1=0;
			TMR1IE=0;
			GIE=1;
		}	
}
 
Última edición por un moderador:
Saludos compañeros, espero alguien me pueda aconsejar.

Como en estos días ando desocupado :cool:, me propuse a avanzar con un proyecto que tenia guardado, en concreto es un control dimmer digital el cual ya funciona (y) muy bien.

Aquí un vídeo que le tome cuando estaba armado.


En ese momento se me ocurrio probarlo con una secadora de pelo y un generador de vapor, principalmente por curiosidad y por que quería probar el triac a 24 amperes :D.

Pero la desventaja es que solo funciona para un elemento, osea solo una salida, por lo cual se me ocurrió agregar mas salidas.

Por experiencia de otro proyecto (control 8 servos) se me ocurrió implementar el código del control de los servos :unsure:.

Pero necesito sincronizar la señal de la linea CA a 60Hz para que en cada cruce por cero, osea cada interrupción externa inicie el contador del timer0 e implementar el control pwm. ;)

Ahora ando con una falla mental y por el momento no se me ocurre nada, quizá sea algo sencillo de solucionar, así que si alguien puede ayudarme de antemano se lo agradezco, si el proyecto avanza no dudare en subirlo al foro(y).
 
Hola:
El TMR0 no tiene un bit de On/Off como el TMR1 o TMR2. Solo se me ocurre que cuando ocurra la interrupción limpies el registro del TMR0 a cero para que inicie la cuenta. Otra es que implementes el On/Off del Timer0 por medio de una variable y que verifique la variable contantemente al momento de generar los pulsos con el timer0, entonces si la variable es '0' no hace nada y si es '1' genera los pulsos.

Saludos
 
Hola:
El TMR0 no tiene un bit de On/Off como el TMR1 o TMR2. Solo se me ocurre que cuando ocurra la interrupción limpies el registro del TMR0 a cero para que inicie la cuenta. Otra es que implementes el On/Off del Timer0 por medio de una variable y que verifique la variable contantemente al momento de generar los pulsos con el timer0, entonces si la variable es '0' no hace nada y si es '1' genera los pulsos.

Saludos

Saludos amigo axel, gracias por la respuesta, me parece interesante tu consejo, ya lo pruevo y comento los resultados. (y)
 
Atrás
Arriba