Autor Tema: AYUDA CON ADC Y USO DE TECLADO  (Leído 2455 veces)

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

Desconectado Ryunagi

  • PIC10
  • *
  • Mensajes: 7
AYUDA CON ADC Y USO DE TECLADO
« en: 21 de Julio de 2019, 00:19:08 »
mi programa consiste en un dimmer, que enciende el foco por medio del timer0, agregando el valor de carga del timer0 mediante el teclado 4x4, lo que necesito es usar el ADC para que me imprima los luxes que mide la LDR, pero el bucle del ADC choca con la libreria de "LEE_NUM16B y KBD"  y no se debe hacer con timer1 o timer2 ya que exite interferencia, un parpadeo constante en el foco, no se que debo hacer el ADC debe estar refrescándose continuamente. ya intente varias maneras pero no funciona sin que afecte al timer0 o se quede en dentro del bucle del ADC.
« Última modificación: 21 de Julio de 2019, 01:48:19 por Ryunagi »

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:AYUDA CON ADC Y USO DE TECLADO
« Respuesta #1 en: 21 de Julio de 2019, 09:02:52 »
Esos son problemas hasta que usas interrupciones.. Por que los delays terminan ocasionando esos problemas si uno no los piensa de otra forma.

Deberias hacer una interrupcion para el Timer que maneja la lampara (supongamon el Timer0). Para cambiar la "potencia" de la lampara simplemente en tu programa principal con el teclado le asignas el valor a una variable. Pero recien en la interrupcion es cuando vas a reemplazarla en el Timer0.

Pienso que a lo mejor tambien necesitas una interrpucion de algun pin como RB0 para la deteccion del cruce por cero y asi activar el Timer0.

Tambien podes usar otro Timer para el ADC... No se que PIC estas usando, pero hay algunos que permiten que al terminarse el Timer inicie la conversion ADC, si tenes activado tu interrupcion del ADC, cuando termine la conversion vas a tener el resultado del ADC en tu interrupcion, aca lo unico que vas a hacer es guardarlo en una variable.

Luego en tu programa principal si haces lo que vos quieras con esos valores. Pero ahora el Timer funcionaria correctamente a Tiempo y el ADC tambien.

Desconectado Ryunagi

  • PIC10
  • *
  • Mensajes: 7
Re:AYUDA CON ADC Y USO DE TECLADO
« Respuesta #2 en: 21 de Julio de 2019, 11:04:52 »
Gracias por contestar, En el programa agregue el adc al timer0 para ver si pasaba lo mismo que el timer1, y también emite que el foco parpadee, si cambia la intensidad del foco y todo pero parpadea con esa intensidad, entonces tendría que usar la interrupción externa pero también ocasiona ese parpadeo, y en esta interrupción esta el cruce por cero en RB0,  y como el ADC se va estar imprimiendo y refrescando digamos cada 20ms y permita ingresar con el teclado en cualquier momento, por el valor de luminosidad que tenga la LDR. y ya no se me ocurre otra manera.
Estoy usando el PIC16F877A

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:AYUDA CON ADC Y USO DE TECLADO
« Respuesta #3 en: 21 de Julio de 2019, 12:23:04 »
Si haces lo que te digo con las interrupciones no deberias tener problemas.

Interrupcion Timer0 para llevar el tiempo del encendido del foco.
Interrupcion Externa ( RB0 ) para la deteccion del cruce por cero.
Timer2 + CCP en Compare para disparar el ADC, no hay necesidad de interrupcion aca.
Interrupcion del ADC para tomar el resultado una ves terminado.
Programa principal ( main ) unicamente teclado, muestra en el LCD y actualiza variables, nada mas.

En fin.... Las interrupciones van a hacer todos los trabajos respecto a los tiempos, por lo que no vas a tener problemas. Todo por hardware para descargar al CPU que se centre unicamente en el teclado con sus delays si quiere. Y mostrar el valor del LDR en donde lo queras mostrar.

Sino VOS estas haciendo algo mal. Solo una cosa... en las interrupciones NO SE USA DELAYS, o bucles que lleven tiempo. Mas detallado:


Interrupcion Timer0:
Cambio de estado salida
Cambio valor del Timer0 para que la proxima ves que entre apago la salida.
Luego desactivo la interrupcion.

