@Puneit-Thukral I have a similar sensor ( PIR + BMP280 + other stuff). I don't use smartSleep ( Since this code is old, only sleep was available ) so I can't speak about the sleep part. Maybe you could try with regular sleep just to see if brings some diference...
Regarding the BME280 (BMP in my case) , I didn't have to use the Wire.begin() / end(), and I use the same library as yours (Adafruit).
Code is bellow, in case you want to compare yourself.
/**
* 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
* (adopted from 5in1 V2.1)
* Version 3.0 - RV - Shifted to BMP280 sensor, added pressure and water leakage (via ROPE https://www.amazon.com/gp/product/B004FTFQ4W/ref=ppx_od_dt_b_asin_title_s01?ie=UTF8&psc=1 )
*
*
* DESCRIPTION
* BMP280 on std SDA/SDL pins (Temp/Pressure)
* LDR on pin A1: GND ---> 10k ---> A1 <-- LDR <-- Vcc
* PIR on D3 and wakeup via interrupt (in case of PIR trigger)
* Smoke on D2 with interrupt wake up too. ( 4n25 4K7 on buzzer, 2M7 Pullup resistor recommended )
* Water Sensing cable on A2: GND --> 100k --> A2 <-- X--X <-- Vcc
* (https://www.amazon.com/gp/product/B004FTFQ4W/ref=ppx_od_dt_b_asin_title_s01?ie=UTF8&psc=1)
*
* Battery voltage is as battery percentage (Internal message), and optionally as a sensor value (See defines below)
*
*/
// Enable debug prints to serial monitor
#define MY_DEBUG
// Board type
#define DRAGON // PRO_MINI // DRAGON / SENSEBENDER
// Define a static node address, AUTO or 1-255 fixed
#define MY_NODE_ID 25 // AUTO
#define MY_PARENT_NODE_ID AUTO
// Enable and select radio type attached
#define MY_RADIO_RF24 // MY_RADIO_RFM69
// Uncomment the line below, to transmit battery voltage as a normal sensor value
#define BATT_SENSOR 199
#define NAME "8in1 Sensor"
#define RELEASE "3.3"
// Pin definitions for sensors
#define SDA_PIN A5 // Just to document std IC2 interface
#define SCL_PIN A4 // Just to document std IC2 interface
#define LDR_PIN A1 // Analog Light sensor (LDR)
#define WATER_PIN A2 // Analog Water Leak sensor (rope)
#define SMOKE_PIN 2 // Digital Smoke sensor (0/1)
#define PIR_PIN 3 // PIR Sensor (0/1)
#define TRIGGER_PIN 4 // Trigger for HC-SR04 sensor
#define ECHO_PIN 5 // Echo for HC-SR04 sensor
#ifdef DRAGON
// #define SPIFLASH_PIN 8
#define LED_PIN 9
#define TEST_PIN A0
#define MY_RF24_CE_PIN 7
#define MY_RF24_CS_PIN 10
// #define MY_SOFTSPI
// #define MY_SOFT_SPI_SCK_PIN 13
// #define MY_SOFT_SPI_MISO_PIN 12
// #define MY_SOFT_SPI_MOSI_PIN 11
#endif
#ifdef SENSEBENDER
#define SPIFLASH_PIN 8
#define TEST_PIN A0
#define OTA_ENABLE A1
#define LED_PIN A2
#define ATSHA204_PIN 17 // A3
#endif
#ifdef PRO_MINI
#define LED_PIN 8
#endif
// Includes ///////////////////////////////////////////
#include <SPIMemory.h>
#include <SPI.h>
#include <MySensors.h>
//#include <Wire.h>
//#include <EEPROM.h>
//#include <sha204_library.h>
//#include <Adafruit_Sensor.h>
#include <Adafruit_BMP280.h>
/// Sketch parameters SETUP ////////////////////////////
// Child sensor ID's
#define CHILD_ID_TEMP 1
#define CHILD_ID_HUM 2
#define CHILD_ID_PRESS 3
#define CHILD_ID_LIGHT 4
#define CHILD_ID_PIR 5
#define CHILD_ID_SMOKE 6
#define CHILD_ID_WATER 7
#define CHILD_ID_TANK 8
// How many milli seconds should we wait for OTA?
#define OTA_WAIT_PERIOD 500
// How many milli seconds between each measurement
#define MEASURE_INTERVAL 720000 // 12min
// How many wakeups to send battery level
#define BAT_INTERVAL 100 // around 20 hours
// FORCE_TRANSMIT_INTERVAL, this number of times of wakeup, the sensor is forced to report all values to the controller
#define FORCE_TRANSMIT_INTERVAL 10 // around 2 hours
// When MEASURE_INTERVAL is 60000 and FORCE_TRANSMIT_INTERVAL is 30, we force a transmission every 30 minutes.
// Between the forced transmissions a tranmission will only occur if the measured value differs from the previous measurement
// HUMI_TRANSMIT_THRESHOLD tells how much the humidity should have changed since last time it was transmitted. Likewise with
// TEMP_TRANSMIT_THRESHOLD for temperature threshold.
#define HUMI_TRANSMIT_THRESHOLD 5
#define TEMP_TRANSMIT_THRESHOLD 0.5
#define LIGHT_TRANSMIT_THRESHOLD 5
#define PRESS_TRANSMIT_THRESHOLD 50
// Flash memory
#ifdef SPIFLASH_PIN
SPIFlash flash( SPIFLASH_PIN );
#endif
// ATSHA204
#ifdef ATSHA204_PIN
atsha204Class sha204( ATSHA204_PIN );
#endif
//Weather Sensor BMP280 on IC2 (Temp/Hum/Pressure):
#ifdef SDA_PIN and SCL_PIN
Adafruit_BMP280 weather_sensor;
#endif
// Sensor messages
MyMessage msgHum(CHILD_ID_HUM, V_HUM);
MyMessage msgTemp(CHILD_ID_TEMP, V_TEMP);
MyMessage msgPressure(CHILD_ID_PRESS, V_PRESSURE );
MyMessage msgLight(CHILD_ID_LIGHT, V_LIGHT_LEVEL);
MyMessage msgMotion(CHILD_ID_PIR, V_TRIPPED);
MyMessage msgSmoke(CHILD_ID_SMOKE, V_TRIPPED );
MyMessage msgWater(CHILD_ID_WATER, V_TRIPPED );
MyMessage msgDist(CHILD_ID_TANK, V_DISTANCE );
#ifdef BATT_SENSOR
MyMessage msgBatt(BATT_SENSOR, V_VOLTAGE);
#endif
// Global settings
int measureCount;
int sendBattery;
boolean isMetric = true;
boolean highfreq = true;
boolean transmission_occured = false;
// Storage of old measurements
float lastTemperature = -100;
float lastHumidity = -100;
float lastPressure = -100;
long lastBattery = -100;
int lastPir = -1;
int lastLight = -100;
int lastSmoke = -1;
int lastWater = -1;
int lastDist = -1;
/****************************************************
*
* Setup code
*
****************************************************/
void setup() {
#ifdef LED_PIN
pinMode(LED_PIN, OUTPUT);
digitalWrite(LED_PIN, HIGH);
#endif
Serial.begin( MY_BAUD_RATE ); // Default for MySensors is 115200
// Test Mode //////////////////////////
#ifdef TEST_PIN
pinMode(TEST_PIN,INPUT_PULLUP);
if (!digitalRead(TEST_PIN)) testMode();
pinMode(TEST_PIN,INPUT);
#endif
// Pin Mode Setup //////////////////////
#ifdef BAT_PIN
pinMode(BAT_PIN , INPUT); // Ext. Batery meter (1M / 470K resistors)
#endif
#ifdef SMOKE_PIN
pinMode(SMOKE_PIN , INPUT );
#endif
#ifdef PIR_PIN
pinMode(PIR_PIN , INPUT);
#endif
#ifdef TRIGGER_PIN
pinMode(PIR_PIN , OUTPUT);
#endif
#ifdef ECHO_PIN
pinMode(ECHO_PIN , INPUT);
#endif
// Startup Info
Serial.print("Board:");
Serial.print( ARDUINO );
Serial.print( "\t" );
Serial.print( F_CPU / 1000000 );
Serial.print(" Mhz\t");
Serial.print( NAME );
Serial.print(" ");
Serial.println( RELEASE );
Serial.print("Nrf24 CE/CS:");
Serial.print( MY_RF24_CE_PIN);
Serial.print("/");
Serial.print( MY_RF24_CS_PIN );
Serial.print("\tNODE ID:");
Serial.print(hwReadConfig(EEPROM_NODE_ID_ADDRESS));
isMetric = getControllerConfig().isMetric;
Serial.print(F("\tisMetric:")); Serial.println(isMetric);
#ifdef OTA_WAIT_PERIOD
Serial.print("OTA FW Enabled");
#endif
// SPI Flash
#ifdef SPIFLASH_PIN
SPI.begin();
Serial.print(F("\tFlash:"));
if ( flash.begin() ) {
Serial.print( flash.getCapacity() / 8000 , 0 );
Serial.print( "KB");
flash.powerDown();
} else Serial.print( flash.error(VERBOSE) );
#endif
// BMP280 init ////////////////////////
#ifdef SDA_PIN and SCL_PIN
Serial.print(F("\tBMP280:"));
if ( weather_sensor.begin() ) {
Serial.print(F("OK"));
/* Default settings from datasheet. */
weather_sensor.setSampling(Adafruit_BMP280::MODE_NORMAL, /* Operating Mode. */
Adafruit_BMP280::SAMPLING_X1, /* Temp. oversampling */
Adafruit_BMP280::SAMPLING_X1, /* Pressure oversampling */
Adafruit_BMP280::FILTER_OFF ); /* Filtering. */
} else Serial.print(F("ERROR!"));
#endif
// Force 1st transmission of all sensors
measureCount = FORCE_TRANSMIT_INTERVAL;
sendBattery = BAT_INTERVAL;
#ifdef LED_PIN
digitalWrite(LED_PIN, LOW);
#endif
Serial.println(F("\n///////////////////// ONLINE /////////////////////"));
Serial.flush();
}
void presentation() {
sendSketchInfo( NAME , RELEASE);
#ifdef SDA_PIN
present(CHILD_ID_TEMP,S_TEMP);
present(CHILD_ID_HUM,S_HUM);
present(CHILD_ID_PRESS, S_BARO );
#endif
#ifdef LDR_PIN
present(CHILD_ID_LIGHT,S_LIGHT_LEVEL);
#endif
#ifdef PIR_PIN
present(CHILD_ID_PIR,S_MOTION);
#endif
#ifdef SMOKE_PIN
present(CHILD_ID_SMOKE, S_SMOKE);
#endif
#ifdef WATER_PIN
present(CHILD_ID_WATER, S_WATER_LEAK );
#endif
#ifdef TRIGER_PIN
present(CHILD_ID_TANK, S_DISTANCE );
#endif
#ifdef BATT_SENSOR
present(BATT_SENSOR, S_POWER);
#endif
}
/***********************************************
*
* Main loop function
*
***********************************************/
void loop() {
#ifdef LED_PIN
digitalWrite( LED_PIN , HIGH );
#endif
boolean forceTransmit = false;
transmission_occured = false;
if ( ++measureCount > FORCE_TRANSMIT_INTERVAL ) { // force a transmission
forceTransmit = true;
Serial.print(F("[Force Transmission]"));
measureCount = 0;
}
// Light, PIR, Smoke, Water leak
sendLight(forceTransmit);
sendPir(forceTransmit);
sendSmoke(forceTransmit);
sendWater(forceTransmit);
sendWeather(forceTransmit);
sendDistance(forceTransmit);
// Battery level report
if ( ++sendBattery > BAT_INTERVAL ) {
sendBattLevel(true);
sendBattery = 0;
}
// Wait for FW update...
if (transmission_occured) {
wait(OTA_WAIT_PERIOD);
measureCount = 0;
}
#ifdef LED_PIN
digitalWrite( LED_PIN , LOW );
#endif
Serial.println();
// Trick to avoid false triggering on PIR
sleep(1000);
// Sleep until interval or PIR or smoke trigger
if ( lastSmoke == 1 ) // In case of Smoke Alarm, don't sleep too much...
sleep( 45000 );
else if ( lastPir == 1 ) // In case of Motion, stop PIR detecting for 1 complete cycle...
sleep( 0 , CHANGE , MEASURE_INTERVAL );
else
sleep( 0 , CHANGE , 1 , CHANGE, MEASURE_INTERVAL); // Default: Wake up on any PIR and Smoke...
// To avoid false Smoke alarm
wait(100);
// Wake
Serial.print( millis() );
Serial.print("[WAKE]");
}
/*********************************************
*
* Sends Motion status
*
*********************************************/
void sendDistance(bool force)
{
long duration;
int distance;
#ifdef TRIGER_PIN
digitalWrite( TRIGER_PIN, LOW);
delayMicroseconds(2);
digitalWrite( TRIGER_PIN , HIGH);
delayMicroseconds(10);
digitalWrite( TRIGER_PIN , LOW);
// Reads the echoPin, returns the sound wave travel time in microseconds
duration = pulseIn( ECHO_PIN , HIGH);
// Calculating the distance
distance = duration * 0.034 / 2;
if ( distance != lastDist || force ) {
Serial.print(" D:");Serial.print(distance);
send(msgDist.set(distance));
transmission_occured = true;
lastDist = distance;
}
#endif
}
/*********************************************
*
* Sends Motion status
*
*********************************************/
void sendPir(bool force)
{
#ifdef PIR_PIN
int currPir = digitalRead( PIR_PIN );
if ( lastPir != currPir || force ) {
Serial.print(" M:");Serial.print(currPir);
send(msgMotion.set(currPir));
transmission_occured = true;
lastPir = currPir;
}
#endif
}
/*********************************************
*
* Sends Smoke status
*
*********************************************/
void sendSmoke(bool force)
{
#ifdef SMOKE_PIN
int currSmoke = !digitalRead( SMOKE_PIN ); // Low = Smoke Triggered
if ( lastSmoke != currSmoke || force ) {
Serial.print(" S:");Serial.print(currSmoke);
send(msgSmoke.set(currSmoke));
transmission_occured = true;
lastSmoke = currSmoke;
}
#endif
}
/*********************************************
*
* Sends Smoke status
*
*********************************************/
void sendWater(bool force)
{
#ifdef WATER_PIN
int currWater = ( analogRead( WATER_PIN ) > 500 ? 1 : 0 ) ;
//Serial.println( analogRead( WATER_PIN ) );
if ( lastWater != currWater || force ) {
Serial.print(" W:");Serial.print(currWater);
send(msgWater.set(currWater));
transmission_occured = true;
lastWater = currWater;
}
#endif
}
/*********************************************
*
* Sends Light Level based on LDR
*
* Parameters
* - force : Forces transmission of a value (even if it's the same as previous measurement)
*
*********************************************/
void sendLight(bool force)
{
#ifdef LDR_PIN
int currLight = map( analogRead( LDR_PIN ) , 0, 1024 , 0 , 100 );
int diffLight = abs( lastLight - currLight );
if (isnan(diffLight) || diffLight >= LIGHT_TRANSMIT_THRESHOLD || force ) {
Serial.print(" L:");Serial.print(currLight);
send(msgLight.set(currLight));
lastLight = currLight;
transmission_occured = true;
}
#endif
}
/*********************************************
*
* Sends temperature and humidity from Si7021 sensor
*
* Parameters
* - force : Forces transmission of a value (even if it's the same as previous measurement)
*
*********************************************/
void sendWeather(bool force)
{
#ifdef SDA_PIN and SCL_PIN
bool tx = force;
// Sensor reading
float temp = weather_sensor.readTemperature();
//float humd = "N/A" ; // Hum is not supported on BMP280 (But it is in BME280)
float pres = weather_sensor.readPressure();
// Temperature delta
float diffTemp = abs( lastTemperature - temp );
if (diffTemp >= TEMP_TRANSMIT_THRESHOLD) tx = true;
// Humidity delta
//float diffHum = abs( lastHumidity - humd );
//if ( isnan(diffHum) || diffHum >= HUMI_TRANSMIT_THRESHOLD) tx = true;
// Pressure delta
float diffPress = abs( lastPressure - pres );
if (diffPress >= PRESS_TRANSMIT_THRESHOLD) tx = true;
if (tx) {
measureCount = 0;
Serial.print(" T:");Serial.print(temp,1);
//Serial.print(" H:");Serial.print(humd,1);
Serial.print(" P:");Serial.print(pres,1);
send(msgTemp.set(temp,1));
//send(msgHum.set(humd,1));
send(msgPressure.set(pres,1));
lastTemperature = temp;
//lastHumidity = humd;
lastPressure = pres;
transmission_occured = true;
}
// BUG? High consumption ...
//digitalWrite( SDA_PIN , LOW );
//digitalWrite( SCL_PIN , LOW );
#endif
}
/********************************************
*
* Sends battery information (battery percentage)
*
* Parameters
* - force : Forces transmission of a value
*
*******************************************/
void sendBattLevel(bool force)
{
#ifdef BAT_PIN
long vcc = ( analogRead( BAT_PIN ) * 3300.0 / 1024.0 ) * 3.13;
#else
long vcc = readVcc();
#endif
if ( abs( ( vcc - lastBattery ) ) > 100 || force) {
lastBattery = vcc;
#ifdef BATT_SENSOR
float send_voltage = float(vcc)/1000.0f;
send(msgBatt.set(send_voltage,3));
#endif
// Calculate percentage
vcc = vcc - 1900; // subtract 1.9V from vcc, as this is the lowest voltage we will operate at
long percent = vcc / 13.0;
//long percent = constrain( map( vcc, 4000 , 9000, 0, 100 ) , 0 , 100 );
Serial.print(" Batt%:"); Serial.print( percent );
sendBatteryLevel(percent);
transmission_occured = true;
}
}
/*******************************************
*
* Internal battery ADC measuring
*
*******************************************/
long readVcc() {
// Read 1.1V reference against AVcc
// set the reference to Vcc and the measurement to the internal 1.1V reference
#if defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
ADMUX = _BV(REFS0) | _BV(MUX4) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
#elif defined (__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__)
ADMUX = _BV(MUX5) | _BV(MUX0);
#elif defined (__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__)
ADcdMUX = _BV(MUX3) | _BV(MUX2);
#else
ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
#endif
delay(2); // Wait for Vref to settle
ADCSRA |= _BV(ADSC); // Start conversion
while (bit_is_set(ADCSRA,ADSC)); // measuring
uint8_t low = ADCL; // must read ADCL first - it then locks ADCH
uint8_t high = ADCH; // unlocks both
long result = (high<<8) | low;
result = 1125300L / result; // Calculate Vcc (in mV); 1125300 = 1.1*1023*1000
return result; // Vcc in millivolts
}
/****************************************************
*
* Verify all peripherals, and signal via the LED if any problems.
*
****************************************************/
void testMode()
{
uint8_t rx_buffer[SHA204_RSP_SIZE_MAX];
uint8_t ret_code;
boolean fail = false;
#ifdef LED_PIN
digitalWrite(LED_PIN, HIGH); // Turn on LED.
#endif
Serial.println(F(" - TestMode"));
Serial.println(F("Testing peripherals!"));
Serial.flush();
#ifdef SDA_PIN
Serial.print(F(" IC2 weather sensor "));
Serial.flush();
if ( weather_sensor.begin() && weather_sensor.readPressure() &&
weather_sensor.readTemperature() > 900 )
{
Serial.println(F("ok!"));
}
else
{
Serial.println(F("failed!"));
fail = true;
}
Serial.flush();
#endif
#ifdef SPIFLASH_PIN
Serial.print(F("-> Flash : "));
Serial.flush();
if (flash.begin())
{
Serial.println(F("ok!"));
}
else
{
Serial.println(F("failed!"));
fail = true;
}
Serial.flush();
#endif
#ifdef ATSHA204_PIN
Serial.print(F("-> SHA204 : "));
ret_code = sha204.sha204c_wakeup(rx_buffer);
Serial.flush();
if (ret_code != SHA204_SUCCESS)
{
Serial.print(F("Failed to wake device. Response: ")); Serial.println(ret_code, HEX);
}
Serial.flush();
if (ret_code == SHA204_SUCCESS)
{
ret_code = sha204.getSerialNumber(rx_buffer);
if (ret_code != SHA204_SUCCESS)
{
Serial.print(F("Failed to obtain device serial number. Response: ")); Serial.println(ret_code, HEX);
fail = true;
}
else
{
Serial.print(F("Ok (serial : "));
for (int i=0; i<9; i++)
{
if (rx_buffer[i] < 0x10) Serial.print('0'); // Because Serial.print does not 0-pad HEX
Serial.print(rx_buffer[i], HEX);
}
Serial.println(")");
}
}
Serial.flush();
#endif
Serial.println(F("Test finished"));
if ( !fail )
{
Serial.println(F("Selftest ok!"));
while (1) // Blink OK pattern!
{
#ifdef LED_PIN
digitalWrite(LED_PIN, HIGH);
delay(200);
digitalWrite(LED_PIN, LOW);
delay(200);
#endif
}
}
else
{
Serial.println(F("----> Selftest failed!"));
while (1) // Blink FAILED pattern! Rappidly blinking..
{
}
}
}