3D printed Wind Tunnel with Arduino sensors - measurement problems

Hi everyone,

I am working on making a 3D printed Wind Tunnel and I want to be able to measure the airspeed in the centre, temperature and humidity. The temperature and humidity will be used to calculate de air density.
After I have this set up I want to measure the pressure difference between the extrados and intrados of a NACA 6409 profile using two pressure sensors mounted inside the profile.

The project is almost done but I encountered difficulties when reading the data from the sensors. I managed to put together a code whit what I fount online since this is my first rodeo with Arduino and programming in general.

Sensors and board used:

  • Arduino MEGA 2560;
  • temperature and humidity: DHT21/AM2301;
  • airspeed: a Pitot-Prandtl tube with MPXV7002DP sensor;
  • pressure sensor: BMP280 CJMCU.

Problems encountered:

  • The two BMP280 sensors use I2C and to change the IP of one, I connected the SDO to Vcc. The problem is that the pressure I get from the sensors is different and I had to calculate an offset value and subtract it from the read value so I can get equal results. Even so, they should read the atmospheric pressure but the values are with 15k Pa smaller compared with the atmospheric pressure provided by the local weather station. I discovered that if I disconnect the SDO from Vcc I get the correct values but the result from the other sensor never changes even if I try to connect the SDO pin to Vcc. What am I doing wrong?

  • When trying to measure the airspeed I get some times negative values or positive values when no air is moving in the tunnel. Another problem is that the speed is not constant and is measured at random intervals with different values. I tried making the tubes that connect the Pitot-Prandtl tube to the sensor as short as possible but no difference. What should I do to fix this issue?
    When it works and I don’t get random values it starts to measure only when the airspeed is 5 m/s or above. Is this the minimum speed this setup can measure?

Thank you!

Code used:

#include <DHT.h>
#include <Wire.h>
#include "SparkFunBME280.h"
#define DHTPIN 22    
#define DHTTYPE DHT22
#define fan 4
float V_0 = 5.0;

BME280 mySensorI; //Uses default I2C address 0x77
BME280 mySensorE; //Uses I2C address 0x76 (jumper closed)

// parameters for averaging and offset
int offset = 0;
int offset_size = 22;
int veloc_mean_size = 1;
int zero_span = 2;
int maxHum = 60;
int maxTemp = 40;
int np = 6;
int Is = 0;
int Es = 0;
int I = 0;
int E = 0;

DHT dht(DHTPIN, DHTTYPE);

void setup() {
  pinMode(fan, OUTPUT);
  Serial.begin(9600);
  Wire.begin();
  mySensorI.setI2CAddress(0x77);
  if(mySensorI.beginI2C() == false) Serial.println("Sensor Intrados connect failed");
  mySensorE.setI2CAddress(0x76);
  if(mySensorE.beginI2C() == false) Serial.println("Sensor Extrados connect failed");
  dht.begin();
  for (int ii=0;ii<offset_size;ii++){
     offset += analogRead(A15)-(1023/2);
  }
  offset /= offset_size;

    for (int ii=0;ii<np;ii++){
     Is+= mySensorI.readFloatPressure();
     Es+= mySensorE.readFloatPressure();
     delay(10);
  }
  I = Is/np;
  E = Es/np;
}
void loop() {
//////////////////////////////////////////////////////////// 
  float adc_avg = 0; 
  float veloc = 0.0;   
  float h = dht.readHumidity(); 
  float t = dht.readTemperature(); 
  float psat = 0; 
  float pv = 0;
  float pd = 0;
  float rho = 0;
  float avgIs = 0;
  float avgEs = 0;
  float avgI = 0;
  float avgE = 0;
  
  psat = 6.102*pow(10,((7.5*(t+273.15))/((t+273.15)+237.8)));
  pv = dht.readHumidity()/100*psat;
  pd = mySensorI.readFloatPressure()-pv;
  rho = (pd*0.028964+pv*0.018016)/(8.314*(dht.readTemperature()+273.15)); 
  
  for (int ii=0;ii<veloc_mean_size;ii++){
    adc_avg+= analogRead(A15)-offset;
  }
  adc_avg/=veloc_mean_size;
  if (adc_avg>512-zero_span and adc_avg<512+zero_span){
  } else{
    if (adc_avg<512){
      veloc = -sqrt((-10000.0*((adc_avg/1023.0)-0.5))/rho);
    } else{
      veloc = sqrt((10000.0*((adc_avg/1023.0)-0.5))/rho);
    }
  }
////////////////////////////////////////////////////////////
  if (isnan(h) || isnan(t)) {
    Serial.println("Failed to read from DHT sensor!");
    return;
  }
  if(h > maxHum || t > maxTemp) {
      digitalWrite(fan, HIGH);
  } else {
     digitalWrite(fan, LOW); 
}
/////////////////////////////////////////////////////////////
  for (int ii=0;ii<np;ii++){
    avgIs+= mySensorI.readFloatPressure()-I;
    avgEs+= mySensorE.readFloatPressure()-E;
    delay(10);
  }
  avgI = avgIs/np;
  avgE = avgEs/np;
/////////////////////////////////////////////////////////////
  //Serial.print("Humidity:"); 
  Serial.print(h);
  Serial.print(" ");
  //Serial.print("%\t");
 // Serial.print(" Temperature:"); 
  Serial.print(t);
  Serial.print(" ");
 // Serial.print("*C");
 // Serial.print(" rho:");
  Serial.print(rho);
  Serial.print(" ");
 // Serial.print(" Velocity:");
  Serial.print(veloc);
  Serial.print(" ");
  //Serial.print(" Pressure Extrados:");
  Serial.print(avgE);
  Serial.print(" ");
  //Serial.print(" Pressure Intrados:");
  Serial.println(avgI);
  //Serial.println(avgE-avgI);
  delay(10); // delay for stability
//////////////////////////////////////////////////////////////
}

