Power calculation for long term use of Arduino.

Hello everyone,

I am trying to make a concrete crack detection system (thanks to all the feedback from arduino experts in this forum). I am not quiet familiar with battery and power consumption. I would appreciate if somebody could guide me in selecting appropriate battery.

My project:
In total I have sixteen arduinos. Each arduino has following:

SHT75 RH-sensors (Datasheet) in three digital pins.
Five potentiometers* in ANALOG pins. All the potentiometer reading is set to max value (ie. 1023) till the circuit breaks down when the reading will be 0.
[These analog pins reading are what i’m using as concrete crack detection system. One pin of power supply (for instance, 5V pin) is connected to 5 feet 30 AWG Kanthal wire. This 5 feet long wire is epoxied to the surface of concrete. When this wire cracks due to crack in concrete, the analog reading will change from 1024 to 0. All I need is the time at which the value changes.]

I’m using Adafruit data logging shield with Sandisk SD card to store the data. Sensors will record RH, and analog reading every 15 minutes. These values will be stored in SD card, in addition to date and time as a .txt file.
In future, my plan is to add a Xigbee module to send the data wirelessly from these arduinos to a master Raspberry Pi.

The system will be deployed in a site without power source, so a battery should be able to support it. I would appreciate if anyone could guide me in selecting battery. From what I have learnt online so far is, I have to figure out how much mA current is drawn by my arduino. Based on the mA I measure, I need to buy a battery with certain mAh.
Hours that my arduino will last = (mAh of battery / mA of my arduino system)

