Autor Tema: Contro de nivel y Temperatura de un calderin por medio de RF  (Leído 24378 veces)

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

Desconectado Micro23

  • Colaborador
  • PIC16
  • *****
  • Mensajes: 226
Re: Contro de nivel y Temperatura de un calderin por medio de RF
« Respuesta #45 en: 29 de Julio de 2009, 16:03:07 »
 :-/ :mrgreen: Me alegro que funcione  :mrgreen: :-/

Saludos y esperamos tus avances
El pesimista se queja del viento
El optimista espera que cambie
El realista ajusta las velas

Desconectado jhozate

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1698
Re: Contro de nivel y Temperatura de un calderin por medio de RF
« Respuesta #46 en: 04 de Agosto de 2009, 23:01:16 »
siguiendo con mis pruebas  est pasando lo siguiente:

* no me ha funcionado el LCD...estoy usando la flex_lcd..aunque voy a hacerme un nuevo hard para el lcd
* El 7805, con el tiempo se calienta de una manera preocupante y lo unico que tengo conectado son el modulo RF y ocho led q por ahora no los utilizo todos, y el AD594
* Siguiendo la sugerencia de MLO_  de enviar los datos de temperatura y nivel entre las letras T%uT y N%uN, esto funciona bien simulado, pero cuando verifico conectado mi circuito y comunicando con Terminal de bray me aparece el dato sin la´s letras, lo estoy enviando asi:

printf("T%uT\r\n",Q);

por otro lado, podria asociar el control de fase a un dimmer...seria lo mismo no?

saludos
« Última modificación: 04 de Agosto de 2009, 23:07:52 por jhozate »
Ser Colombiano es un Premio, Saludos desde CALI-COLOMBIA

Desconectado albejanon

  • PIC10
  • *
  • Mensajes: 4
Re: Contro de nivel y Temperatura de un calderin por medio de RF
« Respuesta #47 en: 06 de Agosto de 2009, 04:10:17 »
Despues de tantos dias, he venido instruyendome en esto del ccs, haciendo programitas, leyendo aqui y alla, al fin y decidido a llevar a cabo este proyeto en lenguaje c. Ahora vengo con nuevas dudas: una de ellas es la siguiente:
1-resulta qu tengo  la termocupla conectada al AD594 que lo que hace tratar de linealizar la lectura de temperatura y asi tengo un comportamiento muy similar al del LM35 con sus 10mV/°C entonces he configurado en el pic un voltaje de referencia de 2,5V y conversion 8bits con lo cual tengo una sensibilidad de aproximadamente 10mV, pero eso tan solo para temperatura y para nivel se tiene un transmisor que entrega 1-5V, entonces no se me serviria el voltaje de referencia de 2.5V.
 q podria hacer entonces?,,,,me preguntaba si programando en c antes de leer el canal que corrresponde a nivel puedo cambiar el voltaje de referencia al voltaje interno osea 5V


Ante todo hola a todos, soy novato en este foro (y con los PICs) y la verdad es que este proyecto me ha llamado mucho la atención... llevo algún tiempo probando aquí y allá para crear un termómetro que tenga una precisión buena y la verdad es que lo que más me ha convencido es el uso de resistencias de platino. Estas resistencias tienen un comportamiento muy bueno y, además con un simple divisor de tensión mediante una resistencia de precisión puedes conseguir fijar los niveles de tensión como gustes (dentro de los 5 voltios de trabajo del PIC) y, además, dependiendo del modelo de la resistencia, puedes incluso sumergirla en el líquido para una medición más realista. Creo que es una solución barata (las encuentras en ebay a muy buen precio) y que brinda una gran precisión ya que tiene un comportamiento bastante lineal en todo el rango de medición que puede llegar desde decenas de grados bajo cero a centenas de grados sobre cero. Tan sólo debes mirar el datasheet de la resistencia. Te adjunto la tabla de valores para las PT100 y PT1000 estándar (si logro saber como adjuntar) :P.

Además, te dejo este link por si te es de ayuda, aunque usa una circuitería añadida para dar más precisión y estabilidad... yo personalmente me quedo con la versión simple del divisor de tensión ;):

 http://www.amplifier.cd/Technische_Berichte/PT100/Temperature_measurement.htm

Se me olvidaba que con la solución del divisor de tensión necesitas una tensión muy muy estable lo cual puedes conseguir con un un circuito como este que adjunto también (modificándolo a tu necesidad).

Añado también en aporte a tu último mensaje que yo usaría el LM317 en lugar del LM78XX ya que por experiencia se obtienen mejores resultados.



Enhorabuena a todos por este foro, a tí por este gran proyecto y espero haberte sido de alguna ayuda. Un saludo.
« Última modificación: 06 de Agosto de 2009, 04:31:11 por albejanon »

Desconectado jhozate

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1698
Re: Contro de nivel y Temperatura de un calderin por medio de RF
« Respuesta #48 en: 06 de Agosto de 2009, 18:06:27 »
gracias albejanon, pero pss es que el hardware en estos momentos lo tengo funcionando con termocupla y el AD594 y hasta ahora todo va bien, con respecto al divisor de tension es valido un divisor con resistencias, lo probe pero fluctuaban un poco entonces implemente un LM336 y dos resistencias y se comporta mejor, pero como no solo debia utilizar un Vref de 2,5V sino de 5V tambien y ademas ya tenia todo montado pues me imagine que podia cambiar los registros para q el micro tome la tension de referencia externa y la tension de referencia interna osea 5V y GND si funcionó bien.

