Autor Tema: AYUDA CON ADC - 18F2550 ...cambio a temas de C.  (Leído 5839 veces)

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

Desconectado sblanco

  • PIC10
  • *
  • Mensajes: 7
AYUDA CON ADC - 18F2550 ...cambio a temas de C.
« en: 11 de Septiembre de 2008, 11:42:10 »
Hola, es mi primera consulta en el foro y estoy teniendo problemas con el ADC. Lo que pretende el programa es leer los 2 potenciometros de un joystick y enviar cada lectura a el dutycycle de los 2 PWMs pero si simulo con MPSIM y veo el duty estan en ceros, si simulo con pickit2 muestra 1023. Tengo conectados a las salidas de PWM 2 leds para ver varias su brillo al mover el stick, este es el programa hasta ahora:

#pragma   config   FOSC = INTOSC_XT, IESO = OFF
#pragma config   PWRT = ON, BOR = OFF
#pragma config   WDT   = OFF
#pragma config   MCLRE   = ON
#pragma config    LVP = OFF

#include   <p18F2550.h>
#include   <delays.h>
#include   <timers.h>
#include   <pwm.h>
#include   <adc.h>
#include   <stdio.h>

int         eje_Y;
int         eje_X;

void      inicializar   (void);


/*******************************************************************/
/*******************************************************************/

void   main   (void)
{
   inicializar();

   while (1)
   {
   OpenADC(ADC_FOSC_8      &
         ADC_RIGHT_JUST   &
         ADC_16_TAD,
         ADC_CH0         &
         ADC_INT_OFF, 15);
   SetChanADC   (ADC_CH0);      // Encender Ch 0 - ADC
   Delay10TCYx   (20);         // Demora para aquisition time
   ConvertADC   ();            // Hacer conversion Ch 0
   while       (BusyADC());   // Esperar hasta completar conversion
                        // Lee ADC y guarda en variable eje_Y:
   eje_Y      = ReadADC() & 0x3FF;
   SetDCPWM1   (eje_Y);      // Programa DC-1 al valor del ADC

/*******************************************************************/
   OpenADC(ADC_FOSC_8      &
         ADC_RIGHT_JUST   &
         ADC_16_TAD,
         ADC_CH1         &
         ADC_INT_OFF, 15);
   SetChanADC   (ADC_CH1);      // Encender Ch 1 - ADC
   Delay10TCYx   (20);         // Demora para aquisition time
   ConvertADC   ();            // Hacer conversion Ch 1
   while       (BusyADC());   // Esperar hasta completar conversion
                        // Lee ADC y guarda en variable eje_X:
   eje_X      = ReadADC() & 0x3FF;
   SetDCPWM2   (eje_X);      // Programa DC-2 al valor del ADC
   }
}
/*******************************************************************/
/*******************************************************************/

void   inicializar   (void)
{
   
   OSCCON   =   0b01100010;      // INTERNAL OSC 4 MHZ
   //ADCON0   =   0x00;
   ADCON1   =   0b00001101;      // PORTA = DIGITAL but AN0 and AN1
   //CMCON   =   0x07;
   TRISA   =   0b00000011;
   PORTAbits.RA2 = 1;
   TRISB   =   0;
   TRISC   =   0;
   
   PORTA   =   0;
   PORTB   =   0;
   PORTC   =   0;
   eje_Y   =   eje_X   =   0;
   PORTAbits.RA2 = 1;

//   Habilitar timer2 y pwm 1 y 2:
   OpenTimer2    (TIMER_INT_OFF & T2_PS_1_1 & T2_POST_1_1);
   OpenPWM1   (0xFF);
   OpenPWM2   (0XFF);
}

QUE PUEDO ESTAR HACIENDO MAL ???
gracias,

Desconectado firepic

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1130
    • JC Servicios
