How to measure air speed using Mpxv7002dp with ADS1115 16bit and Arduino UNO

Hello guys,

I am working on a project in which I need to measure air speed using a pitot tube with MPXV7002DP sensor with 16bit ADS1115 and Arduino UNO board.

But I don't know anything about coding since I am an Aerospace Engineer and coding is not something I am expert in.

If possible, can anyone help me with the code for the same please? Thank you.

Look at the transfer function in the datasheet. I think I have written a code for this exact sensor. I'll look for it.

I found it:

If you use the code I wrote, change the transfer function.

Also, the maximum measurable diff pressure is 0.3psi. That is around 2070 Pa. In any case, the maximum airspeed that you can measure if you consider ISA conditions and sea level is 58m/s that is around 112 knots. I don't know what you will do with this sensor. Just something to consider.

Also, I am not happy with the accuracy of the sensor. All depends on what you need it for. If you want a good sensor, I would advise the Honeywell HSC. I did some wind tunnel testing with it and I am positively surprised at the results. There was a difference of less than 1 Pa to expensive 10'000 dollar sensors.

Is this the code? I have MPXV7002DP data sheet with me here and I see the transfer function in it.

*/

#include “Arduino.h”
#include “SpeedPressure.h”

Pressure::Pressure(int pin){
pinMode(pin,INPUT);
_pin = pin;
}

int Pressure::Init(){
ref_pressure = analogRead(_pin);
for (int i=1;i<=200;i++)
{
ref_pressure = (analogRead(_pin))0.25 + ref_pressure0.75;
delay(20);
}
return ref_pressure;
}

int Pressure::GetAirSpeed(){
int air_pressure = 0;
for (int i = 0; i < 8; i++)
air_pressure += analogRead (_pin);
air_pressure >>= 3;
if (air_pressure < ref_pressure)
air_pressure = ref_pressure;

pitotpressure = 5000.0f * ((air_pressure - ref_pressure) / 1024.0f) + PRESSURE_SEA_LEVEL; // differential pressure in Pa, 1 V/kPa, max 3920 Pa
ambientpressure = PRESSURE_SEA_LEVEL;
temperature = 20.0f + ABSOLUTE_0_KELVIN;
density = (ambientpressure * DRY_AIR_MOLAR_MASS) / (temperature * UNIVERSAL_GAS_CONSTANT);
airspeed_ms = sqrt ((2 * (pitotpressure - ambientpressure)) / density);
airspeed_kmh = airspeed_ms * 3.600; // speed in km/h

return airspeed_kmh;
}

Well, that's the code the OP gave. I was not really happy with it because it uses libraries where, in my opinion, this sensor does not need one. If you want, you can use it. If not, then you can use mine which is on the second page. I also used a Kalman filter library to smooth the data. If you don't need a Kalman filter, then its just like measuring the voltage and converting it using the transfer function. That simple.

You will need to change this:

DP = 1000*((vout/1023.00) -0.04)/0.09 ; // Transfer function converted in Pa (Check datasheet page 6)

to match the TF on page 6 of the datasheet:

I have also not tested my code. So, I don't know if it works. You will have to adjust it until it works. I don't have this sensor. If you buy the Honeywell HSC with the SPI bus, then I can send you my code for that with the perfect filter.

Also note: on the analog pin, measuring 5V will be given as 1023. Therefore, looking at the datasheet Vs is 1023 and not 5V. keep this in mind while generating the transfer function for the arduino.

Transfer function in the sheet:
Transfer Function:
Vout = VS × (0.2 × P(kPa)+0.5) ± 6.25% VFSS
VS = 5.0 Vdc
TA = 10 to 60°C

IS this code correct now?

#include <SimpleKalmanFilter.h> // get from: GitHub - denyssene/SimpleKalmanFilter: A basic implementation of Kalman Filter for single variable models.

SimpleKalmanFilter DPKalmanFilter(50, 50, 0.01);

/*
SimpleKalmanFilter pressureKalmanFilter(e_mea, e_est, q);
e_mea: Measurement Uncertainty - How much do we expect to our measurement vary
e_est: Estimation Uncertainty - Can be initilized with the same value as e_mea since the kalman filter will adjust its value.
q: Process Variance - usually a small number between 0.001 and 1 - how fast your measurement moves. Recommended 0.01. Should be tunned to your needs.

*/