Interrupcion Externa ( RB0 ):
Detecto el cruce por 0
Recargo Timer0 con el valor correcto (variable dada por el teclado )
Activo Timer0 y salgo.

Timer2 + CCP en Compare para disparar el ADC, no hay necesidad de interrupcion aca:
Esto es configurarlo al comienzo del programa y nada mas.

Interrupcion del ADC:
Tomo el resultado del ADC
Guardo en una variable, salgo.

Programa principal ( main ):
Leo teclado
Modifico variables (potencia lampara) si es necesario.
Muestro valor del ADC en el LCD.

Desconectado Ryunagi

  • PIC10
  • *
  • Mensajes: 7
Re:AYUDA CON ADC Y USO DE TECLADO
« Respuesta #4 en: 21 de Julio de 2019, 12:57:10 »
Este es mi código original:
Código: CSS
  1. #include <16f877.h>
  2. #device adc=10
  3. #fuses XT,NOWDT,NOPROTECT,NOWRT,PUT
  4. #use delay(clock=4MHz)
  5.  
  6. #include <lcd_c.c>
  7. #include <kbd_d 4x4.c>
  8. #include <lee_Num16b.c>
  9. INT16 cont=0,angulo=0,angulo1=0;
  10.  
  11.  //VA2=0,VD2=0,VA3=0,VD3=0;
  12.  
  13.  
  14. #BYTE TRISB=0x86
  15. #BYTE PORTB=0x06
  16. #BYTE TRISC=0x87
  17. #BYTE PORTC=0x07
  18. #BYTE TRISD=0x88
  19. #BYTE PORTD=0x08
  20. //
  21. #BYTE OPTION_REG= 0X81
  22. //
  23.  
  24.  
  25. #INT_EXT
  26. void EXT_isr(void)
  27. {
  28.    
  29.    set_timer0(angulo);
  30.    cont=cont+1;
  31.    
  32. }
  33. //
  34. #INT_TIMER0
  35. void TIMER0(void)
  36. {
  37.    output_high(PIN_B7);
  38.    delay_us(20);
  39.    output_low(PIN_B7);
  40.  
  41.  
  42. }
  43.  
  44.  
  45.  
  46. //
  47. void Lux() ;
  48. void main(){
  49.  
  50.    set_tris_C(0b00001000);//0como salidas
  51.    set_tris_D(0b00000000);//0como salidas
  52.    bit_clear(option_reg,0);
  53.    
  54.    lcd_init();
  55.    kbd_init();
  56.    
  57.    setup_adc_ports(AN0);
  58.    setup_adc(ADC_CLOCK_INTERNAL);
  59.    
  60.  
  61.    setup_timer_0(RTCC_INTERNAL|RTCC_DIV_64|RTCC_8_BIT);  
  62.     //enable_interrupts(INT_EXT);
  63.    ext_int_edge(L_TO_H);
  64.    enable_interrupts(GLOBAL);
  65.    
  66.    
  67.    
  68.    while(True){
  69.      
  70.       printf(lcd_putc,"\fLuxes: ");
  71.      
  72.       angulo1=Lee_Num16b();
  73.       delay_ms(20);
  74.      
  75.      
  76.      
  77.  
  78.      if (angulo1>=136 && angulo1 <=250){
  79.      enable_interrupts(INT_TIMER0);
  80.      enable_interrupts(INT_EXT);
  81.      angulo=angulo1;
  82.       Lux();
  83.      delay_ms(100);
  84.      
  85.      
  86.      
  87.      }
  88.      if (angulo1<136){
  89.       disable_interrupts(INT_TIMER0);
  90.       disable_interrupts(INT_EXT);
  91.       output_low(PIN_B7);
  92.       printf(lcd_putc,"\fFuera de Rango \napagado");
  93.       delay_ms(1000);
  94.      
  95.      }
  96.      if (angulo1>250){
  97.       disable_interrupts(INT_TIMER0);
  98.       disable_interrupts(INT_EXT);
  99.       output_high(PIN_B7);
  100.       printf(lcd_putc,"\fFuera de Rango \nprendido");
  101.       delay_ms(1000);
  102.      
  103.      }
  104.    
  105.      
  106.   }
  107.  
  108. }
  109.  
  110. void Lux()
  111. {
  112.  
  113.  float VA1=0, VD1=0;
  114.  //VA2=0,VD2=0,VA3=0,VD3=0;
  115.  float luxw=0;
  116.  //lux2=0,lux3=0,LUXT=0;
  117.  
  118.    setup_adc_ports(AN0);
  119.    setup_adc(ADC_CLOCK_INTERNAL);
  120.    while(true){
  121.       set_adc_channel(0);
  122.       delay_us(20);    
  123.       VA1= read_adc();
  124.       delay_us(5000);    
  125.       VD1= ((5.0*VA1)/1024.0)*0.232;
  126.       luxw= ((2500/VD1)-500)/5;
  127.      
  128.      
  129.       lcd_gotoxy(2,10); printf(lcd_putc,"LUXES: %3.2g ", luxw);
  130.       delay_ms(20);
  131.    }
  132. }
