BMP280 SPI Adafruit



  • Hi guys.
    I got this working just now. I couldnt get the BMP to run over I2C, or on marekd's sketch posted here , even after changing it to SPI.
    So I pinched the bulk of his great sketch and tweaked to to run on the adafruit libraries over SPI. Prediction even works now, neato! All the crazy prediction coding is his, no credit for me.

    /***************************************************************************
      This is a library for the BMP280 humidity, temperature & pressure sensor
    
      Designed specifically to work with the Adafruit BMEP280 Breakout 
      ----> http://www.adafruit.com/products/2651
    
      These sensors use I2C or SPI to communicate, 2 or 4 pins are required 
      to interface.
    
      Adafruit invests time and resources providing this open source code,
      please support Adafruit andopen-source hardware by purchasing products
      from Adafruit!
    
      Written by Limor Fried & Kevin Townsend for Adafruit Industries.  
      BSD license, all text above must be included in any redistribution
     ***************************************************************************/
    // Enable debug prints to serial monitor
    #define MY_DEBUG 
    
    // Enable and select radio type attached
    #define MY_RADIO_NRF24
    
    
    #include <MySensors.h>
    #include <SPI.h>
    #include <Adafruit_Sensor.h>
    #include <Adafruit_BMP280.h>
    
    #define BMP_SCK 5
    #define BMP_MISO 8
    #define BMP_MOSI 6 
    #define BMP_CS 7
    
    Adafruit_BMP280 bme(BMP_CS, BMP_MOSI, BMP_MISO,  BMP_SCK);
    
    #define CHILD_ID_TEMP 1
    #define CHILD_ID_PRESS 2
    
    const char *weather[] = { "stable", "sunny", "cloudy", "unstable", "thunderstorm", "unknown" };
    enum FORECAST
    {
      STABLE = 0,           // "Stable Weather Pattern"
      SUNNY = 1,            // "Slowly rising Good Weather", "Clear/Sunny "
      CLOUDY = 2,           // "Slowly falling L-Pressure ", "Cloudy/Rain "
      UNSTABLE = 3,     // "Quickly rising H-Press",     "Not Stable"
      THUNDERSTORM = 4, // "Quickly falling L-Press",    "Thunderstorm"
      UNKNOWN = 5           // "Unknown (More Time needed)
    };
    
    // for forecast
      float lastPressure = -1;
      float lastTemp = -1;
      int lastForecast = -1;
      const int LAST_SAMPLES_COUNT = 5;
      float lastPressureSamples[LAST_SAMPLES_COUNT];
      // this CONVERSION_FACTOR is used to convert from Pa to kPa in forecast algorithm
      // get kPa/h be dividing hPa by 10
      #define CONVERSION_FACTOR (1.0/10.0)
      int minuteCount = 0;
      bool firstRound = true;
      // average value is used in forecast algorithm.
      float pressureAvg;
      // average after 2 hours is used as reference value for the next iteration.
      float pressureAvg2;
      float dP_dt;
    
    unsigned long SLEEP_TIME = 30000; // Sleep time between reads (in milliseconds)
    
    // MyMessage to controler
    MyMessage msgT1(CHILD_ID_TEMP, V_TEMP);
    MyMessage msgP1(CHILD_ID_PRESS, V_PRESSURE);
    MyMessage msgF1(CHILD_ID_PRESS, V_FORECAST);
    
    const unsigned long tUpdate = 60000; // update interval
    //unsigned long t0;
    
    
    void presentation()
    {
      // Send the sketch version information to the gateway and Controller
      sendSketchInfo("BMP280", "1.1");
      present(CHILD_ID_TEMP, S_TEMP);
      present(CHILD_ID_PRESS, S_BARO);
    }
    
    
    
    
    void setup() {
      Serial.begin(9600);
      Serial.println(F("BMP280 test"));
      
      if (!bme.begin()) {  
        Serial.println(F("Could not find a valid BMP280 sensor, check wiring!"));
        while (1);
      }
      ServerUpdate();
    }
    
    void loop() {
        
        /*int temp = bme.readTemperature();
        long pressure = bme.readPressure();
        send(msgT1.set(temp));
        send(msgP1.set(pressure/100));*/
    
       sleep(SLEEP_TIME); 
       ServerUpdate();
    }
    
    void ServerUpdate() // used to read sensor data and send it to controler
    {
    double T, P;
    T = bme.readTemperature();
    P = bme.readPressure();
    int forecast = sample(P);
    if (P != 0)
     {
    
      send(msgT1.set(T, 1));
          send(msgP1.set(P/100, 1));
          send(msgF1.set(weather[forecast]));
     }
    }
    
    float getLastPressureSamplesAverage()
    {
      float lastPressureSamplesAverage = 0;
      for (int i = 0; i < LAST_SAMPLES_COUNT; i++)
      {
        lastPressureSamplesAverage += lastPressureSamples[i];
      }
      lastPressureSamplesAverage /= LAST_SAMPLES_COUNT;
    
      return lastPressureSamplesAverage;
    }
    
    int sample(float pressure)
    {
      // Calculate the average of the last n minutes.
      int index = minuteCount % LAST_SAMPLES_COUNT;
      lastPressureSamples[index] = pressure;
    
      minuteCount++;
      if (minuteCount > 185)
      {
        minuteCount = 6;
      }
    
      if (minuteCount == 5)
      {
        pressureAvg = getLastPressureSamplesAverage();
      }
      else if (minuteCount == 35)
      {
        float lastPressureAvg = getLastPressureSamplesAverage();
        float change = (lastPressureAvg - pressureAvg) * CONVERSION_FACTOR;
        if (firstRound) // first time initial 3 hour
        {
          dP_dt = change * 2; // note this is for t = 0.5hour
        }
        else
        {
          dP_dt = change / 1.5; // divide by 1.5 as this is the difference in time from 0 value.
        }
      }
      else if (minuteCount == 65)
      {
        float lastPressureAvg = getLastPressureSamplesAverage();
        float change = (lastPressureAvg - pressureAvg) * CONVERSION_FACTOR;
        if (firstRound) //first time initial 3 hour
        {
          dP_dt = change; //note this is for t = 1 hour
        }
        else
        {
          dP_dt = change / 2; //divide by 2 as this is the difference in time from 0 value
        }
      }
      else if (minuteCount == 95)
      {
        float lastPressureAvg = getLastPressureSamplesAverage();
        float change = (lastPressureAvg - pressureAvg) * CONVERSION_FACTOR;
        if (firstRound) // first time initial 3 hour
        {
          dP_dt = change / 1.5; // note this is for t = 1.5 hour
        }
        else
        {
          dP_dt = change / 2.5; // divide by 2.5 as this is the difference in time from 0 value
        }
      }
      else if (minuteCount == 125)
      {
        float lastPressureAvg = getLastPressureSamplesAverage();
        pressureAvg2 = lastPressureAvg; // store for later use.
        float change = (lastPressureAvg - pressureAvg) * CONVERSION_FACTOR;
        if (firstRound) // first time initial 3 hour
        {
          dP_dt = change / 2; // note this is for t = 2 hour
        }
        else
        {
          dP_dt = change / 3; // divide by 3 as this is the difference in time from 0 value
        }
      }
      else if (minuteCount == 155)
      {
        float lastPressureAvg = getLastPressureSamplesAverage();
        float change = (lastPressureAvg - pressureAvg) * CONVERSION_FACTOR;
        if (firstRound) // first time initial 3 hour
        {
          dP_dt = change / 2.5; // note this is for t = 2.5 hour
        }
        else
        {
          dP_dt = change / 3.5; // divide by 3.5 as this is the difference in time from 0 value
        }
      }
      else if (minuteCount == 185)
      {
        float lastPressureAvg = getLastPressureSamplesAverage();
        float change = (lastPressureAvg - pressureAvg) * CONVERSION_FACTOR;
        if (firstRound) // first time initial 3 hour
        {
          dP_dt = change / 3; // note this is for t = 3 hour
        }
        else
        {
          dP_dt = change / 4; // divide by 4 as this is the difference in time from 0 value
        }
        pressureAvg = pressureAvg2; // Equating the pressure at 0 to the pressure at 2 hour after 3 hours have past.
        firstRound = false; // flag to let you know that this is on the past 3 hour mark. Initialized to 0 outside main loop.
      }
    
      int forecast = UNKNOWN;
      if (minuteCount < 35 && firstRound) //if time is less than 35 min on the first 3 hour interval.
      {
        forecast = UNKNOWN;
      }
      else if (dP_dt < (-0.25))
      {
        forecast = THUNDERSTORM;
      }
      else if (dP_dt > 0.25)
      {
        forecast = UNSTABLE;
      }
      else if ((dP_dt > (-0.25)) && (dP_dt < (-0.05)))
      {
        forecast = CLOUDY;
      }
      else if ((dP_dt > 0.05) && (dP_dt < 0.25))
      {
        forecast = SUNNY;
      }
      else if ((dP_dt > (-0.05)) && (dP_dt < 0.05))
      {
        forecast = STABLE;
      }
      else
      {
        forecast = UNKNOWN;
      }
    
      // uncomment when debugging
      //Serial.print(F("Forecast at minute "));
      //Serial.print(minuteCount);
      //Serial.print(F(" dP/dt = "));
      //Serial.print(dP_dt);
      //Serial.print(F("kPa/h --> "));
      //Serial.println(weather[forecast]);
    
      return forecast;
    }
    

  • Contest Winner

    Hi @Matt

    Thanx your for your posting. Hopefully others can benefit from this.


 

466
Online

7.9k
Users

8.7k
Topics

93.6k
Posts