Autor Tema: Problema con Convertidor AD en MikroC  (Leído 4202 veces)

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

Desconectado aitorsp

  • PIC18
  • ****
  • Mensajes: 296
Problema con Convertidor AD en MikroC
« en: 26 de Junio de 2011, 14:20:09 »
Hola:

Adjunto el codigo en mikroC que no consigo que lea bien el canal AN2 (RA2). Debe leer el valor de una resistencia de 1ohm que me da la corriente de manera indirecta. El PIC es el 16F88 funcionando con reloj interno 8Mhz y voltaje de referencia interno para el AD.

// LCD module connections
sbit LCD_RS at RB7_bit;
sbit LCD_EN at RB6_bit;

sbit LCD_D4 at RA0_bit;
sbit LCD_D5 at RA1_bit;
sbit LCD_D6 at RA7_bit;
sbit LCD_D7 at RA6_bit;

sbit LCD_RS_Direction at TRISB7_bit;
sbit LCD_EN_Direction at TRISB6_bit;

sbit LCD_D4_Direction at TRISA0_bit;
sbit LCD_D5_Direction at TRISA1_bit;
sbit LCD_D6_Direction at TRISA7_bit;
sbit LCD_D7_Direction at TRISA6_bit;
// End LCD module connections
long voltage;
char *text;
char *text2;
unsigned int adc_rd;
unsigned char ch;
void main(){
OSCCON=0x70;
while(OSCCON.IOFS==0);
ANSEL=0x04; //AN2 Analog
//ADCON1
ADFM_bit=1;
ADCS2_bit=0;
VCFG1_bit=0;
VCFG0_bit=0;
//ADCON0
GO_DONE_bit=1;
ADON_bit=1;
CHS0_bit=0;
CHS1_bit=1;
CHS2_bit=0;
ADCS0_bit=1;
ADCS1_bit=1;
TRISA2_bit=1; // AN2 entrada
Lcd_Init();                                     // Initialize LCD
Lcd_Cmd(_LCD_CLEAR);    // Clear LCD display
text="I= ";
text2=" mA";
Lcd_Out(1,1,text);
while(1){
adc_rd= ADC_Read(2);   // Get 10-bit results of AD conversion
voltage=(long)adc_rd*5000; // valor en milivoltios
//voltage=voltage/1021;
LCD_Chr(2,1,voltage);
//ch=voltage/1000;
//LCD_Chr(2,9,48+ch);
//LCD_Chr_CP('.');
//ch=(voltage/1)%10;
//LCD_Chr_CP(48+ch);
LCD_Out(2,6,text2);
Delay_ms(10);
}
}

Un saludo

Aitor

Desconectado MLO__

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 4581
Re: Problema con Convertidor AD en MikroC
« Respuesta #1 en: 26 de Junio de 2011, 15:01:45 »
Hola.

No sera un problema de acople de impedancias? Tienes conectado directamente el pin del pic a la resistencia? Seria probar con un AO como seguidor de tension.

Saludos
El papel lo aguanta todo

Desconectado aitorsp

  • PIC18
  • ****
  • Mensajes: 296
Re: Problema con Convertidor AD en MikroC
« Respuesta #2 en: 26 de Junio de 2011, 15:18:07 »
Hola.

No sera un problema de acople de impedancias? Tienes conectado directamente el pin del pic a la resistencia? Seria probar con un AO como seguidor de tension.

Saludos

Hola:

El codigo es correcto?.

Lo del acople de impedancias ya lo pensé pero teniendo una resistencia de 1ohm y suponiendo que la impedancia de entrada en la AN2 ya es bastante alta no haria falta acoplar... ó estoy equivocado?

Un saludo

Aitor

Desconectado tannke

  • PIC16
  • ***
  • Mensajes: 176
Re: Problema con Convertidor AD en MikroC
« Respuesta #3 en: 26 de Junio de 2011, 15:55:25 »
Muy buenas, revisando asi rapido veo un posible problema en la instrucción " LCD_Chr(2,1,voltage); " ya que esta es para escribir en el lcd en la posicion i fila indicados un caracter y tu le estas enviando ahi un long por lo que entiendo que te está solo enviando al lcd los 8bits mas bajos del long.

Microc pro tiene una libreria "Conversions" que en ellla está la función LongToStr, que te puede servir. Personalmente a mi no me gusta esta librería, siempre he preferido hacer yo mismo las conversiones.

Un saludo.

Desconectado tannke

  • PIC16
  • ***
  • Mensajes: 176
