BME280 fails when running on battery

Hi all,

I have the CubeCell-1/2AAA Node (HTTC-AB02A) and want to use it as a low power temperature sensor with BME280. This is what I did so far:

  1. Running the 3rd Party BME280 Example: running fine. But this is not using the LowPower library.
  2. Combining the BME280 Example with Low power: Running fine, but only if I do not shut down the Vext after Transmission:
  • When I do not shut down the Vext after transmission, I see that during LowPower Mode, the current is around 1.2 mA on 1/2 AAA battery
  • When I shut down the Vext after transmission on battery, in LowPower mode i see the expected 4-6 uA, but unfortunatly bme readings are not stable. Sometimes the chipId can not be obtained durion bme.init(), or the sensor data are garbage giving always the same numbers, which is 90% of the cases.
  • When I run the example not from battery but from USB, everything works fine, even if I shut down the Vext after transmission.

After reading the forum, I see related topics, but I could not figure out how that solve my problem:



In fact I start the transmission with Wire.begin() and end it with Wire.end() as proposed by @sbmiller / @rsmedia discussed in the linked topics.

Below my source code for better understanding what I’m doing:

#include "Arduino.h"
#include "Seeed_BME280.h"

#include "LoRaWan_APP.h"

#define DEVICE_ID 0x2
#define DEBUG

#define TX_OUTPUT_POWER 4// dBm

#define timetillsleep 100
#define timetillwakeup 180*1000 //3 min. sleep
static TimerEvent_t sleep;
static TimerEvent_t wakeUp;
uint8_t lowpower=1;

#define RF_FREQUENCY                                434000000 // Hz
#define LORA_BANDWIDTH                              0         // [0: 125 kHz,
#define LORA_SPREADING_FACTOR                       9         // [SF7..SF12]
#define LORA_CODINGRATE                             3         // [1: 4/5,
#define LORA_PREAMBLE_LENGTH                        8         // Same for Tx and Rx
#define LORA_SYMBOL_TIMEOUT                         0         // Symbols
#define LORA_FIX_LENGTH_PAYLOAD_ON                  false
#define LORA_IQ_INVERSION_ON                        false
#define RX_TIMEOUT_VALUE                            1000
#define BUFFER_SIZE                                 16 // Define the payload size here

char txpacket[BUFFER_SIZE];
char rxpacket[BUFFER_SIZE];

static RadioEvents_t RadioEvents;

uint8_t humidity;
float temperature;
uint32_t pressure;

void onSleep()
{
  #ifdef DEBUG
    Serial.printf("Going into lowpower mode, %d ms later wake up.\r\n",timetillwakeup);
  #endif
  lowpower=1;
  //timetillwakeup ms later wake up;
  TimerSetValue( &wakeUp, timetillwakeup );
  TimerStart( &wakeUp );
}
void onWakeUp()
{

  #ifdef DEBUG
    Serial.printf("Woke up, %d ms later into lowpower mode.\r\n",timetillsleep);
  #endif
  lowpower=0;

  BME280 bme280;

  digitalWrite(Vext, LOW);
  delay(500);
  Wire.begin();

  #ifdef DEBUG
    Serial.println("BME init");
  #endif
  if(!bme280.init()){
    #ifdef DEBUG
    Serial.println("Device error!");
    #endif
  }
  delay(500);

  temperature=bme280.getTemperature();
  pressure=bme280.getPressure()/100;//hPa
  humidity=bme280.getHumidity();

  #ifdef DEBUG
    Serial.print("Temp: ");
    Serial.print(temperature);
    Serial.print("C");
    Serial.print("Humidity: ");
    Serial.print(humidity);
    Serial.println("%");
  #endif
  Wire.end();//without that, the bme.init() fails in most cases
  // Vext OFF
  digitalWrite(Vext, HIGH);//without that, current consumption in sleep is too high

  txpacket[0]=DEVICE_ID; //uniqe device id

  double dt1, dt2;
  dt2=modf(temperature+100, &dt1);
  
  txpacket[1]=dt1;//saves the non comma values
  txpacket[2]=(uint8_t)(dt2*100);//save temp fraction
  txpacket[3]=humidity;
  txpacket[4]=pressure;

  #ifdef DEBUG
    Serial.printf("\r\nsending packet: "); 
    for (int i=0; i<BUFFER_SIZE; i++)
      Serial.printf("%d ", txpacket[i]);
    Serial.println();
  #endif
  
  Radio.Send( (uint8_t *)txpacket, strlen(txpacket) ); //send the package out 
  delay(200);
  
  Radio.Sleep();
  #ifdef DEBUG
    Serial.printf("Execution time is: %d\n", (endTime-startTime));
  #endif
  TimerSetValue( &sleep, timetillsleep );
  TimerStart( &sleep );
}

