Change default pin



  • Hi,

    I'm new with mySensors and I'm using them with Domoticz.
    I have running an DHT-22 sensor and that is working fine.

    I'm now building a light + pressure sensor because I think that those sensors are perfect to combine. But, by default the BH1750 and MBP085 are using the same pins on the Arduino.

    Is there a way to override the default pin?

    My current code (it's says:Could not find a valid BMP085 sensor, check wiring!)
    :

    /**
    * The MySensors Arduino library handles the wireless radio link and protocol
    * between your home built sensors/actuators and HA controller of choice.
    * The sensors forms a self healing radio network with optional repeaters. Each
    * repeater and gateway builds a routing tables in EEPROM which keeps track of the
    * network topology allowing messages to be routed to nodes.
    *
    * Created by Henrik Ekblad <henrik.ekblad@mysensors.org>
    * Copyright (C) 2013-2015 Sensnology AB
    * Full contributor list: https://github.com/mysensors/Arduino/graphs/contributors
    *
    * Documentation: http://www.mysensors.org
    * Support Forum: http://forum.mysensors.org
    *
    * This program is free software; you can redistribute it and/or
    * modify it under the terms of the GNU General Public License
    * version 2 as published by the Free Software Foundation.
    *
    *******************************
    *
    * REVISION HISTORY
    * Version 1.0 - idefix
    * 
    * DESCRIPTION
    * Arduino BH1750FVI Light sensor
    * communicate using I2C Protocol
    * this library enable 2 slave device addresses
    * Main address  0x23
    * secondary address 0x5C
    * connect the sensor as follows :
    *
    *   VCC  >>> 5V
    *   Gnd  >>> Gnd
    *   ADDR >>> NC or GND  
    *   SCL  >>> A5
    *   SDA  >>> A4
    * http://www.mysensors.org/build/light
    */
    
    #include <SPI.h>
    #include <MySensor.h>  
    #include <BH1750.h>
    #include <Wire.h> 
    #include <Adafruit_BMP085.h>
    
    #define CHILD_ID_LIGHT 0
    #define CHILD_ID_BARO 1
    unsigned long SLEEP_TIME = 30000; // Sleep time between reads (in milliseconds)
    
    const float ALTITUDE = 4;
    
    BH1750 lightSensor;
    MySensor gw;
    
    // V_LIGHT_LEVEL should only be used for uncalibrated light level 0-100%.
    // If your controller supports the new V_LEVEL variable, use this instead for
    // transmitting LUX light level.
    MyMessage msg(CHILD_ID_LIGHT, V_LIGHT_LEVEL);
    // MyMessage msg(CHILD_ID_LIGHT, V_LEVEL);  
    uint16_t lastlux;
    
    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)
    };
    Adafruit_BMP085 bmp = Adafruit_BMP085();      // Digital Pressure Sensor 
    float lastPressure = -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;
    boolean metric;
    MyMessage pressureMsg(CHILD_ID_BARO, V_PRESSURE);
    MyMessage forecastMsg(CHILD_ID_BARO, V_FORECAST);
    
    void setup()  
    { 
     gw.begin();
    
     // Send the sketch version information to the gateway and Controller
     gw.sendSketchInfo("Light + Pressure", "1.0");
     if (!bmp.begin()) 
     {
       Serial.println("Could not find a valid BMP085 sensor, check wiring!");
       while (1) {}
     }
    
     // Register all sensors to gateway (they will be created as child devices)
     gw.present(CHILD_ID_LIGHT, S_LIGHT_LEVEL);
     gw.present(CHILD_ID_BARO, S_BARO);
    
     metric = gw.getConfig().isMetric;
     
     lightSensor.begin();
    }
    
    void loop()      
    {     
     uint16_t lux = lightSensor.readLightLevel();// Get Lux value
     Serial.println(lux);
     if (lux != lastlux) {
         gw.send(msg.set(lux));
         lastlux = lux;
     }
    
     float pressure = bmp.readSealevelPressure(ALTITUDE) / 100.0;
    
     
     int forecast = sample(pressure);
    
     Serial.print("Pressure = ");
     Serial.print(pressure);
     Serial.println(" hPa");
     Serial.print("Forecast = ");
     Serial.println(weather[forecast]);
    
    
    
     if (pressure != lastPressure) 
     {
       gw.send(pressureMsg.set(pressure, 0));
       lastPressure = pressure;
     }
    
     if (forecast != lastForecast)
     {
       gw.send(forecastMsg.set(weather[forecast]));
       lastForecast = forecast;
     }
     
     gw.sleep(SLEEP_TIME);
    }
    
    float getLastPressureSamplesAverage()
    {
     float lastPressureSamplesAverage = 0;
     for (int i = 0; i < LAST_SAMPLES_COUNT; i++)
     {
       lastPressureSamplesAverage += lastPressureSamples[i];
     }
     lastPressureSamplesAverage /= LAST_SAMPLES_COUNT;
    
     return lastPressureSamplesAverage;
    }
    
    
    
    // Algorithm found here
    // http://www.freescale.com/files/sensors/doc/app_note/AN3914.pdf
    // Pressure in hPa -->  forecast done by calculating kPa/h
    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;
    }
    

    Edit: I'm not using the temperature function and combined both sketches from this site.


  • Mod

    @niek said:

    Is there a way to override the default pin?

    Yes and no. And maybe you don't have to 🙂

    Have you tried connecting both sensors to the same pins? That might work without you having to do anything. If that doesn't work, read on...

    The Adafruit BH1750 and BMP085 libraries do not support configuring which device on the i2c bus to "talk" to. There is an old pull request to add support, but it hasn't been added to the official code. You could download the fork.

    Both sensors communicate using i2c, and it is possible to connect multiple i2c devices to the same i2c bus.

    The two Adafruit libraries use the Wire library underneath. The Wire library handles i2c communication. So if you use the Wire library directly, you can connect both sensors to the same pins and follow the instructions here. Doing that will probably require some programming skills though, since you will need to do the stuff done by Adafruit's libraries manually.

    An alternative might be ut use Soft SPI to use a different set of pins, but I think that would require more work than using the Wire library.


 

429
Online

7.9k
Users

8.8k
Topics

93.8k
Posts