Autor Tema: Problemas con A/D 16F876  (Leído 2960 veces)

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

Desconectado tocaja

  • PIC10
  • *
  • Mensajes: 10
Problemas con A/D 16F876
« en: 14 de Marzo de 2005, 16:01:00 »
Trato de intentar leer con el micro una tensión analógica, y sacarla por un LCD 2x16. Mirandome bien los ejemplos que he encontrado en el foro he conseguido dominar bien el LCD (creo), pero no me pone el valor en el LCD,el resultado es siempre el mismo 255.99. Dejo aqui el código hecho en CCS  haber si alguien me puede hechar un cable, muchas gracias.
NOTA: ME DA UN ERROR EN LA INSTRUCCIÓN #DEVICE ADC=8, POR ESO ESTA COMO COMENTARIO

#include <16f876.h>
#use delay(clock=4000000)
#fuses xt,nowdt,noput,nobrownout,nolvp,noprotect
//#device adc=8                              
#define use_portB_lcd TRUE
#include "lcd.c"
#use standard_io(B)


//migsantiago
// As defined in the following structure the pin connection is as follows:
//     B0  enable
//     B1  rs
//     B2  rw
//     B4  D4
//     B5  D5
//     B6  D6
//     B7  D7


void main(void)
 {
 float entrada; // entrada es el valor analogico que entra al A/D
 float salida;  // salida es el valor que quiero se vea en el LCD

 set_tris_A (0xFF); // Puerto A configurado como entrada
 set_tris_B(0x00); //Puerto B configurado como salida
 port_B_pullups(FALSE);  // Desactivamos pull-ups del puerto B
 lcd_init(); //Inicia LCD

 lcd_putc("MEDIDOR DE CAMPO
"Giño; //Saca texto
 lcd_putc("    MAGNETICO   "Giño; //Saca texto
 delay_ms(3000);
 lcd_putc("f"Giño; //Limpia pantalla
 lcd_putc("  CAMPO  ACTUAL /n"Giño; //Saca texto
 delay_ms(1000);
 lcd_gotoxy(9,2); //Acomoda cursor LCD
 lcd_putc("OERSTED"Giño;

 while (1)
      {
      lcd_gotoxy(2,2);   //Acomoda cursor LCD
      lcd_putc("       "Giño;   //Limpia ese sector de pantalla
      lcd_gotoxy(2,2);   //Acomoda cursor LCD
      setup_adc (adc_clock_div_32);
      setup_adc_ports (RA0_ANALOG);
      set_adc_channel (0); //Elige canal a medir RA0
      delay_us (20);
      entrada=read_adc(); //Capturamos señal analógica que entra por el canal previamente seleccionado (RA0)
      setup_adc (adc_off); //Apaga ADC
      salida=entrada;  //*ganancia;
      printf(lcd_putc,"%3.2f",salida);   // Mostramos en el lcd el contenido de la variable "salida"
      delay_ms(1000);  
      }
 }



Desconectado tornar

  • PIC18
  • ****
  • Mensajes: 342
RE: Problemas con A/D 16F876
« Respuesta #1 en: 16 de Marzo de 2005, 05:13:00 »
Prueba a meterle un delay_ms(5000) despues de iniciar la lectura del conversor. De manera que kede mas o menos asi:

entrada=read_adc();
delay_ms(5000);
setup_adc (adc_off);

Desconectado pocher

  • Moderador Local
  • DsPIC30
  • *****
  • Mensajes: 2568
RE: Problemas con A/D 16F876
« Respuesta #2 en: 19 de Marzo de 2005, 00:22:00 »
El código está bien, debes tener alguna conexión mal.

Aunque funcione igual, yo pondría los setup en el main, no el el while.

Puedes quitar el setup_adc (adc_off);

Puedes ahorrarte la variable salida y usar solo la de entrada.

Respecto a que te dá error el #DEVICE ADC=8, ponlo detrás de #include <16f876.h> y ya no te dará. Si vas a usar una conversión de 8 bits, no hace falta el #DEVICE ADC=8, lo considera así por omisión. Para 10 bits sí que hace falta.

Un saludo

Desconectado tocaja

  • PIC10
  • *
  • Mensajes: 10
RE: Problemas con A/D 16F876
« Respuesta #3 en: 21 de Marzo de 2005, 05:48:00 »
Gracias amigos, entre todos he conseguido hacerlo funcionar, era más un problema de desconocimiento del funcionamiento de un micro.
Mi problema ahora es el siguiente: tengo por ejemplo una entrada analógica de 0.150V, qe pasa por el A/D, y pongo la instrucción para escalar
salida=entrada*5/256;
pues bien,ante esta entrada igual obtengo en el LCD 0.136v
No se si esta inexactitud es normal, podriais aclararmelo??

Desconectado Nocturno

  • Administrador
  • DsPIC33
  • *******
  • Mensajes: 18286
    • MicroPIC
RE: Problemas con A/D 16F876
« Respuesta #4 en: 21 de Marzo de 2005, 06:28:00 »
No entiendo bien tu pregunta.

Cuando dices que haces esto: salida=entrada*5/256;

¿Te refieres a que la medida que estás tomando se mueve entre 0 y 5V?

En cualquier caso, si metiéndole una señal de 0,15V te lee 0,136V estaría representando un error del 10%, lo cual es inadmisible, ante lo cual te recomendaría revisar si estás haciendo bien el proceso y por supuesto, asegurarte bien que esos 0,15V son realmente 0,15V.

Desconectado tocaja

  • PIC10
  • *
  • Mensajes: 10
RE: Problemas con A/D 16F876
« Respuesta #5 en: 21 de Marzo de 2005, 06:50:00 »
Si eso, perdón por no haberme expresado mejor.El micro tiene un rango de 0 a 5v. Copiaré el codigo que tengo actualmente:

#include <16f876.h>
#use delay(clock=4000000)
#fuses xt,nowdt,noput,nobrownout,nolvp,noprotect
#define use_portB_lcd TRUE     //Para que las señales vallan al LCD por el puerto B
#include "lcd.c"
#use standard_io(B)


void main(void)
 {
 float entrada; // entrada es el valor analogico que entra al A/D
 float salida;  // salida es el valor que quiero se vea en el LCD

 set_tris_A (0xFF); // Puerto A configurado como entrada
 set_tris_B(0x00); //Puerto B configurado como salida
 
 port_B_pullups(FALSE);  // Desactivamos pull-ups del puerto B
 lcd_init(); //Inicia LCD

 lcd_putc("MEDIDOR DE CAMPO
"Giño; //Saca texto
 lcd_putc("    MAGNETICO   "Giño; //Saca texto
 delay_ms(3000);
 lcd_putc("f"Giño; //Limpia pantalla
 lcd_putc("  CAMPO  ACTUAL /n"Giño; //Saca texto
 delay_ms(1000);


 while (1)
      {
      setup_adc (adc_clock_div_32);
      setup_adc_ports (RA0_ANALOG);
      set_adc_channel (0); //Elige canal a medir RA0
      delay_us (20);
      entrada=read_adc(); //Capturamos señal analógica que entra por el canal previamente seleccionado (RA0)
      setup_adc (adc_off); //Apaga ADC

      salida=entrada*5/256; //Escalamiento
      salida=salida*1000;
      if ( salida < 176 )
          {
          lcd_gotoxy(9,2); //Acomoda cursor LCD
          lcd_putc("OERSTED"Giño;
          lcd_gotoxy(2,2);   //Acomoda cursor LCD
          lcd_putc("       "Giño;   //Limpia ese sector de pantalla
          lcd_gotoxy(2,2);   //Acomoda cursor LCD
          printf(lcd_putc,"%3.2f",salida);   // Mostramos en el lcd el contenido de la variable "salida"
          delay_ms(1000);
          }
      else
          {
          lcd_gotoxy(4,2); //Acomoda cursor LCD
          lcd_putc("SATURACION"Giño;
          }
      }
 }

Todo simulado con proteus, xq todavia no tengo el micro en mis manos, aunque espero que hasta dentro de poco.

El problema es que las medidas que muestra en el LCD no son exactas respecto a lo que meto en la entrada, por ejemplo para 50mv me muestra 39,06 en pantalla.

LA conexión de los pines es
//     B0  enable
//     B1  rs
//     B2  rw
//     B4  D4
//     B5  D5
//     B6  D6
//     B7  D7

garcias por la colaboración

Desconectado cucaracha

  • PIC24H
  • ******
  • Mensajes: 1409
    • CUCAWEB
RE: Problemas con A/D 16F876
« Respuesta #6 en: 21 de Marzo de 2005, 07:51:00 »
A ver...

50mv sería 0.05*(256/5)=2.56, osea, tu conversor dará una lectura en decimal de 2 (los decimales tendrás que despreciarlos, logicamente). Por tanto, 2*(5/256)=0.0390625... Te suena??

Lo mismo puedes hacer con el otro ejemplo que pusistes y verás que te da lo que lees en pantalla, según el Proteus.

Qué puedes hacer?? Pues usar de momento los 10bits que tiene el conversor del micro seguramente... Hay pocos modelos con sólo 8bits, que de ser uno de esos...

Ver el rango que vas a tener a la entrada. Si va a ser de pocos milivoltios o ni por asomo llega al rango que tienes, pues no uses un rango de 0 a 5v. Modifica eso... O bien cambiando la tensión de referencia o amplificando la entrada.

Y siempre usa una buena tensión de referencia... que lo que obtienes en Proteus es muy bonito.. pero en la realidad.. ya sabes. Un pequeño ruido o una fuente no lo suficientemente estable te hará variar mucho esa lectura.

Espero te sea de ayuda...

Saludos y suerte!!
Saludos desde Huelva (ESPAÑA)

Desconectado tocaja

  • PIC10
  • *
  • Mensajes: 10
RE: Problemas con A/D 16F876
« Respuesta #7 en: 21 de Marzo de 2005, 08:34:00 »
Vale,entiendo lo que me dices, pero lo que no me aclaro es con la solución, xq no entiendo muxo de micros. Por un lado no se que diferencia hay entre usar 8 o 10 bits. Por otro como se modifica el rango de 0 a 5v?? Por otro, no habia considerado ninguna tensión de referencia....... Como ves estoy algo verde aun,jeje. Tb puede ser que las fallas siempre pasan factura.help please

Desconectado Nocturno

  • Administrador
  • DsPIC33
  • *******
  • Mensajes: 18286
    • MicroPIC
RE: Problemas con A/D 16F876
« Respuesta #8 en: 21 de Marzo de 2005, 10:08:00 »
Teóricamente el conversor AD del 16F876 ya trabaja con 10 bits por defecto, por lo que la lectura del mismo la tienes que hacer sobre una variable int16 y los resultados de dicha lectura estarán comprendidos entre 0 y 1023.

No obstante, si quieres asegurarte, puedes añadir esto al principio de tu programa:
#device PIC16F876 ADC=10

Desconectado pocher

  • Moderador Local
  • DsPIC30
  • *****
  • Mensajes: 2568
RE: Problemas con A/D 16F876
« Respuesta #9 en: 22 de Marzo de 2005, 00:29:00 »
El CCS por omisión del #device adc=8 o #device adc=10, trabaja con 8bits.

Para mejorar tu lectura para valores de entrada de mV,  haz lo que te dice Cuca: usa una conversión de 10 bits, para lo cual tendrás que cambiar el #device adc=8 por #device adc=10 y salida=entrada*5/256 por salida=entrada*5/1024

Si quieres mejorar todavía más la lectura usa una tensión de referencia más pequeña, por ejemplo 2,5V.

Un saludo

Desconectado tocaja

  • PIC10
  • *
  • Mensajes: 10
RE: Problemas con A/D 16F876
« Respuesta #10 en: 22 de Marzo de 2005, 12:16:00 »
Vale, muchas gracias, ya lo tengo claro. Ahora lo que intento es en vez de tener 1 entrada analógica, voy a meterle 3, va a ser muy complicado para que salgan las medidas por el LCD???

Desconectado pocher

  • Moderador Local
  • DsPIC30
  • *****
  • Mensajes: 2568
RE: Problemas con A/D 16F876
« Respuesta #11 en: 22 de Marzo de 2005, 23:06:00 »
No, es igual, lo único que tienes que hacer es seleccionar el canal analógico con set_adc_channel (x), hacer las operaciones necesarias con él y mostrar el resultado en pantalla. Cuando acabes con el primer canal eliges con set_adc_channel (x) el siguiente y lo mismo.

Un saludo