Ahora me encuentro con la duda del control de fase, porque el dato de control lo debo recibir desde el pc, pero entonces ya manejo 3 interrupciones: Desbordamiento del TIMER0, Recepcion USART, interrupcion cambio de nibble(cruce por cero)

entonces en condiciones normales hago dos lecturas de canales analogos, muestro en lcd, envio datos de conversion de los canales, luego:
1-recibo correctivos del PC (se activa interrupcion usart)
2-capturo dato recibido, debo discriminar si el dato es de nivel o temperatura
3-si el dato es de nivel, activo o desactivo un pin
4-si el dato es de temperatura, debo activar el interrupcion cambio de nibble para detectar el cruce por cero luego de detectado el cruce por cero activar el Timer0 para hacer el control de fase


es correcto...mi planteamiento??
« Última modificación: 06 de Agosto de 2009, 18:14:12 por jhozate »
Ser Colombiano es un Premio, Saludos desde CALI-COLOMBIA

Desconectado jhozate

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1698
Re: Contro de nivel y Temperatura de un calderin por medio de RF
« Respuesta #49 en: 06 de Agosto de 2009, 20:35:49 »
bueno dandole dandole al programa lo que he hecho es lo siguiente:
En primera instancia defini tres funciones llamadas:
Código: CSS
  1. VOID LECTURA(VOID);
  2. VOID CONTROL_TEMP(VOID);
  3. VOID CONTROL_NIVEL(VOID);


Código: CSS
  1. ////###########################CONNTROL TEMPEPERATURA#####################################
  2. VOID CONTROL_TEMP(VOID)
  3. {                          //INICIO FUNCION CONTROL TEMP
  4.  
  5.  
  6. }                            //FIN FUNCION CONTROL TEMP
  7. //########################################################################################
  8.  
  9.  
  10.  
  11.  
  12. ////###########################CONNTROL NIVEL#####################################
  13. VOID CONTROL_NIVEL(VOID)
  14. {                          //INICIO FUNCION CONTROL TEMP
  15. IF(DATO=='A')
  16.    OUTPUT_HIGH(PIN_B1);
  17. ELSE IF(DATO=='B')
  18.    OUTPUT_LOW(PIN_B1);
  19. }                          //FIN FUNCION CONTROL
  20. //########################################################################################

en LECTURA esta las lecturas de los AD y el envio serie de las conversiones y el muestreo en lcd.
En CONTROL_NIVEL lo que hago es poner a "1" o "0" el bit1 de puertoB, dependiendo de lo que llegue por la usart.
En CONTROL_TEMP lo que deberia hacer seria activar la interrupcion cambio de nibble y  y luego activar el Timer0 para poder hacer el control de fase.
 
En la interrupcion por recepcion lo que hago es diferenciar entre numeros del 1 al 6 y las letras 'A' y 'B' y activo unos flags para indicar si lo que se recibió fue un numero entonces se hara control sobre temperatura y si lo que recibió fue una letra será control sobre nivel, asi:
Código: CSS
  1. #int_RDA             //INTERRUPCION POR RECEPCION SERIE
  2. void  RDA_isr(void)
  3. {
  4.    if(kbhit())
  5.    {
  6.    DATO=GETC();
  7.    IF(DATO=='1'|| DATO=='2' || DATO=='3' || DATO=='4' || DATO=='5' || DATO=='6' ){
  8.       FLAG_TEMP=1;}
  9.    ELSE IF(DATO=='A' || DATO=='B'){
  10.       FLAG_NIVEL=1;}
  11.    
  12.    }
  13. }