Re: AYUDA CON ADC - 18F2550 ...cambio a temas de C.
« Respuesta #1 en: 11 de Septiembre de 2008, 12:03:18 »
Qué tal sblanco, bienvenido al foro!
Bueno yo trabajo con C pero de la casa CCS, aunque es bastante parecido al que tú usas.
Tu código lo veo en general bien, sólo que el trozo "OpenADC", que es la configuración del módulo ADC, no hace falta que lo coloques dentro del while, sino afuera, pero dentro del main. Quedaría así:
Código: C
  1. void   main   (void)
  2. {
  3.    inicializar();
  4.    OpenADC(ADC_FOSC_8      &
  5.          ADC_RIGHT_JUST   &
  6.          ADC_16_TAD,
  7.          ADC_CH0         &
  8.          ADC_INT_OFF, 15);
  9.    while (1)
  10.    {
  11.    SetChanADC   (ADC_CH0);      // Encender Ch 0 - ADC
  12.    Delay10TCYx   (20);         // Demora para aquisition time
  13.    ConvertADC   ();            // Hacer conversion Ch 0
  14.    while       (BusyADC());   // Esperar hasta completar conversion
  15.                         // Lee ADC y guarda en variable eje_Y:
  16.    eje_Y      = ReadADC() & 0x3FF;
  17.    SetDCPWM1   (eje_Y);      // Programa DC-1 al valor del ADC

Dices que lo simulas con el mismo mplab y el duty está en ceros? Supongo que es porque no le das ningún estímulo a la entrada analógica (no he probado jugar con estímulos analógicos), y por eso el simulador siempre dará como resultado de la conversión el valor 0. Ahora bien, pregunto... no lo has probado en proteus?
Yo te aconsejaría que le dieras valores al duty (constantes) a ver si funciona correctamente.. tal vez el error esté en la configuración del módulo PWM. Si al darle distintos valores no funciona, pues ya sabes donde está el error... si funciona, entonces hay que empezar a dudar de la conversión A/D, o del hardware. Porque veo el código bastante ordenado.
Y bueno, esperemos a que algún experto en C del foro dé opinión al respecto, a ver si aclara más la cosa.
Te deseo éxito, saludos!  :mrgreen:
"Por la presunción solo se ocasiona una lucha, pero con los que consultan juntos hay sabiduría" (Proverbios 13:10).
Visita Mi Sitio Web

Desconectado sblanco

  • PIC10
  • *
  • Mensajes: 7
Re: AYUDA CON ADC - 18F2550 ...cambio a temas de C.
« Respuesta #2 en: 11 de Septiembre de 2008, 12:44:54 »
gracias Firepic, estaba colocando las funciones OpenADC dentro del loop por lo que estoy leyendo los 2 canales, entonces tengo una para el Ch0 y otra para el Ch1, no se si es innecesario.  Sobre lo del duty cycle si lo he probado asignando un valor a la variable antes de programarlo y funciona, no lo he visto en Proteus pero tengo osciloscopio y me doy cuenta de la salida que funciona bien. Es bastante facil usar el PWM en C, pero estoy un poco trabado con el ADC, seguramente es algun detalle que luego se me hara facil de manejar.  Por ahora recogi un texto para abrir el ADC con otros parametros a ver si me funciona:

OpenADC(ADC_FOSC_32 & ADC_RIGHT_JUST & ADC_0_TAD,      //Config ADCON2
         ADC_CH0 & ADC_INT_OFF & ADC_VREFMINUS_VSS & ADC_VREFPLUS_VDD,   //Config ADCON0
         11);

Lo intentare esta tarde.

Otras ideas ??

Desconectado firepic

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1130
    • JC Servicios
Re: AYUDA CON ADC - 18F2550 ...cambio a temas de C.
« Respuesta #3 en: 11 de Septiembre de 2008, 13:37:42 »
Guao! Qué bueno ha de ser tener osciloscopio, así se vuelve la cosa una gozada!
Mira a veces los compiladores se ponen un poco cómicos...
Te sugeriría que leyeras bien la detasheet acerca del ADC, y veas directamente allí los registros que hay que configurar. Luego puedes configurarlo a "bajo nivel", escribiendo las palabras de configuración directamente en los registros de propósito especial.
Intento eso y dices qué tal va la cosa...
Saludos!  :mrgreen:
"Por la presunción solo se ocasiona una lucha, pero con los que consultan juntos hay sabiduría" (Proverbios 13:10).
Visita Mi Sitio Web

Desconectado MLO__

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 4581
Re: AYUDA CON ADC - 18F2550 ...cambio a temas de C.
« Respuesta #4 en: 11 de Septiembre de 2008, 13:53:12 »
Hola.

Por lo que deduzco es mcc18. Te posteo un ejemplo de un voltimetro para que te guies (solo cambia el pic a usar y los fuses). Despliego el valor en displays de 7 segmentos. La configuracion del ADC solo se hace una vez fuera del ciclo infinito, ya luego se usa la funcion SetChanADC() para configurar el canal de conversion.
Código: C++
  1. #include <p18f452.h>
  2. #include <adc.h>
  3. #include <timers.h>    
  4. #include <pwm.h>
  5. #include <delays.h>    
  6.  
  7.  
  8.  
  9. int r1;
  10. double r2;
  11. int u,d,c,aux;
  12.  
  13. void main (void)
  14. {      
  15.        
  16.         TRISC = 0x00;                                                  
  17.         TRISA = 0x2f;
  18.         TRISE = 0x07;
  19.         TRISD = 0x00;
  20.  
  21.         OpenADC( ADC_FOSC_16 & ADC_RIGHT_JUST & ADC_8ANA_0REF, ADC_CH0 & ADC_INT_OFF );
  22.         for(;;)
  23.                 {
  24.                         SetChanADC( ADC_CH0 ); 
  25.                         Delay10TCYx( 5 );
  26.                         ConvertADC();
  27.                         while ( BusyADC() )                                                    
  28.                                 r1 = ReadADC();
  29.  
  30.  
  31. //***leo el valor digital de voltage, lo paso a temperatura y lo despliego en display's
  32.  
  33.                         r1 = r1 / 1.023;
  34.                         aux = r1;
  35.  
  36.                         c = 0;
  37.                         while ( aux > 100 )
  38.                                 {
  39.                                 aux = aux - 100;
  40.                                 c++;
  41.                                 }
  42.  
  43.                         d = 0;
  44.                         while ( aux > 10 )
  45.                                 {
  46.                                 aux = aux - 10;
  47.                                 d++;
  48.                                 }
  49.  
  50.                         u = 0;
  51.                         while ( aux > 1 )
  52.                                 {
  53.                                 aux = aux - 1;
  54.                                 u++;
  55.                                 }
  56.  
  57.                                 PORTC = 0x12;
  58.                                 PORTD = c;
  59.                                 Delay100TCYx( 1 );
  60.  
  61.                                 PORTC = 0x04;
  62.                                 PORTD = d;
  63.                                 Delay100TCYx( 1 );     
  64.  
  65.                                 PORTC = 0x18;
  66.                                 PORTD = u;
  67.                                 Delay100TCYx( 1 );
  68.  
  69.                 }
  70.  
  71.  
  72.         CloseADC();
  73. }

Saludos
El papel lo aguanta todo

Desconectado MLO__

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 4581
Re: AYUDA CON ADC - 18F2550 ...cambio a temas de C.
« Respuesta #5 en: 11 de Septiembre de 2008, 13:56:58 »
Hola

Otra cosa. Los fusibles de configuracion se colocan despues del #include<p18F...>. Revisa el MPLAB C18 Libraries para escoger bien la configuracion del ADC.

Saludos
El papel lo aguanta todo

Desconectado sblanco

  • PIC10
  • *
  • Mensajes: 7
Re: AYUDA CON ADC - 18F2550 ...cambio a temas de C.
« Respuesta #6 en: 11 de Septiembre de 2008, 16:35:19 »
Gracias a todos, esta noche ensayo todos estos cambios y tan pronto me funcione posteare el programa final para que veamos cual era el problema.

Saludos,

Desconectado firepic

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1130
    • JC Servicios
Re: AYUDA CON ADC - 18F2550 ...cambio a temas de C.
« Respuesta #7 en: 11 de Septiembre de 2008, 16:48:58 »
Bueno te dejo con MLO que si es un experto.
Solo un pequeño detalle sblanco, si ves que un tema encaja mejor en otro lugar del foro que donde lo colocaste antes, sólo tienes que darle a un botón que dice "mover", para cambiarlo de sitio... o sencillamente elimina el anterior... para no tener hilos duplicados y llevar la cosa más ordenada. Una pequeña sugerencia no más.  :lol:
Ok saludos!  :mrgreen:
"Por la presunción solo se ocasiona una lucha, pero con los que consultan juntos hay sabiduría" (Proverbios 13:10).
Visita Mi Sitio Web

Desconectado MLO__

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 4581
Re: AYUDA CON ADC - 18F2550 ...cambio a temas de C.
« Respuesta #8 en: 11 de Septiembre de 2008, 17:46:38 »
Oye Javier!!! no soy experto!!!  aprendiendo, aprendiendo :D :D Honor que me haces amigo!!!

Saludos
El papel lo aguanta todo

Desconectado sblanco

  • PIC10
  • *
  • Mensajes: 7
Re: AYUDA CON ADC - 18F2550 ...cambio a temas de C.
« Respuesta #9 en: 12 de Septiembre de 2008, 11:10:04 »
Hola Amigos! finalmente anoche funciono el programa, anexo este por si necesitan algoi asi. En realidad estos son los primeros pasos para la construccion de una silla de ruedas electrica. Faltan detalles pero la base ya esta:

/          *Proposito:   Programa para lectura de Joystick y envio de lectura a
            duty cycle de PWM's. En salidas de PWMs se encuentran 2
            leds que simulan motores para graduar su brillo / velocidad
            de acuerdo al movimiento del Joystick. Entradas por AN0 y
            AN1, salidas por CCP1 y CCP2 del chip 18F2550 usando
            lenguaje MCC18 de Microchip.
*/
   /*******************************************************************/

#include   <p18F2550.h>
#include   <delays.h>
#include   <timers.h>
#include   <pwm.h>
#include   <adc.h>
#include   <stdio.h>

#pragma   config   FOSC = INTOSC_XT, IESO = OFF   // Configuracion Inicial.
#pragma config   PWRT = ON, BOR = OFF
#pragma config   WDT   = OFF
#pragma config   MCLRE   = ON
#pragma config    LVP = OFF

int      eje_Y;               // Variables de los 2 ejes.
int      eje_X;

void      inicializar   (void);


   /*******************************************************************/
   /*******************************************************************/

void   main   (void)
{
   inicializar();

   OpenADC(ADC_FOSC_32 & ADC_RIGHT_JUST & ADC_0_TAD,               //Config ADCON2
        ADC_CH0 & ADC_INT_OFF & ADC_VREFMINUS_VSS & ADC_VREFPLUS_VDD,   //Config ADCON0
        11);                                              //Config ADCON1

   while (1)
   {
   SetChanADC   (ADC_CH0);      // Encender Ch 0 - ADC
   Delay10TCYx   (5);         // Demora para aquisition time
   ConvertADC   ();            // Hacer conversion Ch 0
   while       (BusyADC());   // Esperar hasta completar conversion
                        // Lee ADC y guarda en variable eje_Y:
   eje_Y      = ReadADC() & 0x3FF;
   SetDCPWM1   (eje_Y);      // Programa DutyCycle1 al valor del ADC

   /*******************************************************************/

   SetChanADC   (ADC_CH1);      // Encender Ch 1 - ADC
   Delay10TCYx   (5);         // Demora para aquisition time
   ConvertADC   ();            // Hacer conversion Ch 1
   while       (BusyADC());   // Esperar hasta completar conversion
                        // Lee ADC y guarda en variable eje_X:
   eje_X      = ReadADC() & 0x3FF;
   SetDCPWM2   (eje_X);      // Programa DutyCycle2 al valor del ADC
   }
}
   /*******************************************************************/
   /*******************************************************************/

void   inicializar   (void)
{
   OSCCON   =   0b01100010;      // INTERNAL OSC 4 MHZ
   ADCON1   =   0b00001101;      // PORTA = ALL DIGITAL but AN0 and AN1
   TRISA   =   0b00000011;      // Todos output excepto AN0 y AN1
   TRISB   =   0;
   TRISC   =   0;
   
   PORTA   =   0;
   PORTB   =   0;
   PORTC   =   0;
   eje_Y   =   eje_X   =   0;
   PORTAbits.RA2 = 1;         // Para saber si pasó por acá.

   /*******************************************************************/

   //   Habilitar timer2 y pwm 1 y 2:

   OpenTimer2    (TIMER_INT_OFF & T2_PS_1_1 & T2_POST_1_1);
   OpenPWM1   (0xFF);
   OpenPWM2   (0XFF);
}


Saludos!

Desconectado MLO__

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 4581
Re: AYUDA CON ADC - 18F2550 ...cambio a temas de C.
« Respuesta #10 en: 12 de Septiembre de 2008, 12:27:43 »
Hola.

Me parece muy bien. Un consejo: Cuando hagas la adquisicion del dato analogico es bueno usar un filtro software (moving average de unos 50 datos), lo cual toma algun tiempo (1 o 2 mS) que aunque no es mucho puede afectar la sincronizacion de los dos motores, por lo que es recomendable que el tiempo que pasa en asignar el PWM1 y el PWM2 sea el minimo posible, asi que seria conveniente que asignaras el dutty secuencialmente, es decir:

Código: [Seleccionar]
....
  while (1)
   {
   SetChanADC   (ADC_CH0);      // Encender Ch 0 - ADC
   Delay10TCYx   (5);         // Demora para aquisition time
   ConvertADC   ();            // Hacer conversion Ch 0
   while       (BusyADC());   // Esperar hasta completar conversion
                        // Lee ADC y guarda en variable eje_Y:
   eje_Y      = ReadADC() & 0x3FF;
   /*******************************************************************/

   SetChanADC   (ADC_CH1);      // Encender Ch 1 - ADC
   Delay10TCYx   (5);         // Demora para aquisition time
   ConvertADC   ();            // Hacer conversion Ch 1
   while       (BusyADC());   // Esperar hasta completar conversion
                        // Lee ADC y guarda en variable eje_X:
   eje_X      = ReadADC() & 0x3FF;
   SetDCPWM2   (eje_X);      // Programa DutyCycle2 al valor del ADC
   SetDCPWM1   (eje_Y);      // Programa DutyCycle1 al valor del ADC
   //La diferencia de asignacion entre duttys es mucho menor
   }
}

Saludos
El papel lo aguanta todo

Desconectado firepic

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1130
    • JC Servicios
Re: AYUDA CON ADC - 18F2550 ...cambio a temas de C.
« Respuesta #11 en: 12 de Septiembre de 2008, 19:20:09 »
Felicitaciones sblanco! Qué bien que terminaste esa parte del proyecto.  :-/
Ojalá nos dejes seguir viendo tus progresos en los otros módulos.
Un cordial saludo, nos leemos!  :mrgreen:
"Por la presunción solo se ocasiona una lucha, pero con los que consultan juntos hay sabiduría" (Proverbios 13:10).
Visita Mi Sitio Web


 

anything