y este es el que modifique con interrupcion AD Y TIMER2 pero tengo un error que no imprime nada en el LCD
Código: CSS
  1. #include <16f877.h>
  2. #device adc=10
  3. #fuses XT,NOWDT,NOPROTECT,NOWRT,PUT
  4. #use delay(clock=4MHz)
  5.  
  6. #include <lcd_c.c>
  7. #include <kbd_d 4x4.c>
  8. #include <lee_Num16b.c>
  9. INT16 cont=0,angulo=0,angulo1;
  10.  
  11.  
  12.  
  13.  
  14. #BYTE TRISB=0x86
  15. #BYTE PORTB=0x06
  16. #BYTE TRISC=0x87
  17. #BYTE PORTC=0x07
  18. #BYTE TRISD=0x88
  19. #BYTE PORTD=0x08
  20. //
  21. #BYTE OPTION_REG= 0X81
  22. //
  23.  
  24.  
  25. #INT_EXT          //CRUCE POR CERO
  26. void EXT_isr(void)
  27. {
  28.    
  29.    set_timer0(angulo);
  30.    cont=0;
  31.  
  32. }
  33. //
  34. #INT_TIMER0
  35. void TIMER0(void) //
  36. {
  37.    output_high(PIN_B7);
  38.    delay_us(20);
  39.    output_low(PIN_B7);
  40.  
  41. }
  42. #INT_AD
  43. void ADC(){
  44.  
  45.  
  46.       float VA1=0;
  47.      
  48.       set_adc_channel(0);
  49.       delay_us(20);    
  50.       VA1= read_adc();
  51.       delay_us(100);    
  52.       Read_ADC(ADC_START_ONLY);
  53.      
  54. }
  55.  
  56. //
  57. void Lux() ;
  58. void main(){
  59.  
  60.    set_tris_C(0b00001000);//0como salidas
  61.    set_tris_D(0b00000000);//0como salidas
  62.    bit_clear(option_reg,0);
  63.    
  64.    lcd_init();
  65.    kbd_init();
  66.    
  67.    setup_adc_ports(AN0);
  68.    setup_adc(ADC_CLOCK_INTERNAL);
  69.    
  70.    setup_timer_2(T2_DIV_BY_4,124,1);
  71.  
  72.    setup_timer_0(RTCC_INTERNAL|RTCC_DIV_64|RTCC_8_BIT);  
  73.    
  74.    enable_interrupts(INT_TIMER2);
  75.    enable_interrupts(int_ad);
  76.    ext_int_edge(L_TO_H);
  77.    enable_interrupts(GLOBAL);
  78.    
  79.    
  80.    
  81.    while(True){
  82.        
  83.       printf(lcd_putc,"\fLuxes:  ");
  84.      
  85.       angulo1=lee_Num16b();
  86.       delay_ms(20);
  87.      
  88.      
  89.      
  90.  
  91.      if (angulo1>=136 && angulo1 <=250){
  92.      enable_interrupts(INT_TIMER0);
  93.      enable_interrupts(INT_EXT);
  94.      angulo=angulo1;
  95.      delay_ms(100);
  96.      Lux() ;
  97.  
  98.      
  99.      
  100.      
  101.      }
  102.      if (angulo1<136){
  103.       disable_interrupts(INT_TIMER0);
  104.       disable_interrupts(INT_EXT);
  105.       output_low(PIN_B7);
  106.       printf(lcd_putc,"\fOFF");
  107.       delay_ms(1000);
  108.      
  109.      }
  110.      if (angulo1>250){
  111.       disable_interrupts(INT_TIMER0);
  112.       disable_interrupts(INT_EXT);
  113.       output_high(PIN_B7);
  114.       printf(lcd_putc,"\fON");
  115.       delay_ms(1000);
  116.      
  117.      }
  118.    
  119.      
  120.   }
  121.  
  122. }
  123.  
  124. void Lux()
  125. {
  126.  
  127.  float VA1=0, VD1=0;
  128.  float luxw=0;
  129.  
  130.        disable_interrupts(int_ad);  
  131.       VD1= ((5.0*VA1)/1024.0)*0.232;
  132.       luxw= ((2500/VD1)-500)/5;
  133.      
  134.      
  135.       lcd_gotoxy(2,10); printf(lcd_putc,"%3.2g",luxw);
  136.       delay_ms(2000);
  137.        enable_interrupts(int_AD);
  138.        Read_ADC(ADC_START_ONLY);
  139.      
  140.    
  141.    
  142. }