Re: Problema con Convertidor AD en MikroC
« Respuesta #4 en: 26 de Junio de 2011, 16:19:58 »
Por otro lado una recomendación sobre el "LCD_Out(2,6,text2);" en aplicaciones donde escribes poco en el LCD no es problema, pero si te das cuenta todos los textos se almacenan en RAM y esta es escasa! Te recomiendo usar esta función en lugar de LCD_Out :
Código: [Seleccionar]
void LCD_Out2(char fila, char col, const char *dat)
{
     while(*dat)
     {
         Lcd_Chr(fila,col++, *dat++);
     }
}

Su utilización es la misma, solo que declaramos las variables como constantes:

Código: [Seleccionar]
const char *texto= "Prueba";

void main()
{
       LCD_Out2(1,1, texto);
       
      // o tambien:

      LCD_Out2(2,1, "Prueba 2");
}

Saludos

Desconectado aitorsp

  • PIC18
  • ****
  • Mensajes: 296
Re: Problema con Convertidor AD en MikroC
« Respuesta #5 en: 26 de Junio de 2011, 17:15:43 »
Por otro lado una recomendación sobre el "LCD_Out(2,6,text2);" en aplicaciones donde escribes poco en el LCD no es problema, pero si te das cuenta todos los textos se almacenan en RAM y esta es escasa! Te recomiendo usar esta función en lugar de LCD_Out :
Código: [Seleccionar]
void LCD_Out2(char fila, char col, const char *dat)
{
     while(*dat)
     {
         Lcd_Chr(fila,col++, *dat++);
     }
}

Su utilización es la misma, solo que declaramos las variables como constantes:

Código: [Seleccionar]
const char *texto= "Prueba";

void main()
{
       LCD_Out2(1,1, texto);
       
      // o tambien:

      LCD_Out2(2,1, "Prueba 2");
}

Saludos


Hola:

Muchas gracias

Un saludo

Aitor

Desconectado tannke

  • PIC16
  • ***
  • Mensajes: 176
Re: Problema con Convertidor AD en MikroC
« Respuesta #6 en: 26 de Junio de 2011, 17:26:19 »
Buenas de nuevo, revisandolo un poco mas creo ver algunos fallos mas. Por un lado no entiendo que multiplicando por 5000 se saque el valor en milivoltios :P. Bueno, al tema, yo te pongo aqui y tu comparas y pruebas:

te cambio de momento el long por float:


Código: [Seleccionar]
// LCD module connections
sbit LCD_RS at RB7_bit;
sbit LCD_EN at RB6_bit;

sbit LCD_D4 at RA0_bit;
sbit LCD_D5 at RA1_bit;
sbit LCD_D6 at RA7_bit;
sbit LCD_D7 at RA6_bit;

sbit LCD_RS_Direction at TRISB7_bit;
sbit LCD_EN_Direction at TRISB6_bit;

sbit LCD_D4_Direction at TRISA0_bit;
sbit LCD_D5_Direction at TRISA1_bit;
sbit LCD_D6_Direction at TRISA7_bit;
sbit LCD_D7_Direction at TRISA6_bit;
// End LCD module connections

float voltage;                <---Cambiada a float
char *text;
char *text2;
unsigned int adc_rd;
unsigned char ch;
char txt[15];                 <---Nueva

void main()
{
  OSCCON=0x70;
  while(OSCCON.IOFS==0);
  ANSEL=0x04; //AN2 Analog

//ADCON1
  ADFM_bit=1;
  ADCS2_bit=0;
  VCFG1_bit=0;
  VCFG0_bit=0;

//ADCON0
  GO_DONE_bit=1;
  ADON_bit=1;
  CHS0_bit=0;
  CHS1_bit=1;
  CHS2_bit=0;
  ADCS0_bit=1;
  ADCS1_bit=1;
  TRISA2_bit=1; // AN2 entrada

  Lcd_Init();                                     // Initialize LCD
  Lcd_Cmd(_LCD_CLEAR);    // Clear LCD display

  text="I= ";
  text2=" mA";
  Lcd_Out(1,1,text);

while(1)
{
  adc_rd= ADC_Read(2);                      // Get 10-bit results of AD conversion
  voltage=(float)adc_rd*0.00488;          // valor en voltios*
 
  FloatToStr(voltage, txt);

  LCD_Chr(2,1,txt);

  //ch=voltage/1000;
  //LCD_Chr(2,9,48+ch);
  //LCD_Chr_CP('.');
  //ch=(voltage/1)%10;
  //LCD_Chr_CP(48+ch);

  //LCD_Out(2,6,text2);
  Delay_ms(10);
}
}

* De donde sale ese (0.00488) en caso de no utilizár Vref distintos, tenemos que la tensióm maxima muestreable son 5v, por otro lado tenemos que el resultado de la conversión se almacena en 10bits(en decimal 1023) y 5 / 1023 = 0.00488

Espero te sirva. Un saludo

