Saturday, October 17, 2020

0000 0000 0100 0101

BME280 as an altimeter

The BME280 is a useful critter which can accurately measure temperature, humidity and air pressure. It's a little more expensive than some of it's cousins (e.g. the BMP280), but packs a lot of punch into a tiny I2C driven module.


I have used the module before for tracking all three measurements (in the long running "hot house" project), but I was asked if I could make an altimeter for a school science project. Challenge accepted! Using the well known science principle that air pressure drops with altitude, I was able to adapt the code that Adafruit provides and put together a cute little project box with the required outcome.

/***************************************************************************
  Altimeter based on http://www.adafruit.com/products/2650

  OneCircuit Monday 12 October  19:27:44 AEDT 2020
 ***************************************************************************/

#include <Wire.h>
#include <SPI.h>
#include <TM1637Display.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>
#include <SimpleRotary.h>

#define CLK 2
#define DIO 3
float SEALEVELPRESSURE_HPA = 1000;
float SEALEVELPRESSURE_HPA_PREC = 0;
volatile byte pushed = 0;
volatile byte whichway = 0;
unsigned long delayTime = 500;

SimpleRotary rotary(6, 5, 7);
TM1637Display display(CLK, DIO);
Adafruit_BME280 bme;

void printValues() {
  float alt = bme.readAltitude(SEALEVELPRESSURE_HPA);
  display.setBrightness(0x0f);
  display.showNumberDec(alt);
}

void setup() {
  rotary.setTrigger(HIGH);
  rotary.setDebounceDelay(5);
  rotary.setErrorDelay(250);
  unsigned status;
  status = bme.begin();
  if (!status) {
    while (1);
  }
}

void loop() {
  pushed = rotary.push();
  if (pushed == 1) {
    pushed = 0;
    while (pushed == 0) {
      display.setBrightness(0x0f);
      display.showNumberDec(SEALEVELPRESSURE_HPA);
      pushed = rotary.push();
      whichway = rotary.rotate();
      if (whichway == 1) {
        SEALEVELPRESSURE_HPA++;
      }
      if (whichway == 2) {
        SEALEVELPRESSURE_HPA--;
      }
    }
    pushed = 0;
    while (pushed == 0) {
      display.setBrightness(0x0f);
      display.showNumberDec(SEALEVELPRESSURE_HPA_PREC);
      pushed = rotary.push();
      whichway = rotary.rotate();
      if ((whichway == 1) && (SEALEVELPRESSURE_HPA_PREC < 9)) {
        SEALEVELPRESSURE_HPA_PREC++;
      }
      if ((whichway == 2) && (SEALEVELPRESSURE_HPA_PREC > 0)) {
        SEALEVELPRESSURE_HPA_PREC--;
      }
    }
    SEALEVELPRESSURE_HPA = SEALEVELPRESSURE_HPA + SEALEVELPRESSURE_HPA_PREC / 10;

  }
  printValues();
  delay(delayTime);
}

/***************************************************************************
Sketch uses 12144 bytes (39%) of program storage space.
Maximum is 30720 bytes.
Global variables use 534 bytes (26%) of dynamic memory,
leaving 1514 bytes for local variables. Maximum is 2048 bytes.
 ***************************************************************************/

Packaged up in a box with a Nano doing the grunt work the project looks like a bit of dog's breakfast, but it actually works well as intended. If I had the time I'd look into modifying the code a bit to take into account the rotary encoder switch bounce, probably using this site as a resource.


And here is the little chap sitting on the console of our car as we bounce down our ridiculously bumpy driveway.


All in all a nice little project that shows the value of third party libraries when you need fast results to fulfill a request (in this case for an altimeter).






No comments:

Post a Comment