seguiré tratando gracias por tu ayuda.
« Última modificación: 21 de Julio de 2019, 18:19:37 por Ryunagi »

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:AYUDA CON ADC Y USO DE TECLADO
« Respuesta #5 en: 22 de Julio de 2019, 20:36:13 »
No uso CCS, por lo tanto el código que voy a pasar es "tentativo" queda en vos revisar y modificar la parte del CCP y Timer 1 para que sea correcto.

Ademas considero que hay varias cosas sin calcular:

- El valor de Timer0 me parece algo ilógico. Si quisiera variar el brillo, por que comenzar desde 160 a 250, ademas es inverso, si se dispara antes el TRIAC es mas brillo la lampara, es decir que mientras mas cerca del 0 mas brillo, y mientras mas cerca del valor a calcular (maximo 8ms aprox en el Timer para 50Hz y dar un margen ) es minimo brillo. Tu logica esta al reves y lo deje asi. Ni siquiera se si es correcto el tiempo, no lo calcule, ya que eso es un deber tuyo.

- El CCP se maneja con el Timer1 para el modo Compare, el Timer 2 es para el PWM, fue un error mio, hay que corregirlo en el codigo para que sea el Timer1, poner bien el tiempo, y ademas cargar correctamente los registros del CCP.

- La formula de calculo de lux es absurdamente grande ( me parece ).....

Código: C
  1. VD1= ((5.0*VA1)/1024.0)*0.232;
  2.       luxw= ((2500/VD1)-500)/5;

Estas ecuaciones quedaria de la misma forma asi:

Código: C
  1. VD1= 0.0011328125*VA1;
  2.       luxw= ((500/VD1)-100);

Si la reemplazo en la de abajo me queda:

Código: C
  1. luxw= ((500/0.0011328125*VA1)-100);

Lo que es igual a:

Código: C
  1. luxw= 441379.3103 * VA1 - 100;

Si uno considera los valores entremos que puede obtener del ADC son: 0 y 1024....
Para 0 tendrias -100 lux (Observar que es un numero negativo)
Y para 1024 tendrias 451.972.313,7931 lux.... Parece un poquito exagerado... seguramente las ecuaciones estén mal.


Código de guía:

Código: C
  1. #include <16f877.h>
  2. #device adc=10
  3. #fuses XT,NOWDT,NOPROTECT,NOWRT,PUT
  4. #use delay(clock=4MHz)
  5.  
  6. #include <lcd_c.c>
  7. #include <kbd_d 4x4.c>
  8. #include <lee_Num16b.c>
  9.  
  10. volatile int16 resultadoADC=0,recargaTimer=0;
  11.  
  12.  
  13.  
  14. #INT_EXT          //CRUCE POR CERO
  15. void EXT_isr(void)
  16. {
  17.     if(!recargaTimer){
  18.         set_timer0(recargaTimer);
  19.         enable_interrupts(INT_TIMER0);
  20.     }
  21. }
  22.  
  23.  
  24. #INT_TIMER0
  25. void TIMER0(void)
  26. {
  27.     output_high(PIN_B7);
  28.     delay_us(10);
  29.     output_low(PIN_B7);
  30.     disable_interrupts(INT_TIMER0);
  31. }
  32.  
  33. #INT_AD
  34. void ADC(){
  35.     resultadoADC = read_adc(ADC_READ_ONLY);
  36. }
  37.  
  38.  
  39. void main(){
  40.  
  41.    set_tris_C(0b00001000);//0como salidas
  42.    set_tris_D(0b00000000);//0como salidas
  43.    
  44.    lcd_init();
  45.    kbd_init();
  46.    
  47.    setup_adc_ports(AN0);
  48.    setup_adc(ADC_CLOCK_INTERNAL);
  49.    
  50.    setup_timer_1(T1_DIV_BY_4,124,1);
  51.    setup_ccp1(CCP_COMPARE_RESET_TIMER);
  52.  
  53.    setup_timer_0(RTCC_INTERNAL|RTCC_DIV_64|RTCC_8_BIT);  
  54.    
  55.    enable_interrupts(int_ad);
  56.    ext_int_edge(L_TO_H);
  57.    enable_interrupts(GLOBAL);
  58.    
  59.    set_adc_channel(0);
  60.    
  61.    while(True){
  62.        
  63.       int16 lectura;
  64.        
  65.       printf(lcd_putc,"\fLuxes:  ");
  66.      
  67.       lectura=lee_Num16b();
  68.  
  69.       if (lectura < 136)
  70.       {
  71.         recargaTimer = 0;
  72.         output_low(PIN_B7);
  73.         printf(lcd_putc,"\fOFF");
  74.       } else if( lectura > 250) {
  75.         recargaTimer = 0;
  76.         output_high(PIN_B7);
  77.         printf(lcd_putc,"\fON");        
  78.       } else {
  79.         recargaTimer = lectura;
  80.       }
  81.  
  82.       float luxw;
  83.  
  84.       disable_interrupts(INT_AD); // Desactivo por posibles problemas
  85.       luxw = 441379.3103 * resultadoADC - 100;
  86.       enable_interrupts(INT_AD);
  87.  
  88.       lcd_gotoxy(2,10); printf(lcd_putc,"%3.2g",luxw);
  89.  
  90.       delay_ms(1000);
  91.      
  92.      }
  93.      
  94. }

Desconectado Ryunagi

  • PIC10
  • *
  • Mensajes: 7
Re:AYUDA CON ADC Y USO DE TECLADO
« Respuesta #6 en: 23 de Julio de 2019, 04:27:45 »
Gracias de nuevo por tu ayuda, trate de hacerlo así como mencionaste, pero resulta que hay unos problemas, la única forma que funciona es así y cada 524ms parpadea el foco, lo que veo es que cuando se imprime en el timer1 o AD, causa ese parpadeo, si lograra imprimir luxw como en un ciclo sin que se bucle infinito.
ya que si lo mando a imprimir al final dentro del while(); solo lo imprime 1 vez y se borra.
este es el código como el que me diste de guía solo modifique cosas, algunas interferían para que se pudiera controlar y encendiera.

PD: no se si hice bien la parte del ccp, por eso da problemas con el timer1.