Desconectado aitorsp

  • PIC18
  • ****
  • Mensajes: 296
Re: Problema con Convertidor AD en MikroC
« Respuesta #7 en: 26 de Junio de 2011, 17:29:48 »
Buenas de nuevo, revisandolo un poco mas creo ver algunos fallos mas. Por un lado no entiendo que multiplicando por 5000 se saque el valor en milivoltios :P. Bueno, al tema, yo te pongo aqui y tu comparas y pruebas:

te cambio de momento el long por float:


Código: [Seleccionar]
// LCD module connections
sbit LCD_RS at RB7_bit;
sbit LCD_EN at RB6_bit;

sbit LCD_D4 at RA0_bit;
sbit LCD_D5 at RA1_bit;
sbit LCD_D6 at RA7_bit;
sbit LCD_D7 at RA6_bit;

sbit LCD_RS_Direction at TRISB7_bit;
sbit LCD_EN_Direction at TRISB6_bit;

sbit LCD_D4_Direction at TRISA0_bit;
sbit LCD_D5_Direction at TRISA1_bit;
sbit LCD_D6_Direction at TRISA7_bit;
sbit LCD_D7_Direction at TRISA6_bit;
// End LCD module connections

float voltage;                <---Cambiada a float
char *text;
char *text2;
unsigned int adc_rd;
unsigned char ch;
char txt[15];                 <---Nueva

void main()
{
  OSCCON=0x70;
  while(OSCCON.IOFS==0);
  ANSEL=0x04; //AN2 Analog

//ADCON1
  ADFM_bit=1;
  ADCS2_bit=0;
  VCFG1_bit=0;
  VCFG0_bit=0;

//ADCON0
  GO_DONE_bit=1;
  ADON_bit=1;
  CHS0_bit=0;
  CHS1_bit=1;
  CHS2_bit=0;
  ADCS0_bit=1;
  ADCS1_bit=1;
  TRISA2_bit=1; // AN2 entrada

  Lcd_Init();                                     // Initialize LCD
  Lcd_Cmd(_LCD_CLEAR);    // Clear LCD display

  text="I= ";
  text2=" mA";
  Lcd_Out(1,1,text);

while(1)
{
  adc_rd= ADC_Read(2);                      // Get 10-bit results of AD conversion
  voltage=(float)adc_rd*0.00488;          // valor en voltios*
 
  FloatToStr(voltage, txt);

  LCD_Chr(2,1,txt);

  //ch=voltage/1000;
  //LCD_Chr(2,9,48+ch);
  //LCD_Chr_CP('.');
  //ch=(voltage/1)%10;
  //LCD_Chr_CP(48+ch);

  //LCD_Out(2,6,text2);
  Delay_ms(10);
}
}

* De donde sale ese (0.00488) en caso de no utilizár Vref distintos, tenemos que la tensióm maxima muestreable son 5v, por otro lado tenemos que el resultado de la conversión se almacena en 10bits(en decimal 1023) y 5 / 1023 = 0.00488

Espero te sirva. Un saludo

Hola:

gracias, aplicare los cambios que me has aconsejado.

un saludo

Aitor

Desconectado aitorsp

  • PIC18
  • ****
  • Mensajes: 296
Re: Problema con Convertidor AD en MikroC
« Respuesta #8 en: 26 de Junio de 2011, 18:15:39 »
Hola:

Empieza a ir un poco mejor.

Este es el codigo:


// LCD module connections
sbit LCD_RS at RB7_bit;
sbit LCD_EN at RB6_bit;

sbit LCD_D4 at RA0_bit;
sbit LCD_D5 at RA1_bit;
sbit LCD_D6 at RA7_bit;
sbit LCD_D7 at RA6_bit;

sbit LCD_RS_Direction at TRISB7_bit;
sbit LCD_EN_Direction at TRISB6_bit;

sbit LCD_D4_Direction at TRISA0_bit;
sbit LCD_D5_Direction at TRISA1_bit;
sbit LCD_D6_Direction at TRISA7_bit;
sbit LCD_D7_Direction at TRISA6_bit;
// End LCD module connections
float voltage;
char *text;
char txt[15];
unsigned int adc_rd;
unsigned char ch;
void main(){
OSCCON=0x70;
while(OSCCON.IOFS==0);
ANSEL=0x04; //AN2 Analog
//ADCON1
ADFM_bit=1;
ADCS2_bit=0;
VCFG1_bit=0;
VCFG0_bit=0;
//ADCON0
GO_DONE_bit=1;
ADON_bit=1;
CHS0_bit=0;
CHS1_bit=1;
CHS2_bit=0;
ADCS0_bit=1;
ADCS1_bit=1;
TRISA2_bit=1; // AN2 entrada
Lcd_Init();                                     // Initialize LCD
Lcd_Cmd(_LCD_CLEAR);    // Clear LCD display
text="I=";
Lcd_Out(1,1,text);
while(1){
adc_rd= ADC_Read(2);   // Get 10-bit results of AD conversion
voltage=(float)adc_rd*0.0045; // valor en voltios
FloatToStr(voltage,txt);
LCD_Out(2,1,txt);
Delay_ms(10);
}
}

