Weather station - power saving problem

Hi all,
I am working on a weather station project and yeasterday I tested the setup for the first time.
The setup consists in:

  • genuino mini (original)
  • 1 DHT22 sensor (temperature and relative humidity)
  • 1 BMP180 sensor by Sparkfun (pressure)
  • 1 DS18B20 sensor (foliage temperature)
  • 1 SEN-13322 sensor by Sparkfun (soil moisture)
  • 1 Photoresistor (ambient light)
  • 1 microSD Breakout by Sparkfun (data storage)
  • 1 battery pack (4 AA rechargeable batteries, 1.2V @ 2000 mAh)

The setup seems to use about 50 mA in Active Mode and 40 mA in Sleep Mode.

I used the LowPower library to power down the Arduino for about 5 min. Measurements are taken for about 2300 ms.

How can I improve the effeciency of my setup?

The sketch I am using is the following:

#include <LowPower.h>
#include "DHT.h"
#include <SFE_BMP180.h>
#include <Wire.h>

// Temperature and Relative humidity sensor
#define DHTPIN 7
#define DHTTYPE DHT22

// Scheda MicroSD
#include <SPI.h>
#include <SdFat.h>

DHT dht(DHTPIN, DHTTYPE);
SFE_BMP180 pressure;

const int sensorPin = A1; // Foliage temperature sensor
int SoilPin = A2;    // Soil sensor PIN
double sensorReading8,sensorReading7; // Pressure (sensorReading7), Temperature (sensorReading8)

String dataString = "";
const uint8_t chipSelect = 8;
const uint32_t interval = 300000; // time intervall in ms
uint32_t elaptime = 0;
SdFat sd;
SdFile myFile;

void setup() {
  //Serial.begin(115200);
  dht.begin();
  pressure.begin();
  sd.begin(chipSelect, SPI_QUARTER_SPEED);
}

void loop() {
  char status;
  delay(2000);
  uint32_t t1 = millis();
  int sensorReading1 = analogRead(0); // Light
  float sensorReading2 = dht.readHumidity(); // Relative Humidity
  double sensorReading3 = dht.readTemperature(); // Temperature (°C)
  float sensorReading4 = dht.computeHeatIndex(float(sensorReading3), sensorReading2, false); // Heat Index (°C)
  float sensorReading5 = analogRead(sensorPin); // Foliage temperature (°C)
  int sensorReading6 = analogRead(SoilPin); // Soil Moisture
  status = pressure.startTemperature();
  delay(status);
  pressure.getTemperature(sensorReading7); // Temperature (pressure sensor)
  status = pressure.startPressure(3);
  delay(status);
  pressure.getPressure(sensorReading8,sensorReading3); // Pressure
  dataString = String(t1) + "," + String(elaptime) + "," + String(sensorReading1) + "," + String(sensorReading2) + "," + String(sensorReading3) + "," + String(sensorReading4) 
  + "," + String(sensorReading5) + "," + String(sensorReading6) + "," + String(sensorReading7) + "," + String(sensorReading8); // convert to CSV
  saveData(); // save to SD card
  //Serial.println(dataString);
  elaptime = millis() - t1;
  delay(50);
  while (elaptime < interval){
    //delay(4000);
    LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF);
    elaptime = elaptime + 8000;
  }
}

void saveData(){
  myFile.open("data.csv", O_WRITE | O_CREAT | O_AT_END);
  myFile.println(dataString);
  myFile.close(); // close the file
}

Thank you in advance!

Are you powering down all your peripheral sensors as well as the arduino in sleep mode?

regards

Allan.

Uhm, I suppose no! I thought that the sleep mode performs an auto-shutdown of all peripheral sensors!

How can I do it? Can you give me an example?

Fraid not!..

You’ll have to use another digital output pin from the arduino to run a power switch - I append a possible schematic.

pretty much any small NPN and PNP devices would be OK.

Put a ‘high’ on the pin to turn external devices ON.

regards

Allan

ard pswitch.pdf (18.4 KB)

.... addendum.

Being a Brit, I'm used to such devices as the BC337 NPN and BC327 PNP. Both are 1A devices - plenty.

And I'd change R1 to about 2k to give plenty of drive to the PNP

No values are very critical.

regards

Allan.

Nick Gammon's tutorials and examples on low power operation are the best available:
Power saving techniques
Battery powered temp and humdity
Solar powered Arduino

I will try in the next few days and I will update the topic with possible progress.

Thank you both!

This is pretty strange.

I performed a test on the DHT22 sensor with an amperometer.

