[SOLUCIONADO] Mapear Sensor de Temp y Presion Bosch

Buenas,
Tengo un Sensor Bosch con referencia 0261230340 que controla presión y temperatura de aceite.
Pero no tengo muy claro como mapearlo.
El sensor tienes 4 pines, positivo (5V), masa, salida presión y salida temperatura.
0 261 230 340 Data Sheet_70496907_Pressure_Sensor_Combined_PST-F_1.pdf (865.7 KB)

En el datasheet que adjunto la escala dice que es de 0.5v a 4.5v, con lo cual creo que 0.5v seria 0br y -40ºC.

Estoy un poco bloqueado en que parámetros poner en el mapeo.

Gracias

const int sensorPresion = A0;        // Lectura del sensor de presion
const int sensorTemperatura= A1;     // Lectura sensor de Temperatura

float presionActual;                 // Variable para guardar el valor del Sensor Presion 
float temperaturaActual;             // Variable para guardar el valor del Sensor Temperatura


void setup() {


  Serial.begin(9600);

}


void loop() {

presionActual = map(analogRead(sensorPresion), 0, 0, 0, 0);

temperaturaActual = map(analogRead(sensorTemperatura), 0, 0, 0, 0);

}

image

Bueno si estas usando correctamente los pines entonces. Vamos por partes.
Presion. salidas de 0.5 a 4.5 voltios para 0 a 1000kpa

Las cuentas me dan esto
y (en Kpa) = 250 * (x-0.5V)
Entonces tu lees con el arduino X y obtienes y en presion Kpa

float presion() {
    float tmp;
     unsigned int valor = analogRead(sensorPresion))*5/1023;
    tmp = 250 * (valor - 0.5);
     return tmp;
}

Con la Resistencia hay que hacer una regresión para ver que se aproxima. Un polinomio o una logaritimica supongo.

Según esto Calculadora en línea: Aproximación de funciones con análisis de regresión
obtuve esto