ahora todo junto seria asi:
Código: CSS
  1. #BYTE ADCON1=0X9F
  2. #BYTE PORTB=0X06
  3. #include "flex_lcd.c"
  4.  
  5. ////////////VARIABLES//////
  6. int8 O,Q;
  7. FLOAT P,R;
  8. CHAR DATO;
  9. CHAR FLAG_TEMP=0;
  10. CHAR FLAG_NIVEL=0;
  11. ///////////////////////////
  12.  
  13.  
  14. ///////////FUNCIONES//////
  15. VOID LECTURA(VOID);
  16. VOID CONTROL_TEMP(VOID);
  17. VOID CONTROL_NIVEL(VOID);
  18.  
  19. ///////////////////////////
  20.  
  21.  
  22. /* #######################INTERRUPCIONES##########################
  23. #int_RB              //CAMBIO DE NIBBLE
  24. void  RB_isr(void)
  25. {
  26.  
  27. }*/
  28.  
  29. #int_RDA             //INTERRUPCION POR RECEPCION SERIE
  30. void  RDA_isr(void)
  31. {
  32.    if(kbhit())
  33.    {
  34.    DATO=GETC();
  35.    IF(DATO=='1'|| DATO=='2' || DATO=='3' || DATO=='4' || DATO=='5' || DATO=='6' ){
  36.       FLAG_TEMP=1;}
  37.    ELSE IF(DATO=='A' || DATO=='B'){
  38.       FLAG_NIVEL=1;}
  39.    
  40.    }
  41. }
  42.          
  43. /*#int_TIMER0          //INTERRUCPION DESBORDAMIENTO TMR0
  44. void  TIMER0_isr(void)
  45. {
  46.  
  47. }
  48.  
  49. #######################FIN INTERRUPCIONES#############################*/
  50.  
  51.  
  52.  
  53.  
  54. void main()
  55. {
  56.  
  57.    
  58.    setup_adc(ADC_CLOCK_DIV_8);
  59.    //setup_psp(PSP_DISABLED);
  60.    //setup_spi(SPI_SS_DISABLED);
  61.    setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
  62.    setup_timer_1(T1_DISABLED);
  63.    setup_timer_2(T2_DISABLED,0,1);
  64.    setup_comparator(NC_NC_NC_NC);
  65.    setup_vref(FALSE);
  66.    //enable_interrupts(INT_RB);
  67.    //enable_interrupts(INT_EXT);
  68.    enable_interrupts(INT_RDA);
  69.    //enable_interrupts(INT_TIMER0);
  70.    //port_b_pullups(TRUE);
  71.    //enable_interrupts(GLOBAL);
  72.  
  73.    // TODO: USER CODE!!
  74.    DELAY_MS(250);
  75.    SET_TRIS_B(0);
  76.    LCD_INIT();
  77.    LCD_PUTC("PRUEBA LCD");
  78.    DELAY_MS(1000);
  79.    LCD_PUTC("\f");
  80.    
  81.    FOR(;;)
  82.    {
  83.       IF(FLAG_TEMP==1)
  84.          {
  85.           disable_interrupts(INT_RDA);
  86.           FLAG_TEMP=0;
  87.           CONTROL_TEMP();
  88.           LECTURA();
  89.           enable_interrupts(INT_RDA);
  90.          }
  91.       ELSE IF(FLAG_NIVEL==1)
  92.          {
  93.           disable_interrupts(INT_RDA);
  94.           FLAG_NIVEL=0;
  95.           CONTROL_NIVEL();
  96.           LECTURA();
  97.           enable_interrupts(INT_RDA);
  98.          }
  99.    
  100.  
  101.    
  102.    
  103.    }//FIN DEL FOR
  104. }//FIN DEL MAIN
  105.  
  106.  
  107. ////################################LECTURA######################################
  108. VOID LECTURA(VOID)
  109. {
  110.    ADCON1=0B00001101; //AN0 AN1 VREF+ VREF-
  111.    SET_ADC_CHANNEL(0);
  112.    DELAY_US(20);
  113.    Q=READ_ADC();
  114.    
  115.    
  116.    ADCON1=0B00000100;//AN0 AN1 VREF+=VCC VREF-=GND
  117.    SET_ADC_CHANNEL(1);
  118.    DELAY_US(20);
  119.    O=READ_ADC();
  120.    
  121.    P=(2.5*Q)/255.0;
  122.    R=(5.0*O)/255.0;
  123.    PRINTF(LCD_PUTC,"\fADC'S=%u  %u",Q,O);
  124.    PRINTF(LCD_PUTC,"\nV1=%1.2fV V2=%1.2fV",P,R);
  125.    PRINTF("T%uT\r\n",Q);
  126.    PRINTF("N%uN\r\n",O);
  127.    DELAY_ms(1);
  128.  
  129. }
  130. //#################################################################################
  131.  
  132.  
  133.  
  134. ////###########################CONNTROL TEMPEPERATURA#####################################
  135. VOID CONTROL_TEMP(VOID)
  136. {                          //INICIO FUNCION CONTROL TEMP
  137.  
  138.  
  139. }                            //FIN FUNCION CONTROL TEMP
  140. //########################################################################################
  141.  
  142.  
  143.  
  144.  
  145. ////###########################CONNTROL NIVEL#####################################
  146. VOID CONTROL_NIVEL(VOID)
  147. {                          //INICIO FUNCION CONTROL TEMP
  148. IF(DATO=='A')
  149.    OUTPUT_HIGH(PIN_B1);
  150. ELSE IF(DATO=='B')
  151.    OUTPUT_LOW(PIN_B1);
  152. }                          //FIN FUNCION CONTROL
  153. //########################################################################################


Pero me poner  a dudar el uso de los flags, al estar en el FOR infinito  verifico el estado de los flags,deshabilito la INT_RDA reseteo los flags y luego llamo a la funcion de control que corresponde....
Ser Colombiano es un Premio, Saludos desde CALI-COLOMBIA

Desconectado MLO__

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 4581
Re: Contro de nivel y Temperatura de un calderin por medio de RF
« Respuesta #50 en: 06 de Agosto de 2009, 21:52:02 »
Hola.

El control de fase debes hacerlo siempre. Me imagino que los numeros son para asignar un nivel de calentamiento, a lo cual correspondera un cambio al angulo de disparo cierto?