Do you have a circuit diagram?

Please post links to the data sheet and application notes of the pressure sensor or module you use, and a circuit diagram. I cannot find a SDO pin with this sensor, and 15 kPa is far beyond the listed 2 kPa range.

How do you ensure that the air flow is continuous, undisturbed? Have you got an airspeed profile of your tunnel?

wolframore:
Do you have a circuit diagram?

I have attached a circuit diagram.

DrDiettrich:
Please post links to the data sheet and application notes of the pressure sensor or module you use, and a circuit diagram. I cannot find a SDO pin with this sensor, and 15 kPa is far beyond the listed 2 kPa range.

How do you ensure that the air flow is continuous, undisturbed? Have you got an airspeed profile of your tunnel?

The airflow is ensured by a drone propeller mounted inside the tunnel body and it is controlled via the drones radio controller :grin: . You can make an idea on how it works by going to this link and visualize the 3D model of the tunnel: https://a360.co/2FJ68sv

Datasheet for MPX7002DP: datasheet MPXV7002DP

Datasheet for BMP280:https://cdn-shop.adafruit.com/datasheets/BST-BMP280-DS001-11.pdf

What do you mean by application notes?
If you mean the data shown in the serial monitor, you can see below an example:

Humidity:46.20 %	 Temperature:24.60 *C rho:0.95  Viteza:0.00  Presiune Extrados:98308.97  Presiune Intrados:98302.32
Humidity:46.20 %	 Temperature:24.60 *C rho:0.95  Viteza:-3.94  Presiune Extrados:98309.39  Presiune Intrados:98303.65
Humidity:46.20 %	 Temperature:24.60 *C rho:0.95  Viteza:0.00  Presiune Extrados:98309.79  Presiune Intrados:98304.98
Humidity:46.20 %	 Temperature:24.60 *C rho:0.95  Viteza:0.00  Presiune Extrados:98306.07  Presiune Intrados:98301.88
Humidity:46.20 %	 Temperature:24.60 *C rho:0.95  Viteza:0.00  Presiune Extrados:98307.73  Presiune Intrados:98301.87
Humidity:46.20 %	 Temperature:24.60 *C rho:0.95  Viteza:0.00  Presiune Extrados:98308.97  Presiune Intrados:98301.88
Humidity:46.20 %	 Temperature:24.60 *C rho:0.95  Viteza:0.00  Presiune Extrados:98306.48  Presiune Intrados:98302.32
Humidity:46.20 %	 Temperature:24.60 *C rho:0.95  Viteza:0.00  Presiune Extrados:98306.90  Presiune Intrados:98303.20
Humidity:46.20 %	 Temperature:24.60 *C rho:0.95  Viteza:0.00  Presiune Extrados:98304.84  Presiune Intrados:98304.53
Humidity:46.20 %	 Temperature:24.60 *C rho:0.95  Viteza:0.00  Presiune Extrados:98309.79  Presiune Intrados:98304.09
Humidity:46.20 %	 Temperature:24.60 *C rho:0.95  Viteza:0.00  Presiune Extrados:98306.50  Presiune Intrados:98304.53
Humidity:46.20 %	 Temperature:24.60 *C rho:0.95  Viteza:0.00  Presiune Extrados:98306.07  Presiune Intrados:98303.21
Humidity:46.20 %	 Temperature:24.60 *C rho:0.95  Viteza:0.00  Presiune Extrados:98306.90  Presiune Intrados:98307.20
Humidity:46.20 %	 Temperature:24.60 *C rho:0.95  Viteza:0.00  Presiune Extrados:98306.90  Presiune Intrados:98303.21
Humidity:46.20 %	 Temperature:24.60 *C rho:0.95  Viteza:0.00  Presiune Extrados:98306.07  Presiune Intrados:98304.98
Humidity:46.20 %	 Temperature:24.60 *C rho:0.95  Viteza:0.00  Presiune Extrados:98307.32  Presiune Intrados:98300.54
Humidity:46.20 %	 Temperature:24.60 *C rho:0.95  Viteza:-3.94  Presiune Extrados:98309.39  Presiune Intrados:98302.76
Humidity:46.20 %	 Temperature:24.60 *C rho:0.95  Viteza:0.00  Presiune Extrados:98308.56  Presiune Intrados:98306.32
Humidity:46.20 %	 Temperature:24.60 *C rho:0.95  Viteza:0.00  Presiune Extrados:98308.15  Presiune Intrados:98306.32