type or paste code here
```y=257.9126−30.3200⋅lnx
con un Coeficiente de correlación
0.9956
entonces temperatura requiere un divisor resisitivo para obtener algo con que leer en el Arduino.
Luego lo hago si no me ganan.

EDITO 1:
Esto es una aproximación solamente, no dará el valor de temperatura.

float rTemperatura() {
float Rtmp;
unsigned int valor = analogRead(sensorTemperatura)5/1023;
Rtmp = 257.9126−30.3200
log(valor);
return Rtmp;
}

A esta expresion le falta incorporar el divisor resistivo o bien un puente de Weasthone. La hoja de datos sugiere usar una R de 4k6 ohms
Si pongo el divisor con 4k6 como pullup (conectada entre 5V y la Resistencia del sensor) entonces tenemos

Vout = 5.0 */ Rs / (4.6+Rs) = 5.0 * 1 / (4k6/Rs +1)

Entonces
Bueno con un poco de matemática que no se si viene al caso surge

Rs = 4k6 / (5.0/Vout -1))

EDITO 2:
Bueno el despeje estaba bien.
Con la fórmula anterior encuentras Rs y con Rs en la expresión que corresponde a la regresión logarítmica se encuentra la temperatura

float temperatura() {
     float temp;
     float rsensor;
     unsigned int valor = analogRead(sensorTemperatura)*5/1023;
     rsensor = 4.6/(5.0-valor)-1.0);
     temp = 257.9126−30.3200*log(rsensor);
     return temp;
}

Bien esta ultima función te debería dar la temperatura. La aproximación es bastante buena pero falla para valores cercanos a 0 °C. No falla, tiene bastante error.

image

Se podría utilizar la ecuación Steinhart–Hart, los tutoriales de Luis llamas como este: MEDIR TEMPERATURA CON ARDUINO Y TERMISTOR (MF52) es un buen inicio, para aplicar esa ecuación necesitas obtener los valores de los coeficientes para eso puedes utilizar la tabla de resistencias y temperatura que tienes en la hoja de datos, intenta elegir los valores cerca del rango en el cual va a trabajar el sensor y luego utilizas esta calculadora para obtener los coeficientes https://www.thinksrs.com/downloads/programs/therm%20calc/ntccalibrator/ntccalculator.html

Gracias Surbyte,
He tardado en contestar por que me gusta estudiar lo que me explicas y ufff me ha costado un poco.
Este fin de semana de tendré mas tiempo y lo probare.
Lo único que me pasa es que me da error a compilar esta linea.

 temp = 257.9126−30.3200*log(rsensor);

El error es :

Sensor_presion_y_temp:36:21: error: stray '\222' in program
   temp = 257.9126 − 30.3200 * log(rsensor);
                     ^
C:\Users\Jose Luis\Desktop\Sensor_presion_y_temp\Sensor_presion_y_temp.ino: In function 'float temperatura()':
Sensor_presion_y_temp:36:23: error: expected ';' before numeric constant
   temp = 257.9126 − 30.3200 * log(rsensor);
                       ^~~~~~~
exit status 1
stray '\342' in program

Parece que hace referencia a un ";" pero no lo veo.

Gracias

reescribe la fórmula. Eso ocurió por copiarla del sistema Web.
Escríbela en el IDE:
Este código no me da errores

#include <LibPrintf.h>

float temperatura() {
     float temp;
     float rsensor;
     unsigned int valor = analogRead(sensorTemperatura)*5/1023;
     rsensor = 4.6/(5.0-valor)-1.0);
     temp = 257.9126−30.3200*log(rsensor);
     return temp;
}

float presion() {
    float tmp;
     unsigned int valor = analogRead(sensorPresion))*5/1023;
    tmp = 250 * (valor - 0.5);
     return tmp;
}

void setup() {
    Serial.begin(115200);
}

void loop() {
    static float ftemp, fpresion;
    ftemp = temperatura();
    fpresion = presion();
    printf("Presion : %f", fpresion);
    printf("Temp    : %f", ftemp);
   delay(1000);
}

Puse el delay porque el programa no hace nada mas que presentar 2 datos, sino de ningún modo lo usaría.

Gracias,
Estabas en lo cierto, lo he escrito y compila.

Pues lo dicho lo probare este fin de semana y te cuento.

Muchas Gracias

Buenas,

Pues he estado probando el sensor y pasa algo raro, mira lo que marca:

Midiendo el sensor de presión:
Esto me mide con el sensor conectado y sin presión (esta al aire libre),supongo que debería de marcar cero. No he podido meterle presión, porque aqui en casa no tengo medios.
Sensor Conectado

Midiendo el sensor de temperatura:
Y esto es lo que me mide el de temperatura, la temperatura de la habitación donde estoy es un unos 26 grados. He probado a darle algo de calor con un mechero y marca "nan" (no se porque). Luego le puse un hielo para enfriar y empezó a marcar 271 y bajando.
Temperatura

Veamos que hice cuando lo pense.
Si no tienes presion deberias leer 0.5V entonces

tmp = 250 * (valor - 0.5);

tmp = 250 (0.5-0.5) = 0
De modo que hay otro problema.
Cuando tengas 4.5V o sea el máximo
tmp = 250*(4.5-0.5= = 250*4 = 1000
La ecuacion esta bien.

Agrega a la funcion presion un simple Serial.print para ver que lee cuando no tiene nada conectado

float presion() {
    float tmp;
     unsigned int valor = analogRead(sensorPresion))*5/1023;
    Serial.println("Presion del ADC = " +String(valor));
    tmp = 250 * (valor - 0.5);
     return tmp;
}

Esto es lo que lee con el sensor puesto pero sin presión en el ADC

Presion ADC

A ver a ver... la hoja de datos dice que entrega valores entre 0.5 y 4.5V no entre 0 y otra cosa
Revisa. Ese 0 que esta dando esta mal o algo no se corresponde con el pdf que pusiste en el post#1


Muestra una curva , recta truncada rara en rojo para presiones entre -100 y 0 pero dices que no tiene presión asi que supongo que esta simplemente entregando 0.5V
Prueba por faVor con un tester/multímetro a ver que tensión sale en esa prueba.

Pero lo que acabo de ver es que tomé valores de la gráfica para la temperatura y estaban todos los valores en la hoja de datos. Voy a volver a hacer la regresión para que ajuste mejor la temperatura.

Recordé que habia una calculadora para los NTC y con los valores del datasheet obtuve esto


La aproximación es muy buena.
A = 1.285647349 e-3
B = 2.620994050 e-4
C = 1.612308649 e-7

R(25°C) = 2032.12 Ω
β = 3407.49 K
Ahora con esta rutina leeras la temperatura

#include <Arduino.h>
#include <math.h>
#define A 1.285647349e-3
#define B 2.620994050e-4 
#define C 1.612308649e-7 

// configurar el pin utilizado para la medicion de voltaje del divisor resistivo del NTC
#define CONFIG_THERMISTOR_ADC_PIN A0
// configurar el valor de la resistencia que va en serie con el termistor NTC en ohms
#define CONFIG_THERMISTOR_RESISTOR 4600
 
/**
 * @brief Obtiene la resistencia del termistor resolviendo el divisor resistivo.
 * 
 * @param adcval Valor medido por el convertidor analógico a digital.
 * @return int32_t Resistencia electrica del termistor.
 */
int32_t thermistor_get_resistance(uint16_t adcval)
{
  // calculamos la resistencia del NTC a partir del valor del ADC
  return (CONFIG_THERMISTOR_RESISTOR * ((1023.0 / adcval) - 1));
}
 
/**
 * @brief Obtiene la temperatura en grados centigrados a partir de la resistencia
 * actual del componente.
 * 
 * @param resistance Resistencia actual del termistor.
 * @return float Temperatura en grados centigrados.
 */
float thermistor_get_temperature(int32_t resistance) {
  // variable de almacenamiento temporal, evita realizar varias veces el calculo de log
  float temp;
 
  // calculamos logaritmo natural, se almacena en variable para varios calculos
  temp = log(resistance);
 
  // resolvemos la ecuacion de STEINHART-HART
  // http://en.wikipedia.org/wiki/Steinhart–Hart_equation
  temp = 1 / (A+ (B * temp) + (C * temp * temp * temp));
 
  // convertir el resultado de kelvin a centigrados y retornar
  return temp - 273.15;
}


Asi va lal R de 4k6 que en realidad no la vas a conseguir. Usa 4k7 pro modifica en el código

Fuente

Buenas Surbyte

He medido la tensión con un tester en el pin de la presión y marca 0.48v.
Después probé a medir lo que da el sensor sin formula ninguna, que seguramente no valga para nada, pero salió esto con este sketch:

const int sensorPresion = A0;        // Lectura del sensor de presion

float presionActual;                 // Variable para guardar el valor del Sensor Presion

void setup() {
  Serial.begin(115200);
}

void loop() {

  presionActual = analogRead(sensorPresion);
  Serial.print("Presion=  ");
  Serial.println(presionActual);
  delay(1000);
}

Presion directa

Y si le meto presión simplemente soplando varia de 104 a 106 mis pulmones no dan para mas.
Si por el contrario vario esta linea :

 presionActual = analogRead(sensorPresion)*5/1023;

Ya marca 0.00 pero por mucho que soplo no varia nada.
El sensor no creo que este malo, lo compre hace unas dos semanas en un servicio bosch.

Voy a probar ahora lo de la temperatura.

Vamos con la temperatura

Esto es lo que mide:
Temp surb

Jugando con los valores de la calculadora:

conseguí que midiera esto, no es exacto, hay una diferencia de unos 2 - 3 grados:

Temp valores mio

Lo que ocurre es que mide del revés, si le aplico calor la temperatura baja en ves de subir y si le aplico frio sube.

El cálculo correcto de valor leído a voltios es

presionActual = analogRead(sensorPresion)*5/1023.0;

sino, por defecto, la división es entre enteros y da un resultado entero (o sea sin decimales) aunque el destino sea float.
Por eso siempre da 0, porque trunca los decimales (piensa que 104 equivale a poco mas de 0.5V)

Como pusiste la NTC del lado conectada a VCC o del lado conectado a GND?
Te puse un esquema para que lo hicieras correctamente.
Ahora caigo.. el esquema propuesto es para NTC que estan en forma de resistencia. El tuyo esa fijo y no puedes separarlo.
Asi que tenemos que hace un cambio en la matemática.
Dejame ver y te respondo

Buenas Surbyte,

Si lo monte bien, de hecho si lo monto del revés me mide en negativo.
Gracias

He revisado mis cuentas.
Con el NTC abajo entonces te queda esta expresión

R = V*Rc/(Vcc-V)
V es la tensión del ADC
Vcc = 5V
Rc la resistencia del divisor resistivo pull up

#include <math.h>
const int Rc = 10000; //valor de la resistencia
const int Vcc = 5;
const int SensorPIN = A0;
#define A 1.285647349e-3
#define B 2.620994050e-4 
#define C 1.612308649e-7 
float K = 2.5; //factor de disipacion en mW/C

void setup() {
  Serial.begin(9600);
}

void loop()  {
  float raw = analogRead(SensorPIN);
  float V =  raw / 1023.0 * Vcc;
  float R = (Rc * V ) / (Vcc - V);
  
  float logR  = log(R);
  float R_th = 1.0 / (A + B * logR + C * logR * logR * logR );
  float kelvin = R_th - V*V/(K * R)*1000;
  float celsius = kelvin - 273.15;
  Serial.print("T = ");
  Serial.print(celsius);
  Serial.print("C\n");
}

Prueba a ver si ahroa refleja valores correctamente.

Lo acabo de probar y sigue midiendo del revés

Si aplico calor la temperatura baja:

NEW CODIGO

A parte aunque he cambiado la resistencia de pull up en el código, los valores no son los correctos, que eso ahora mismo no importa mucho por que supongo que variando los valores A,B y C conseguiremos mejorarlo.
Lo que no me explico es porque mide del revés.
No se si comprar otro sensor no sea que este venga mal, pero es que vale 75€.

Ahora esta con R de

const int Rc = 10000; //valor de la resistencia

Pone tu valor. NTC abajo como tenes.