Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BME280/BMP280 high power comsumption when sleeping #522

Open
bpbastos opened this issue Jun 18, 2020 · 9 comments
Open

BME280/BMP280 high power comsumption when sleeping #522

bpbastos opened this issue Jun 18, 2020 · 9 comments
Labels
Projects

Comments

@bpbastos
Copy link

bpbastos commented Jun 18, 2020

Hi,

I'm getting about 0.50mA when deep sleeping using BME280/BMP280, just arduino and radio gives me 5uA.
I've tried to power the sensor from digital pins 5,6 - PowerManager power(5,6) - but still gets 0.50mA when sleeping.

@user2684
Copy link
Contributor

Weird, would you mind ensuring with a multimeter that while sleeping ping 5 and 6 and both 0v? thanks

@bpbastos
Copy link
Author

bpbastos commented Jun 19, 2020

Weird, would you mind ensuring with a multimeter that while sleeping ping 5 and 6 and both 0v? thanks

Here it's:
WhatsApp Image 2020-06-19 at 15 52 36

Sorry for the bad picture. I'm still geting 3.48v through ping 5,6 even when sleeping.
My Sketch:

/**********************************
 * MySensors node configuration
 */

// General settings
#define SKETCH_NAME "escritorio"
#define SKETCH_VERSION "1.0"
#define MY_NODE_ID 10

// NRF24 radio settings
#define MY_RADIO_NRF24

// Advanced settings
#define MY_BAUD_RATE 9600
#define MY_SPLASH_SCREEN_DISABLED
#define MY_SIGNAL_REPORT_ENABLED


/***********************************
 * NodeManager configuration
 */

#define NODEMANAGER_DEBUG ON
#define NODEMANAGER_INTERRUPTS ON
#define NODEMANAGER_SLEEP ON
#define NODEMANAGER_RECEIVE ON
#define NODEMANAGER_DEBUG_VERBOSE OFF
#define NODEMANAGER_POWER_MANAGER ON
#define NODEMANAGER_CONDITIONAL_REPORT OFF
#define NODEMANAGER_EEPROM OFF
#define NODEMANAGER_TIME OFF
#define NODEMANAGER_RTC OFF
#define NODEMANAGER_SD OFF
#define NODEMANAGER_HOOKING OFF
#define NODEMANAGER_OTA_CONFIGURATION OFF
#define NODEMANAGER_SERIAL_INPUT OFF

// import NodeManager library (a nodeManager object will be then made available)
#include <MySensors_NodeManager.h>

/***********************************
 * Add your sensors
 */
PowerManager power(5,6);
 
#include <sensors/SensorBattery.h>
SensorBattery battery;

#include <sensors/SensorSignal.h>
SensorSignal signal;

//#include <sensors/SensorDoor.h>
//SensorDoor door(3);

#define NODEMANAGER_SENSOR_BOSCH_LITE
#include <sensors/SensorBME280.h>
SensorBME280 bme280;

/***********************************
 * Main Sketch
 */

// before
void before() {
	
  /***********************************
   * Configure your sensors
   */

 // send unit prefixes to controller (i.e. V, A, hPa, %, etc.)
  nodeManager.setSendUnitPrefix(true);
  nodeManager.setSleepMinutes(15);

  // let controller know ambient pressure sensor reports in hPa
  bme280.children.get(3)->setUnitPrefix("hPa");
  bme280.children.get(1)->setFloatPrecision(1);  
  bme280.children.get(2)->setFloatPrecision(1);  
  bme280.setReportIntervalMinutes(15);

  // report battery level every 60 minutes
  battery.setReportIntervalMinutes(60);
  battery.setMinVoltage(1.8);
  battery.setMaxVoltage(3.2);

  // report radio signal level every 10 minutes
  signal.setReportIntervalMinutes(10);

  // only a pseudo SR_TX_RSSI and SR_UPLINK_QUALITY are available for NRF24
  // radio. All other methods return as INVALID.
  signal.setSignalCommand(SR_UPLINK_QUALITY);

  //power all the nodes through dedicated pins
  nodeManager.setPowerManager(power);  
  
  nodeManager.before();
}

// presentation
void presentation() {
  // call NodeManager presentation routine
  nodeManager.presentation();
}

// setup
void setup() {
  // call NodeManager setup routine
  nodeManager.setup();
}

// loop
void loop() {
  // call NodeManager loop routine
  nodeManager.loop();
}

#if NODEMANAGER_RECEIVE == ON
// receive
void receive(const MyMessage &message) {
  // call NodeManager receive routine
  nodeManager.receive(message);
}
#endif

#if NODEMANAGER_TIME == ON
// receiveTime
void receiveTime(unsigned long ts) {
  // call NodeManager receiveTime routine
  nodeManager.receiveTime(ts);
}
#endif

@bpbastos
Copy link
Author

bpbastos commented Jun 21, 2020

Using mysensors library directly with the sketch below, I was able to get 7uA during sleep.

// Enable debug prints to serial monitor
#define MY_DEBUG
//#define MY_REPEATER_FEATURE

// Enable and select radio type attached
#define MY_RADIO_NRF24

#define MY_NODE_ID 100

//#define MY_PARENT_NODE_ID

#include <SPI.h>
#include <MySensors.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h> // I had to change I2C address in library for 0x76 (line 32)
#include <Wire.h>

Adafruit_BME280 bme; // I2C

#define CHILD_ID_HUM 0
#define CHILD_ID_TEMP 1
#define CHILD_ID_PRESS 2

// MyMessage to controler
MyMessage msgT1(CHILD_ID_TEMP, V_TEMP);
MyMessage msgP1(CHILD_ID_PRESS, V_PRESSURE);
MyMessage msgF1(CHILD_ID_PRESS, V_FORECAST);
MyMessage msgH1(CHILD_ID_HUM, V_HUM);