Código: CSS
  1. #include <16f877.h>
  2. #device adc=10
  3. #fuses XT,NOWDT,NOPROTECT,NOWRT,PUT
  4. #use delay(clock=4MHz)
  5.  
  6. #include <lcd_c.c>
  7. #include <kbd_d 4x4.c>
  8. #include <lee_Num16b.c>
  9.  
  10. #define VALOR_T1 0  //carga a 0 es 524.288ms
  11. volatile int16 resultadoADC=0,recargaTimer=0;
  12.    volatile float luxw;
  13.  
  14. #INT_EXT          //CRUCE POR CERO
  15. void EXT(void)
  16. {
  17.    
  18.         set_timer0(recargaTimer);
  19.        
  20.    
  21. }
  22.  
  23.  
  24. #INT_TIMER0
  25. void TIMER0(void)
  26. {
  27.     output_high(PIN_B7);
  28.     delay_us(20);
  29.     output_low(PIN_B7);
  30.  
  31. }
  32.  
  33. #INT_AD
  34. void ADC(){
  35.          
  36.          luxw= ((500/(0.0011328125*resultadoADC))-100);    // esta formula la deje asi ya que el resultadoADC
  37.                                                         //primero debe  multiplicarse
  38.                                                        //y luego la division y despues la resta
  39.                                                       // por eso te da un valor muy grande.
  40.                                                            
  41.          lcd_gotoxy(2,10); printf(lcd_putc,"%3.2g",luxw); // si imprimo en int_AD o en timer1 el foco parpadea leve
  42.                                                        //y logro que se imprima constante el valor LUXW
  43.                                                       //y no logro saber donde colocarlo para que no parpade
  44.                                                      // solo asi logre que funcionara.
  45.                                   //si activo el CCP_COMPARE_RESET_TIMER ya no me hace el muestreo.
  46. }
  47. #INT_TIMER1
  48. void TIMER1(void)          //aqui me hace un muestreo cada 524ms
  49. {
  50.      
  51.      resultadoADC = read_adc();
  52.      delay_us(20);
  53.      set_timer1(VALOR_T1);
  54.      
  55.      
  56. }
  57.  
  58.  
  59. void main(){
  60.  
  61.    set_tris_C(0b00001000);//0como salidas
  62.    set_tris_D(0b00000000);//0como salidas
  63.    
  64.    lcd_init();
  65.    kbd_init();
  66.    
  67.    
  68.    setup_adc(ADC_CLOCK_INTERNAL);
  69.    setup_adc_ports(AN0);
  70.    
  71.  
  72.    setup_timer_1(T1_INTERNAL| T1_DIV_BY_8); //prescaler de 8
  73.    //setup_ccp1(CCP_COMPARE_RESET_TIMER); //si lo activo ya no funciona el ADC y el timer1
  74.  
  75.    setup_timer_0(RTCC_INTERNAL|RTCC_DIV_64|RTCC_8_BIT);   // prescaler de 64 y 16ms, sercas casi lo que es el ciclo completo
  76.    
  77.    //ccp_1=20000; // 20ms a 4MHz       //si lo activo ya no funciona el ADC y el timer1
  78.    
  79.    enable_interrupts(int_ad);
  80.    ext_int_edge(L_TO_H);
  81.    enable_interrupts(INT_TIMER1);
  82.    set_timer1(VALOR_T1);      //carga a 0 es 524.288ms
  83.    enable_interrupts(GLOBAL);
  84.    
  85.    
  86.  
  87.    
  88.    while(True){
  89.        
  90.       int16 lectura;
  91.        
  92.       printf(lcd_putc,"\fLuxes:  ");
  93.      
  94.       lectura=lee_Num16b();
  95.  
  96.       if (lectura < 136)
  97.       {
  98.         recargaTimer = 0;
  99.         output_low(PIN_B7);
  100.         printf(lcd_putc,"\fOFF");
  101.       } else if( lectura > 250) {
  102.         recargaTimer = 0;
  103.         output_high(PIN_B7);
  104.         printf(lcd_putc,"\fON");        
  105.       } else {
  106.         recargaTimer = lectura;
  107.         enable_interrupts(INT_TIMER0);
  108.         enable_interrupts(INT_EXT);
  109.       }
  110.  
  111.      
  112.      }
  113.      
  114. }

y aqui dejo mi codigo con el timer1 que digamos es lo mismo jejeje
pero hace el mismo parpadeo...

