Me ha llegado un sensor de presión mide hasta 12 bares y la señal es entre 0,5V y 4,5V, lo he conectado a un puerto analógico y la lectura que me muestra es 342 en el monitor serie, entre la masa y la señal hay 0,49V. La cuestión es que no sé muy bien como mostrar el valor real de presión, ya que entiendo que en el monitor debería mostrarme esos 0,5V o 500mv sin nada conectado y como he dicho obtengo 342. Se supone que es lineal, he probado con la función map, pero al estar el 0 bares en 0,5v no termino de aclararme. Seguro que es sencillo, pero soy novato.
Espero podáis iluminarme. Os dejo los datos de donde lo compré.
victorjam:
¿Desde donde alimentas el sensor?¿Has unido los GND de sensor y Arduino?
Gracias por contestar Victorjam.
Lo tengo todo conectado a arduino, la placa es MEGA . También he probado con una fuente, pero no sabía si conectar a la masa de la fuente o de la placa. Como el polímetro no me daba los 0,5v lo he dejado todo conectado a arduino, gnd,alimentación y señal.
Comprueba con el tester y continuidad quien es quien el conector, aunque la lógica dicte : Rojo-5v, Negro-GND, Verde-0v, quizás no sea asi.
¿Cúal es el código? Por los valores que te arroja y que el polimetro marque 0.49, me parece que esta utilizando la referencia de tensión interna. Comprueba que el pin AREF este al aire o conectado a tierra con un condensador de 100nF.
Y siempre se ha dicho que una imagen vale mas que mil palabras, una foto del conexionado ayudaria a entender bastante.
Muchas gracias.
Todos los pines están bien, los he comprobado. He podido hacer pruebas con un compresor que tengo en el garaje y me sale lineal. El valor que me da, no sé si son mV o que. El pin AREF lo tengo al aire, supongo que tengo que adaptar los datos en bruto para que me marque de 0 a 12 B. Estoy un poco perdido ya que la referencia no empieza en 0, para hacer la ecuación. adjunto una gráfica con las mediciones que he podido hacer de presión que me marcaba el compresor (con manómetro digital) y el valor que me devuelve arduino.
Gracias.
Creo que estoy cerca. Voy a subir el código para si podéis revisarlo y así corregir los errores. He ido comprobando con el monitor serie el valor bruto del sensor y he aplicado la fórmula para imprimirlo en la pantalla LCD en bares con un decimal.
Muchaas gracias.
#include <LiquidCrystal.h>
LiquidCrystal lcd(7,6,5,4,3,2);
float SENSOR1;
float PRESION;
void setup() {
Serial.begin(9600);
lcd.begin(16, 2);
}
void loop() {
SENSOR1 = analogRead(A0);
if( SENSOR1 <= 100){ // Aquí ponemos todas las lecturas inferiores a 100 en 100, es nuestro 0
SENSOR1 = 100;
}
PRESION = ((SENSOR1-100)/68); //paso valor de lectura a bares
lcd.print (PRESION, 1); //imprimo en LCD el valor de presión con 1 decimal
lcd.setCursor(2,1);
Serial.println(SENSOR1); //imprimo en monitor serie el valor del sensor
delay(500);
}
Según veo en tu codigo estas imprimiendo el valor del ADC que está en un rango de 0 a 1023 , si quieres que te devuelva el voltaje deveras convertir ese valor. Prueba con este código y mide el valor con el multimetro.
#include "Arduino.h"
#define InT_Mensaje 1000
int ADC_SenP = 0;
float V_SenP = 0;
unsigned long T_AntLec = 0;
void setup()
{
Serial.begin(9600);
}
void loop()
{
ADC_SenP = analogRead(A0);
V_SenP = (float)ADC_SenP * 5 / 1023;
if (millis() - T_AntLec >= InT_Mensaje)
{
T_AntLec = millis(); // Actualiza el tiempo para la siguiente lectura
Serial.print("ADC:\t");
Serial.print(ADC_SenP);
Serial.print("\tV:\t");
Serial.println(V_SenP);
}
}
EDITO: Si el valor devuelto es correspondiente a lo que mides en el multímetro revisa este post para transformar el valor de Voltaje a presión surbyte explica muy bien lo que tienes que hacer: Lectura de transductor de presión
Vale, por lo que veo es que el sensor funciona correctamente, pero el problema es el código.
El problema es que has usado la función map y no ha funcionado. ¿Por qué? Por una sencilla razón: map no funciona con floats. Los tipos de la función map son unsigned long, así que cuando un parámetro es del tipo float lo convierte, truncándolo de mala manera y los resultados no son los esperados.
La solución: modificar map para que trabaje con float
int a; // Una varaible para guardar el valor del ADC.
float v; // Calculamos la tensión del ADC y la guardamos en esta variable.
float p; // La presión.
float mapfloat(float x, float in_min, float in_max, float out_min, float out_max)
{
return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}
void setup() {
Serial.begin(9600);
}
void loop() {
// Obtengo el valor del ADC.
a = analogRead(A0);
// Obtengo la tensión que se corresponde a ese valor.
v = a*5.0/1023.0;
// Obtengo el valor de la presión.
p = mapfloat(v, 0.5, 4.5, 0.0, 12.0);
Serial.print("La tension en el ADC es: ");
Serial.print(v);
Serial.print(" (");
Serial.print(a);
Serial.print(")");
Serial.print(" que corresponde a un presion de: ");
Serial.print(p);
Serial.println(" Bar");
}
Si ejecutas el programa verás que los valores serán muy aproximados a los de tu tabla.
He introducido el programa tal cual y me maca de ADC 102 ( que es la lectura del canal analógico) y Voltaje 0,50v. Con el voltímetro medido directamente entre la masa y señal son 0,51 hay una fluctuación de 0,01 0,02v con respecto al monitor (Supongo que es normal y asumible con un sensor de estas características) voy a empaparme bien de esta conversión con el enlace que me has facilitado a ver si logro entenderlo y aprender, que es de lo que se trata.
Si, al principio intenté usar map, pero como bien has dicho no funcionaba, en el código que he pasado antes ya no uso map, sino la función recta del valor del sensor, lo que aún no tengo claro es el valor en bruto que me muestra arduino, pero bueno. Voy a echar un ojo al ejemplo que me has enviado y ver que forma es la que mejor se adapta a mi caso. Seguiré preguntando.
Te envié privado, por favor leelo y lleva adelante lo que te pido.
A mi el código de victorjam me funciona perfectamente usando una simulación con random
ADC: 2.55 (521) presion de: 6.14 Bar
ADC: 2.52 (516) presion de: 6.07 Bar
ADC: 2.53 (518) presion de: 6.10 Bar
ADC: 2.53 (518) presion de: 6.10 Bar
ADC: 2.55 (522) presion de: 6.15 Bar
ADC: 2.53 (517) presion de: 6.08 Bar
ADC: 2.54 (520) presion de: 6.12 Bar
ADC: 2.54 (519) presion de: 6.11 Bar
ADC: 2.51 (513) presion de: 6.02 Bar
ADC: 2.53 (517) presion de: 6.08 Bar
ADC: 2.55 (521) presion de: 6.14 Bar
int a; // Una varaible para guardar el valor del ADC.
float v; // Calculamos la tensión del ADC y la guardamos en esta variable.
float p; // La presión.
float mapfloat(float x, float in_min, float in_max, float out_min, float out_max) {
return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}
void setup() {
Serial.begin(9600);
}
void loop() {
// Obtengo el valor del ADC.
a = random(512, 523); analogRead(A0);
// Obtengo la tensión que se corresponde a ese valor.
v = a*5.0/1023.0;
// Obtengo el valor de la presión.
p = mapfloat(v, 0.5, 4.5, 0.0, 12.0);
Serial.print("ADC: ");
Serial.print(v);
Serial.print(" (");
Serial.print(a);
Serial.print(")");
Serial.print(" presion de: ");
Serial.print(p);
Serial.println(" Bar");
delay(1000);
}
Mi respuesta de porque el método que explico surbyte en ese post y por que el mio también funciona, es por que es lo mismo, pero escrito de otra forma.
Y para el que le interese, lo acabo de explicar en documentación
Perdón por no decirlo. Yo no hice nada, solo tomé tu código @victorjam y lo modiqué levemente para mostrar menos salida por el Serial.
Agregué un random para que se vieran valores y explicar que la funcion fmap funciona correctamente.
Asi que no hay explicación para que @rososatriani diga que a el no le funciona.
Moderador:
Te he enviado 2 o 3 privados @rososatriani pidiendo que edites los post donde repites comentarios inutilmente.
Por favor hazlo!
No he podido responderle antes por qué como comprenderá y por suerte tengo más vida que estar metido en el foro. No sé lo que es para usted mensajes inútiles, si se refiere a dar las gracias a los compañeros que me han ayudado, no creo que lo sean, no he leído que no se pueda citar el mensaje para responder, pero estoy convencido que lo que si es inútil, es una actitud chulesca y amenazadora por mensajes privados que no entiendo realmente, y no estaría de más una pastilla de humildad a primera hora de la mañana para pasar el día.