Measuring airspeed with multiple MPXV7002 sensors with 16bit ADC

Dear all,

I would like to measure four air speed sensors MPXV7002DP through the 16bit A/D convertor ADC1115 (more info here. Analog outputs from MPXV is connected to each channel of ADC and power supply is through breadboard from Arduino UNO. The problem is, if I connect only one sensor and in code I have reading of only one channel - it works. If I try to code reading from 4 channels it shows this reading

16:56:20.323 -> 98.36	ovf	nan	0.00

Where the last reading is connected channel with sensor.

Can I kindly ask you, if you could give me direction what could be problem?

Wiring of the ADC to Arduino is showed on following link

The skectch of code is below.

#include <Wire.h>
#include <Adafruit_ADS1015.h>

Adafruit_ADS1115 ads_a(0x48);

float V_0 = 5.0; // supply voltage to the pressure sensor
float rho = 1.204; // density of air 

int offset0, offset1, offset2, offset3 = 0;
int offset_size = 5;
int veloc_mean_size = 10;
int zero_span = 2;

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  ads_a.begin();
  int16_t adc0, adc1, adc2, adc3;
  
  adc0 = ads_a.readADC_SingleEnded(0);
    for (int ii=0;ii<offset_size;ii++){
    offset0 += ads_a.readADC_SingleEnded(0)-(32768/2);
  }
  offset0 /= offset_size;
   
//---------------------
   
  adc1 = ads_a.readADC_SingleEnded(1);
  for (int ii=0;ii<offset_size;ii++){
    offset1 += ads_a.readADC_SingleEnded(1)-(32768/2);
  }
  offset1 /= offset_size;
  
//---------------------
    
  adc2 = ads_a.readADC_SingleEnded(2);
  for (int ii=0;ii<offset_size;ii++){
    offset3 += ads_a.readADC_SingleEnded(2)-(32768/2);
  }
  offset2 /= offset_size;
  
//---------------------
  
  adc3 = ads_a.readADC_SingleEnded(3);
  for (int ii=0;ii<offset_size;ii++){
    offset3 += ads_a.readADC_SingleEnded(3)-(32768/2);
  }
  offset3 /= offset_size;


}

void loop() {
  // put your main code here, to run repeatedly:

// average a few ADC readings for stability
  
//---------------------
  
  for (int ii=0;ii<veloc_mean_size;ii++){
    adc_avg0 += ads_a.readADC_SingleEnded(0)-offset0;
  }
  adc_avg0/=veloc_mean_size;
  
  // make sure if the ADC reads below 512, then we equate it to a negative velocity
  if (adc_avg0>16384-zero_span and adc_avg0<16384+zero_span){
  } else{
    if (adc_avg0<16384){
      veloc0 = -sqrt((-10000.0*((adc_avg0/32768)-0.5))/rho);
    } else{
      veloc0 = sqrt((10000.0*((adc_avg0/32768)-0.5))/rho);
    }
  }

    
//---------------------

  for (int ii=0;ii<veloc_mean_size;ii++){
    adc_avg1 += ads_a.readADC_SingleEnded(1)-offset1;
  }
  adc_avg1/=veloc_mean_size;
  
  // make sure if the ADC reads below 512, then we equate it to a negative velocity
  if (adc_avg1>16384-zero_span and adc_avg1<16384+zero_span){
  } else{
    if (adc_avg1<16384){
      veloc1 = -sqrt((-10000.0*((adc_avg1/32768)-0.5))/rho);
    } else{
      veloc1 = sqrt((10000.0*((adc_avg1/32768)-0.5))/rho);
    }
  }
    
//---------------------

  for (int ii=0;ii<veloc_mean_size;ii++){
    adc_avg2 += ads_a.readADC_SingleEnded(2)-offset2;
  }
  adc_avg2/=veloc_mean_size;
  
  // make sure if the ADC reads below 512, then we equate it to a negative velocity
  if (adc_avg2>16384-zero_span and adc_avg2<16384+zero_span){
  } else{
    if (adc_avg2<16384){
      veloc2 = -sqrt((-10000.0*((adc_avg2/32768)-0.5))/rho);
    } else{
      veloc2 = sqrt((10000.0*((adc_avg2/32768)-0.5))/rho);
    }
  }
    
//---------------------

  for (int ii=0;ii<veloc_mean_size;ii++){
    adc_avg3 += ads_a.readADC_SingleEnded(3)-offset3;
  }
  adc_avg3/=veloc_mean_size;
  
  // make sure if the ADC reads below 512, then we equate it to a negative velocity
  if (adc_avg0>16384-zero_span and adc_avg0<16384+zero_span){
  } else{
    if (adc_avg3<16384){
      veloc3 = -sqrt((-10000.0*((adc_avg3/32768)-0.5))/rho);
    } else{
      veloc0 = sqrt((10000.0*((adc_avg3/32768)-0.5))/rho);
    }
  }

  Serial.print(veloc0,2); // print velocity
  Serial.print("\t");
  Serial.print(veloc1,2); // print velocity
  Serial.print("\t");
  Serial.print(veloc2,2); // print velocity*/
  Serial.print("\t");
  Serial.print(veloc3,2); // print velocity
  Serial.println();
  delay(50); // delay for stability
}

The output of those ratiometric sensors also depends on their power supply voltage,
which means the supply must be as stable as the resolution of the 16-bit 15-bit ADS1115,
or... you also must measure that supply, and compensate readout with the result.

Better (easier) to use a ratiometric A/D for those sensors, not an absolute A/D like the ADS1115.
I doubt if the sensor is 'better' than a default 10-bit A/D of an Arduino Uno.
Leo..

Dear Leo,

Thank you very much for your reply. I was afraid of the power supply too. I tried to use external 12V power supply for Arduino, but the result was the same.

10-bit ADC do not allow me to use the sensors for measurement in low velocities (0 - 8 m/s - > tens of Pascals), while reference min. step of measurement with 10-bit ADC is about 4.88 Pa which is quiet big step.

I also must say, the problem occurs even there are not connected more than one sensor, in code it is written.

You get indeed about 4.88 Pa per A/D step with a 10-bit A/D,
but with an ADS1115 you're swapping resolution for accuracy and stability.
If you only want to measure tens of Pascal, then you should maybe get the right sensor for that.

If you want to improve on the A/D of the Uno, then get an external 12-bit ratiometric (external reference) A/D.
The ADS1115 with it's internal reference is not a good choice.
Leo..