Desde la publicación del dimmer, he recibido muchos correos preguntando ciertas particularidades del software que lo controla. Esta es la razón por la cual he decidido crear esta serie de entradas con la intención de facilitar la tarea a todos aquellos que prefieren crear su propio software y hardware en vez de usar alguno de otro proyecto disponible en la red.
El firmware básicamente realiza las siguientes tareas:
- Monitorea el pin de detección de cruce por cero y carga el valor apropiado en un timmer del PIC, para que este se desborde en algún momento del semiciclo y disparar entonces el Triac.
- Esta atento a los cambios de estado del pin en el que esta conectado el receptor infrarrojo, si se detecta un cambio en este pin se inicia la captura del tiempo del pulso (recordar que el protocolo IR de sony utiliza codificación por ancho de pulsos.
- Detecta y reconoce las pulsaciones cortas y largas del pulsador para el control manual del dimmer.
En esta primera parte me voy a concentrar en la detección de cruce por cero y el disparo del triac.
Detección de los cruces por cero.
Utilizaremos la interrupción externa del PIC para detectar cuando el voltaje se aproxima a cero y por lo tanto cuando debe comenzar el conteo para disparar el TRIAC.
Hablaremos entonces sobre la función void vInterruptZeroCross()
que esta asociada a la interrupción externa. La variable iIntControl sirve para recordar que flanco queremos detectar en la siguiente interrupción externa, mientras que la variable global iLampBrightness contiene el valor a cargar en el timer y es modificada por las funciones que desean cambiar el brillo de la lámpara.
Por otra parte, iTriacFlag se utiliza como auxiliar para generar un pulso de corta duración en la interrupción de desbordamiento del timer0 y se explicará más adelante.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | #INT_EXT void vInterruptZeroCross() { static int iIntControl = 0; output_low( _TRIAC_CONTROL ); // Turn triac output to low level, just in case it is still high iTriacFlag = FALSE; // Set triac status flag to off status set_timer0( iLampBrightness ); // Prepare timer to trigger the triac on the next TMR0 interrupt if( iIntControl== 0 ) // Change the external interrupt edege alternately { iIntControl = 1; ext_int_edge( H_TO_L ); } else { iIntControl = 0; ext_int_edge( L_TO_H ); } return; } |
En esta interrupción se realiza la carga del valor necesario al timer0 para que se desborde dentro de un intervalo de tiempo que corresponda con el periodo del semiciclo de corriente alterna.
Para esto hay que configurar los prescalers para obtener un desbordamiento del timer un cada poco más de 8 milisegundos (1/(2*60)) para la red eléctrica de 60 Hz. El tiempo de incremento del timer determinara cuantos Tics nos caben en cada semiciclo de la red y por lo tanto la resolución con la que podremos controlar el brillo de la lámpara.
Idealmente tendríamos 256 posibles niveles de intensidad, que corresponden a los posibles valores que podemos cargar al timer, sin embargo, hay factores prácticos que limitan este rango: como la precisión del detector de cruce por cero, la corriente mínima requerida para encender el triac y mantenerlo en estado de conducción, etc.
Por lo tanto, de todos los valores posibles a cargar en el timer hay que descartar los primeros y los últimos. En mi caso, mediante experimentación con un osciloscopio y mi depurador ICD2 decidí limitar los valores a cargar en el timmer con las siguientes definiciones en el código fuente.
1 2 | #define _LAMP_TOP 225 #define _LAMP_MIN 40 |
Siempre se puede jugar con este valor hasta obtener un funcionamiento óptimo. Estas definiciones me dejan con 186 valores útiles para cargar al timer.
Hay que recordar que _LAMP_TOP representa el brillo máximo y por lo tanto el timer se debe cargar con un valor grande que haga que se desborde prácticamente al comienzo del semiciclo, mientras que _LAMP_MIN representa la mínima salida lumínica y si se carga ese valor al timer la interrupción de este ocurrirá prácticamente al final del semiciclo, permitiendo que el triac conduzca durante solamente un breve periodo de tiempo.
Concluimos que para aumentar el brillo hay que incrementar el valor de la variable iLampBrightness, mientras que para disminuir el brillo hay que decrementarlo. Dicho esto podemos elaborar las funciones que controlan el brillo a través de las teclas + / -, por ejemplo para aumentar el nivel de brillo:
1 2 3 4 5 6 7 8 | void vLampBright() { output_high( _STATUS_LED ); iLampBrightness = ( iLampBrightness + 5 < _LAMP_TOP ) ? iLampBrightness + 5 : _LAMP_TOP; delay_ms( 20 ); output_low( _STATUS_LED ); return; } |
Disparo del Triac
Cuando ocurre una interrupción del timer0, el microcontrolador envía un pulso al gate del Triac para que este comience a conducir, una vez que el triac se ha disparado, podemos interrumpir el pulso al terminal de compuerta y el dispositivo seguirá conduciendo hasta que la corriente a través de los terminales MT1 y MT2 cae por debajo de cierto valor umbral, que es una característica propia de cada dispositivo.
Al deshabilitar rápidamente el pulso en la compuerta evitamos consumir energía de manera innecesaria (hay que recordar que estamos limitados en este aspecto por la fuente capacitiva).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | #INT_TIMER0 void vInterruptTimer0() { if( !iTriacFlag ) //If the triac pin is low we change the state and prepare the timer { if( iLampBrightness > _LAMP_MIN ) // Do not trigger if level is set to min output_high( _TRIAC_CONTROL ); // Turn on triac set_timer0( 250 ); // Next timer overflow will clear the triac pin iTriacFlag = TRUE; // Flag now signals that we need to turn off the triac output pin } else { //The triac has been triggered, cut the pulse output_low( _TRIAC_CONTROL ); set_timer0( 0 ); //Set timer period to maximum, timer should not overflow untill next zero cross interrupt iTriacFlag = FALSE; //Change Triac Flag status, triac pin is now low } return; } |
Este código genera un pulso en el pin definido como _TRIAC_CONTROL. La primera interrupción coloca un 1 lógico en el pin del triac, cambia el valor de la variable iTriacFlag a 1 y coloca un valor grande en el registro del timer, lo cual produce una interrupción poco después de que se envío el pulso al terminal gate.
Esta segunda interrupción del timer0, desactiva el pulso de gate al triac. Cambiando el valor cargado al timer en la primera interrupción (cuando !iTriacFlag se evalúa como verdadero) se pueden lograr pulsos más largos o más cortos para manejar la compuerta del triac.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | #INT_TIMER0 void vInterruptTimer0() { if( !iTriacFlag ) //If the triac pin is low we change the state and prepare the timer { if( iLampBrightness > _LAMP_MIN ) // Do not trigger if level is set to min output_high( _TRIAC_CONTROL ); // Turn on triac set_timer0( 250 ); // Next timer overflow will clear the triac pin iTriacFlag = TRUE; // Flag now signals that we need to turn off the triac output pin } else { //The triac has been triggered, cut the pulse output_low( _TRIAC_CONTROL ); set_timer0( 0 ); //Set timer period to maximum, timer should not overflow untill next zero cross interrupt iTriacFlag = FALSE; //Change Triac Flag status, triac pin is now low } return; } |
Conclusión
Con los fragmentos de código anteriores, es posible construir un dimmer basado en PIC, tal vez no a control remoto, pero se pueden colocar un par de botones, los cuales aumenten y/o disminuyan la intensidad de la luz.
Hay que recordar que trabajar con equipos conectados directamente a la red de 120 o 220 volts es peligroso y en la medida de lo posible hay que evitarlo. Conviene hacer las pruebas con un generador de funciones o alguna otra fuente que nos permita obtener una señal de 60 Hz para aplicar al PIC, o con un transformador y una lámpara de 12 volts.
Si finalmente deciden conectarlo a la red eléctrica queda advertirles que es completamente bajo su responsabilidad.
Che…pongan un poco de uds. para poder hacer el dimmer. Les está sirviendo el proyecto en bandeja…que mas quieren? Saludos.
Pues me gustaria que subieras mas fragmentos de codigo para realizar el dimer con dos pulsadores
Oigan pongan mas datos para terminar el dimmer ya que no lo he podidod relizar
Hola Rubén me siento muy orgulloso de que tu genialidad sobre la eletrónica sea tratada tan bien por un joven brillante y mexicano… he leido poco pero lo suficiente para decir esto de tu blog, espero podamos colaborar juntos, ya que mi mejor hobby es la electrónica, te dire que soy autodidacta y tu historia es muy similar a la mía… desarmando aparatos de casa… después intuí que debería tener una memoria sobre cuanto aparato o dispositivo electrónico “cayera” en mis manos, por lo que me hice “adicto” a sacarles el diagrama electrónico, entendiendo de alguna manera tan solo por el diagrama; de que dispositivo se trataba, ahora con el manejo de sistemas microcontrolados… pués existe una enorme potencialización de los dispositivos, que también me ha gustado diseñar, sin embargo no me había dado por compartir, como tu lo haces, el acervo o pasión que tenemos por la electrónica espero en esto, poder colaborar contigo, aportaciones, dudas o sugerencias que en ambos sentidos se generen,de nuevo mis saludos y reconocimientos.
Atte.
Juan Angel M.G.
Hola buenas,
queria hacerte una pregunta a ver si me puedes ayudar, estoy haciendo un proyecto de fin de carrera y necesito variar una resistencia(de calor) en alterna, y me preguntaba si con el dimmer se podria hacer pero no necesito control por ir, solo variando yo la tension de continua con un controlador
Muchas gracias
Hola mi estimado amigo.
Si es posible controlar una resistencia eléctrica usando un triac de manera muy similar a como se hace con la lámpara, ya que también es una carga mayormente resistiva.
Con la resistencia tienes la ventaja de que no impone limitantes en cuanto a los tiempos de encendido y apagado (para evitar parpadeos), por lo que puedes realizar la conmutación únicamente en los cruces por cero, disminuyendo bastante la interferencia producida por el cambio brusco en la corriente.
Hay una nota de aplicación de microchip en la que te dan mas información, espero que no tengas problema para leer en ingles. Checa la sección titulada “zero cross switching”
http://ww1.microchip.com/downloads/en/AppNotes/00958A.pdf
Saludos José y éxito.
TE AGRADEZCO INFINITAMENTE TU CONTRIBUCION A MI FORMACION.TU TEMA INTERESANTE.UNA PREGUNTA QUE LIBROS PUEDO CONSULTAR PARA APRENDER A LEER SEÑALES EXTERNAS COMO UN CONTROL REMOTO Y TAMBIEN A GENERARLAS???MI LIMITACION QUE LOS PROGRAMAS LOS HAGO EN C .
Hola Alexander.
La información de los protocolos la obtuve de una página web en inglés que habla de muchos protocolos. Concretamente lo encontré aquí: http://www.sbprojects.com/knowledge/ir/ir.htm.
Para algunos protocolos puedes encontrar más información en Wikipedia o en la Web. De momento no conozco un libro que trate el tema especificammente, los algoritmos los puedes idear tu, conociendo los parámetros de la señal en los cuales va codificada la información (periodo del pulso para SIRC por ejemplo).
Saludos.
Este es mi desarrollo
http://www.youtube.com/watch?v=pFzIqUd7ZDU
saludos…
Se vé bastante bien Automatik, ojala pudieras mostrar como te quedo el PCB.
Saludos.
Agradezco cualquier información que me envien. tozal00968 en hotmail.com referente al tema:dimmer por infrarojos.me ayudará a entender y a despejar dudas.
Hola Alexander, tal vez quieras revisar el artículo original que escribí, ahí esta un poco más detallado el protocolo de Sony. También, en la segunda parte de este articulo se verá el firmware, solo que aún no la tengo lista.
Gracias por toda la información publicada.Trabajo la electrónica pero apenas me inicio en el microcontrol.Me fascina el tema .Felicitaciones .Adelante con la ciencia y la investigación. desde cali – colombia un amigo.Alexander zapata [email protected]
Ah…con el dimmer y otros productos iR que comercializo me va excelente. Saludos
Automatik.
Incluiste en tu diseño la red Snubber para el triac?, el detalle es que en mi caso no esta incluida, pero he leido que es necesario cuando se manejan cargas inductivas.
Saludos y mucha suerte, me gustaría algun día comercializar un producto mio 😉
Hola de nuevo, muchas gracias por los links…actualmente estoy modificando mi desarrollo para trabajar con trafos electrónicos para dicros de 12v y estoy obteniendo muy buenos resultados. Cuando lo finalice te paso alguna data. Saludos
Ah…no hay que modificar el hard, hay que hacer algunas trampitas a nivel de soft (option_reg) y modificar ángulos. ;=)
Hola que tal, dejame felicitarte por tu proyecto me ha sido de mucha ayuda para mi proyecto de la universidad, me gustaria que me explicaras como es que detectas la tecla del control (IR)ya que es en lo que me he trabado y es en calidad de urgente!!!!, espero y me puedas responder y de antemano agradesco tu aporte y atencion,
saludos!!!
Hola Andres.
Para la recepción de IR, más especificamente del protocolo de sony, lo que hago es medir los tiempos entre los flancos de la señal (mediante un timer y la interrupción por cambio de estado) y decidir si se trata de un uno o un cero lógico. Esos unos y ceros los voy guardando en una variable hasta recibir la trama completa y finalmente se hace un switch sobre el valor recibido para decidir que se debe hacer.
Te recomiendo que revises esto:
http://ww1.microchip.com/downloads/en/AppNotes/00566b.pdf
Saludos 🙂
Hola automatik.
¿Como te va con tu dimmer?
No tengo un circuito como tal para lámparas halógenas, sin embargo tengo en mis favoritos algunos enlaces bastante interesantes que hablan sobre dimmers para cargas inductivas y/o SMPS para iluminación con led:
http://www.epanorama.net/documents/lights/lightdimmer.html#inductive
http://members.misty.com/don/bulb1.html
En estos enlaces tienes una idea de que hacer y que NO hacer cuando estas regulando cargas inductivas. Si encuentras un diseño de referencia para lamparas halógenas, me gustaría verlo 😉
Saludos.
Hola actualmente comercializo un dimmer remoto que desarrollé hace un tiempo, muy buena tu explicación sobre como encarar el tema a nivel de soft. Tenés alguna data de dimmer para transformador electrónico o mecánico para dicroicas o AR111 12v? Saludos…