sólo un par de cosas:

1.- La tensión de alimentacion la tengo en 4.6 V por lo que habria que corregir el valor de 4.6/1023 =0.045

2.- Cuando la tension es menor de 1V aparece el simbolo e-1 pero nada mas subir la tension por encima de 1 V el e-1 no desaparece. Como puedo hacer para corregir este error?

Un saludo

Aitor

Desconectado tannke

  • PIC16
  • ***
  • Mensajes: 176
Re: Problema con Convertidor AD en MikroC
« Respuesta #9 en: 27 de Junio de 2011, 10:41:12 »
Muy buenas, a la primera pregunta yo diría que sí, pero cuidado que te falta un 0 són 0.0045. Y para el tema del e-1 (esta es una de las cosas por lo que no me gusta la libreria de conversions) hay dos maneras para solucionarlo. Una sería borrando de nuevo el LCD cada vez que vayas a escribir en el, y la otra sería si ese "e-1" siempre aparece en la misma posición del LCD sobreescribirlo con dos espacios, y si este aparece en distintas posiciones (que creo es el caso) sobreescribir con espacios toda la linea asignada para la lectura, esto con la instrucción "LCD_Out" o con la que te comenté anteriormente.

Bueno, otra opción podría ser evitar que te salga ese e-1 multiplicando por 1000 antes del "FloatToStr" cuando esta sea menor a 1v y dar el resultado en mV en lugar de V.

Por otra parte si las tensiones a medir oscilan siempre por debajo de 1v, 2v o lo que sea podría ser recomendable y si no necsitas RA3 cambiar la tensión de vref+ para así obtener mas precisión en esas medidas.

EDIT: Sobre lo de borrar la linea o sobreescribirla con espacios yo lo haria siempre ya que si la primera lectura es 1.23456 y la segunda es 2.5 y no has borrado la anterior te saldrá 2.53456

Un saludo
« Última modificación: 27 de Junio de 2011, 10:47:26 por tannke »

Desconectado aitorsp

  • PIC18
  • ****
  • Mensajes: 296
Re: Problema con Convertidor AD en MikroC
« Respuesta #10 en: 27 de Junio de 2011, 11:54:13 »
Muy buenas, a la primera pregunta yo diría que sí, pero cuidado que te falta un 0 són 0.0045. Y para el tema del e-1 (esta es una de las cosas por lo que no me gusta la libreria de conversions) hay dos maneras para solucionarlo. Una sería borrando de nuevo el LCD cada vez que vayas a escribir en el, y la otra sería si ese "e-1" siempre aparece en la misma posición del LCD sobreescribirlo con dos espacios, y si este aparece en distintas posiciones (que creo es el caso) sobreescribir con espacios toda la linea asignada para la lectura, esto con la instrucción "LCD_Out" o con la que te comenté anteriormente.

Bueno, otra opción podría ser evitar que te salga ese e-1 multiplicando por 1000 antes del "FloatToStr" cuando esta sea menor a 1v y dar el resultado en mV en lugar de V.

Por otra parte si las tensiones a medir oscilan siempre por debajo de 1v, 2v o lo que sea podría ser recomendable y si no necsitas RA3 cambiar la tensión de vref+ para así obtener mas precisión en esas medidas.

EDIT: Sobre lo de borrar la linea o sobreescribirla con espacios yo lo haria siempre ya que si la primera lectura es 1.23456 y la segunda es 2.5 y no has borrado la anterior te saldrá 2.53456

Un saludo

Hola:

Otra forma de evitar el e-1 seria indicarlo de este modo:

0.234 V

Para este caso existe alguna conversion en mikroC ?

Un saludo

Aitor

Desconectado tannke

  • PIC16
  • ***
  • Mensajes: 176
Re: Problema con Convertidor AD en MikroC
« Respuesta #11 en: 27 de Junio de 2011, 12:38:21 »
Pues mirando el help de mikroC me parece que no ... y en los foros de mikroc encontré una pregunta parecida y le contestaron que tratara el "string" resultante despues de la conversion... otra opción es crearte tu la librería pero creo que es algo complicado los "floats" yo almenos no entiendo como van... solo se que estan formados por 4bytes y que hay varios formatos distintos (IEEE, microchip...)

Saludos y suerte.