Hola amigos!
Estoy retomando el proyecto del dimmer.
Se trata de un dimmer de 1 canal , se puede ajustar a 5 niveles de operación 0%,25%,50%,75% y 95% y se controla serialmente(4800bps,8bits,1stop,N).
Si envian 0x30H esta apagado
Si envian 0x31H " 1 " esta trabajando al 25%
Si envian 0x32H " 2 " esta trabajando al 50%
Si envian 0x33H " 3 " esta trabajando al 75%
Si envian 0x34H " 4 " esta trabajando al 95%Código: C
#include <12F683.h> #FUSES INTRC_IO,NOWDT,PUT,NOMCLR,BROWNOUT,PROTECT,CPD,NOIESO,NOFCMEN #use delay(internal=8MHZ) //Oscilador interno 8MHz #use rs232(baud=4800,rcv=PIN_A3) //Velocidad limitada por receptor el receptor infrarrojo #use fast_io(A) #zero_ram #priority timer0,int_ra //************************************************************// #define debug // Comment line out for no debug #define Carga1 pin_A0 #define Carga2 pin_A1 #define Carga3 pin_A4 #define LED_status pin_A5 //************************************************************ char intensidad[5]={0,159,191,224,254}; //Equivale a 0%,25%,50%,75%,95% char nivel_intensidad; char desborde_T0; char cruce_detectado; char zero_HtoL; char dato_recibido; //************************************************************ void main(){ // setup_comparator(NC_NC_NC_NC); //Comparadores desactivados // SETUP_ADC_PORTS(NO_ANALOGS); output_a(0); //Precargar Latch de Salida set_tris_a(0b001100); //Configurción de pines //A0=Out-Carga 1 //A1=Out-Carga 2 //A2=In -Cruce por Cero //A3_MCLR=In -Detector Infrarrojo //A4=Out-Carga 3 //A5=Out-LED de Estado SETUP_TIMER_0(T0_INTERNAL); SETUP_TIMER_0(T0_DIV_128); //incremento cada 64us si Osc = 8MHz ENABLE_INTERRUPTS(INT_EXT); //Initerrupcion externa por A2 EXT_INT_EDGE(H_TO_L); //flanco de bajada ENABLE_INTERRUPTS(INT_RA3); //Interrupcion por cambio de estado usada para Recepción Serial ENABLE_INTERRUPTS(GLOBAL); //Habilitar Interrupciones //********************************************************* //******* Programa Principal **********************// //********************************************************* while(1){ if(cruce_detectado==TRUE){ cruce_detectado=FALSE; if(nivel_intensidad!=0){ //Si el nivel de intensidad es 0 entonces siempre apagado SET_TIMER0(intensidad[nivel_intensidad]); //Se actualiza timer ENABLE_INTERRUPTS(INT_TIMER0); //Habilitar Interrupción por desborde de Timer0 while(desborde_T0==false); //Esperar a que desborde el timer0 DISABLE_INTERRUPTS(INT_TIMER0); //Deshabilitar Interrupción por desborde de Timer0 desborde_T0=FALSE; output_high(Carga1); //Disparo1= ON delay_us(50); }//if intensidad output_low(Carga1); //Disparo1= OFF }//if cruce detectado sleep(); // }//end_while }//end_main //********************************************************** //****** Interrupciones *******************************// //********************************************************** #int_ext void z_cross(){ if(zero_HtoL==TRUE){ EXT_INT_EDGE(L_TO_H); //por flanco de subida zero_HtoL=FALSE; }//if else{ EXT_INT_EDGE(H_TO_L); //por flanco de bajada zero_HtoL=TRUE; }//else cruce_detectado=TRUE; #ifdef DEBUG output_toggle(LED_status); //Solo para pruebas #endif }//int cruce por cero //************************************************************ #int_timer0 void overflow_T0(){ desborde_T0=TRUE; //Ocurrio desborde de timer0 }//int desborde timer0 //************************************************************ #INT_RA void recepcion(){ //Interrupcion por cambio de estado en pines if(input(PIN_A3)==0){ // Bit de inicio ??? pin A3 es 0 ? nivel_intensidad=dato_recibido-0x30; // Se resta 0x30 para pasar a decimal }//if bit de inicio } //int_ra3 recepcion serial //************************************************************
Saludos!
Debes utilizar un opto-acoplador sin detección de cruce por cero por ejemplo
MOC3011 o MOC3021
saludos que optocoplador usuarias??
saludos que optocoplador usuarias??
Uso el 4n25
Esto esta probado a 120VCA , las resistencias son de 1/2 Watt.
Hola amigos!
Estoy retomando el proyecto del dimmer.
Se trata de un dimmer de 1 canal , se puede ajustar a 5 niveles de operación 0%,25%,50%,75% y 95% y se controla serialmente(4800bps,8bits,1stop,N).
Si envian 0x30H esta apagado
Si envian 0x31H " 1 " esta trabajando al 25%
Si envian 0x32H " 2 " esta trabajando al 50%
Si envian 0x33H " 3 " esta trabajando al 75%
Si envian 0x34H " 4 " esta trabajando al 95%Código: C
#include <12F683.h> #FUSES INTRC_IO,NOWDT,PUT,NOMCLR,BROWNOUT,PROTECT,CPD,NOIESO,NOFCMEN #use delay(internal=8MHZ) //Oscilador interno 8MHz #use rs232(baud=4800,rcv=PIN_A3) //Velocidad limitada por receptor el receptor infrarrojo #use fast_io(A) #zero_ram #priority timer0,int_ra //************************************************************// #define debug // Comment line out for no debug #define Carga1 pin_A0 #define Carga2 pin_A1 #define Carga3 pin_A4 #define LED_status pin_A5 //************************************************************ char intensidad[5]={0,159,191,224,254}; //Equivale a 0%,25%,50%,75%,95% char nivel_intensidad; char desborde_T0; char cruce_detectado; char zero_HtoL; char dato_recibido; //************************************************************ void main(){ // setup_comparator(NC_NC_NC_NC); //Comparadores desactivados // SETUP_ADC_PORTS(NO_ANALOGS); output_a(0); //Precargar Latch de Salida set_tris_a(0b001100); //Configurción de pines //A0=Out-Carga 1 //A1=Out-Carga 2 //A2=In -Cruce por Cero //A3_MCLR=In -Detector Infrarrojo //A4=Out-Carga 3 //A5=Out-LED de Estado SETUP_TIMER_0(T0_INTERNAL); SETUP_TIMER_0(T0_DIV_128); //incremento cada 64us si Osc = 8MHz ENABLE_INTERRUPTS(INT_EXT); //Initerrupcion externa por A2 EXT_INT_EDGE(H_TO_L); //flanco de bajada ENABLE_INTERRUPTS(INT_RA3); //Interrupcion por cambio de estado usada para Recepción Serial ENABLE_INTERRUPTS(GLOBAL); //Habilitar Interrupciones //********************************************************* //******* Programa Principal **********************// //********************************************************* while(1){ if(cruce_detectado==TRUE){ cruce_detectado=FALSE; if(nivel_intensidad!=0){ //Si el nivel de intensidad es 0 entonces siempre apagado SET_TIMER0(intensidad[nivel_intensidad]); //Se actualiza timer ENABLE_INTERRUPTS(INT_TIMER0); //Habilitar Interrupción por desborde de Timer0 while(desborde_T0==false); //Esperar a que desborde el timer0 DISABLE_INTERRUPTS(INT_TIMER0); //Deshabilitar Interrupción por desborde de Timer0 desborde_T0=FALSE; output_high(Carga1); //Disparo1= ON delay_us(50); }//if intensidad output_low(Carga1); //Disparo1= OFF }//if cruce detectado sleep(); // }//end_while }//end_main //********************************************************** //****** Interrupciones *******************************// //********************************************************** #int_ext void z_cross(){ if(zero_HtoL==TRUE){ EXT_INT_EDGE(L_TO_H); //por flanco de subida zero_HtoL=FALSE; }//if else{ EXT_INT_EDGE(H_TO_L); //por flanco de bajada zero_HtoL=TRUE; }//else cruce_detectado=TRUE; #ifdef DEBUG output_toggle(LED_status); //Solo para pruebas #endif }//int cruce por cero //************************************************************ #int_timer0 void overflow_T0(){ desborde_T0=TRUE; //Ocurrio desborde de timer0 }//int desborde timer0 //************************************************************ #INT_RA void recepcion(){ //Interrupcion por cambio de estado en pines if(input(PIN_A3)==0){ // Bit de inicio ??? pin A3 es 0 ? nivel_intensidad=dato_recibido-0x30; // Se resta 0x30 para pasar a decimal }//if bit de inicio } //int_ra3 recepcion serial //************************************************************
Saludos!
AKENAFAB me explicas como es el programa porque por mas que lo razono no entiendo algunas cosas por ejemplo el pin A0 es el mismo que GP0???sigo sin entender tu programa y esque quisiera hacer algo similar en el pic 16f877A agradezco tu ayuda
Por lo general cuando se hace una pregunta esta debe ser específica. Es decir, que cosa del programa no entiendes. De lo contrario no sabremos como ayudarte.
Si el problema es que no entiendes el programa completo, probablemente se deba a que no conoces mucho de C ni de PICs. Si ese es el caso te recomiendo que primero aprendas sobre estos antes de adentrarte a un proyecto.
Lo primero que debes hacer es convertir el valor Binario a un valor decimal, por ejemplo
0010=2
luego realizas una regla de 3
1111=15 dec = 5V
0010= 2 dec = x
por lo tanto
x = 5V * 2dec / 15 dec = 0.6667 V
Hola
Es la forma correcta como dices hypnos00, pero mira que si tienes un Vref=5v y un ADC de 4 bits, vas a tener la razon: 5/15, la cual es la que multiplicas por el valor ADC que te entrega el PIC.
Si tienes un ADC de 8 bits, la razon sera de 5/255, tal y como lo recuerdas :)
Saludos
a que hacen referencia con la formula retardo=(int16)(255-data)*32 ya que cual es el objetivo de poner int16 entre parentesis, y de donde sale el 32,
a que hacen referencia con la formula retardo=(int16)(255-data)*32 ya que cual es el objetivo de poner int16 entre parentesis, y de donde sale el 32,
Ese (int16) convierte del valor de (255-data) a un entero de 16 bits mediante casting ya que data es un entero de 8 bits. Por ejemplo si data es igual a 0 entonces 255-data sería igual a 255. Si multiplicas 255 por 32, el resultado debería ser 8160 (que es un entero de mas de 8bits), pero si 255 esta almacenado en una variable de 8 bits, la multiplicación daría 224 debido a que se pierden los demás bits. Es por ello que es necesario convertir el resultado de la resta a un entero de 16 bits antes de realizar la multiplicación.
Por otro lado la multiplicación por 32 se debe a que el valor maximo obtenido es 8160. Este valor luego es pasado a la función delay_us. Es decir, conviertes los valores del ADC a retardos, dando como máximo retardo 8.16ms lo que equivale a medio ciclo de la onda senoidal.
a que hacen referencia con la formula retardo=(int16)(255-data)*32 ya que cual es el objetivo de poner int16 entre parentesis, y de donde sale el 32,
Ese (int16) convierte del valor de (255-data) a un entero de 16 bits mediante casting ya que data es un entero de 8 bits. Por ejemplo si data es igual a 0 entonces 255-data sería igual a 255. Si multiplicas 255 por 32, el resultado debería ser 8160 (que es un entero de mas de 8bits), pero si 255 esta almacenado en una variable de 8 bits, la multiplicación daría 224 debido a que se pierden los demás bits. Es por ello que es necesario convertir el resultado de la resta a un entero de 16 bits antes de realizar la multiplicación.
Por otro lado la multiplicación por 32 se debe a que el valor maximo obtenido es 8160. Este valor luego es pasado a la función delay_us. Es decir, conviertes los valores del ADC a retardos, dando como máximo retardo 8.16ms lo que equivale a medio ciclo de la onda senoidal.
colega me das permiso de agregarte al msn???
:oops: Lo siento, tienes razon.
En ese caso no se cual utilizar, pero tambien puedes utilizar un divisor de voltaje mediante resistencias. Es decir, puedes utilizar una resistencia de 10k conectada en serie con una de 2M. Esto hará que practicamente lleguen los 170Vp de la fuente al PIC, pero con muy poca cantidad de corriente, limitada por la resistencia de 10k.
No
Para obtener el valor de potencia debes tomar en cuenta lo siguiente
P=V*I=(V^2)/R=(170^2)/2M=0.01445W
Puedes utilizar una resistencia de 1/4W pero lo mejor es una de 1/2W por seguridad.
Por cierto, no es un divisor de voltaje, es la Resistencia de 2M directamente a la entrada del PIC, pero esta debe ser una entrada con diodos de protección. Por lo general todas las entradas q sirven para ADC traen esa protección. De lo contrario tendrás que poner los diodos de protección.
Que pasa si empleo moc 3041 que viene con detector cruce cero; como modifica el programa del pic?