El valor de asignacion de angulo de disparo lo puedes hacer directamente en la interrupcion, e inmediatamente se actualizara en el control de fase. Para que quede mejor, podrias usar del 1 al 9 para los valores de control de temperatura.

El programa principal podria dedicarse a hacer la conversion AD y mostrar los datos en la LCD.

Código: [Seleccionar]
while(true)
{
 Lectura();
}

y en la interrupcion RDA hacer las asignaciones.

Código: [Seleccionar]
#int_RDA
void RDA_isr(void)
{
 dato=0;
 if(knhit())
 {
  dato=getc();
  switch(dato)
  {
   case '1' : SetPointFase = 10;//Asigno el angulo de disparo
                 break;
   case '2' : ...
   ...
   case 'A' : output_high(pin_b1);
                 break;
   ...
  }
 }
}

Saludos

« Última modificación: 06 de Agosto de 2009, 22:00:22 por MLO__ »
El papel lo aguanta todo

Desconectado jhozate

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1698
Re: Contro de nivel y Temperatura de un calderin por medio de RF
« Respuesta #51 en: 06 de Agosto de 2009, 22:26:39 »
exactamente, los numero son para los angulos...habia estructurado mi programa de otra manera pero esta q me decís esta mucho mejor...entonces seria algo asi:

Código: CSS
  1. #BYTE ADCON1=0X9F
  2. #BYTE PORTB=0X06
  3. #include "flex_lcd.c"
  4.  
  5. ////////////VARIABLES//////
  6. int8 O,Q;
  7. FLOAT P,R;
  8. CHAR DATO;
  9. CHAR SETPOINTFASE=0;
  10.  
  11.  
  12. ///////////////////////////
  13.  
  14.  
  15. ///////////FUNCIONES//////
  16. VOID LECTURA(VOID);
  17. ///////////////////////////
  18.  
  19.  
  20.  //#######################INTERRUPCIONES##########################
  21. #int_RB              //CAMBIO DE NIBBLE
  22. void  RB_isr(void)
  23. {
  24. #ASM
  25. MOVF PORTB,W
  26. #ENDASM
  27. SET_TIMER0(128);
  28. }
  29.  
  30. #int_RDA             //INTERRUPCION POR RECEPCION SERIE
  31. void  RDA_isr(void)
  32. {
  33.  DATO=0;
  34.  IF(KBHIT())
  35.    {
  36.    DATO=GETC();
  37.    SWITCH(DATO)
  38.    {
  39.    CASE '1':disable_interrupts(INT_RDA);
  40.             SETPOINTFASE=1;
  41.             enable_interrupts(INT_RB);
  42.             break;
  43.    CASE '2':disable_interrupts(INT_RDA);
  44.             SETPOINTFASE=2;
  45.             enable_interrupts(INT_RB);
  46.             break;
  47.    CASE '3':disable_interrupts(INT_RDA);
  48.             SETPOINTFASE=3;
  49.             enable_interrupts(INT_RB);
  50.             break;
  51.    CASE '4':disable_interrupts(INT_RDA);
  52.             SETPOINTFASE=4;
  53.             enable_interrupts(INT_RB);
  54.             break;
  55.    CASE '5':disable_interrupts(INT_RDA);
  56.             SETPOINTFASE=5;
  57.             enable_interrupts(INT_RB);
  58.             break;
  59.    CASE '6':disable_interrupts(INT_RDA);
  60.             SETPOINTFASE=6;
  61.             enable_interrupts(INT_RB);
  62.             break;
  63.  
  64.    CASE 'A':OUTPUT_HIGH(PIN_B1);
  65.             break;
  66.  
  67.    CASE 'B':OUTPUT_LOW(PIN_B1);
  68.             break;
  69.    }
  70.   }
  71. }
  72.          
  73. #int_TIMER0
  74. void  TIMER0_isr(void)
  75. {
  76. disable_interrupts(INT_RB);
  77. DELAY_MS(2); ///TIEMPO INACTIVO TRIAC
  78. DELAY_MS(SETPOINTFASE);
  79. OUTPUT_HIGH(PIN_B0);
  80. DELAY_US(100);
  81. OUTPUT_LOW(PIN_B0);
  82. }
  83.  
  84.  
  85.  
  86. //#######################FIN INTERRUPCIONES#############################
  87.  
  88.  
  89.  
  90.  
  91. void main()
  92. {
  93.  
  94.    
  95.    setup_adc(ADC_CLOCK_DIV_8);
  96.    setup_psp(PSP_DISABLED);
  97.    //setup_spi(SPI_SS_DISABLED);
  98.    setup_timer_0(RTCC_INTERNAL|RTCC_DIV_8);
  99.    setup_timer_1(T1_DISABLED);
  100.    setup_timer_2(T2_DISABLED,0,1);
  101.    setup_comparator(NC_NC_NC_NC);
  102.    setup_vref(FALSE);
  103.    //enable_interrupts(INT_RB);
  104.    //enable_interrupts(INT_EXT);
  105.    //enable_interrupts(INT_RDA);
  106.    //enable_interrupts(INT_TIMER0);
  107.    //port_b_pullups(TRUE);
  108.    enable_interrupts(GLOBAL);
  109.    
  110.    DELAY_MS(250);
  111.    LCD_INIT();
  112.    LCD_PUTC("PRUEBA LCD");
  113.    DELAY_MS(1000);
  114.    LCD_PUTC("\f");
  115.    output_high(PIN_B0);
  116.    DELAY_MS(1000);
  117.    OUTPUT_LOW(PIN_B0);
  118.    
  119.    
  120.    while(true)
  121.    {
  122.     enable_interrupts(INT_RDA);
  123.     LECTURA();
  124.    }
  125.    
  126.      
  127.    
  128. }//FIN DEL MAIN
  129.  
  130.  
  131. ////################################LECTURA######################################
  132. VOID LECTURA(VOID)
  133. {
  134.    ADCON1=0B00001101; //AN0 AN1 VREF+ VREF-
  135.    SET_ADC_CHANNEL(0);
  136.    DELAY_US(20);
  137.    Q=READ_ADC();
  138.    
  139.    
  140.    ADCON1=0B00000100;//AN0 AN1 VREF+=VCC VREF-=GND
  141.    SET_ADC_CHANNEL(1);
  142.    DELAY_US(20);
  143.    O=READ_ADC();
  144.    
  145.    P=(2.5*Q)/255.0;
  146.    R=(5.0*O)/255.0;
  147.    PRINTF(LCD_PUTC,"\fADC'S=%u  %u",Q,O);
  148.    PRINTF(LCD_PUTC,"\nV1=%1.2fV V2=%1.2fV",P,R);
  149.    PRINTF("T%uT\r\n",Q);
  150.   //PRINTF("N%uN\r\n",O);
  151.    DELAY_MS(500);
  152.  
  153. }
  154. //#################################################################################

