Autor Tema: Urgente!!!! Ayuda con conversor A/D del pic  (Leído 3050 veces)

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

Desconectado toxete

  • PIC10
  • *
  • Mensajes: 44
Urgente!!!! Ayuda con conversor A/D del pic
« en: 30 de Mayo de 2006, 08:13:29 »
:? :? :? :? :? :? :? :? :? :? :? :? :? :?
Hola a todos de nuevo!
Vereis tengo un problemilla que tengo que solucionar en breve con repecto al conversor A/D del pic.
Me explico:

Tengo que obtener señales analógicas con el pic, en concreto 16, por esto utilizo un multiplexor analogico de 16 canales. Utilizo el canal 0 del puerto A del pic como entrada analogica para el conversor y las siguientes cuatro del mismo puerto para las entradas de seleccion del multiplexor (como se puede ver en la imagen), y entre la salida del mux y la entrada del pic tengo un filtro. Bueno el tema es que si yo selecciono el canal 0 del mux por ejemplo y obtengo la señal la  convierto y me suele dar unos 0.3 0.4 0.5 voltios de diferencia (mas o menos) y todo esto hasta realizando un promedio por ejemplo de 100 muestras o asi, sigue habiendo diferencia.

Este es un problema pero el que sigue me "jode" aun mas y es que si por ejemplo selecciono un canal solo como he dicho antes mas o menos me da la tension aproximada pero si selecciono un canal y convierto y a continuacion selecciono otro canal y lo convierto, ninguna de las dos medidas se parecen en nada a la realidad. Aqui os dejo un ejemplo de codigo que utilizo en el que convierto dos canales y adjunto el esquema del circuito con el mux. No se si deberia tener tension de referencia o que, o cambiar las patillas de seleccion del mux a otro puerto pero es que ya no se que hacer.


#include <18F2525.h> // Dispositivo a utilizar
 
#device adc=8 // Resolución de 8 bits para el conversor ADC
#fuses HS,NOWDT,NOPROTECT,NOLVP,NOBROWNOUT // Fusibles
#use delay(clock=19660800) // Velocidad del cristal
#use   i2c(master,sda=PIN_C4, scl=PIN_C3,FORCE_HW)
#use   rs232(baud=19200, xmit=PIN_C6, rcv=PIN_C7)        

#include <STDIO.H>   //Para las funciones RS232
#include <STDLIB.H>   //Para la función atol
#include <STRING.H>   //Para funciones con strings

#use fast_io(A)
#use fast_io(B)
int dato;

const int escala = 255; // Escala del conversor ADC (8 bits)
const float v_max = 4.98; // Voltaje máximo que entrega mi fuente

 
void calcula(int canal,float val)
   {
   float voltaje;
    voltaje = (val*v_max)/escala;
   printf("\r\n%u:%1.2f",canal,voltaje);
   delay_ms(50);
   }


#INT_RDA                         //Tratamiento de la interrupcion por recepcion
void rs232_isr(void)
{
 
   dato=getch();

 }

void main()
{

   int canal;
   int16 i;
    int8 valor; // La declaración de variables SIEMPRE debe ir lo primero
   float valort;
    float voltaje; //
   set_tris_a(0b00000001);   //RA0 configurado como entrada

    set_tris_B(0b00000000); // Puerto B configurado como salida
    port_b_pullups(FALSE); // Desactivamos pull-ups del puerto B
   disable_interrupts(GLOBAL);      // Apaga todas las interrupciones
   enable_interrupts(INT_RDA);      // Da permiso a la interrupcion por recepcion RS232
   
   enable_interrupts(GLOBAL);      // Ahora habilitamos todas

    setup_adc(ADC_CLOCK_INTERNAL); // Reloj para el conversor
    setup_adc_ports(AN0);
    set_adc_channel(0); // Seleccionamos el canal 0 (RA0)
   setup_vref(FALSE);

   for(;;) // Bucle infinito,que se ejecuta de forma indefinida
   {
   canal=1;

   delay_us(50);
   output_A(canal<<1);
   delay_ms(10);
   for(i=0; i<1000; i++){
       read_adc(ADC_START_ONLY);
         valor=read_adc(ADC_READ_ONLY);
         valort+=valor;
   }
   valort/=1000;
    calcula(canal,valort); // Le mandamos el parámetro "valor" y nos devuelve "voltaje"
    delay_ms(10); // Retardo de un 10 ms

   canal=0;

   delay_us(50);
   output_A(canal<<1);
   delay_ms(10);
   for(i=0; i<1000; i++){
      read_adc(ADC_START_ONLY);
        valor=read_adc(ADC_READ_ONLY);
       valort+=valor;
   }
   valort/=1000;
    calcula(canal,valort); // Le mandamos el parámetro "valor" y nos devuelve "voltaje"
    delay_ms(10); // Retardo de un 10 ms

   }
}