DOUBTS:

  • How do I compute the mA consumed by my Arduino? I read that I should make a multimeter a part of system and measure it. With my arduino and shield, how do I measure that?
  • My another doubt is in selection of potentiometer such that my power consumption is reduced. So, each potentiometer is connected to analog pins from A0 to A4 (and to gnu and 5V). Which potentiometer is good to reduce current consumption of the system? 10K, 50K, 100K, 500K as all I need to know is the time when the analog reading drops from 1023 to 0? Some noise can be alright (even change of value as much as 100 or 200 is alright.
  • Do i need to only focus on mAh of battery? What other parameter do I need to consider? Or is it as simple as getting a bunch of 9v batteries with very high mAh?
  • For the batteries, to last about 1 or 2 months (or even more — longer the better), can I connect a bunch of batteries (for instance - 9V batteries) in parallel and connect to arduino ?
  • Is there any feature in arduino (such as shutting down the system or putting it in sleep mode) to reduce the power consumption?
  • What type of battery will be suitable for long term deployment? Also, if solar system is used, how would I determine the power of panel.

Please let me know if I’m not clear in explaining my situation. I would really appreciate if someone can help me. This is a wonderful forum and I am being really inspired to use arduino in my project after getting the feedback about the project. I hope to get good suggestions again.

Thank you very much.
S

PS: Does anyone know any receptacles that can be used with SHT75? I did not find a suitable receptacle for it. I want to solder and use shrink tube on the spliced part before embedding the RH gage inside concrete.

How do I compute the mA consumed by my Arduino? I read that I should make a multimeter a part of system and measure it. With my arduino and shield, how do I measure that?

Get a regular multimeter, set it to read current, stick it in series with the battery (or power supply), and take the reading.

My another doubt is in selection of potentiometer such that my power consumption is reduced. So, each potentiometer is connected to analog pins from A0 to A4 (and to gnu and 5V). Which potentiometer is good to reduce current consumption of the system? 10K, 50K, 100K, 500K as all I need to know is the time when the analog reading drops from 1023 to 0? Some noise can be alright (even change of value as much as 100 or 200 is alright.

Current is inversely proportional to resistance (Ohm's Law). A 10K pot will consume 50 times the current of a 500K pot. Essentially no current flows into the Arduino's input pin. Higher resistance will pick-up more noise, but a capacitor can filter it (and the capacitor won't consume any current once it's charged).

Do i need to only focus on mAh of battery? What other parameter do I need to consider?

That's it. Higher voltage will help too, but you'll be wasting energy if you're using a linear regulator. For example, a 9V battery can go down to about 6V and the 5V circuits will still work. A 12V battery can also go down to 6V (past it's mAh rating) and the 5V circuits will still work.

can I connect a bunch of batteries (for instance - 9V batteries) in parallel and connect to arduino ?

Usually not a good design because all of the battery voltages will be slightly different and you can get into a situation where some batteries are trying to charge the others.

There are some strange statements in post#0
Maybe I’m missing something.
Why do you need pots to sense a broken wire.
Why analogue inputs to detect that (0 or 1023).
Digital inputs with internal pullup resistors enabled can do all of that.

It seems OP just needs low power 8Mhz arduinos, supplied from a single cell LiPo battery.
Maybe a 8Mhz Pro-Mini (20 inputs) with RTC module. And lots of sleep in the code.
A single LiPo is also easier to charge (solar).
Leo…

Thank you DVDdoug and WaWa.

I’ve attached the schematic of my arduino connection. Three SHT57 is connected.
I changed the reading from Analog (using potentiometer) to just digital input (like what WaWa suggested) and connected it to 10K resistor to minimize current flow.

I’m trying to implement sleep codes to take the arduino to power saving mode.
I tried the low power library (link)
Using that library, I modified the code as following:

#include "LowPower.h"


void setup()
{
  Serial.begin(9600);
  Serial.println ("Initializing");       
  pinMode (13, OUTPUT); 
}

int i = 0;
void loop() {   

 if(i > 5) {
digitalWrite(13,HIGH);
Serial.print ("Measuring");
 
// DO ALL MEASUREMENTS for crack and RH here

 i = 0;
Serial.println ("Sleeping"); 

digitalWrite(13,LOW);
 
 }

    else {
        i++;
    // Enter power down state for 8 s with ADC and BOD module disabled
LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF);  
 }
  

}

I thought this code would do measurement every 40 seconds, take a reading and sleep. However, it has a few problems. The first printing in the screen (which is by void setup ) is in 40 seconds.
This would still be alright for my case, as i will miss the first reading and then start the reading. I would appreciate if someone can tell a solution to this problem.

Has anyone used this Low power library before?

How is it different from watchdog timer (like this post)? If this library works as watchdog timer, this library is very easy to implement ( at least for a person like me who has very less knowledge of programming and electronics).

I used a 9V battery and could only do the reading for about 10 hours. Can I use powerbank (like this) to power the system instead?

My site is 25 miles away and it is not convenient to go and change the battery everyday.

PS: Sorry if these are very basic questions. But I’m a person from a different field and want to learn and implement these things. I would really appreciate the help.

Thanks,
S

Seems like ATtiny chips can support these SHT sensors.

As far as "detecting concrete breaks", a parallel to serial IC will give a simple "still intact" and "broken" response on one pin. You could get a 16bit shift register and monitor 16 wires on one ATtiny85.

Id then use on another pin a 433Mhz Tx to send the data to a central arduino that would store the data.

Connect the break wire between a digital pin and GROUND.

NO resistors.

In pinMode, enable the inbuild 20k pullup resistors with: pinMode(wireOne, INPUT_PULLUP);

The LOGIC is now reversed, so adjust your code. LOW == not broken, HIGH == broken.
Breakwires now also don't carry the supply (safer).

Analogue inputs can also be used as digital inputs.
Leo..

Thanks Johnny and Wawa.

Wawa, I tried with no resistors and internal pullup. It helped me and consumes slightly higher (not high enough to create problem in the project at least ) than with resistor. Thank you very much.

I am really having a problem connecting the SHT75 gauges. No matter what I do, temperature is always shown -40.

Can anyone help please. I would really help any assistance. Thanks.

Sachindra:
Wawa, I tried with no resistors and internal pullup. It helped me and consumes slightly higher (not high enough to create problem in the project at least ) than with resistor. Thank you very much.

??
Should be LESS.
If you replace 10k external resistors with 20k (20k-50K) internal resistors, you drop ~0.5mA per input.

Sachindra:
I am really having a problem connecting the SHT75 gauges. No matter what I do, temperature is always shown -40.

Can anyone help please. I would really help any assistance. Thanks.

Post the full code you have now.
And a picture/wiring diagram.
Leo…

#include <Arduino.h>
 
#include <Sensirion.h>
 
 
const uint8_t dataPin1 =  9;              // SHT serial data 1
const uint8_t dataPin2=  10;              // SHT serial data 2
const uint8_t dataPin3 =  11;              // SHT serial data 3
const uint8_t sclkPin =  12;              // SHT serial clock
const uint8_t ledPin  = 13;              // Arduino built-in LED
const uint32_t TRHSTEP   = 5000UL;       // Sensor query period
const uint32_t BLINKSTEP =  250UL;       // LED blink period
 
Sensirion sht1 = Sensirion(dataPin1, sclkPin);
Sensirion sht2 = Sensirion(dataPin2, sclkPin);
Sensirion sht3 = Sensirion(dataPin3, sclkPin);
 
uint16_t rawData;
float temperature1;
float humidity1;
float dewpoint1;
float temperature2;
float humidity2;
float dewpoint2;
float temperature3;
float humidity3;
float dewpoint3;
 
byte ledState = 0;
byte measActive = false;
byte measType = TEMP;
 
unsigned long trhMillis = 0;             // Time interval tracking
unsigned long blinkMillis = 0;
 
void setup() {
    Serial.begin(9600);
 
    pinMode(ledPin, OUTPUT);
    delay(15);                           // Wait >= 11 ms before first cmd
    // Demonstrate blocking calls
    sht1.measTemp(&rawData);              // sht.meas(TEMP, &rawData, BLOCK)
    temperature1 = sht1.calcTemp(rawData);
    sht1.measHumi(&rawData);              // sht.meas(HUMI, &rawData, BLOCK)
    humidity1 = sht1.calcHumi(rawData, temperature1);
    dewpoint1 = sht1.calcDewpoint(humidity1, temperature1);

//SECOND
    sht2.measTemp(&rawData);              // sht.meas(TEMP, &rawData, BLOCK)
    temperature2 = sht2.calcTemp(rawData);
    sht2.measHumi(&rawData);              // sht.meas(HUMI, &rawData, BLOCK)
    humidity2 = sht2.calcHumi(rawData, temperature2);
    dewpoint2 = sht2.calcDewpoint(humidity2, temperature2);

//THIRD
    sht3.measTemp(&rawData);              // sht.meas(TEMP, &rawData, BLOCK)
    temperature3 = sht3.calcTemp(rawData);
    sht3.measHumi(&rawData);              // sht.meas(HUMI, &rawData, BLOCK)
    humidity3 = sht3.calcHumi(rawData, temperature3);
    dewpoint3 = sht3.calcDewpoint(humidity3, temperature3);
    logData();


    
}
 
void loop() {
    unsigned long curMillis = millis();          // Get current time
    // Rapidly blink LED.  Blocking calls take too long to allow this.
    if (curMillis - blinkMillis >= BLINKSTEP) {  // Time to toggle the LED state?
        ledState ^= 1;
        digitalWrite(ledPin, ledState);
        blinkMillis = curMillis;
    }
 
    // Demonstrate non-blocking calls
    if (curMillis - trhMillis >= TRHSTEP) {      // Time for new measurements?
        measActive = true;
        measType = TEMP;
        sht1.meas(TEMP, &rawData, NONBLOCK);      // Start temp measurement
        trhMillis = curMillis;
    }

    //FIRST
    
    if (measActive && sht1.measRdy() ) {           // Note: no error checking
        if (measType == TEMP) {                  // Process temp or humi?
            measType = HUMI;
            temperature1 = sht1.calcTemp(rawData); // Convert raw sensor data
            sht1.meas(HUMI, &rawData, NONBLOCK);  // Start humidity measurement
        }
        else {
            measActive = false;
            humidity1 = sht1.calcHumi(rawData, temperature1); // Convert raw sensor data
            dewpoint1 = sht1.calcDewpoint(humidity1, temperature1);
            logData();
        }
    }

 // SECOND

     if (measActive && sht2.measRdy() ) {           // Note: no error checking
        if (measType == TEMP) {                  // Process temp or humi?
            measType = HUMI;
            temperature2 = sht2.calcTemp(rawData); // Convert raw sensor data
            sht1.meas(HUMI, &rawData, NONBLOCK);  // Start humidity measurement
        }
        else {
            measActive = false;
            humidity2 = sht2.calcHumi(rawData, temperature2); // Convert raw sensor data
            dewpoint2 = sht2.calcDewpoint(humidity2, temperature2);
            logData();
        }
    }

    //THIRD

        if (measActive && sht3.measRdy() ) {           // Note: no error checking
        if (measType == TEMP) {                  // Process temp or humi?
            measType = HUMI;
            temperature3 = sht3.calcTemp(rawData); // Convert raw sensor data
            sht3.meas(HUMI, &rawData, NONBLOCK);  // Start humidity measurement
        }
        else {
            measActive = false;
            humidity3 = sht3.calcHumi(rawData, temperature3); // Convert raw sensor data
            dewpoint3 = sht3.calcDewpoint(humidity3, temperature3);
            logData();
        }
    }
 }
 
void logData() {
   
 Serial.print("Temperature1 = ");
    Serial.print(temperature1);
 
    Serial.print(" C, Humidity1 = ");
    Serial.print(humidity1);
 
    Serial.print(" %, Dewpoint1 = ");
    Serial.print(dewpoint1);
    Serial.println(" C");

//Second
 Serial.print("Temperature2 = ");
    Serial.print(temperature2);
 
    Serial.print(" C, Humidity2 = ");
    Serial.print(humidity2);
 
    Serial.print(" %, Dewpoint2 = ");
    Serial.print(dewpoint2);
    Serial.println(" C");

//THIRD
    Serial.print("Temperature3 = ");
    Serial.print(temperature3);
 
    Serial.print(" C, Humidity3 = ");
    Serial.print(humidity3);
 
    Serial.print(" %, Dewpoint3 = ");
    Serial.print(dewpoint3);
    Serial.println(" C");

Serial.println("==============================================================================");

        
 
}

This is the code.

I’ve used common GND, VCC, and SCK (pin D12).
Data of three SHT75 goes to D9, D10, and D11.

Between each DATA and VCC there is a resistor of 10K ohm.

Please help me find the solution. I am really getting frustrated by not being able to solve thing. :frowning: :frowning: :frowning:

http://playground.arduino.cc/Code/Sensirion#Example
I suppose you are using the latest libraries, and have tried this with a single sensor before using three sensors.
Leo..

Yes. I have tested with the code using single SHT75. Each of them work properly. But, when I connect three of them, they give weird result.

Either only one gives the value and other two are -40 temp (which means wrong connection) or 100% humidity.

I thought that connecting two first would be better than connecting three. So, I tried to modify the code for two RH gauge. If two RH gauge work properly, I’ll add the third one as well – which is what my project requires.

I’ve tried using one common resistor. Using separate resistor. Nothing is working for me. :frowning:

Schematic for three RH gauge (and common resistor is attached)

Code for two RH gauge:

   // SD Card
 
 
#include <Arduino.h>
 
#include <Sensirion.h>
 
 
const uint8_t dataPin1 =  9;              // SHT serial data
const uint8_t dataPin2 =  10;              // SHT serial data
const uint8_t dataPin3 =  11;              // SHT serial data

const uint8_t sclkPin =  8;              // SHT serial clock
const uint8_t ledPin  = 13;              // Arduino built-in LED
const uint32_t TRHSTEP   = 5000UL;       // Sensor query period
 
Sensirion sht1 = Sensirion(dataPin1, sclkPin);
Sensirion sht2 = Sensirion(dataPin2, sclkPin);
Sensirion sht3 = Sensirion(dataPin3, sclkPin);
 
uint16_t rawData1, rawData2, rawData3;
float temperature1, temperature2, temperature3;
float humidity1, humidity2, humidity3;
float dewpoint1, dewpoint2, dewpoint3;
 
byte measActive = false;
byte measType = TEMP;
 
unsigned long trhMillis = 0;             // Time interval tracking
unsigned long blinkMillis = 0;
 
void setup() {
    Serial.begin(9600);

// Demonstrate blocking calls
   //1
    sht1.measTemp(&rawData1);              // sht.meas(TEMP, &rawData, BLOCK)
    temperature1 = sht1.calcTemp(rawData1);
    sht1.measHumi(&rawData1);              // sht.meas(HUMI, &rawData, BLOCK)
    humidity1 = sht1.calcHumi(rawData1, temperature1);
    dewpoint1 = sht1.calcDewpoint(humidity1, temperature1);
    logData();
    
    //2
    sht2.measTemp(&rawData2);              // sht.meas(TEMP, &rawData, BLOCK)
    temperature2 = sht2.calcTemp(rawData2);
    sht2.measHumi(&rawData2);              // sht.meas(HUMI, &rawData, BLOCK)
    humidity2 = sht2.calcHumi(rawData2, temperature2);
    dewpoint2 = sht2.calcDewpoint(humidity2, temperature2);
    logData();
    
    //3
}
 
void loop() {
    unsigned long curMillis = millis();          // Get current time


    // Demonstrate non-blocking calls
    if (curMillis - trhMillis >= TRHSTEP) {      // Time for new measurements?
        measActive = true;
        measType = TEMP;
        sht1.meas(TEMP, &rawData1, NONBLOCK);      // Start temp measurement
        sht2.meas(TEMP, &rawData2, NONBLOCK);      // Start temp measurement
        sht3.meas(TEMP, &rawData3, NONBLOCK);      // Start temp measurement
        trhMillis = curMillis;
    }
    
    //1
    
    if (measActive && sht1.measRdy()) {           // Note: no error checking
        if (measType == TEMP) {                  // Process temp or humi?
            measType = HUMI;
            temperature1 = sht1.calcTemp(rawData1); // Convert raw sensor data
            sht1.meas(HUMI, &rawData1, NONBLOCK);  // Start humidity measurement
        }
        else {
            measActive = false;
            humidity1 = sht1.calcHumi(rawData1, temperature1); // Convert raw sensor data
            dewpoint1 = sht1.calcDewpoint(humidity1, temperature1);
            logData();
        }
    }



    //2
    
    if (measActive && sht2.measRdy()) {           // Note: no error checking
        if (measType == TEMP) {                  // Process temp or humi?
            measType = HUMI;
            temperature2 = sht2.calcTemp(rawData2); // Convert raw sensor data
            sht2.meas(HUMI, &rawData2, NONBLOCK);  // Start humidity measurement
        }
        else {
            measActive = false;
            humidity2 = sht2.calcHumi(rawData2, temperature2); // Convert raw sensor data
            dewpoint2 = sht2.calcDewpoint(humidity2, temperature2);
            logData();
        }
    }
 
}
 
void logData() {
   
 Serial.print("Temperature (C) = ");
    Serial.print(temperature1);
    Serial.print("          ");
    Serial.println(temperature2);
 
    Serial.print("Humidity(%)= ");
    Serial.print(humidity1);
    Serial.print("          ");
    Serial.println(humidity2);

 
    Serial.print("Dewpoint (C)= ");
    Serial.print(dewpoint1);
    Serial.print("          ");
    Serial.println(dewpoint2);


    Serial.println("------------------ ");
  
}

Please help me.