compilando me tira un warning: line 161(0,1) interrupts disable during call to prevent re-entrancy: [@delay_ms1], pero lo dice en una linea en donde no hay codigo

Detecto algunos inconvenientes, por ahora, despues de que envio los datos le doy una delay de medio segundo, y al recibir datos como q se genera algun conflicto...pero es por q casi q coinciden el envio y la recepcion de datos..pero lo que mas me preocupa es q no me funciona el control de fase, ahora solo lo simulo con un bombillo a 110V y deberia ver cambiar la intensidad pero no funciona...sera q tengo error de codigo en cuanto eso?
« Última modificación: 07 de Agosto de 2009, 00:27:16 por jhozate »
Ser Colombiano es un Premio, Saludos desde CALI-COLOMBIA

Desconectado MLO__

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 4581
Re: Contro de nivel y Temperatura de un calderin por medio de RF
« Respuesta #52 en: 07 de Agosto de 2009, 02:16:22 »
Hola

El warning es por el delay_ms(2); que tienes en la interrupcion del Timer0.

Te puedes ahorrar el deshabilitar las interrupciones RDA en el switch (asignar la variable no toma tiempo critico en la interrupcion).

El control de fase no te funciona, porque no esta trabajando constantemente y solo se activan si llega un dato por la RDA. Si quieres que funcione correctamente, se debe estar atento al cambio de flanco para asignar el tiempo de espera.

Código: C#
  1. //Haciendolo con la interrupcion de RB0
  2. #int_EXT
  3. void ZeroCross(void)
  4. {
  5.         if(Flanco==subida)//Detecto el flanco
  6.         {
  7.                 enable_interrupts(INT_TIMER0);//Habilito el Timer para que comience el conteo de espera de activacion del TRIAC
  8.                 ext_int_edge(L_TO_H);
  9.                 Flanco=bajada;
  10.         }
  11.         else
  12.         {
  13.                 enable_interrupts(INT_TIMER0);
  14.                 ext_int_edge(H_TO_L);
  15.                 Flanco=subida;
  16.         }
  17. }

Y en la interrupcion del Timer0 seria:
Código: C#
  1. #int_TIMER0
  2. void pulse0_isr(void)
  3. {
  4.         IntsTimer++;
  5.         if(IntsTimer>SetPoint)//Hasta que no llegue al valor, el pin trigger0 estara en bajo
  6.         {
  7.                 on(trigger0);//Habilito el pulso de activacion del TRIAC
  8.                 IntsTimer=0;
  9.                 disable_interrupts(INT_TIMER0);
  10.                 delay_us(100);
  11.                 off(trigger0);
  12.         }
  13.         set_timer0(0);
  14. }

Esto siempre debe estar activo para garantizar el control, ya que la onda senoidal es continua. En el codigo principal, debes habilitar la interrupcion en RB0, para que comience a hacer el control de fase en un valor predefinido -por lo general, el minimo-
Código: C#
  1. void main(void)
  2. {
  3.  ...
  4.  ext_int_edge(H_TO_L);
  5.  Flanco=subida;
  6.  SetPoint=1;
  7.  enable_interrupts(INT_EXT);
  8.  ...
  9. }
« Última modificación: 07 de Agosto de 2009, 02:28:46 por MLO__ »
El papel lo aguanta todo