The DHT22 use about 2 mA when reading only. Thus, apparently, there is no need to shutdown the sensor.

Why Nick Gammon did it? Problably, there is something that I do not understand...

Why Nick Gammon did it?

Battery life. His circuits are designed to run for years without battery changes, and 2 mA is WAY too much for that.

jremington:
Battery life. His circuits are designed to run for years without battery changes, and 2 mA is WAY too much for that.

This is pretty clear to me. However, on the basis of my measurement, the DHT22 sensor uses 0 mA when is not reading.

RoMZERO:
This is pretty clear to me. However, on the basis of my measurement, the DHT22 sensor uses 0 mA when is not reading.

Just use a single 800mA transistor to feed the sensors power. It takes 1 pin to do and will mean you can really power down.

Have you measure the idle power draw of each sensor? A quick look at those ones would seem they use very little power in idle...maybe sub 10uA?

How is your photoresistor wired? Is it always pulling current from +ve to GND and you are using it as a voltage divider?

Johnny010:
Just use a single 800mA transistor to feed the sensors power. It takes 1 pin to do and will mean you can really power down.

Have you measure the idle power draw of each sensor? A quick look at those ones would seem they use very little power in idle...maybe sub 10uA?

How is your photoresistor wired? Is it always pulling current from +ve to GND and you are using it as a voltage divider?

Ok, thank you. I will turn off all sensors and I will try again to measure the arduino consumption in sleep mode.

I just measured the idle power draw of the DHT22.

I connected the photoresistor using the following scheme:

Is it responsible for the high power consumption?

Thank you for your help!

Yes.

If you pick a resistor that keeps the power consumption under 20mA, then you can power this from an Arduino output pin. Or put it on the bigger transistor with all the other sensors.

MorganS:
Yes.

If you pick a resistor that keeps the power consumption under 20mA, then you can power this from an Arduino output pin. Or put it on the bigger transistor with all the other sensors.

I use this photocell Mini Photocell - SEN-09088 - SparkFun Electronics

The max power used by the photocell is equal to 100mW. Consequently, the max amperage should be equal to 100 mW / 5v = 20 mA. Is it right? Could I then use it as you suggested?

I am pretty new with Arduino and thus, just to be sure, I have another question.
For example, do I need to move the photocell +5v pin to a digital pin?

What about the soil moisture sensor? Is it affected by the same power consumption problem?

Thank you in advance.

I am pretty new with Arduino and thus, just to be sure, I have another question.
For example, do I need to move the photocell +5v pin to a digital pin?

Yes, that's exactly what I'm suggesting. That way you only switch on the 'power' for a millisecond to take a reading.

The soil moisture sensor is another problem. That sensor you linked is a DC type. It's almost useless for long term monitoring. It will corrode away to nothing in a week if continuously powered. I guess you can make it last longer if you power it intermittently but do you want to recalibrate it each month as it wears out?

MorganS:
Yes, that's exactly what I'm suggesting. That way you only switch on the 'power' for a millisecond to take a reading.

The soil moisture sensor is another problem. That sensor you linked is a DC type. It's almost useless for long term monitoring. It will corrode away to nothing in a week if continuously powered. I guess you can make it last longer if you power it intermittently but do you want to recalibrate it each month as it wears out?

I connected the soil moisture sensor to two iron bars. I toke this idea directly from the gardenbot website. In this way, I should avoid corrosion of the sensor. Obviously, the iron bars must be periodically replaced (this is another problem). However, is the soil moisture sensor always powered on? If yes, how can I turn it off?

Edit: I found the answer here ( Soil Moisture Sensor Hookup Guide - learn.sparkfun.com ).
"This is a good time to mention that if you want to prolong the life of your soil moisture sensor - meaning you don’t want it to corrode as quickly - you can instead hook up VCC to a digital pin and only power it at 5V when you want to take a quick reading, and then turn it off. If you constantly have the soil moisture sensor powered it will corrode over time, and the more water in your soil, the faster that will happen. Another way to protect your soil moisture sensor from corroding is by encasing the probes in gypsum; this allows water from the soil to be detected, but delays corrosion significantly."

Hi all,
I am here again with some additional tests.

I modified my project by adding a BC547B (NPN) transistor as follow:

  • Collecter - Arduino mini GND
  • Base - Arduino mini D11
  • Emitter - Sensors GND

However, I still have high power consumption and also a strange problem.
At the beginning, when the Arduino mini is power on, the consumption is equal to 6-7 mA.
After 8 sec sleep, Arduino mini wakes up, the D11 is set to HIGH, sensors are intialized and then data are acquired and saved. After this first cycle, the power consumption rises to ~40mA and never drops.