void presentation() {
  // Send the sketch version information to the gateway and Controller
  sendSketchInfo("BME280 Test", "1.0");
  present(CHILD_ID_TEMP, S_TEMP);
  present(CHILD_ID_PRESS, S_BARO);
  present(CHILD_ID_HUM, S_HUM);  
}

void setup() {
  //GND
  pinMode(5,OUTPUT);
  digitalWrite(5, LOW);
  //VCC
  pinMode(6,OUTPUT);
  digitalWrite(6, HIGH);
  //Baudrate
  Serial.begin(9600);
  //BME280 init  
  initBme280();
  //Initial reading
  serverUpdate(); 
}


void loop() { 
  digitalWrite(6, HIGH);
  initBme280();
  serverUpdate();
  //delay(200);
  digitalWrite(6, LOW);
  digitalWrite(SDA, LOW); // disable internal pullup
  digitalWrite(SCL, LOW);  // disable internal pullup  
  sleep(60000); //sleep 1 minute
}


void initBme280() {
  if (!bme.begin(0x76)) {
    Serial.println("Could not find a valid BME280 sensor, check wiring!");
    while (1);
  }
}

// used to read sensor data and send it to controller
void serverUpdate() {
  double T, P, H;
  T=bme.readTemperature();
  P=bme.readPressure()/100.0;
  H=bme.readHumidity();
  delay(10);
  send(msgT1.set(T, 1));
  send(msgP1.set(P, 1));
  send(msgH1.set(H,1));
      
   // unmark for debuging
  Serial.print("T = \t"); Serial.print(T, 1); Serial.print(" C\t");
  Serial.print("P = \t"); Serial.print(P, 1); Serial.print(" mBar\t");
  Serial.print("H = \t"); Serial.print(H, 1); Serial.print(" %\t");
}

The code below seems to be the key for the power consumpition drop:

digitalWrite(SDA, LOW); // disable internal pullup
digitalWrite(SCL, LOW);  // disable internal pullup  

@user2684 user2684 added this to Triage in v1.9 via automation Jun 22, 2020
@user2684
Copy link
Contributor

Ok thanks so seems to be two different issues: first of all when the node is sleeping, PowerManager should bring both the pins to 0V but doesn't look the case for you. Weird cause I have a similar configuration and would have noticed a battery drain. Which NodeManager version are you using?
Second issue is with SDA/SCL, actually your recommendation makes sense since the internal pullup is always on so potentially some current would flow. I'll add this into the code. Thanks!

@bpbastos
Copy link
Author

Thank you! I'm using the latest developement branch - 1.9-dev. I don't now if it's related, but I was trying to do an multi-sensor node, bme/p280 + door sensor.

@bpbastos
Copy link
Author

bpbastos commented Jun 27, 2020

I did some further improvements in power consumption. By default, the Adfruit library uses normal mode that's not indicated for battery-powered nodes. I had changed SensorBME280's onLoop method to use forced mode:

	// define what to do during loop
	void onLoop(Child* child) {
#if defined(NODEMANAGER_SLEEP)	
		setSampling(Adafruit_BME280::MODE_FORCED,
			    Adafruit_BME280::SAMPLING_X8,  // temperature
			    Adafruit_BME280::SAMPLING_X16, // pressure
			    Adafruit_BME280::SAMPLING_X8,  // humidity
			    Adafruit_BME280::FILTER_X16, //filter
			    Adafruit_BME280::STANDBY_MS_0_5);   		
		_bm->takeForcedMeasurement();							
#endif	
		// temperature sensor
		if (child->getType() == V_TEMP) {
			// read the temperature
			float temperature = _bm->readTemperature();
			// convert it
			temperature = nodeManager.celsiusToFahrenheit(temperature);
			// store the value
			child->setValue(temperature);
		}
		// Humidity Sensor
		else if (child->getType() == V_HUM) {
			// read humidity
			float humidity = _bm->readHumidity();
			// store the value
			child->setValue(humidity);
		}
		// Pressure Sensor
		else if (child->getType() == V_PRESSURE) {
			// read pressure
			float pressure = _bm->readPressure() / 100.0F;
			// store the value
			child->setValue(pressure);
		}
#if !defined(NODEMANAGER_SENSOR_BOSCH_LITE)
		// Forecast Sensor
		else if (child->getType() == V_FORECAST) {
			float pressure = _bm->readPressure() / 100.0F;
			child->setValue(_forecast(pressure));
		}
#endif
	};

Now it's using 15uA when sleeping. Probably the code above can be much better coded and placed taking into account my poor c++ skills. Unfortunately, I wasn't able to use PowerManager and the code above, which I believe, would bring more power savings.

@user2684 user2684 moved this from Triage to Bugs in v1.9 Jun 28, 2020
@user2684
Copy link
Contributor

OK thanks, what I need to do for my own reference is:

  1. Check if PowerManager is working as expected
  2. Check if disabling internal pullup for I2C is ok for all the sensors and if so, add it to powerManager
  3. Apply your change in the BME280 code

thanks!

@bpbastos
Copy link
Author

bpbastos commented Jun 29, 2020

Thank you @user2684! Just to let you known, I had made some testing disabling SDA an SCL internal pullup, but this brought the need to re-initiate the sensor every loop. This added some seconds to the sketch making it more power-hungry.

@user2684
Copy link
Contributor

user2684 commented Jul 1, 2020

Thanks for the feedback, yes this is what I was afraid of, that the attached sensors needed to be re-initialized. Ok so I will keep the SDA/SCL on during sleeping as per the original code base. Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
v1.9
  
Bugs
Development

No branches or pull requests

2 participants