Desconectado jhozate

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1698
Re: Contro de nivel y Temperatura de un calderin por medio de RF
« Respuesta #53 en: 07 de Agosto de 2009, 19:26:28 »
Con dificultad y de manera Incorrecta logro ver el cambio de intensidad, creo q como cambie el programa se esta mas atento del control de fase, ahora lo q hice fue que el pic solo envia hacia el PC las conversiones AD cuando recibe el '7', el resto del tiempo se la pasa leyendo los canales AD y mostrando en lcd, ademas del control de fase.

asi:
Código: CSS
  1. int8 O,Q;
  2. FLOAT P,R;
  3. CHAR DATO;
  4. CHAR SETPOINTFASE=1;
  5. CHAR CONTADOR=0;
  6. CHAR FLAG_LECTURA=0;
  7.  
  8.  
  9. ///////////////////////////
  10.  
  11.  
  12. ///////////FUNCIONES//////
  13. VOID LECTURA(VOID);
  14.  
  15. ///////////////////////////
  16.  
  17.  
  18.  //#######################INTERRUPCIONES##########################
  19. #int_RB              //CAMBIO DE NIBBLE
  20. void  RB_isr(void)
  21. {
  22. #ASM
  23. MOVF PORTB,W
  24. #ENDASM
  25. SET_TIMER0(131);
  26. enable_interrupts(INT_TIMER0);
  27. }
  28.  
  29. #int_RDA             //INTERRUPCION POR RECEPCION SERIE
  30. void  RDA_isr(void)
  31. {
  32.  DATO=0;
  33.  IF(KBHIT())
  34.    {
  35.    DATO=GETC();
  36.    SWITCH(DATO)
  37.    {
  38.    CASE '1':SETPOINTFASE=1;
  39.             break;
  40.            
  41.    CASE '2':SETPOINTFASE=2;
  42.             break;
  43.            
  44.    CASE '3':SETPOINTFASE=3;
  45.             break;
  46.            
  47.    CASE '4':SETPOINTFASE=4;
  48.             break;
  49.            
  50.    CASE '5':SETPOINTFASE=5;
  51.             break;
  52.            
  53.    CASE '6':SETPOINTFASE=6;
  54.             break;
  55.    
  56.    CASE '7':FLAG_LECTURA=1;
  57.             break;
  58.  
  59.    CASE 'A':OUTPUT_HIGH(PIN_B1);
  60.             break;
  61.  
  62.    CASE 'B':OUTPUT_LOW(PIN_B1);
  63.             break;
  64.    }
  65.    
  66.   }
  67.  
  68. }
  69.          
  70. #int_TIMER0
  71. void  TIMER0_isr(void)
  72. {
  73. CONTADOR++;
  74.                              
  75. IF(CONTADOR==7){
  76.    CONTADOR=0;}
  77. IF(CONTADOR==SETPOINTFASE)
  78.    {
  79.    DELAY_MS(SETPOINTFASE);
  80.    OUTPUT_HIGH(PIN_B0);
  81.    DELAY_US(300);                        
  82.    OUTPUT_LOW(PIN_B0);                    
  83.    }
  84. }
  85.  
  86.  
  87.  
  88. //#######################FIN INTERRUPCIONES#############################
  89.  
  90.  
  91.  
  92.  
  93. void main()
  94. {
  95.  
  96.    
  97.    setup_adc(ADC_CLOCK_DIV_8);
  98.    setup_psp(PSP_DISABLED);
  99.    setup_timer_0(RTCC_INTERNAL|RTCC_DIV_8);
  100.    setup_timer_1(T1_DISABLED);
  101.    setup_timer_2(T2_DISABLED,0,1);
  102.    setup_comparator(NC_NC_NC_NC);
  103.    setup_vref(FALSE);
  104.    //enable_interrupts(INT_RB);
  105.    //enable_interrupts(INT_EXT);
  106.    //enable_interrupts(INT_RDA);
  107.    //enable_interrupts(INT_TIMER0);
  108.    //port_b_pullups(TRUE);
  109.    enable_interrupts(GLOBAL);
  110.    
  111.    DELAY_MS(250);
  112.    LCD_INIT();
  113.    LCD_PUTC("PRUEBA LCD");
  114.    DELAY_MS(1000);
  115.    LCD_PUTC("\f");
  116.    output_high(PIN_B0);
  117.    DELAY_MS(1000);
  118.    OUTPUT_LOW(PIN_B0);
  119.    
  120.    
  121.    while(true)
  122.    {
  123.     LECTURA();
  124.     enable_interrupts(INT_RDA);
  125.     enable_interrupts(INT_RB);
  126.     IF(FLAG_LECTURA==1)
  127.       {
  128.       FLAG_LECTURA=0;
  129.       PRINTF("T%uT\r\n",Q);
  130.       PRINTF("N%uN\r\n",O);
  131.       }
  132.     }
  133.    
  134.      
  135.    
  136. }//FIN DEL MAIN
  137.  
  138.  
  139. ////################################LECTURA######################################
  140. VOID LECTURA(VOID)
  141. {
  142.    ADCON1=0B00001101; //AN0 AN1 VREF+ VREF-
  143.    SET_ADC_CHANNEL(0);
  144.    DELAY_US(20);
  145.    Q=READ_ADC();
  146.    
  147.    
  148.    ADCON1=0B00000100;//AN0 AN1 VREF+=VCC VREF-=GND
  149.    SET_ADC_CHANNEL(1);
  150.    DELAY_US(20);
  151.    O=READ_ADC();
  152.    
  153.    P=(2.5*Q)/255.0;
  154.    R=(5.0*O)/255.0;
  155.    PRINTF(LCD_PUTC,"\fADC'S=%u  %u",Q,O);
  156.    PRINTF(LCD_PUTC,"\nV1=%1.2fV V2=%1.2fV",P,R);
  157.    
  158. }  
  159.  
  160.  
  161. //#################################################################################

