Trouble sleeping


  • Hero Member

    Hi guys,

    I have a battery-powered moteino with the RFM96 radio and a WeatherShield attached for environment measurements (and for hardware simplicity). I am powering everything from 3 1.5 V AA cells in series.

    The node sleeps for 900000 seconds after reading the various sensor measurements from the board (temperature, humidity, pressure, and battery level). I set the node up last night and it lasted for around seven hours before the battery ran out. Apparently it appears not to be sleeping as it should. What am I doing wrong? Sketch is included below.

    // Enable debug prints to serial monitor
    #define MY_DEBUG
    
    // Enable and select radio type attached
    #define MY_RADIO_RFM69
    #define MY_IS_RFM69HW
    #define MY_RFM69_FREQUENCY   RF69_868MHZ
    
    #include <SPI.h>
    #include <MySensors.h>
    
    #include <DHT.h>
    #include <SFE_BMP180.h>    //get it here: https://github.com/LowPowerLab/SFE_BMP180
    #include <SI7021.h>        //get it here: https://github.com/LowPowerLab/SI7021
    #include <Wire.h>
    
    #define REPORT_INTERVAL 900000
    #define ALTITUDE 220
    
    
    #define CHILD_TEMPERATURE 1
    #define CHILD_HUMIDITY 2
    #define CHILD_PRESSURE 3
    #define CHILD_POWER 4
    
    SI7021 sensor;
    SFE_BMP180 pressure;
    int BATTERY_SENSE_PIN  = A7;  // select the input pin for the battery sense point
    char *weather[] = {"stable", "sunny", "cloudy", "unstable", "thunderstorm", "unknown"};
    int minutes;
    float pressureSamples[180];
    int minuteCount = 0;
    bool firstRound = true;
    float pressureAvg[7];
    float dP_dt;
    
    MyMessage temperatureMessage(CHILD_TEMPERATURE, V_TEMP);
    MyMessage humidityMessage(CHILD_HUMIDITY, V_HUM);
    MyMessage pressureMessage(CHILD_PRESSURE, V_PRESSURE);
    MyMessage forecastMsg(CHILD_PRESSURE, V_FORECAST);
    MyMessage powerMessage(CHILD_POWER, V_VOLTAGE);
    
    bool changed = false;
    float lastPressure = -1;
    float lastTemperature = -1;
    float lastHumidity = -1;
    int lastForecast = -1;
    float lastBattery = -1;
    void setup()
    {
      // use the 1.1 V internal reference
    #if defined(__AVR_ATmega2560__)
      analogReference(INTERNAL1V1);
    #else
      analogReference(INTERNAL);
    #endif
      sensor.begin();
      if (pressure.begin())
        Serial.println("BMP180 init success");
      else
      {
        // Oops, something went wrong, this is usually a connection problem,
        // see the comments at the top of this sketch for the proper connections.
    
        Serial.println("BMP180 init fail\n\n");
        //while(1); // Pause forever.
      }
    }
    
    void presentation()  {
      // Send the sketch version information to the gateway and Controller
      sendSketchInfo("Outdoors environment", "2.0");
    
      // Register all sensors to gateway (they will be created as child devices)
      present(CHILD_TEMPERATURE, S_TEMP);
      delay(250);
      present(CHILD_HUMIDITY, S_HUM);
      delay(250);
      present(CHILD_PRESSURE, S_BARO);
      delay(250);
      present(CHILD_POWER, S_POWER);
    
    }
    
    void loop()
    {
      changed = false;
      float temperature = sensor.getCelsiusHundredths() / 100;
      int humidity = sensor.getHumidityPercent();
      if (lastTemperature != temperature) {
        changed = true;
        lastTemperature = temperature;
      }
      if (lastHumidity != humidity) {
        changed = true;
        lastHumidity = humidity;
      }
    
      pinMode(A3, OUTPUT);
      digitalWrite(A3, LOW);
      lastBattery = analogRead(A7) / 10;
      pinMode(A3, INPUT);
    #ifdef MY_DEBUG
      float batteryV  = lastBattery * 0.003363075 * 10;
      Serial.print("Battery Voltage: ");
      Serial.print(batteryV);
      Serial.println(" V");
    
      Serial.print("Battery percent: ");
      Serial.print(lastBattery);
      Serial.println(" %");
    #endif
    
      char status;
      double T, P, p0, a;
      status = pressure.startTemperature();
      if (status != 0)
      {
        // Wait for the measurement to complete:
        delay(status);
    
        // Retrieve the completed temperature measurement:
        // Note that the measurement is stored in the variable T.
        // Function returns 1 if successful, 0 if failure.
    
        status = pressure.getTemperature(T);
        if (status != 0) {
    
          status = pressure.startPressure(3);
          if (status != 0)
          {
            delay(status);
            status = pressure.getPressure(P, T);
            if (status != 0)
            {
              p0 = pressure.sealevel(P, ALTITUDE); // we're at 1655 meters (Boulder, CO)
              int forecast = 5;//sample(p0);
              if (lastPressure != p0) {
                changed = true;
                lastPressure = p0;
                Serial.print("relative (sea-level) pressure: ");
                Serial.print(p0, 2);
                Serial.print(" mb, ");
              }
              if (lastForecast != forecast) {
                changed = true;
                lastForecast = forecast;
              }
            }
            else Serial.println("error retrieving pressure measurement\n");
          }
          else Serial.println("error starting pressure measurement\n");
        }
        else Serial.println("error retrieving temperature measurement\n");
      }
      else Serial.println("error starting temperature measurement\n");
    
      if (changed) {
        send(temperatureMessage.set(lastTemperature, 1));
        send(pressureMessage.set(lastPressure, 1));
        send(humidityMessage.set(lastHumidity, 1));
        sendBatteryLevel( lastBattery);
        if (lastForecast > -1)
          send(forecastMsg.set(weather[lastForecast]));
      }
      sleep(REPORT_INTERVAL);
    }

  • Mod

    If the node is not sleeping you should get very frequent reports. Do you? If not, sleeping is working. You could add serial print statements before and after the sleep to verify.

    My guess is that the WeatherShield draws power all the time. How is it connected to power? Can it be put to sleep (like the nrf radio)? If not, can you control the power from a pin on the arduino (maybe using a mosfet) and re-initalize the shield after sleeping?


  • Hero Member

    I am not getting frequent reports, so if you are right that means that sleep is working as you suggest. I believe the weather shield is not drawing much power, it is simply a collection of a temperature and humidity sensor, a barometric pressure sensor, and a battery voltage reading circuit which is switched off when not used. More information about this shield is here: http://lowpowerlab.com/blog/2015/01/30/weathershield-is-here/.


  • Hardware Contributor

    Hello

    Seems a bit weird, sure..
    Looking to your sketch seems ok. The only thing which can consume (but I'm a bit tired today!) are:

    • you don't sleep your bmp280, you could save a bit. but that's not the problem here as this sensor (datasheet) does not consume so much..
    • do you use a voltage regulator on your board? I think so if you're using 3xAA as rfm69 is 3.9v max.. So how do you connect your battery voltage to the adc? with a resistor divider? could be that.

    do you have uCurrent or something to measure power consumption? On my side, I get expected power consumption during sleep..

    Update: you beat me! so you cut off your battery reading. arghh! If you have something to measure current, you could check the node power consumption without your weathershield, and a very basic sketch with sleep.


  • Hero Member

    I have a generic multi meter, but I was not able to measure the current with this. I'm not sure why, I put it between the battery and the final connection terminal of the battery compartment.


Log in to reply
 

Suggested Topics

  • 4
  • 9
  • 2
  • 4
  • 20
  • 8

3
Online

11.4k
Users

11.1k
Topics

112.7k
Posts