const long SERIAL_REFRESH_TIME = 10;
long refresh_time;

int DPPin = A0;

float vout;
float DP;
float DP_kalman;
float rho = 1.225; //ISA density in kg/m3.
float V_IAS;
float V_kmh;

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

void loop() {

vout = analogRead(DPPin); // read the input pin

DP = 1000*((vout+0.625*Vfss)/1023.00) -0.5)/0.2 ; // Transfer function converted in Pa (Check datasheet page 6)
DP_kalman = DPKalmanFilter.updateEstimate(DP);

V_IAS = sqrt(2*DP/rho); // Indicated Air Speed in m/s. This is not TRUE!!! If you want true, get a static pressure port and a temperature probe. Something like the BMP280.

V_kmh = V_IAS * 3600; //km/h

if (millis() > refresh_time) {

Serial.print(DP);
Serial.print(",");
Serial.print(DP_kalman);
Serial.print(",");
Serial.print(V_IAS);
Serial.print(",");
Serial.print(V_kmh);
Serial.println();

refresh_time=millis()+SERIAL_REFRESH_TIME;
}
}

DP = 1000.00*(-0.5 + vout/1023.00)/0.20;

FSS stands for Full Scale Span. This means that There is an error of +-6.25% of the measurement that I don't think is correctable. You can see this by looking at the graph in the datasheet. The min and max line.

SimpleKalmanFilter DPKalmanFilter(50, 50, 0.01);

This you will have to adjust by looking at your measurements. With the 3rd component (0.01), you can control your lag. Change this depending on how fast you will change the measurements.

Edit: Sorry accidentally put a minus on the TF.
Edit: It was correct before, I ran out of coffee beans so I am really tired.

Thanks for the help.

Also, if possible do send me the honeywell HSC sensor code along with the sensor model details. I am thinking of getting one. Thanks again.

#include <HoneywellTruStabilitySPI.h> //https://github.com/huilab/HoneywellTruStabilitySPI

TruStabilityPressureSensor sensor( 37, -15.0, 15.0 );

void setup() {
  Serial.begin(115200); // start Serial communication
  SPI.begin(); // start SPI communication
  sensor.begin(); // run sensor initialization
}

void loop() {
  // the sensor returns 0 when new data is ready
  if( sensor.readSensor() == 0 ) {
    Serial.print( "temp [C]: " );
    Serial.print( sensor.temperature() );
    Serial.print( "\t pressure [psi]: " );
    Serial.println( sensor.pressure() );
  }
  
  delay( 100 ); // Slow down sampling to 10 Hz. This is just a test.

}

https://www.mouser.ch/Search/Refine?Ntk=P_MarCom&Ntt=115000945

There are different bus types (I²C, SPI, Analog) Make sure you get SPI. Also, check the pressure range and packaging type aswell. I used a 1psi for my experiments and if you want to use the Kalman filter: 10 , 10 , 0.01 works very well.

jaybhimani:
I am working on a project in which I need to measure air speed using a pitot tube with MPXV7002DP sensor with 16bit ADS1115 and Arduino UNO board.

The ADS1115 and MPX pressure sensors are a poor match. The ADS is absolute and the MPX is ratiometric, which makes the setup dependent on pressure and supply voltage. You must therefore also take supply voltage into the equation, which could be a pain (ripple/noise).
Leo..

Wawa:
The ADS1115 and MPX pressure sensors are a poor match. The ADS is absolute and the MPX is ratiometric, which makes the setup dependent on pressure and supply voltage. You must therefore also take supply voltage into the equation, which could be a pain (ripple/noise)

Absolutely correct. Luckily for the OP the solution is not that hard: connect the sensor's Vcc supply to a separate input of the ADS1115 to measure the actual voltage the sensor is powered at. Ripple should be taken care of by proper decoupling as suggested in the datasheet.
It seems that there's no 3.3V version of this sensor available (I've used the MP3V5004 before, works great for water level measurement) or that would offer another solution: use the 3.3V output of the Arduino. That's about as stable as can be.