estoy cometiendo algun error???
Ser Colombiano es un Premio, Saludos desde CALI-COLOMBIA

Desconectado MLO__

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 4581
Re: Contro de nivel y Temperatura de un calderin por medio de RF
« Respuesta #54 en: 07 de Agosto de 2009, 21:41:12 »
Hola.

Mira el codigo que te postee para el control de fase. Tu estas asignando un delay_ms() dentro de la interrupcion del Timer0, la idea es NO hacerlo, ya que en ese tiempo el PIC no atiende nada mas. Si lo haces como te indique arriba, la cuenta del tiempo es independiente de todo lo demas que estas haciendo.

Debes asignar bien el tiempo de desborde el Timer0, para contar asi los mS de espera antes de dispara el TRIAC.

Saludos
El papel lo aguanta todo

Desconectado jhozate

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1698
Re: Contro de nivel y Temperatura de un calderin por medio de RF
« Respuesta #55 en: 07 de Agosto de 2009, 23:02:24 »
 :-) :-) efectivamente  :D..ya capte mas o menos la idea..lo que pasa es que yo no tomaba muy encuenta los tiempos de las interrupciones..y es que despues de la interrupcion por cambio nibble(cruce por cero) tengo aprox 7mS hasta el proximo cruce, ademas ese delay dentro de la int_rda somete al pic a no prestar atencion a nada mas pero suponia ese delay para el tiempo de espera para activar el triac...ya lo corregì...sin embargo, funciona bien para las primeras 3 intensidades y es mas notorio el cambio de la 1 a la 3..en las siguientes se observa una oscilacion de la luminosidad...q podría ser??en la interrupcion hice esto:
Código: CSS
  1. #int_TIMER0
  2. void  TIMER0_isr(void)
  3. {
  4. CONTADOR++;
  5.                                          
  6.  
  7. IF(CONTADOR==SETPOINTFASE)        
  8.    {
  9.    OUTPUT_HIGH(PIN_B0);
  10.    CONTADOR=0;
  11.    disable_interrupts(INT_TIMER0);
  12.    DELAY_US(300);                        
  13.    OUTPUT_LOW(PIN_B0);
  14.        
  15.    }
  16.    SET_TIMER0(131);
  17.   enable_interrupts(INT_TIMER0);
  18. }

estoy utilizando una fuente de pc..sera q introduce ruido??
Ser Colombiano es un Premio, Saludos desde CALI-COLOMBIA

Desconectado MLO__

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 4581
Re: Contro de nivel y Temperatura de un calderin por medio de RF
« Respuesta #56 en: 08 de Agosto de 2009, 01:19:31 »
Hola.

Que cristal estas usando? Si quieres que el tiempo que toma la int_RDA no te afecte mucho el cruce por cero, usa un cristal de mas de 12MHz.

Si te titila la luminosidad, puede ser por que el tiempo de disparo del TRIAC no es el mismo y esta desfasado algunos uS.

Segun veo en tu codigo, activas la interrupcion int_TIMER0 en la int_TIMER0 y no deberia ser asi, si miras bien el codigo que te postee, yo activo la interrupcion del Timer0 en la interrupcion del cambio de fase, para que el timer comience a contar, luego, cuando el valor de conteo del Timer llega al SetPoint, activo el pulso y desactivo la interrupcion del Timer0, ya que solo me interesa que comience a contar desde el punto del cruce por cero  :z) -espero no enredarte-

Saludos
El papel lo aguanta todo

Desconectado jhozate

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1698
Re: Contro de nivel y Temperatura de un calderin por medio de RF
« Respuesta #57 en: 08 de Agosto de 2009, 01:39:03 »
si estoy un XT de 4Mhz...probare uno de 20Mhz...tengo una duda,,cuando ser escribe set_timer() se escribe solo el valor a cargar en el TIMER0 y cuando se escribe enable_interrupts(INT_TIMER0) se modifica el bit el TMROIE del registro de interrupcion? es decir habilita el bit de interrupcion del TMR0 pero no habilita el permiso goblal (bit GIE de INTCON)?

ahora, en el codigo q me pusiste cuando no se cumple
Código: CSS
  1. if(IntsTimer>SetPoint)
haces una carga del timero set_timer(0); ...habilitas de nuevo el valor de tiempo a desbordar?

supongo que debeeria funcionar asi: cuando se detecta el cruce por cero hay q activar el timer0, luego este se desborda en 1ms y se hace la comparacion con el setpoint if(contador==setpoint), sin son iguales desactivo el timer0 y envio pulso, si son diferentes debo poner otra vez la precarga del timer0 y habilitar la interrupcion para q vuelva a contar 1ms...y asi es como veo tu codigo..

