Measuring Height with Atmospheric Pressure
Height Demo Code
Once the library is installed, go ahead and open up a blank sketch. Make sure to select your board (SparkFun ESP32 Thing Plus) and COM port before uploading, and to hold down the boot button on your Thing Plus during the upload! The boot button is also what we’ll be using to tell the system when we’d like to take a reading; let us away to the code!
//SparkFun Qwiic MicroPressure Height Measuring Demo
//Original Demo by: Dryw Wade, Adapted for Qwiic MicroPressure by: Mariah Kelly
#include <Wire.h>
#include <SparkFun_MicroPressure.h> // Click here to get the library: https://github.com/sparkfun/SparkFun_MicroPressure_Arduino_Library/archive/main.zip
#define EOC_PIN -1
#define RST_PIN -1
#define MIN_PSI 0
#define MAX_PSI 25
SparkFun_MicroPressure mpr(EOC_PIN, RST_PIN, MIN_PSI, MAX_PSI);
// Button pin (using boot button on board)
int buttonPin = 0;
// Interrupt flag for button presses
volatile bool buttonPressed = false;
// Time to wait after a button press before reading the next button press (helps with debouncing)
unsigned long timerDelay = 500;
// Measured pressure at the bottom and top of the measurement
int bottomPressure = 0;
int topPressure;
// Calibrated number of inches per Pascal of pressure difference. Note that it's negative, because lower altitude results in higher pressure
float inchesPerPascal = -3.3;
// Using arrays to take multiple readings and display average
#define numReadings 500
int bottomReadings[numReadings];
int topReadings[numReadings];
// Breaking up array calculations
boolean measuring = true;
boolean showData = true;
void setup() {
// Start serial
Serial.begin(115200); //Be sure that your Serial Monitor is set at this rate!
Serial.println("MicroPressure height demo begin!");
// Initialize the I2C library
Wire.begin();
if (!mpr.begin()) {
Serial.println("Cannot connect to MicroPressure sensor.");
while (1);
}
// Configure button pin as interrupt
attachInterrupt(digitalPinToInterrupt(buttonPin), myISR, FALLING);
}
void loop() {
// Wait for button press
if (buttonPressed) {
// Check whether the bottom pressure has been measured
if (bottomPressure == 0) {
if (measuring) {
for (int i = 0; i < numReadings; i++) {
// Bottom pressure has not been measured, store this measurement as the bottom
bottomPressure = mpr.readPressure(PA);
bottomReadings[i] = bottomPressure;
}
measuring = false;
}
if (showData) {
for (int i = 0; i < numReadings; i++) {
bottomPressure += bottomReadings[i];
}
bottomPressure = bottomPressure / numReadings;
// Print out the bottom pressure
Serial.print("Bottom pressure: ");
Serial.print(bottomPressure);
Serial.print(" Pa ");
showData = false;
}
measuring = true;
showData = true;
} else {
if (measuring) {
for (int i = 0; i < numReadings; i++) {
// Bottom pressure has been measured, this is the top pressure
topPressure = mpr.readPressure(PA);
topReadings[i] = topPressure;
}
measuring = false;
}
if (showData) {
for (int i = 0; i < numReadings; i++) {
// Print out the top pressure
topPressure += topReadings[i];
}
topPressure = topPressure / numReadings;
Serial.print("Top pressure: ");
Serial.print(topPressure);
Serial.print(" Pa ");
showData = false;
}
// Compute the difference in pressure
int pressureDifference = topPressure - bottomPressure;
// Compute total height in inches using known inches per Pascal
int inches = pressureDifference * inchesPerPascal;
// Compute number of feet in this height
int feet = inches / 12;
// Subtract that many feet from the total number of inches
inches -= feet * 12;
// Print computed height in ft'in"
Serial.print("Height: ");
Serial.print(feet);
Serial.print("' ");
Serial.print(inches, 1);
Serial.print("\"");
Serial.println();
// Reset bottom pressure for next measurement
bottomPressure = 0;
}
// Wait for button to stop bouncing
delay(timerDelay);
// Reset flags
buttonPressed = false;
measuring = true;
showData = true;
}
}
void myISR() {
// Button just got pressed, set the flag
buttonPressed = true;
}
Now that we’ve uploaded our code, we can find something to measure! I used my desk–including a tape measure for reference–which is about 29 inches tall. Start by placing your system at the lowest point; this is where we’ll take our reading for the bottom pressure (we measure bottom to top, since a lower altitude results in a higher pressure, and vise-versa). The code has a built-in sampling system to help stabilize the sensor readings, so it’ll take a second or two after pressing the boot button to pop up on the serial monitor; it takes our ‘numReadings’ value of readings, which is 500 to start, but feel free to change that up as you see fit! Then, all there’s left to do is the same series of steps for our top pressure:
Now that we have our readings, let’s see how we did!
Not too shabby! We’re a few inches off, but that’s to be expected with this project. Now the super fun part is experimenting with how you might be able to tweak it to be even more accurate! I tried lots of different things and managed to get the margin of error down to a few inches, rather than feet.