por favor a ver si alguien puede ayudarme por que no se por donde tirar.

Un saludo

 :( :( :( :( :( :( :(

Desconectado fastyx

  • Colaborador
  • PIC18
  • *****
  • Mensajes: 353
Re: Urgente!!!! Ayuda con conversor A/D del pic
« Respuesta #1 en: 30 de Mayo de 2006, 09:34:49 »
te hago una pregunta: los pines del mux a0, a1,  a2 y a3 le mandan informacion al pic o el pic le manda al mux?

la pregunta surge porque si es el primer caso ,tenes el tris del puerto a con a0 solamente definido como entrada, por ahi te puede servir ,pero si es el el segund caso no.

espero haber sido de ayuda...

Desconectado toxete

  • PIC10
  • *
  • Mensajes: 44
Re: Urgente!!!! Ayuda con conversor A/D del pic
« Respuesta #2 en: 30 de Mayo de 2006, 09:55:09 »
te hago una pregunta: los pines del mux a0, a1,  a2 y a3 le mandan informacion al pic o el pic le manda al mux?

la pregunta surge porque si es el primer caso ,tenes el tris del puerto a con a0 solamente definido como entrada, por ahi te puede servir ,pero si es el el segund caso no.

espero haber sido de ayuda...

hola fastyx,
con respecto a tu pregunta, las cuatro patillas del pic son salidas porque son las cuatro entradas de seleccion del mux. Al ser un mux de 16 canales tiene 4 entradas de seleccion 2^4=16, lo unico que hacen estas patillas es colocar el codigo correspondiente en binario para activar la entrada correspondiente a dicho codigo.


Sigo sin solucionar el problemilla :( :( :( :( :( :( :( :(

Desconectado fastyx

  • Colaborador
  • PIC18
  • *****
  • Mensajes: 353
Re: Urgente!!!! Ayuda con conversor A/D del pic
« Respuesta #3 en: 30 de Mayo de 2006, 13:29:52 »
aca te mando por ahi te sirve un pdf de conversion ad en pics

habla de un tiempo de adquisicion y de un tiempo de espera para una nueva lectura a-d

espero que te sirva( la respuesta a la pregunta es micro)

Desconectado toxete

  • PIC10
  • *
  • Mensajes: 44
Re: Urgente!!!! Ayuda con conversor A/D del pic
« Respuesta #4 en: 30 de Mayo de 2006, 16:45:54 »
 :-/ :-/ :-/ :-/ :-/ :-/ :-/ :-/ :-/ :-/ :-/ :-/ :-/ :-/ :-/ :-/ :-/ :-/ :-/ :-/ :-/ :-/ :-/ :-/
                                         funcionando
 :-/ :-/ :-/ :-/ :-/ :-/ :-/ :-/ :-/ :-/ :-/ :-/ :-/ :-/ :-/ :-/ :-/ :-/ :-/ :-/ :-/ :-/ :-/ :-/

gracias fastyx por respnder y facilitarme el pdf sobre el ad del pic. el tema parece que ya lo tengo solucionado, utilizando la interrupcion del AD.
Al parecer era un fallo en el programa.

seguire probando y si falla algo y me quedo trabado ya os pedire ayuda como hasta entonces.

muxas gracias y un saludo!

Desconectado fastyx

  • Colaborador
  • PIC18
  • *****
  • Mensajes: 353
Re: Urgente!!!! Ayuda con conversor A/D del pic
« Respuesta #5 en: 30 de Mayo de 2006, 18:05:32 »
bueno me alegro que lo hayas solucionado!!!!

me parece interesante si es que tenes tiempo que hagas un pequeño comentario de que parte del programa era el que te estaba trabando ,y como lo solucionaste, asi podemos tener una base de datos con esos "trucos" o cosas que a veces se nos pasan por alto.

un Abrazo

Desconectado toxete

  • PIC10
  • *
  • Mensajes: 44
Re: Urgente!!!! Ayuda con conversor A/D del pic
« Respuesta #6 en: 31 de Mayo de 2006, 06:15:34 »
bueno me alegro que lo hayas solucionado!!!!

me parece interesante si es que tenes tiempo que hagas un pequeño comentario de que parte del programa era el que te estaba trabando ,y como lo solucionaste, asi podemos tener una base de datos con esos "trucos" o cosas que a veces se nos pasan por alto.

un Abrazo

Hola de nuevo fastyx!! :-) :-) :-) :-)

Pues al parecer era un problema de tiempos al cambiar de canal con el mux y al hacer la conversion, pero al utilizar la interrupcion de AD parece ser que se ha solucionado. Pongo el codigo de la prueba que he realizado por si a alquien le sirve.

Saludos!

#include <18F2525.h>
#device ICD=TRUE
//#define *=16
#device   ADC=8

//------Declaraciones para el compilador-------
#use   delay(clock =19660800)                                 //frecuencia de reloj
#use   i2c(master,sda=PIN_C4, scl=PIN_C3,FORCE_HW)
#use   rs232(baud=19200, xmit=PIN_C6, rcv=PIN_C7)              //configuracion puerto serie
//#fuses   HS,WDT,PUT,NOPROTECT,BROWNOUT
#fuses HS, NOPROTECT, NOPUT,NOBROWNOUT,NOLVP,NOCPD,WRT
//#use standard_io ( a )
#use fast_io(A)



int8 VALUE;
int canal=0;
int ok=FALSE;
int dato;
float valor;
float calibracion;

void calibrar(void){

  int i;
  float total;
  float suma;
  canal=4;
  set_adc_channel(0);
  read_adc(ADC_START_ONLY);
   OUTPUT_A(canal<<1);
//  for(i=0; i<10; i++){   
   if(ok==TRUE){
 
   delay_ms(10);
   read_adc(ADC_START_ONLY);
//   suma+=(float)VALUE;
   delay_ms(1);
   ok=FALSE;
   }
// }
// suma/=10;
 total= (float)VALUE*4.98/255;
 calibracion=4.98-total;
  printf("\r\n%1.2f",calibracion);
   printf(" \r\nvalor calibracion: %1.2f",calibracion);   
   printf(" \r\nvalor : %1.2f",total);   
   printf(" \r\nvalor total: %1.2f",(total+calibracion));

}

float convertir (int channel){
   int canal;

   int cont=0;
   float promedi=0.00;
      canal=channel;   
   while(cont!=5){
      if(ok==TRUE){
          OUTPUT_A(canal<<1);
         delay_ms(1);
         read_adc(ADC_START_ONLY);
         valor=(float)VALUE*4.98/255;
         valor+=calibracion;
        //   printf("\r\n%u:%1.2f",canal,valor);
         promedi+=valor;
         cont++;
         delay_ms(1);
         ok=FALSE;
      }
   }
   cont=0;
   promedi/=5;
   return(promedi);

}

void main (void)
{
   float promedio=0.00;
   int numero_canal=0;

  SET_TRIS_A(0b00000001);
  SET_TRIS_B(0x00);
  setup_adc(ADC_CLOCK_INTERNAL);
  setup_adc_ports(AN0);
  set_adc_channel(0);
  read_adc(ADC_START_ONLY);
  disable_interrupts(global);
  enable_interrupts(INT_RDA);
  enable_interrupts(INT_AD);
  enable_interrupts(global);
  calibracion=0.00;

  calibrar();
  delay_ms(50);

   while(1){

      numero_canal=0;
      promedio=convertir(numero_canal);
      printf("\r\n%u:%1.2f",numero_canal,promedio);
      delay_ms(10);
      
      numero_canal=1;
      promedio=convertir(numero_canal);
      printf("\r\n%u:%1.2f",numero_canal,promedio);
      delay_ms(10);
      
      numero_canal=2;
      promedio=convertir(numero_canal);
      printf("\r\n%u:%1.2f",numero_canal,promedio);
      delay_ms(10);
      
      numero_canal=3;
      promedio=convertir(numero_canal);
      printf("\r\n%u:%1.2f",numero_canal,promedio);
      delay_ms(10);
      
      numero_canal=4;
      promedio=convertir(numero_canal);
      printf("\r\n%u:%1.2f",numero_canal,promedio);
      delay_ms(10);

  }
}

#INT_AD
Conversion_Ad()
{
  VALUE= READ_ADC(ADC_READ_ONLY);
  delay_us(10);
  read_adc(ADC_START_ONLY);
  ok=TRUE;   
}   


#INT_RDA                         //Tratamiento de la interrupcion por recepcion
void rs232_isr(void)
{
 
  dato=getch();

}

 8) 8) 8) 8) 8) 8) 8) 8) 8) 8) 8) 8) 8) 8) 8) 8) 8) 8) 8) 8) 8) 8)

Desconectado toxete

  • PIC10
  • *
  • Mensajes: 44
Re: Urgente!!!! Ayuda con conversor A/D del pic
« Respuesta #7 en: 01 de Junio de 2006, 12:34:50 »
 :x :x :x :x :x :x :x :x :x :x :x :x :x :x :x :x :x :x :x :x :x :x :x :x :x :x :x :x :x :x :x :x :x :x

Hola a todos de nuevo y perdonar que sea tan pesao pero me ha vuelto a fallar y no se por donde tirar.

En la patilla del A/D RA0 tengo la tension correcta pero el pic me da la lectura que le pasa por los ..........

si alguien sabe a que es debido esto, por favor diganmelo que llevo toda la semana con lo mismo y me estoy volviendo tarumba.


Un saludo!!