mirando los dos codigos:
Código: CSS
  1. #int_TIMER0
  2.  
  3.  void pulse0_isr(void)
  4.   {
  5.    IntsTimer++;
  6.     if(IntsTimer>SetPoint)                   //Hasta que no llegue al valor, el pin trigger0 estara en bajo
  7.       {
  8.         on(trigger0);//Habilito el pulso de activacion del TRIAC
  9.         IntsTimer=0;
  10.         disable_interrupts(INT_TIMER0);
  11.         delay_us(100);
  12.         off(trigger0);
  13.       }
  14.       set_timer0(0);
  15.        }

el mio:
Código: CSS
  1. #int_TIMER0
  2. void  TIMER0_isr(void)
  3. {
  4. CONTADOR++;
  5.                                          
  6.  
  7. IF(CONTADOR==SETPOINTFASE)        
  8.    {
  9.    OUTPUT_HIGH(PIN_B0);
  10.    CONTADOR=0;
  11.    disable_interrupts(INT_TIMER0);
  12.    DELAY_US(300);                        
  13.    OUTPUT_LOW(PIN_B0);
  14.        
  15.    }
  16.    SET_TIMER0(131);
  17.   enable_interrupts(INT_TIMER0);     ////// si quito esta linea ya no prende el bombillo
  18. }
« Última modificación: 08 de Agosto de 2009, 01:58:41 por jhozate »
Ser Colombiano es un Premio, Saludos desde CALI-COLOMBIA

Desconectado MLO__

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 4581
Re: Contro de nivel y Temperatura de un calderin por medio de RF
« Respuesta #58 en: 08 de Agosto de 2009, 02:23:06 »
Hola.

Para habilitar la interrupcion particular se usa enable_interrupts(INT_xxx), si escribo: enable_interrupts(GLOBAL); habilito el permiso global de interrupciones.

La carga del Timer0 es para garantizar que siempre va a contar el mismo tiempo siempre sin que me afecte los uS tomados dentro de la interrupcion, si quitas la precarga se vera que el pulso de habilitacion es inestable, lo que se traduce en un titileo en el bombillo.

Creo que lo que esta fallando en tu codigo es la deteccion de cruce por cero. Creo que lo que estas haciendo es detectar el cruce y de ahi empiezas a temporizar, el Timer siempre esta contando, asi que siempre esta disparando el TRIAC, pero ese disparo no es sincronizado con el cruce por cero.

En tu codigo de la interrupcion del Timer0, cuando se cumple que CONTADOR=SETPOINTFASE envia el pulso de activacion, deshabilitas la interrupcion y luego la vuelves a habilitar. Al no tener sincronia el pulso de disparo del TRIAC con el cruce por cero, puede pasar cualquier cosa.

El timer0 debe contar el tiempo desde el cruce por cero hasta el tiempo en el cual se da el disparo del GATE del TRIAC, luego permanece inactivo hasta el nuevo cruce por cero:


Hasta que no se ponga disable_interrupts(INT_TIMER0), la interrupcion sigue activa, y por ende, el Timer0 sigue su cuenta.

Saludos
El papel lo aguanta todo

Desconectado jhozate

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1698
Re: Contro de nivel y Temperatura de un calderin por medio de RF
« Respuesta #59 en: 08 de Agosto de 2009, 14:17:47 »
si...es q el problema esta en la interrrupcion del timer, por que cuando entra en la interrupcion y se cumple que IF(CONTADOR==SETPOINTFASE) deshabilito la interrupcion del timer0, pero se cumpla o no se cumpla la condicion vuelvo y habilito el timer0 entonces siempre esta desbordandose cada 1ms.....y lo que debe pasar el que al cumplirse el IF se debe deshabilitar el timer0, enviar el pulso..y esperar el proximo cruce por cero...

para tratar de solucionar eso hice esto:
Código: CSS
  1. #int_TIMER0
  2. void  TIMER0_isr(void)
  3. {
  4. CONTADOR++;
  5. IF(CONTADOR==SETPOINTFASE)
  6.    {
  7.    disable_interrupts(INT_TIMER0);
  8.    OUTPUT_HIGH(PIN_B0);
  9.    CONTADOR=0;
  10.    DELAY_US(300);                        
  11.    OUTPUT_LOW(PIN_B0);
  12.    FLAG_TIMER=1;
  13.    }
  14.  
  15. IF(FLAG_TIMER==1){
  16.    disable_interrupts(INT_TIMER0);}
  17. ELSE
  18.    SET_TIMER0(131);
  19.    enable_interrupts(INT_TIMER0);
  20. }

ya lo puse a correr a 20Mhz, mejoró mucho pero la intensidad 5 oscila

Otra aspecto, tengo dos triac de gate sensible, pero solo necesito uno para el control de fase, el otro quiero cambiarlo para switchear nada mas, es decir, on-off y asi no tener q preocuparme tambien por el cruce por cero y poder activar ese triac..cual seria recomendable?
« Última modificación: 08 de Agosto de 2009, 14:57:31 por jhozate »
Ser Colombiano es un Premio, Saludos desde CALI-COLOMBIA


 

anything