The power consumption rises to 40mA also when sensors are not initialized and both data functions (i.e. readdata() and savedata()) are disabled.

I hope someone can help me! Thank you!

Here my code:

#include <LowPower.h>
#include <Wire.h>
#include <SPI.h>

// DHT22 configuration
#include "DHT.h"
#define DHTPIN 7
#define DHTTYPE DHT22
DHT dht(DHTPIN, DHTTYPE);

// MicroSD configuration
#include <SPI.h>
#include <SdFat.h>
const uint8_t chipSelect = 8;
SdFat sd;
SdFile myFile;

//BMP180 (pressure sensor) configuration
#include <SFE_BMP180.h>
SFE_BMP180 pressure;

// Waterproof temperature sensor configuration
int FruitPin = A1; // PIN

// Soil moisture sensor configuration
int SoilPin = A2; // PIN

// Sensors variables
int sR1, sR5; // Light, Soil Moisture
float sR2, sR4; // Relative Humidity, Fruit Temperature (°C)
double sR3, sR6, sR7; // Temperature DHT22 (°C), Pressure, Temperature BMP180 (°C)

// Other variables
char status;
uint32_t timer1, timer2, pause;
String dataString = "";
const int sleepTimes = 1; // 1 sleepTime = 8000 ms
int counter = 0;
int POWER = 11; // Power On/Off PIN

void setup() {
  //Serial.begin(115200);
  pinMode(POWER, OUTPUT);
  digitalWrite (POWER, LOW);
}

void loop() {
  //sleep for 8 seconds
  //delay(8000);
  LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF);

  // count number of sleeps
  counter++;

  if (counter >= sleepTimes){
    powerOn();
    pause = counter * 8000;
    timer1 = millis();
    readData(); // read data from sensors
    timer2 = millis();
    saveData(); // save to SD card
    //Serial.println(dataString);
    powerOff();
    counter = 0;
  }
}

// Data saving
void saveData(){
  sd.begin(chipSelect, SPI_HALF_SPEED);
  SPI.begin();
  dataString = String(pause) + "," + String(timer1) + "," + String(timer2) + "," + String(sR1) 
  + "," + String(sR2) + "," + String(sR3) + "," + String(sR4) + "," + String(sR5) + "," + String(sR6) + "," + String(sR7); // convert to CSV
  myFile.open("data.csv", O_WRITE | O_CREAT | O_AT_END);
  myFile.println(dataString);
  myFile.sync();
  myFile.close(); // close the file
  delay(100);
  SPI.end();
} // end of data saving

// Modules power ON
void powerOn(){
  digitalWrite (POWER, HIGH);  // turn power ON
  delay (10); // time to power up    
}  // end of powerOn

// Modules power OFF
void powerOff(){
  delay(10); // pause before power down
  //digitalWrite (POWER, LOW);  // turn power OFF 
  for (byte pin = 0; pin < 14; pin++){
    pinMode (pin, OUTPUT);  
    digitalWrite (pin, LOW);
    }
  //delay(10); // time to power down
}  // end of powerOff

// Data reading
void readData(){
  dht.begin();
  pressure.begin();
  delay(2000);
  sR1 = analogRead(0); // Light
  sR2 = dht.readHumidity(); // Relative Humidity
  sR3 = dht.readTemperature(); // Temperature (°C)
  sR4 = analogRead(FruitPin); // Fruit temperature (°C)
  sR5 = analogRead(SoilPin); // Soil Moisture
  status = pressure.startTemperature();
  delay(status);
  pressure.getTemperature(sR6); // Temperature (pressure sensor)
  status = pressure.startPressure(3);
  delay(status);
  pressure.getPressure(sR7, sR3); // Pressure
}

You need a resistor in the base of the BD745 - suggest 470 ohms.

regards

Allan.

RoMZERO:
I modified my project by adding a BD745 (NPN) transistor as follow:

  • Collecter - Arduino mini GND
  • Base - Arduino mini D11
  • Emitter - Sensors GND

You need to swap emitter and collector for a NPN transistor, that one is good for a PNP.

Ciao, Ale.

allanhurst:
You need a resistor in the base of the BD745 - suggest 470 ohms.

regards

Allan.

I am really sorry, there was a mistake: it is a BC547B transistor (an Arduino starter kit transistor).

ilguargua:
You need to swap emitter and collector for a NPN transistor, that one is good for a PNP.

Ciao, Ale.

I tried to add the 470 ohme resistor and also to swap emitter and collector, but the result was the same.

I am pretty confused!