Using MPX7002DP differentia pressure sensor
This post will discuss how to take that sensor and use it to make a spirometer - a measurement instrument used to measure air inhalation and exhalation. Doctors and medical professionals use a spirometer to assess a person's respiratory function. The information is then used to provide treatment for such conditions such as Asthma, Emphysema, chronic bronchitis etc.
If more information about Spirometry is required please check out the links below:
https://www.asthmafoundation.org.nz/your-health/living-with-copd/what-is-spirometry
https://patient.info/health/spirometry-leaflet
https://en.wikipedia.org/wiki/Spirometer
In order to make a spirometer we will need a special kind of tube known as a Pnuemotachograph, A Pneumotachograph is a tube with two distinct sections separated by a known restrictive plate. I didn't make my own Pneumotachograph, as helpfully, a friend who is also a doctor, supplied me with one! If people do need to make their own tube they could be easily constructed or 3D printed.
A medical pneumotacograph |
The theory behind all this was first discovered by a very clever Swiss gentlemen called Daniel Bernoulli:
https://en.wikipedia.org/wiki/Daniel_Bernoulli
Amongst other work Mr Bernoulli discovered that one could calculate the rate at which fluids and gases flow. He noticed that if the pressure applied to a fluid or gas decreases then at the same time the speed or velocity of the fluid or gas would increase. This has become known as the 'Bernoulli Principle' and is used considerably in science and engineering - particularly in aerodynamics.
We are going to apply Bernoulli's principle to calculate the velocity of the air flow (volumetric Flow Rate) when someone breathes into the pneumotachograph and from that calculate volumetric flow which is measured in litres / second or litres per minute.
https://www.grc.nasa.gov/www/k-12/airplane/bern.html
The mathematics is quite complicated and I have never been particularly good at mathematics...Here is the theory and the associated mathematics:
In a pneumotachograph tube the downstream pressure after the obstruction (a thin plate like flap in the spherical section) will be lower than the upstream pressure in the first part of the tube. To understand pneumotachograph tubes it is necessary to explore Bernoulli's equation. If it can be assumed that a fluid flows in a horizontal manner (neglecting the minor elevation difference between the measuring points) then Bernoulli's equation can be expressed as:
where:
P1 is the pressure in first part of tube and P2 is the pressure in the second part of the tube.
ρ = density of air at standard temperature and pressure in kg/m3
v = flow velocity in metres / second
Again making an assumption that the air flows in each section without restriction - the continuity equation can be expressed as:
where
Q = flow rate in metres / second
A1 = cross sectional area of first part of the tube in m3
A2 = cross sectional area of the second part of the tube in m3
Combining (1) and (2), gives the equation needed:
The above equation is technically an application of the Venturi Effect. Both Venturi and Bernoulli worked on similar experiments and could be equally credited. More information on the Venturi Effect here:
https://en.wikipedia.org/wiki/Venturi_effect
If we apply the equation to the Pneumotachograph tube dimensions and the differential pressure measured it should be possible to calculate the flow rate (Q) and from that we can then re-arrange equation 2 and calculate V1 or V2.
From this information we can write some firmware to calculate the velocity of flow directly from the differential pressure measurement made by the MSP7002DP sensor.
My one concern with this method is that I have no information concerning the internal dimensions of the pneumotach tube provided. I have measured it as best as I can and I have also performed some simple experiments but I suspect the accuracy will be slightly compromised because I don't have that information. I think this will work but as I'm striving for accuracy it would be better to have the datasheet. I may well make my own to compare to it - that way I have the mechanical data and I can share how to make a pneumotach tube with everyone else...which might be useful...
Anyway having measured the length and diameter of the tube section, the cross sectional area can easily be calculated. The middle section of the device is (sort of) conical and therefore I need to take account of that extra area. The area of a cone can be calculated with:
I'm guessing at the radius of the conical section as I have no way of accurately measuring it.
Lets say that the cone radius is 12 mm
Lets say that the cone height is 24 mm
The area of the full cone is:
but....because the shape is not a full cone...it's top section has been removed it's a type of shape known as a conical frustum and the area of a conical frustum is calculated by:
Next the tube section must be calculated. The formula for that is:
If we now add those two figures together we have the area of the first section of the pneumotach tube.
which is 0.00309579817057 m2
The areas of each section of the tube are the same so A1 = A2.
The fluid density of air is 1.225 kg / cubed metre, lets select P1 as 320 Pa and P2 as 200 Pa and then lets plug all of the values into the first formula and find the volumetric flow rate:
Lets now apply the velocity of flow formula:
Well...that was a considerable amount of work! I'm not convinced this is quite correct. I would be more comfortable with applying known values for the areas for the different sections of the pneumotach tube. Incorrect values for area will affect the accuracy...
Anyway...with the mathematics sorted we can now write a program which performs the conversions for us.
Note m3 /s can be converted to litres / second by multiplying by 1000.
Here is the arduino code to read in the differential pressure measurement and then calculate the volumetric flow rate and the velocity of flow:
// 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
//variables
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 diffPressure = 0; // variable to store converted kPa value
float volumetricFlowExhale = 0; // variable to store volumetric flow rate value when Exhaling
float volumetricFlowInhale = 0; // variable to store volumetric flow rate value when Inhaling
float velocityFlowExhale = 0; // variable to store velocity of flow value when Exhaling
float velocityFlowInhale = 0; // variable to store velocity of flow value when Inhaling
float offset = 0; // variable to store offset differential pressure
//constants - these will not change
const float tubeArea1 = 0.003095; // area of pneumotach first section
const float tubeArea2 = 0.003094; // area of pneumotach second section
const float airDensity = 1.225;
void setup() {
// start serial port at 9600 bps and wait for port to open:
Serial.begin(9600);
pinMode(sensorPin, INPUT); // Pressure sensor is on Analogue pin 0
Serial.flush();
Serial.println();
//Header for CSV data
Serial.print("Sample Number,Differential Pressure, Volumetric Flow Rate (Exhale), Volumetric Flow Rate (Inhale), Velocity of Flow Exhale, Velocity of Flow Inhale,");
Serial.println();
Serial.print(" , Pa , m^3/second , m^3/second , m/s , m/s ,");
Serial.println();
}
void loop() {
// read the value from the sensor:
sensorValue = analogRead(sensorPin);
// initial value
sensorValue = sensorValue - 48;
// increment sample counter
sampleNumber++;
// map the Raw data to kPa
diffPressure = map(sensorValue, 0, 1023, -2000, 2000);
// convert reading to a positive value
if (diffPressure < 0) {
diffPressure = diffPressure * -1;
//calculate volumetric flow rate for Inhalation
volumetricFlowInhale = tubeArea2 * (sqrt((2 / airDensity) * (diffPressure / (1 - sq(tubeArea2 / tubeArea1)))));
//calculate velocity of flow
velocityFlowInhale = volumetricFlowInhale / tubeArea2;
} else {
//calculate volumetric flow rate for Exhalation
volumetricFlowExhale = tubeArea1 * (sqrt((2 / airDensity) * (diffPressure / (sq(tubeArea1 / tubeArea2) - 1))));
//calculate velocity of flow
velocityFlowExhale = volumetricFlowExhale / tubeArea1;
}
// Print the results as comma separated values for easier processing
// in a spreadsheet program
Serial.print(sampleNumber);
Serial.print(",");
Serial.print(diffPressure);
Serial.print(",");
Serial.print(volumetricFlowExhale);
Serial.print(",");
Serial.print(volumetricFlowInhale);
Serial.print(",");
Serial.print(velocityFlowExhale);
Serial.print(",");
Serial.print(velocityFlowInhale);
Serial.print(",");
Serial.println();
// wait 100 milliseconds before the next loop
// for the analog-to-digital converter and
// pressure sensor to settle after the last reading:
delay(100);
}
It is a little more complicated than the previous code but here is essentially how it works:
- All the variables needed are declared, the variable names should explain what their purpose is.
- All the constants we need are declared, again their names should explain their purpose.
- The setup function is called next. It initialises the serial monitor and declares the sensorInput variable as an input. Next it writes some messages to the serial monitor to create a header for a comma separated value file - an easy way to copy and paste the data from the serial monitor into a text file so it can then be important into a spreadsheet program for graphing. More on this later.
- The loop function is called next. The sample count is incremented by one every time the loop runs. This is for graphing purposes - we take a sample every 100 ms. Next the differential pressure sensor is read and the results are converted to Pascals. If the result is negative (someone is inhaling) then the value taken is converted to a positive number - if we don't do this the calculations will not be correct - it is not possible to take the square root of a negative number (Unless the quantity is complex - not relevant here!)
- Next volumetric flow rate is calculated for both exhalation and inhalation after that the velocity of flow rates are calculated and then all these results are sent to the serial monitor. Then the program loops back to the start.
If one were to copy and paste this data into an ascii text editor and save that file as a CSV extension then the data can be imported into a Spreadsheet or graphing program. Here are graphs of some of the data taken:
That's all for now. The next post will deal with graphing the data live to a rolling display. - Take care people - Alex!
This comment has been removed by a blog administrator.
ReplyDeleteThat's an amazing job. Congrats. I'm trying to do something like this. Ot will help a lot. Thanks.
ReplyDeleteYou are welcome - thanks for reading my blog!
ReplyDeleteSomething is not quite right... In the formula for Q that includes the A1 and A2 terms, if A1 = A2, isn't there a divide by zero (0)? The equations would seem to be for a true venturi setup where A1 != A2.
ReplyDeleteI suspect the pneumotacograph shown has a resistive element that produces the differential pressure. If true, then the key thing needed is that resistance.
Otherwise, this can definitely work. Probably the best thing to do is to calibrate using something that produces known air flows... Then work backwards. The relationship for this design (Fleish/Lilly) is something like ΔP = a*Q^2+b*Q, a and b are constants
BTW, I designed a 3D printed pneumotachograph that works quite well. The resistive element can be a bundle of small tubes, or something that is 3D printed, though the latter tends to create turbulence because of the not smooth ports...
DeleteIf you look at my next post...I also made a 3D printed pneumotachograph ;)
Deletehttps://langster1980.blogspot.com/2017/05/making-venturi-tube.html
Hi just starting to have a look at this again. I had a full system running on a riscos/ archimedes many decades ago. I think you have to calibrate daily to account for atmospheric changes and use a 3 litre volumetric calibration syringe for the best results.
ReplyDeleteThe pneumotachs are usually designed to be linear over a specific flow range so as to limit turbulent flow and too much resistance. I seem to remember we used a set of 3 rated linear at 300, 600 and 900 l/m.
I wiil watch with interest to see how this develops.
Bob
Hi BobR thanks for commenting. I have been asked to design a new version of a 3D printed pneumotach for some engineers in Sudan to assist with a covid-19 respirator. I will write up my design shortly and share all the information I have. Just researching their requirements to ensure it is feasible.
Delete