Código: CSS
  1. #include <16f877.h>
  2. #fuses XT, NOWDT
  3. #device adc= 10
  4. #use delay (clock =4 MHz)
  5. #use standard_io(a)
  6. #use standard_io(b)
  7. #include<LCD_C.c>
  8. #include <KBD_D 4X4.c>
  9. #include <Lee_Num16b.c>
  10. //
  11. #BYTE TRISB=0x86
  12. #BYTE PORTB=0x06
  13. #BYTE TRISC=0x87
  14. #BYTE PORTC=0x07
  15. #BYTE TRISD=0x88
  16. #BYTE PORTD=0x08
  17. //
  18. #BYTE OPTION_REG= 0X81 //activa pull-ups
  19. //
  20. #define VALOR_T1 0 //carga a 0 es 524ms tiempo maximo del timer1 a prescaler de 8
  21. //
  22. volatile int16 recargaTimer=0 ,lectura;
  23. volatile float VA1=0, lux=0;
  24. //
  25. #INT_TIMER1
  26. void LDR() {
  27.    set_adc_channel(0);
  28.    delay_us(20);    
  29.    VA1= read_adc();    
  30.    lux= ((500/(0.0011328125*VA1))-100);
  31.    set_timer1(VALOR_T1);
  32.    lcd_gotoxy(1,1); printf(lcd_putc,"LUXES: %3.2g    ", lux);
  33. }
  34. //
  35. #INT_EXT
  36. void EXT_isr(void) {
  37.     set_timer0(recargaTimer);
  38. }
  39.  
  40.  
  41. #INT_TIMER0
  42. void TIMER0(void) {
  43.    output_high(PIN_B7);
  44.    delay_us(20);
  45.    output_low(PIN_B7);
  46. }
  47. //
  48. void main() {
  49.    set_tris_C(0b00001000);//0como salidas
  50.    set_tris_D(0b00000000);//0como salidas
  51.    bit_clear(option_reg,0);
  52.    //
  53.    lcd_init();
  54.    kbd_init();
  55.    //
  56.    setup_adc_ports(AN0);
  57.    setup_adc(ADC_CLOCK_INTERNAL);
  58.    setup_timer_0(RTCC_INTERNAL|RTCC_DIV_64|RTCC_8_BIT); // prescaler de 64 y 16ms, sercas casi lo que es el ciclo completo
  59.    setup_timer_1(T1_INTERNAL| T1_DIV_BY_8); // prescaler de 8 a 524ms
  60.    ext_int_edge(L_TO_H);
  61.    enable_interrupts(INT_TIMER1);
  62.    set_timer1(VALOR_T1);
  63.    enable_interrupts(GLOBAL);
  64.    //
  65.    while(TRUE){
  66.       lcd_gotoxy(1,2);printf(lcd_putc,"LUX= ");
  67.       lectura= Lee_Num16b();
  68.       delay_ms(20);
  69.       //
  70.      
  71.       if (lectura < 136)
  72.       {
  73.         recargaTimer = 0;
  74.         output_low(PIN_B7);
  75.         printf(lcd_putc,"\nOFF");
  76.         delay_ms(1000);
  77.       } else if( lectura > 250) {
  78.         recargaTimer = 250;
  79.         output_high(PIN_B7);
  80.         printf(lcd_putc,"\nON");
  81.         delay_ms(1000);
  82.       } else {
  83.      enable_interrupts(INT_TIMER0);
  84.      enable_interrupts(INT_EXT);
  85.         recargaTimer = lectura;
  86.       }
  87.    
  88.    
  89.    
  90.    
  91.       //
  92.    }
  93. }
Gracias por tu ayuda. a seguir ideando mas soluciones.
 
« Última modificación: 23 de Julio de 2019, 04:32:36 por Ryunagi »

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:AYUDA CON ADC Y USO DE TECLADO
« Respuesta #7 en: 23 de Julio de 2019, 06:39:42 »
Vos tenes que entender que mi codigo NO usa el main para encender el led, asi que si hay algun problema es porque los tiempos estan mal o las interrupciones estan mal.

Entonces el problema fue obvio..

   
Código: C
  1. ext_int_edge(L_TO_H);

Unicamente estoy considerando el paso de bajo a alto..... Dependiendo del circuito que tenes, puede que esto solo tenga en cuenta la mitad de la onda senoidal. Asi que un problema seria contemplar que tambien lo haga de alto a bajo.

Código: C
  1. #use delay(clock=4MHz)
  2.    setup_timer_0(RTCC_INTERNAL|RTCC_DIV_64|RTCC_8_BIT);   // prescaler de 64 y 16ms, sercas casi lo que es el ciclo completo

Aca tenes otro problema, como te comente los tiempos... Si vos conoces el cruce por 0, necesitas activar la salida apenas cruza por cero (maximo brillo) o antes de cumplirse todo el medio ciclo es decir 10ms para 50Hz (minimo brillo). Asi tambien para el otro semiciclo, esto se repite...