void setup() {
  // put your setup code here, to run once:
  #ifdef DEBUG
  Serial.begin(115200);
  #endif
  pinMode(Vext, OUTPUT);

  boardInitMcu( );
  Radio.Init( &RadioEvents );
  Radio.SetChannel( RF_FREQUENCY );
  Radio.SetTxConfig( MODEM_LORA, TX_OUTPUT_POWER, 0, LORA_BANDWIDTH,
                                      LORA_SPREADING_FACTOR, LORA_CODINGRATE,
                                      LORA_PREAMBLE_LENGTH, LORA_FIX_LENGTH_PAYLOAD_ON,
                                      true, 0, 0, LORA_IQ_INVERSION_ON, 3000 ); 
  Radio.Sleep( );
  TimerInit( &sleep, onSleep );
  TimerInit( &wakeUp, onWakeUp );
  onWakeUp();

}

void loop() {
  if(lowpower){
    //note that lowPowerHandler() runs six times before the mcu goes into lowpower mode;
    lowPowerHandler();
  }
  // put your main code here, to run repeatedly:
}

I hope you guys have some hints for me how to trace down/solve the issue.

/mcgreg

I have to admit, it makes no difference if it is running on battery or from USB. Even on USB I see false Temperature readings.

I found the BME280 hard to use and ended up with HDC1080 in my design with the CubeCell. The only hint I had was the CubeCell and HDC1080 would both run well at lower voltages, and the BME280 would only work reliably on a fully powered ESP32. I didn’t chase it too far to see whether that was my test rig or something inherent in the chip. I also ended up putting a Wire.end() call just before my Wire.begin() in the wakeup code. It seems there was something about the Vext shutdown and CubeCell lowPower restart that was messing up the I2C bus. The sequence looks something like: digitalWrite( VEXT, LOW); delay(250); Wire.end(); Wire.begin(); That lets me use lowPowerHandler() and work with a DS3231 and HDC1080 very reliably even when the battery voltage has started to drop off and the local environment is a mess. I do think the 250ms delay is a bit excessive and can likely be trimmed down quite a bit.

Yes, I read about the wire.End(), wire.Begin() sequence, but it didnt helped.
Thank you for sharing your working sensor types, in fact, I’m also testing the si7021 sensor, and already the example for that is ready to use with lowPower mode, so I’ll stick to that if there is no other option.
I like the accuracy/reaction time on temperature/humidity changes of the bme280, I hope there is a solution for this.

I have a CubeCell Dev Board/BME280 combination running since 10 month on one Li-Ion Accu 3.7V 8800mAh.
I used the script from this: https://github.com/Securethingsuk/Heltec_CubeCell/tree/master/LoRaWan_BME280_THP and changed only the IsTxConfirmed to false (TTN Fair Access Policy).
10 month ago it startet with 4.181V. Today, after 10 month, it reports 3.914V.
I’ll see what happens when the voltage drops below 3V in a year;-)

I saw that example already. The BME library is/is based on the Seeed BME280 Library which one I also use.

In fact, the interesting part on BME is this:

  pinMode(Vext, OUTPUT);
  digitalWrite(Vext, LOW);
  delay(500); //delay to let power line settle
  
 if(!bme280.init()){
    Serial.println("Device error!");}
    
    
  //  BME280.begin();
  delay(100); // To let Sensor settle
  float temperature = (bme280.getTemperature()); //In Deg C
  float pressure = (bme280.getPressure()/100); //Presssure in HPa
  float humidity = (bme280.getHumidity()); // in %
  
  
  Wire.end();

  //digitalWrite(Vext, HIGH); // turn off Vext

Where you can see that switching off the Vext in the end is commented out.
I’m surprised about your battery lifetime. I will check the code above against my multimeter.
Thank you.

So far as I know: LoRaWAN.Sleep() cals the LowPower_Handler(). And this function handles the VExt. I measured the power consumption 10 month ago. It was a little above what was promised by HelTec.

I just checked it, @damo, you are completly right about the LoRaWAN.Sleep(). Then it makes it more mysterious why my device is failing - sometimes.