Can a pressure sensor tell whether your device moved upstairs?

You are building a wearable, a portable logger or an indoor device, and you want it to notice a change in height. A small pressure sensor looks like an appealing shortcut: read a number, convert it into meters and work out the floor. The difficult part is deciding whether the number changed because the device moved.

On our bench we connected three barometric sensor modules, a BMP390, a DPS310 and an MS5611, to a MicroPython controller and got pressure readings from each. That is the necessary first step. It is not floor recognition, and the next experiment has to connect those readings to movements you can check yourself.

The distinction matters outside the workbench. In a Bosch community discussion about tracking moving equipment, a developer with both wall-mounted and mobile BMP388 units reported large differences in their calculated heights. It concerns a different sensor, but the product question is the same: putting two readings into the same formula does not make them comparable.

For a first prototype, aim to distinguish a short upward or downward move from a stationary device. An absolute floor number needs more: a known starting point or other reference, and the building's floor heights.

Decide what the number is supposed to mean

Air pressure usually decreases as you climb. It also changes with the weather while a device sits on the same desk. A barometer measures pressure; software supplies the reference and assumptions that turn it into a height estimate.

A phrase such as "high-precision altitude sensor" hides three different promises. Resolution is the smallest change the output can represent. Relative accuracy concerns changes under specified conditions. Absolute accuracy concerns how close a reading is to the actual pressure. None of them promises that a finished device will name the correct floor.

For example, Bosch specifies the BMP390's typical relative pressure accuracy as ±0.03 hPa, equivalent to ±25 cm under the stated pressure and temperature conditions. Its typical absolute accuracy is a separate specification. These are manufacturer figures, not results from our module or a completed wearable.

That scopes the work. A demonstration that responds when someone climbs stairs can start with relative changes. A device that identifies the floor after being switched on in an unfamiliar building needs a reference strategy as well as a working sensor.

Start with one connected module

Each GraftSense carrier connected to a GraftPort RP2040 controller over I2C, with SDA on GP4 and SCL on GP5. The carriers include a regulator between their 5 V connector supply and the 3.3 V sensor circuitry. That does not make the bare chips 5 V devices.

Connect and check one module at a time. These sensors can share I2C addresses, so attaching all three at once is not a useful first comparison. Record the detected address and the board revision. A successful scan tells you something answered; initialization and a plausible, correctly scaled result are the next steps.

Keep the driver version with the experiment record. The driver applies the chip's calibration coefficients, and two libraries may return pressure in different units. We used community MicroPython drivers: octaprog7's BMP390 driver (MIT), and Jose D. Montoya's DPS310 (MIT) and MS5611 drivers.

BMP390: one reading at a time versus continuous sampling

The BMP390 ran on a 400 kHz bus at address 0x77. The program read the chip identity and calibration coefficients, then configured oversampling and filtering. Oversampling takes extra internal measurements; filtering smooths changes across measurements. Both shape the response you eventually see, so record them rather than treating a quiet display as proof of accuracy. Note that the driver takes configuration codes, not literal sample counts.

The first loop triggered a single measurement, waited 300 ms, checked the status and read temperature before pressure. That order matters in this driver: the pressure calculation uses the temperature compensation value. After twenty single reads, the program switched to continuous measurement.

The visible output showed readings around 100,075 Pa and temperatures around 25.5 °C. That shows the setup producing data. We had no measured-height route, reference instrument or long stationary log, so it says nothing about altitude accuracy.

DPS310: keep units and startup behavior visible

The DPS310 test used SoftI2C at 100 kHz, scanned the bus and used the detected address. Its loop was simple:

i2c = SoftI2C(sda=Pin(4), scl=Pin(5), freq=100000)
sensor = dps310.DPS310(i2c, address=0x76)  # the address your scan found
while True:
    print("Pressure: %.2f hPa" % sensor.pressure)
    time.sleep(1)

This driver returns hPa. One hPa equals 100 Pa, so convert before putting the DPS310 beside the BMP390's Pa output; otherwise a unit difference looks like a large sensor error.

The log began around 826 hPa, then showed readings around 965 hPa, declining through the displayed sample. We do not have an explanation for the first value or a record of the surrounding conditions. Keep startup readings in your log and investigate them; do not silently drop them to make a result look stable. These samples were not recorded alongside the BMP390, so the different values do not show which sensor is more accurate.

MS5611: explore the sampling tradeoff, then verify the math

The MS5611 ran at 400 kHz on address 0x77. This test changed one setting at a time: temperature oversampling from 256 to 4096 with pressure held at 4096, then the reverse, then paired settings with five readings each, reporting an average and a maximum-minus-minimum spread. That structure is worth keeping because it ties a configuration change to an observable output. But the sample count is small, and the code labeled the full spread with a plus/minus sign. That spread is not an accuracy figure or a confidence interval.

There is also a concrete reason to revisit the driver copy we used before trusting its output for height. Each three-byte ADC result was assembled with the first byte repeated in the lowest-byte position, and the low-temperature correction omitted squared terms that appear in the datasheet. The final run displayed about 50 kPa, with no reference pressure or location to explain it. The code issues alone do not establish the cause, but a stream of similar numbers cannot validate the pressure scale, much less a height estimate.

Once the driver is verified, repeat the same controlled comparison and measure both noise and response time. More smoothing can make a stationary display look better while delaying the change a moving device needs to notice.

Make the next test about a real movement

After one module gives a credible pressure output, leave it at a fixed location and log pressure, temperature and timestamps. Then carry it along a short route with known stops: starting floor, next floor, and back to the start. Keep the mounting orientation and handling consistent. We have not run this test yet; it adds the height information our bench runs lack.

Returning to the start is especially useful. It shows whether pressure returned to its earlier level, whether the response lagged the movement, and whether the device drifted while stationary. Repeat the route after fitting the enclosure: the sensor needs a path to ambient air, and the finished assembly may respond differently from an open board.

If you use a second sensor as a fixed reference, first place both units together and compare their readings over time, with timestamps so you know which readings belong together. A reference helps separate shared changes in ambient pressure; it does not replace checking offsets, temperature behavior and the final installation.

For a fitness product, ask one more question: does "upward movement" mean the activity you want to count? A Garmin user discussion describes floors counted during passive movement, with a reply reporting different behavior on other models. Those are user reports, not a confirmed diagnosis, but they show why pressure change and "stairs climbed" need separate acceptance criteria.

Choose the smallest useful promise

For an early demonstration, a clearly labeled relative-height change may be enough. For floor identification, define how the device establishes its starting floor and what happens when the reference becomes unreliable. For a user trial, keep the raw pressure log alongside the displayed decision so a wrong result can be investigated.