Pero veamos tus valores.... Una cuenta de 160 significa que pasaron 1us * 64 * 160 = 10.24ms si observas nos pasamos en MUCHO tiempo.
Ni hablar de 250 que son 16ms.

Entonces.....
Si sumamos el tema de que solo actuamos sobre un semiciclo mas el tema de los tiempos veo porque puede estar fallando la idea.

El Timer0 y la interrupcion externa manejan la lampara.

-----------------------------------------

Los calculos especialmente en flotante son no pueden ir en las interrupciones, por que demoran demasiado tiempo. Y afecta a las demas interrupciones.

Mostrame el circuito de como es que detectas el cruce por cero para tener una mejor idea.

Desconectado Ryunagi

  • PIC10
  • *
  • Mensajes: 7
Re:AYUDA CON ADC Y USO DE TECLADO
« Respuesta #8 en: 23 de Julio de 2019, 12:50:44 »
aquí dejo el proteus  trabajo a 60Hz

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:AYUDA CON ADC Y USO DE TECLADO
« Respuesta #9 en: 23 de Julio de 2019, 17:07:40 »
Me vas a disculpar pero no poseo Proteus, asi que vas a tener que poner una imagen del esquema.

Desconectado Ryunagi

  • PIC10
  • *
  • Mensajes: 7
Re:AYUDA CON ADC Y USO DE TECLADO
« Respuesta #10 en: 23 de Julio de 2019, 20:22:29 »
la imagen

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:AYUDA CON ADC Y USO DE TECLADO
« Respuesta #11 en: 24 de Julio de 2019, 16:52:33 »
Vamos por parte entonces....

Supongamos que con tu circuito tenes un pulso por cada cruce por 0 (uno por cada medio ciclo), en 60Hz cada medio ciclo es de 8.33ms, es decir debemos activar nuestro TRIAC en ese tiempo. Como el cruce por 0 no es tan perfecto vamos a dejar un pequeño margen de seguridad al iniciar, y al terminar.

Vamos a suponer un minimo de tiempo de disparo de 1ms y un maximo de tiempo de 7ms

Si uso un preescaler de 1:32 para el Timer0, obtengo que:

1ms - Cargo 31 en el Timer
7ms - Cargo 218 en el Timer

Esos van a ser los limites... menos de 31 significa encendido siempre, mas de 218 significa apagado siempre. Por lo tanto corregimos esta parte del programa:


Código: C
  1. if (lectura < 136)
  2.       {
  3.         recargaTimer = 0;
  4.         output_low(PIN_B7);
  5.         printf(lcd_putc,"\fOFF");
  6.       } else if( lectura > 250) {
  7.         recargaTimer = 0;
  8.         output_high(PIN_B7);
  9.         printf(lcd_putc,"\fON");        
  10.       } else {
  11.         recargaTimer = lectura;
  12.         enable_interrupts(INT_TIMER0);
  13.         enable_interrupts(INT_EXT);
  14.       }

por

Código: C
  1. if (lectura > 218)
  2.       {
  3.         recargaTimer = 0;
  4.         output_low(PIN_B7);
  5.         printf(lcd_putc,"\fOFF");
  6.       } else if( lectura < 31) {
  7.         recargaTimer = 0;
  8.         output_high(PIN_B7);
  9.         printf(lcd_putc,"\fON");        
  10.       } else {
  11.         recargaTimer = lectura;
  12.         enable_interrupts(INT_TIMER0);
  13.         enable_interrupts(INT_EXT);
  14.       }

Y respecto al CCP, si no podes hacerlo funcionar.... que seria muy extraño, pero debido a que no estoy acostumbrado al compilador y por eso no te puedo ayudar.
Podrias hacer que el Timer 1 esa quien inicie el ADC, y tomas el valor de alli, PERO OJO!, no esperes la conversion DENTRO de la interrupcion.

Desconectado Ryunagi

  • PIC10
  • *
  • Mensajes: 7
Re:AYUDA CON ADC Y USO DE TECLADO
« Respuesta #12 en: 25 de Julio de 2019, 02:36:37 »
Gracias por tu ayuda. tratare de ver posibles soluciones