Thank you, guys!

Do you have shutters to eliminate the rotation of the air caused by the propeller?

Paul

Paul_KD7HB:
Do you have shutters to eliminate the rotation of the air caused by the propeller?

Paul

I don't think they are necessary because the intake has a rectangular grid to direct the air and the test section is far from the propeller

Dan

Interesting project. I am curious of the math to calculate the airspeed from a differential pressure.

Did you run i2cScan.ino to verify that you have two 2C addresses? (I think there's one in samples, otherwise google it).

How do you plan to calibrate the readings? You can get a hand-held anemometer to measure the actual airspeed. How are the fans powered? If they are DC motors, you could do a simple fan-speed to airspeed calibration.

If you plan to use the differential pressure measurements, you could zero the port differences before you start the fan. Measure one and apply a correction to the other sensor. These are not precision devices and I would bet that if you put them next to each other, they won't agree the same way twice.

SteveMann:
Interesting project. I am curious of the math to calculate the airspeed from a differential pressure.

If you refer to the difference in pressure between the intrados and extrados in order to calculate the airspeed, unfortunately, I don't have the math for that.

SteveMann:
Did you run i2cScan.ino to verify that you have two 2C addresses? (I think there's one in samples, otherwise google it).

Yes, I did and it discovered two addresses 0x77 and 0x76.

SteveMann:
How do you plan to calibrate the readings? You can get a hand-held anemometer to measure the actual airspeed. How are the fans powered? If they are DC motors, you could do a simple fan-speed to airspeed calibration.

In order to calibrate the readings, I was planning to use a U shaped differential pressure sensor to measure the pressure difference in mmH20 and compare the results with the data acquired by the sensors. Unfortunately, I was not able to design a good enough profile with two pressure gages at the same place in the profile as the sensors and measure a pressure difference. Due to the fact that the airspeed in the tunnel is not great, I was able to only see a slight deformation of the water surface in the tube when the profile was perpendicular with the flow.

Interesting idea, I will try to find an anemometer at my local university and maybe they will let me use it. Thanks!

The fan is powered by a tiny DC motor. How can I get the airspeed from the fan speed? I have a photoresistor and I can make a simple circuit to measure the fan rotation but I don't have any idea how to get the airspeed out of it. I am thinking that the propeller shape is an important factor.
Hmm, I could use the U shaped differential pressure sensor to measure the pressure difference between two different sections in the tunnel and get the airspeed using Bernoulli equation between these two sections. I will try this.

SteveMann:
If you plan to use the differential pressure measurements, you could zero the port differences before you start the fan. Measure one and apply a correction to the other sensor. These are not precision devices and I would bet that if you put them next to each other, they won't agree the same way twice.

I did a correction and got the values within 1-7 Pa apart.
That is exactly what I discovered. The pressure reading is totally different and the response time of the sensors is slow. I have to take a measurement and wait one minute so the values of the sensors go back to normal.

Are you at sea level or elevation?
The pressure your local weather station gives is sea level pressure. If you're not at sea level you have to compensate for this. This 15 kPa suggests you're at about 1330m above sea level.

wvmarle:
Are you at sea level or elevation?

I am not at sea level and cording to GPS data I am at 75 m above sea level.

Hi,
Welcome to the forum.

Please read the first post in any forum entitled how to use this forum.
http://forum.arduino.cc/index.php/topic,148850.0.html .
Then look down to item #7 about how to post your code.
It will be formatted in a scrolling window that makes it easier to read.

Can you please post a copy of your circuit, in CAD or a picture of a hand drawn circuit in jpg, png?

Do you get stable readings with no air flow?
How have you got the BME280 units mounted to measure their relative pressure, especially the unit inside the tunnel?

We need to see your code.

Can you post a picture(s) of your windtunnel and how it is setup?
How are you powering your controller?
How are you controlling the fan speed?
Have you kept the wiring of the sensors away from the fan motor wiring?

Can you operate the BME280 at 5V?
Check the spec.

Have you tried code that has JUST the BME280 in it, JUST one.
Then;
Have you tried code that has JUST the TWO BME280 in it, JUST two, no other hardware connected.

If you only have one I2C address, try this wiring setup that worked for me with some optical sensors with the same address.


You then use pins 8 and 9 to select which I2C slave gets clock pulses and responds.

Tom... :slight_smile:

TomGeorge:
You then use pins 8 and 9 to select which I2C slave gets clock pulses and responds.

Now that’s a neat trick to do I2C multiplexing!

He posted it. The BMP looks like it’s on 3.3v

The 3D model link doesn’t work for me model

wvmarle:
Now that's a neat trick to do I2C multiplexing!

Not my idea, but it works really well.
Just need to do two I2C initializations, each with its respective select pin HIGH.
Tom.. :slight_smile:

Hi,
Thank you for welcoming me!

Can you please post a copy of your circuit, in CAD or a picture of a hand drawn circuit in jpg, png?

Here is my circuit.

Do you get stable readings with no air flow?
How have you got the BME280 units mounted to measure their relative pressure, especially the unit inside the tunnel?

With no airflow, I have relative stable readings with the value difference of the two sensors of 1-7 Pa. I had to subtract from the read value the mean value of the first 10 readings, make a mean value of the difference and then print the result. The problem is that the values read by the two sensors are not close to the atmospheric air pressure and I observed that if I disconnect the SDO from + the value is close to normal atmospheric pressure.
The two sensors are mounted inside the tunnel on a wing profile. I am trying to measure the pressure difference between the two sides of the wing at different attack angles.

We need to see your code.

#include <DHT.h>
#include <Wire.h>
#include "SparkFunBME280.h"
#define DHTPIN 22    
#define DHTTYPE DHT22
#define fan 4
float V_0 = 5.0;

BME280 mySensorI; //Uses default I2C address 0x77
BME280 mySensorE; //Uses I2C address 0x76 (jumper closed)

// parameters for averaging and offset
float offset = 0;
float offset_s = 0;
int offset_size = 20;
int veloc_mean_size = 1;
int zero_span = 2;
int maxHum = 60;
int maxTemp = 40;
int np = 20;
int nps = 10;
float Is = 0;
float Es = 0;
float I = 0;
float E = 0;

DHT dht(DHTPIN, DHTTYPE);

void setup() {
  pinMode(fan, OUTPUT);
  Serial.begin(9600);
  Wire.begin();
  delay(3000);
  mySensorI.setI2CAddress(0x77);
  if(mySensorI.beginI2C() == false) Serial.println("Sensor Intrados connect failed");
  mySensorE.setI2CAddress(0x76);
  if(mySensorE.beginI2C() == false) Serial.println("Sensor Extrados connect failed");
  dht.begin();
  for (int ii=0;ii<offset_size;ii++){
     offset_s += analogRead(A15)-(1023/2);
     delay(10);
  }
  offset =offset_s/offset_size;
  for (int ii=0;ii<np;ii++){
     Is+= mySensorI.readFloatPressure();
     Es+= mySensorE.readFloatPressure();
     delay(10);
  }
  I = Is/np;
  E = Es/np;
}
void loop() {
//////////////////////////////////////////////////////////// 
  float adc_avg = 0; 
  float veloc = 0.0;   
  float h = dht.readHumidity(); 
  float t = dht.readTemperature(); 
  float psat = 0; 
  float pv = 0;
  float pd = 0;
  float rho = 0;
  float avgIs = 0;
  float avgEs = 0;
  float avgI = 0;
  float avgE = 0;
  
  psat = 6.102*pow(10,((7.5*(t+273.15))/((t+273.15)+237.8)));
  pv = dht.readHumidity()/100*psat;
  pd = mySensorI.readFloatPressure()-pv;
  rho = (pd*0.028964+pv*0.018016)/(8.314*(dht.readTemperature()+273.15)); 
  for (int ii=0;ii<veloc_mean_size;ii++){
    adc_avg+= analogRead(A15)-offset;
  }
  adc_avg/=veloc_mean_size;
  if (adc_avg>512-zero_span and adc_avg<512+zero_span){
  } else{
    if (adc_avg<512){
      veloc = -sqrt((-10000.0*((adc_avg/(pow(2, 10)-1))-0.5))/rho);
    } else{
      veloc = sqrt((10000.0*((adc_avg/(pow(2, 10)-1))-0.5))/rho);
    }
  }
////////////////////////////////////////////////////////////
  if (isnan(h) || isnan(t)) {
    Serial.println("Failed to read from DHT sensor!");
    return;
  }
  if(h > maxHum || t > maxTemp) {
      digitalWrite(fan, HIGH);
  } else {
     digitalWrite(fan, LOW); 
}
/////////////////////////////////////////////////////////////
  for (int ii=0;ii<nps;ii++){
    avgIs+= mySensorI.readFloatPressure()-I;
    avgEs+= mySensorE.readFloatPressure()-E;
    delay(3);
  }
  avgI = avgIs/nps;
  avgE = avgEs/nps;
/////////////////////////////////////////////////////////////
  //Serial.print("Humidity:"); 
  //Serial.print(h);
  //Serial.print(" ");
  //Serial.print("%\t");
  //Serial.print(" Temperature:"); 
  //Serial.print(t);
  //Serial.print(" ");
  //Serial.print("*C");
  //Serial.print(" rho:");
  //Serial.print(rho);
  //Serial.print(" ");
  //Serial.print(" Viteza:");
  Serial.print(veloc);
  Serial.print(" ");
  //Serial.print(" Presiune Extrados:");
  Serial.print(avgE);
  Serial.print(" ");
  //Serial.print(" Presiune Intrados:");
  Serial.println(avgI);
  //Serial.println(avgE-avgI);
  delay(10); // delay for stability
//////////////////////////////////////////////////////////////
}

Can you post a picture(s) of your windtunnel and how it is setup?

How are you powering your controller?

I was powering all the sensors directly from the board and the board from USB. I realised the voltage was fluctuating and the results ware altered and I was getting negative airspeed when the fan was off. I have changed the power supply to the breadboard power supply and I have a more stable voltage but I can still see negative airspeed when the fan is off.

How are you controlling the fan speed?
Have you kept the wiring of the sensors away from the fan motor wiring?

The fan speed is controlled with a radio controller. I am using the drone's board to power and control the propeller speed. So the motor wiring is separated from the rest of the circuit.

Can you operate the BME280 at 5V?

No. I powered them up at 5V by mistake and after that, they stopped working for a while.

Have you tried code that has JUST the BME280 in it, JUST one.
Then;
Have you tried code that has JUST the TWO BME280 in it, JUST two, no other hardware connected.

Yes, I did this when I first programmed the sensors then added the code to the main code.

As an example, I did some measurements and plotted the airspeed and the two pressures. As you can see there is a difference between the two pressures while the air is flowing and after that, they become almost equal in this case and the values are decreasing until they get close to 0. In other cases, they never get back to being equal nor being close to 0 and while the motor is running the plot is chaotic going up and down while the motor speed is constant.
In this example, you can see that the speed is not registered constantly and I get negative airspeed after I turn off the fan.

Thank you!
Dan

Is the question on trying to measure air speed ?

a Pitot tube has two pressures. one is static pressure, the other is total pressure pressure.
you must use a differential pressure transducer. This is not optional.
The output of that will be velocity pressure
TP - SP = VP

I am in the US, so use feet and inches of water column.

for your manometer, put in a drop of red food coloring.
mount your tube on a gradient, 20-30 degrees above horizontal. You need to get a good meniscus so you can read the edge of it. google slant tube manometer.

Using a differential pressure transmitter, you will eliminate your zero and negative reading problems.

for a simple Pitot tube, total pressure hole facing directly into the airstream without any turbulence and static pressure holes for the low pressure sensing. The formal for velocity is 4005 x sq. root of the VP

As a note Static Pressure is a defined, scientific thing, it is not a casual hole in duct or tube.

so, at 1 inch of water column, you get 4,005 feet per minute (45 mph)
at 0.25" dp, you get 2,002.5 FPM

The standard pitot tube has the total pressure hole facing the air stream and uses static pressure as the low side.
there are other designs that do not use static pressure, but a negative pressure to create an amplified reading. one hole into the air stream, the other facing exactly opposite so it is not seeing true static but a depressed static pressure. the amplified values are not very high so may not help.

The key is to get a sensitivity of the transmitter that can resolve the differential pressure. a rule of thumb is that you want 4 times more sensitivity than your desired accuracy when measuring linear devices and 10 times the sensitivity when measuring square root devices. this is a square root formula.

Check the sensitivity of your differential pressure sensor.
Create a spreadsheet and see what a one step in sensing value will give you in velocity at the ranges you are interested in. [100 FPM error at full scale might be 1,000 FPM at half speed]

One of the reasons that there is nill information on Arduino's and pitot tubes for reading air speed is because the electronics for the differential pressure transmitter are so expensive and large. [bulky]

The reason that two devices cannot work is that the noise in the air stream is sonic, ie: speed of sound. the single differential pressure device eliminates the background noise because the sensor eliminates it [in hardware]. using 2 different devices will amplify it hence getting negative readings. You have no chance of eliminating it in software. [ crap in = crap out ]

if you would like to get readings on a reference device, see if you can find a hot wire anemometer on e-bay. some older used instruments can be had for reasonable costs.

the DIY ultrasonic anemometers have some value in getting readings in the ranges you will want.

BTW, what country are you in ?
You might guess that I have a few devices for this application from years of pharmaceutical lab air flow controls.

lastly, teh entering profile needs to be aerodynamic so that there is no turbulence at the pitot tube. google ASME nozzle, you can get the shape of a bellmouth and can duplicate that with a solid printer.

DanPascal:
What do you mean by application notes?

Documents written by the manufacturer about how to use their product. Bosch very likely has application notes related to the BME280 (and related BMP280 and BMP180) giving you suggestions on how to use them.

Measuring the pressure of a moving fluid such as air is VERY difficult. No surprise you get great results in static air, but noisy values all over the place when it's moving.
The moment you have air flow over the end of a tube (tube vertical, air flow horizontal) the pressure inside the tube drops, even if the pressure outside doesn't change at all. Change the orientation of that tube in the same air flow and same air pressure, and the pressure inside the tube changes.
Now look at your BMP280, you will see this tiny hole. That's similar to this tube. So when air flows over the sensor the pressure it measures depends on how it's oriented in the flow. Very likely your flow is turbulent as well, and that will give a lot of noise in the readings. You mentioned 3D printing the parts, so the walls will be rough adding more turbulence.
For any chance of accurate readings you have to talk to people that are specialised in wind tunnels, pressure measurements, etc. They will at least be able to tell you what the problems are and ways to overcome them. Not much chance to find those folk on this forum... I also only know just enough to know it's not exactly straightforward.