estoy conectando una sonsa de nivel de agua a un arduino Mega 2560.
La sonda da una salida de 0 a 5v.
El problema que tengo que es aunque la sonda da una salida estable, arduino me muestra valores inestables.
Es decir, si yo mido con un voltímetro la salida de la sonda, me da por ejemplo: 0.117 voltios, pero arduino me da : 0 , 0.1, 0.3, 0, 0.2, etc...... es decir me va dando valores inestables.
La salida de la sonda está conectada directamente a A0 de arduino.
¿Alguien me podría dar una idea de cual puede ser el problema?.
Bienvenido al mundo real, eso quiere decir que siempre te encontrarás con situaciones de este tipo.
La forma mas rápida de acomodar las cosas es leer muchas lecturas sucesivas y luego promediarlas.
Eso trae como consecuencia una demora en la presentación de los datos pero supon que los muestras cada 1 segundos, entonces tienes 1 segundo para leer la mayor cantidad de datos del sensor y promediarlos y luego presentarlos.
Usa una variable unsigned int y acumula todos los datos leidos y lleva un contador de muestras.
Al final divides el resultado del acumulado por el contador y tienes el promedio y lo escalas, o sea lo multiplas por 5 y divides por 1023 para tener el valor en voltios.
Tendras una lectura mucho mas estable.
podria ser mas o menos asi
// rutina promediacion
unsigned long sumaADC = 0;
unsigned long start;
unsigned int contador;
void setup() {
Serial.begin(9600);
start = millis();
contador = 0;
}
void loop() {
sumaADC += analogRead(A0); // modifica A0 para que coincida con el pin Analogico que estes usando
contador++;
if (millis()-start > 1000UL){ // 1000 milisegundos = 1seg
float promedio = (float) (sumaADC/contador)* 5.0/1023.0;
Serial.print("AD = ");
Serial.println(promedio);
sumaADC = 0;
contador = 0;
start = millis(); // preparo para proxima presentación
}
}
Detalle.. si tienes delay() en tu loop la rutina que te presenté funcionará pero estará supeditada a las demoras que introduzcas en tu código.
delay y millis() no se llevan bien. No porque no puedan funcionar juntos sino que no tiene sentido usar millis() cuando usas delay.
Espero me entiendas.
Tenia un bucle de 10 segundos para promediar las lecturas, que en este caso mapeo a tantos porciento.
Pero al ver lo poco estable que es la entrada analógica, no sabia si esto se podía resolver de alguna forma que no fuese vía programación, es decir, colocando alguna resistencia por medio que estabilice la entrada o algo así.
Por programación, efectivamente yo había pensado lo que he has dicho y claro está cuantas mas muestras pueda analizar entiendo que mas estable será el valor, pero como te digo me llama la atención que teniendo un valor de sensor tan estable arduino oscile tanto.
¿esto es un problema de arduino? o cualquier dispositivo de este tipo tiene estos problemas.
El arduino mega 2560 lo alimento con una fuente de alimentación de 12v que es la misma fuente que alimenta el sensor, que también es de 12v, por tanto los dos, arduino mega y sensor, están conectados a la misma fuente de alimentación, pero aunque lo dos negativos están unidos en la misma fuente, no lo conecto a un pin GND de arduino.
No se si me he explicado bien.
Ademas la fuente de alimentación tiene dos salidas, una a 12v y otra a 5v, la de 5v la uso para conectar una pantalla LCD, un RTC y dos relees.
Es decir que, siempre evito que arduino no alimente nada, sino que todo se alimente desde la fuente de alimentación.
Yo tengo un medidor de tanque del mismo modo que te plantee y no tengo mas que lecturas estables.
Y para que le pones delay(1000);?
deja que tome mas lecturas si no te afecta en nada que asi lo haga.
No solo 11 con un delay de 1 seg entre cada una.
Yo te hablé de todas las que quepan en 1 segundo y tu tardas 11 segundos en promediar.
Con mi rutina te saco 11 promedios de +100 lecturas o mas luego te digo cuantas, o te lo digo ahora aproximadamente.
He hecho capturas con el ADC a 1mseg o sea que tranquilamente puedo tomar 1000 lecturas.
total 11*1000= 11000 mediciones.
Dime quien crees que tendrá una lectura mas estable, tu rutina o la que yo te sugiero?
que es exagerado, si claro, pero repito, no tiene mas nada que hacer.
creo que entiendo lo que dices, he cambiado el código para que lea todas las muestras que le sea posible en un segundo y luego las promedie.
lo he modificado de la siguiente forma:
// Leemos el sensor de presion.
// Para ello leemos el numero maximo de muestras en un segundo y las promediamos.
bucle = 0;
sensorValue = 0;
sensorValueTMP = 0;
start = millis();
while (millis()-start < 1000UL) // durante un segundo va a leer todo lo que pueda
{
sensorValueTMP += analogRead( TANK_SENSOR );
bucle ++;
}
sensorValue = sensorValueTMP / bucle;
constrainedValue = constrain( sensorValue, TANK_EMPTY, TANK_FULL );
tankLevel = map( constrainedValue, TANK_EMPTY, TANK_FULL, 0, 100 );
voltajeLectura = (sensorValue * (5.0/1023.0));
Esta tarde lo pruebo.
Muchas gracias por tu ayuda.
Por curiosidad: ¿porque arduino no mantiene estable la lectura que recibe por su entrada analógica?.
Bien, es una forma con la que no estoy a gusto pero va a funcionar.
No estoy a gusto porque por 1 segundo se queda tomando muestras del AD y no atiende el resto del mundo.
Si tuvieras cosas que controlar eso es como poner delay(1000) de hecho es lo mismo solo que ahora si haces el promedio en 1 segundo.
Bueno, tal vez tu sistema no deba hacer mas que eso, o no afecte el que se quede 1 seg por loop haciendo la tarea.
Asi que adelante!!
colocale un condensador de 100 nanofaradios entre la entrada analógica y GND.
mas o menos es lo mismo que estas haciendo por soft pero por hard.
y no estaría de mas otro condensador electrolítico en la alimentación del sensor.
10uFx16V son suficientes. Es un sensor. Consume no mas de 5mA como mucho. No hay mucho que estabilizar pero es bueno que este el capacitor.
Hablo de colocar este capacitor entre los pines de alimentación del sensor.