Hi! Thanks for checking out our spirometer design!
Spirometers are used in the clinical setting to measure the amount of air inspired and expired by a person's lungs. This data can be used to determine normal lung function, as well as diagnose a variety of pulmonary conditions.
This project was completed in a Biomedical Instrumentation class at Vanderbilt University. The spirometer uses a differential pressure sensor to calculate the flow rate and volume of air blown through the tube over a given time. We used the principle of the Venturi tube, where a difference in pressures sampled at two different tube diameters can be used to calculate flow rate with Bernoulli's principle.
We chose to interface with the Arduino using MATLAB's Arduino Simulink package so that we could keep all programming within MATLAB and show output on the computer screen with an easy-to-use graphical user interface (GUI). The GUI allows us to modify the time interval over which to record and save the data in a variety of formats. An alternative to this would be to use an Arduino-compatible LCD screen and do all necessary computations completely within the Arduino platform. This approach would allow for greater portability, but a more complex interface would be needed to save the data and adjust recording parameters.
- Arduino Uno
- Arduino Project Enclosure
- Honeywell ASDXRRX005NDAA5 Differential Pressure Transducer
- Wires and USB-A to USB-B cable
- Venturi Tube: (note: a single diameter tube will not work for this design!)
- 1.5 inch inner diameter (ID) PVC pipe
- 0.5 inch ID PVC pipe
- 1.5 inch to 0.5 inch ID PVC Reducer
- 3/38 inch ID fuel line tubing
Step 1: Venturi Tube Principle
A Venturi meter is an apparatus that can be used to measure the volumetric flow rate of a fluid. The principle of the Venturi meter is derived from the Bernoulli principle, which is derived from the conservation of the energy of a fluid. The Bernoulli equation for incompressible fluids is as follows:
Where v = velocity (m/s), g = acceleration due to gravity (m/s^2), P = pressure (Pa), ρ = density (kg/m^3), and C is equal to some constant. This equation tells us that the sum of kinematic, potential, and internal energy must stay the same, or that a change in one would cause a change in the others such that the net change in energy is zero.
The tube that we built for our spirometer was comprised of two pieces of PVC pipe: one with a diameter of 1.5 inches and the other with a diameter of 0.5 inches. As the fluid (air in this case) flows from the pipe of larger diameter to the pipe of smaller diameter, its velocity must increase, due to the principle of mass continuity. When the spirometer is held level, there is no change in the height of the fluid, so there must be a pressure drop to account for the increased velocity. All of these concepts combine to create an equation for the volumetric flow rate (V):
V = A*v
(P1- P2)/ρ+(v1^2-v2^)/2 = 0
V = A2*sqrt((2*(P1-P2))/(ρ*(1-(A2/A1)^2)))
Where A1 = cross sectional area of larger pipe, A2 = cross sectional area of the smaller pipe, and P1 - P2 can easily be measured by a differential pressure transducer.
Step 2: Pressure Sensor
We used a Honeywell ASDX series differential pressure transducer for this project. This transducer worked very well for the project, and we have attached the data sheet for reference.
Differential pressure transducers typically contain a mechanical diaphragm, with a pressure input on either side. The difference in the two input pressures will deflect the diaphragm, and this deflection can be converted into an electrical signal. In our case, the pressure differential was related to the percentage of the supply voltage that was transmitted.
Step 3: Putting It All Together
Because the pressure transducer was the only circuit element for this project, assembly was relatively straightforward. We began by putting the Arduino into the project case, then soldering the pressure transducer onto a circuit board. We cut the circuit board down to a small size so that it would fit into the project case, then we used hot glue and some plastic standoffs to secure the circuit board at an angle, so that the pressure sensor inlets would be pointed toward the opening in the top of the project case.
To connect the pressure transducer to the Arduino:
- PIN 1 --> Arduino 5V
- PIN 2 --> Arduino A0
- PIN 3 --> Arduino GND
To connect the Venturi tube to the pressure transducer, we have configured it so that the small diameter section of the tube connects to the top input on the pressure transducer, although either way will work as long as you account for the absolute value of the pressure difference in your code.
Step 4: Writing the Code
As we mentioned earlier, we opted to write a custom GUI for the spirometer. Because everyone reading this may not have access to MATLAB, we will simply provide the general equations, and leave out the messy details of the GUI in this guide. We will outline the basics of the code in a few steps.
Within a for loop that iterates over the sample time, where ii is the iteration:
- Read voltage from A0, and apply a moving average filter to reduce noise
- voltage(ii) = *read voltage from pin (implementation will depend on whether you are using MATLAB or Arduino*
- Using the equation from the pressure transducer's datasheet, convert the voltage into a pressure difference (psi).
- dP_psi(ii) = (14.6959 / 2) * (voltage(ii) - V_reference)
- Convert the pressure to Pascals for easier computations
- dP_Pa(ii) = dP_psi(ii)*6894.76
- Using the equation for the volumetric flow rate through a Venturi tube, (IDs is the inner diameter of the small portion of the tube, and beta is the ratio of the two diameters. Rho is the density of air at a given temperature)
V(ii) = A2*sqrt((2*(P1-P2))/(ρ*(1-(A2/A1)^2)))
See step 2 for more info on this equation
- If you want to calculate the total volume of air expired in your sample range, we can use a simple numerical integration:
- VolTotal += V(ii) * dt
- Where dt is the sample rate
Step 5: Try It Out!
The only thing left to do now is to try out your spirometer! We found that this design gave a pretty reasonable rough estimate of the flow rate and total volume of air expired in one expiration.
Notes on performance:
We found that when compared to normal forced expiratory volumes (FEVs) and flow rates, our equations were off by around a factor of 10, which also skewed the numerical integration step. Although we did not have the time to do this in our short development period, a calibration would be required, where a known flow rate and volume of air is applied to the spirometer, and the equations adjusted accordingly.
Also of note, I suspect that when using the MATLAB interface, the sample rate is determined by the speed at which each iteration of the for loop is executed, since an explicit sample rate cannot be set through the MATLAB interface. As a result, a better approach may be to sample the data using the Arduino code directly, then processing using any preferred method.