Monday, 8 May 2017

Making a Venturi Tube

In order to perform a little more testing on the Spirometer device I have designed a venturi tube which can be 3D printed.  It is possibly the most ugly and square shaped device ever to be designed but it will 3D print perfectly and because I designed it - I know the internal dimensions.  It was designed in the free version of google sketchup and assuming it works well I will share the design files.

The previous post for those that are interested is below:

Knowing the internal dimensions means the calculations performed will be more correct which in theory means the accuracy of the measurements will be correct.

I'm not going to go into how I designed the venturi tube - there are plenty of diagrams available.

Here is a picture of how the tube will look when printed:

Solid Version Venturi Tube
See Through Diagram of the Venturi Tube with dimensions
I used this and many other sites as a reference on how to make a venturi tube:

I'm going to 3D print this tomorrow but in the mean time lets repeat the calculations to calculate the areas of the first and second sections (The internal tube sections).

In order to make the measurements using the arduino we need the areas calculating for A1 and A2. The formula we are applying in total is:

The dimensions of A1 can be calculated using:


Next A2 can be calculated in the same way:


Lets now attempt to calculate Q, the Volumetric flow rate.  Lets use a value of 320 for P1 and 200 for P2:

Simplifying gives:

And for the second thinner section:

Simplifying gives:

Both values come in almost exactly the same - close enough for my requirements.  Good to know the mathematics works out!

From that as before the velocity of flow can then be calculated using:

Just for completeness lets use the value for A2 also:

We can now check all is correct as:

This actually computes to:

Which is really good - as we set the values for P1 and P2 to be 320 and 200 Pa to begin with!  The really small error is probably due to rounding errors creeping in with my calculations.  Not of significant importance in this case.

Here is a picture of the tube printed and displayed connected to the mask:

The venturi tube connected to a face mask

We can now use the values for A1 and A2 in the arduino code with the newly printed venturi tube. Hopefully the accuracy will be much improved.

Here is the new code - same as before but updated with the new constants for the venturi tube.

 // MPX7002DP Test Code with conversion   
 // to volumetric flow rate and velocity   
 // of flow  
 // A.Lang - 2017  
 // This code exercises the MPX7002DP  
 // Pressure sensor connected to A0  
 #include <Average.h>  
 Average<float> averageValue(100);  
 int sampleNumber = 0;      // variable to store the sample number   
 int sensorPin = A0;       // select the input pin for the Pressure Sensor  
 int sensorValue = 0;      // variable to store the Raw Data value coming from the sensor  
 float averageInitialValue = 0; // variable to store the average inital value  
 float diffPressure = 0;     // variable to store converted kPa value   
 float volumetricFlow = 0;    // variable to store volumetric flow rate value   
 float velocityFlow = 0;     // variable to store velocity of flow value   
 float offset = 0;        // variable to store offset differential pressure  
 //constants - these will not change  
 const float tubeArea1 = 0.01592994; // area of venturi tube first section 0.003095 0.01592994  
 const float tubeArea2 = 0.0042417; // area of venturi tube second section  
 const float airDensity = 1.225;  
 void setup() {  
  // start serial port at 9600 bps and wait for port to open:  
  pinMode(sensorPin, INPUT);  // Pressure sensor is on Analogue pin 0  
  //Header for CSV data  
  Serial.print("Sample Number,  Raw Sensor Value, Differential Pressure,  Volumetric Flow Rate,  Velocity of Flow,");  
  Serial.print("       ,     bits    ,      Pa     ,    m^3/second    ,     m/s    ,");  
  // get initial sensor value  
   for (int i = 0; i < 100; i++) {  
     // read the value from the sensor:   
     sensorValue = analogRead(sensorPin);   
     //push sensor values to averageValue object  
   for (int i = 0; i < 100; i++)   
    // get average Sensor values  
   //calculate mean average sensor and store it  
   averageInitialValue = averageValue.mean();   
   Serial.print("Average Initial Value :");  
 void loop() {  
   //read the value from the sensor:   
   sensorValue = analogRead(sensorPin);   
   // initial value   
   sensorValue = sensorValue - (int)averageInitialValue;  
   // increment sample counter   
  // map the Raw data to kPa  
  diffPressure = map(sensorValue, 0, 1023, 0, 4000);   
  if (sensorValue >= 0)  
     //calculate volumetric flow rate for Exhalation  
     volumetricFlow = tubeArea1 * (sqrt((2/airDensity) * (diffPressure/(sq(tubeArea1/tubeArea2)-1))));  
     //calculate velocity of flow   
     velocityFlow = volumetricFlow / tubeArea1;  
  // convert reading to a positive value  
  else if (sensorValue <= 0) {  
   diffPressure = diffPressure *-1;  
    //calculate volumetric flow rate for Inhalation  
    volumetricFlow = tubeArea2 * (sqrt((2/airDensity) * (diffPressure/(1-sq(tubeArea2/tubeArea1)))));  
    //calculate velocity of flow   
    velocityFlow = volumetricFlow / tubeArea2;  
  // Print the results as comma separated values for easier processing  
  // in a spreadsheet program  
  // wait 100 milliseconds before the next loop  
  // for the analog-to-digital converter and  
  // pressure sensor to settle after the last reading:  

I have added to the setup function to provide an initial average.  This zeros the sensorValue so that there are no issues with negative numbers during the calculation stage.  It is always a good idea to zero things before performing calculations.  I have also reduced the number of variables needed.

If people wish to use this code they will need to download the Average.H library from here:

The library has been kindly provided by Majenko Technologies and appears to work very well.  It was much quicker to use this library than to write my own function to calculate the average!

Here is the output from the new arduino serial plotter - which is very cool!

Blue trace: Raw sensor Value
Red trace: Differential pressure value, (Positive = Exhaling, Negative = Inhaling)
Green trace: Volumetric Flow
Orange trace: Velocity of Flow

If I could adjust the scales and print each graph on a separate line I'd be half way to displaying the data as requested!

I'm going to look at python scripting to achieve this functionality as I believe it will work best.

That is all for now people - take care always!