TODOPIC
Microcontroladores PIC => Lenguaje C para microcontroladores PIC => Mensaje iniciado por: loverman24 en 15 de Septiembre de 2005, 11:01:00
-
Hola, tengo un problema tonto, pero no se como arreglarlo. Os explico por encima: quiero hacer la media de 10 valores de tension q me entran por un adc del pic. El programa:
#include <16f877.h>
#device adc=10
#fuses XT, NOPROTECT, NOPUT, NOWDT, NOBROWNOUT, NOLVP, NOCPD
#use delay (clock= 4000000)
#use rs232(BAUD=9600, BITS=8, PARITY=N, XMIT=PIN_C6, RCV=PIN_C7)
void main() {
float const resoluc= 5.0/1024.000; //Resolución del convertidor
float corriente= (2*5.0)/11000.000;
float tension; //Valor tension sacada
long int valor; //Numero de pasos de la medida
float v_ohmico, v_ohmicom, v_ohmicot; //Valor ohmico del potenciometro
int i; //Indice que vamos a utilizar
setup_adc_ports (ALL_ANALOG); //Todas las entradas del covertidor son analogicas
setup_adc (ADC_CLOCK_INTERNAL); //Selecciono reloj interno del pic
v_ohmicom= 0; //Inicializo variables (valor ohmico medio)
v_ohmicot= 0; //Inicializo variables (valor ohmico total)
for (;
{ //Bucle infinito
for (i= 1; i<12; i++) { //Bucle que va obteniendo 10 valores de tension
set_adc_channel (0); //Elige el canal 0
delay_us(20); //Retardo para que de tiempo de cargarse el condensador del adc
valor= read_adc(); //Obtiene el valor del adc
tension= valor*resoluc; //Calcula la tension
v_ohmico= (2*tension)/corriente; //Calculo valor ohmico de los potenciometros
v_ohmicot= (v_ohmicot+v_ohmico); //Va sumando los valores ohmicos de los 10 datos
}
v_ohmicom= v_ohmicot/10; //Media del valor ohmico
printf ("%1.4f ", v_ohmicom); //Saca a hyperterminal valor ohmico
delay_ms(20); //Retraso de 20ms y vuelta a empezar
}
}
La cosa esta en q no funciona, me saca unos numeros pero no se de donde (supongo q seran sumas raras etc). El fin de este programa es reducir la fluctuacion del valor q me envia al pc por puerto serie. Haber si alguien tiene paciencia y me da una pista.
Un saludo
Gracias
-
Te paso una rutina que hace el promedio de tantas mediciones como quieras entre 1 y 100.
Yo lo uso con un conversor de 12 bits...
int16 Leer_AD_Filtrado (int Canal,int Filtro)
{
int i;
unsigned int32 Data=0;
int16 Valor_Filtrado=0; //variables locales
if(Filtro > 100) Filtro = 100;
if(Filtro < 1) Filtro = 1;
for (i=0;i<Filtro;++i)
Data += read_analog( Canal );
Valor_Filtrado = Data / Filtro;
return Valor_Filtrado;
}
espero te sirva !!


-
¿los numeros que te sacan que tipo tienen?, es decir son solamente numeros o son tb caracteres raros?
-
Has probado a poner el fichero "float.h" como include?
prueba haber, puede ser que no te este utilizando las funciones con coma flotante. Un saludo.
-
me acabo de dar cuenta, pero esto
v_ohmicom= 0; //Inicializo variables (valor ohmico medio)
v_ohmicot= 0; //Inicializo variables (valor ohmico total)
tiene que estar dentro del bucle infinito y antes de la toma de datos... 
saludos
-
otra cosa lo acabo de compilar y hacer una prueba, creo que el problema te puede venir por esta espresion:
v_ohmico= (2*tension)/corriente; //Calculo valor ohmico de los potenciometros
v_ohmicot= (v_ohmicot+v_ohmico); //Va sumando los valores ohmicos de los 10 datos
prueba a enviar la tension que lees al pc y luego revisa la expresion. Un saludo.
-
Hola compa�er@s de nuevo!!!
Antes de todo decir que no lo puedo compilar porque no tengo el CCS
, pero bueno teoricamente puede ser que el siguiente codigo te funcione.
Nota: Coloco en negrita los cambios realizados, que creo que son convenientes para solucionar el problema.
/***************************************************************/
#include <16f877.h>
#device adc=10
#fuses XT, NOPROTECT, NOPUT, NOWDT, NOBROWNOUT, NOLVP, NOCPD
#use delay (clock= 4000000)
#use rs232(BAUD=9600, BITS=8, PARITY=N, XMIT=PIN_C6, RCV=PIN_C7)
void main() {
float const resoluc= 5.0/1024.000; //Resoluci�n del convertidor
float corriente= (2*5.0)/11000.000;
float tension; //Valor tension sacada
float valor; //Numero de pasos de la medida
float v_ohmico, v_ohmicom, v_ohmicot; //Valor ohmico del potenciometro
int i; //Indice que vamos a utilizar
setup_adc_ports (ALL_ANALOG); //Todas las entradas del covertidor son analogicas
setup_adc (ADC_CLOCK_INTERNAL); //Selecciono reloj interno del pic
for ( ; ; ) { //Bucle infinito
v_ohmicom = 0; //Inicializo variables (valor ohmico medio)
v_ohmicot = 0; //Inicializo variables (valor ohmico total)
for (i= 1; i<11; i++) { //Bucle que va obteniendo 10 valores de tension
set_adc_channel (0); //Elige el canal 0
delay_us(20); //Retardo para que de tiempo de cargarse el condensador del adc
valor= read_adc(); //Obtiene el valor del adc
tension= valor*resoluc; //Calcula la tension
v_ohmico= (2*tension)/corriente; //Calculo valor ohmico de los potenciometros
v_ohmicot= (v_ohmicot+v_ohmico); //Va sumando los valores ohmicos de los 10 datos
}
v_ohmicom= v_ohmicot/10; //Media del valor ohmico
printf ("%1.4f ", v_ohmicom); //Saca a hyperterminal valor ohmico
delay_ms(20); //Retraso de 20ms y vuelta a empezar
}
}
/***************************************************************/
Los problemas que he encontrado a simple vista son:
1º.- Los valores de v_ohmicom y v_ohmicot, los tendras que inicializar a 0
2º.- Al poner el for for (i= 1; i<12; i++) se repite 11 veces
3º.- Y más importante, es el de tension= valor*resoluc; , puesto que: float = long int * float const; , por eso he declarado la variable valor como float.
Si quieres que valor sea long int, podrias colocarlo comotension= (float) (valor) * resoluc;, y declarar valor como long int
Si decides declararlo como float, pero solo quieres la parte entera puedes redondearlo hacia arriba o hacia abajo utilizando math.h, las instrucciones ceil o floor, segun el gusto 
Bueno un saludo para tod@s!!! Espero que te sirva, sino pues a ver que puedo hacer sin ese compilador para ayudar.
-
Ok, muchisimas gracias por vuestra ayuda. Lo mirare mañana mas detenidamente q hoy ya es muy tarde.
un saludo
P.D:Se me olvidaba,los datos que me da son solo numeros, pero valores desorbitados
-
Bueno pues ya lo he probado y funciona (meti la inicializacion de variables dentro del for infinito), aun me fluctua, pero no tanto como antes, supongo q aumentando el numero de valores para hacer la media bastara.
Muchas gracias a todos por vuestra ayuda.
Un saludo