power saving tips

Hi,

Im working on a project where I need to measure two temperatures over time to see the difference between the two.
I am storing this on an SD card once every five mins.
The idea is to leave the device outside recording for up to 72 hours.
I have an uno board, with a network shield on it, the network shield being only to give me access to the sd card without having to wire up some dodgy arrangement on a pro mini like I have done in the past, I want this to be a bit more rugged.

I have two lm335 sensors for temp,
The problem is that when running it from a 6v battery the voltage drop on the onboard regulator is quite high, I adjusted for this in code, and then the battery ran out in approx 30 hours, its a 6v 6ah sla battery. I would have expected it to easily last longer.

even though the battery technically lasted 30 hours, the voltage reference changed wildy and caused my reading to be incorrect. although the difference logged between the two sensors still seemed to be logical.
learning from the mistake, and with 30 hours of logged data I adjusted the multiplication factor in the code to bring both sensors as close to equal readings and actual room temp as possible, the nicked the battery bank from a mini solar system I have.

the second battery has a regulated 5v output, this is a 12v 7ah battery it only lasted for 30.5 hours, then the arduino can be seen to be power cycling, I know this as a header is saved to the sd card each time its powered up, along with an increment in a "file number" stored in eeprom that is saved in the header.

so given the fact it has a 5v regulated output, all the data is within the predicted temp ranges, but I have no way to tell the time between the data reads during the "low voltage" so it remains useless to me, although still indicative of a general temp curve, albeit without knowing the time over which the curve takes place.

So I would like to ask if there are any power saving tricks I can emply to make the battery last longer, I think a 7ah 12v sla battery should be enough to give me 48 - 72 hours of data logging on such a simple device, so Im sure that ive messed something up.

can any one give me any pointers?
here is my code :

/*
  SD card datalogger

 This example shows how to log data from three analog sensors
 to an SD card using the SD library.

 The circuit:
 * analog sensors on analog ins 0, 1, and 2
 * SD card attached to SPI bus as follows:
 ** MOSI - pin 11
 ** MISO - pin 12
 ** CLK - pin 13
 ** CS - pin 4

 created  24 Nov 2010
 modified 9 Apr 2012
 by Tom Igoe

 This example code is in the public domain.

 */

#include <SPI.h>
#include <SD.h>
#include <EEPROM.h>
//////////calibration
int outputPin3= A2;
int sensor3=0;

///////////eeprom 
byte fileNumber;
byte newFileNumber=0;
int fileNumberWrite=0;
///////////sd card 
const int chipSelect = 4;
int count=0;
/////////temperature
int outputPin1= 0;
float celsius1=0;
float kelvin1=0;
float sensor1=0;
float millivolts1=0;

int outputPin2= 1;
float celsius2=0;
float kelvin2=0;
float sensor2=0;
float millivolts2=0;

float difference=0;

void setup() {
  //////////read eeprom file number
fileNumber = EEPROM.read(0);
newFileNumber= (fileNumber +1);

EEPROM.write(0, newFileNumber);


  
  // Open serial communications and wait for port to open:
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }


  Serial.print("Initializing SD card...");

  // see if the card is present and can be initialized:
  if (!SD.begin(chipSelect)) {
    Serial.println("Card failed, or not present");
    // don't do anything more:
    return;
  }
  Serial.println("card initialized.");
  Serial.println(newFileNumber);
}

void loop() {
  ///////////delay to adjust reading times
  
  ///////////calibration
 // sensor3 = analogRead(outputPin3);
  ////////////sensor 1
    sensor1 = analogRead(outputPin1);
    //millivolts1= (sensor1/1024.0) * 3900;
   // millivolts= analogRead(outputPin);
    millivolts1 = (sensor1*4700.0)/1024.0;

    kelvin1=millivolts1/10;
    celsius1= kelvin1 - 273.15;
    delay(200);

    /////////sensor 2
     sensor2 = analogRead(outputPin2);
    millivolts2= (sensor2/1024.0) * 4685;
    
    kelvin2=millivolts2/10;
    celsius2= kelvin2 - 273.15;

difference= celsius1 - celsius2;
    
   

  // open the file. note that only one file can be open at a time,
  // so you have to close this one before opening another.
  File dataFile = SD.open("datalog.txt", FILE_WRITE);

  // if the file is available, write to it:
  if (dataFile) {
    digitalWrite(13,HIGH);
    if(fileNumberWrite==0){
      dataFile.print("FIVE MINS : newFileNumber,");
    dataFile.print(newFileNumber);
    dataFile.println("NEGATIVE SHOWS HOTTER PLATE, POSITIVE SHOWS HOTTER GROUND");
    dataFile.print("GROUND TEMP,");
    dataFile.print("PLATE TEMP,");
    dataFile.println("DIFFERENCE,");
    fileNumberWrite=1;
    Serial.println("file number updated");
    }
    //dataFile.println(millivolts);
 dataFile.print(count);
    dataFile.print(",");
    count=count+1;
    //dataFile.print(sensor3);
    //dataFile.print(",");
    dataFile.print(celsius1);
    dataFile.print(",");
     dataFile.print(celsius2);
    dataFile.print(",");
     dataFile.print(difference);
    dataFile.println(",");
    dataFile.close();
    delay(100);
    digitalWrite(13,LOW);
    // print to the serial port too:
    //Serial.println(millivolts);
    Serial.println(celsius1);
   Serial.println(celsius2);
   // Serial.println(difference);
  }
  // if the file isn't open, pop up an error:
  else {
    Serial.println("error opening datalog.txt");
  }
  delay(300000);
}

spruce_m00se:
can any one give me any pointers?

Yes, ignore the code.

You should first measure how much current each of the constituent parts uses first.

How much does the network shield use, how much does the SD card use, etc.

lol

I was hoping someone could give me some pointers to put the arduino to sleep or something instead of using a large delay funciton,

I have measuered the current pulled, it is in the region of 100ma. it spikes at 140 ma when writing to sd. Which annoyingly suggests that I have only gotten half of my "predicted" usage from the battery.

Here is something you can try. Download and install the Low-Power library. Then change your code from

delay(300000);

to

  LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF);
  LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF);
  LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF);
  LowPower.powerDown(SLEEP_4S, ADC_OFF, BOD_OFF);
  LowPower.powerDown(SLEEP_2S, ADC_OFF, BOD_OFF);

See how much that helps. If that's not enough, you will have to look at your choice of hardware. Your pro-mini was a better choice. You need to ask for advice about making that more robust and less dodgy.

$_1 (2).JPG

Here is the definitive guide to power saving techniques: Gammon Forum : Electronics : Microprocessors : Power saving techniques for microprocessors
A Uno with all its power hungry components, regulator, USB interface, LEDs etc. etc. is not an ideal starting point. Better would be the raw ATMEGA328P chip which is the basis of the Uno.

spruce_m00se:
lol

I was hoping someone could give me some pointers to put the arduino to sleep or something instead of using a large delay funciton,

I have measuered the current pulled, it is in the region of 100ma. it spikes at 140 ma when writing to sd. Which annoyingly suggests that I have only gotten half of my "predicted" usage from the battery.

A bare UNO, running from the power connector will consume around 10mA to 20mA. Yes you can put the arduino (processor) to sleep and save maybe half of that, but it seems rather pointless if you have 100mA or more going eleswhere.

So how much does the UNO consume without the network shield plugged in ?

I suspect up to half of that 100mA is the use of an entire Ethernet shield, just to use an SD card. Have you got one of these?
$_1 (2).JPG

Potential savings may also include:

  1. reducing the frequency of temperature measurement.
  2. reducing the frequency of logging (the time during which the SD card is enabled)
  3. reducing the time the network card is enabled (it is apparently used for only sporadic access).

PaulRB:
I suspect up to half of that 100mA is the use of an entire Ethernet shield, just to use an SD card. Have you got one of these?
$_1 (2).JPG

I have one of those for a full size sd card, it was the wiring of that to the pro mini that made it "dodgy"
i suppose that I wanted to avoid as many wire connections as possible as I need to stick this outside and collect it repeatedly, i didnt want wires to snap off etc.

could go get the hot glue gun out if that is going to be the easiest way to save power.

6v6gt:
Potential savings may also include:

  1. reducing the frequency of temperature measurement.
  2. reducing the frequency of logging (the time during which the SD card is enabled)
  3. reducing the time the network card is enabled (it is apparently used for only sporadic access).
  1. two readings are taken and a difference between them is calculated every 5 mins, this is then written to the sd card, and then a delay is called for five mins.
    2)i cant imagine that the card file is open for more than a few ms every five min cycle.
    3)the network part of the shield isnt needed at all, just the SD , can it be turned off with code?

srnet:
A bare UNO, running from the power connector will consume around 10mA to 20mA. Yes you can put the arduino (processor) to sleep and save maybe half of that, but it seems rather pointless if you have 100mA or more going eleswhere.

So how much does the UNO consume without the network shield plugged in ?

ok, so there are three sources of consumption I have found,

the actual battery untit has some LED's on it to show voltage level. there is a consumption of 20ma for the MCU and LED's of the battery unit, taken when removing the positive lead to the battery and putting the DMM inline to the battery.
this 20ma could be reduced for this project, but I am not a super fan of removing the LED's as I want them when it goes back on normal duty in the solar rig I nicked it from.

That 20ma becomes 50ma with the bare arduino uno on the 5v output of the battery system.

with the ethernet shield it goes to 140-150ma, changes between the two, the DMM isnt great.

so yes, the main source of drain is the ethernet shield.
perhaps removing the LEDs from that would help?

spruce_m00se:

  1. two readings are taken and a difference between them is calculated every 5 mins, this is then written to the sd card, and then a delay is called for five mins.
    2)i cant imagine that the card file is open for more than a few ms every five min cycle.
    3)the network part of the shield isnt needed at all, just the SD , can it be turned off with code?

OK. If you are using the SD card reader only for a few mS every 5 minutes and the attached ethernet card is not really used at all, then you should be able to disable the whole thing most of the time. Post a link to your combined ethernet/SD card reader and maybe you get more suggestions here.

6v6gt:
OK. If you are using the SD card reader only for a few mS every 5 minutes and the attached ethernet card is not really used at all, then you should be able to disable the whole thing most of the time. Post a link to your combined ethernet/SD card reader and maybe you get more suggestions here.

http://www.ebay.co.uk/itm/UNO-R3-Board-Ethernet-Shield-W5100-SD-Slot-Expansion-Board-USB-CableFor-Arduino-/272504158643?var=&hash=item3f728379b3:m:m6zFGDnzovAKsQ_IipGNQEg

its one of these, the ethernet isnt needed, so I am thinking maybe lift the input leg to the regulator on the board and see if the sd card still works? if not maybe find a component that can be tombstoned and just lose power to the ethernet controller?

the regulator and ethernet chip are actually running quite hot, so i guess they are the main culprits.

any have any experience with these boards?

PaulRB:
Here is something you can try. Download and install the Low-Power library. Then change your code from

delay(300000);

to

  LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF);

LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF);
  LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF);
  LowPower.powerDown(SLEEP_4S, ADC_OFF, BOD_OFF);
  LowPower.powerDown(SLEEP_2S, ADC_OFF, BOD_OFF);




See how much that helps. If that's not enough, you will have to look at your choice of hardware. Your pro-mini was a better choice. You need to ask for advice about making that more robust and less dodgy.

The difference between :
//delay(299400);
LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF);
LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF);
LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF);
LowPower.powerDown(SLEEP_4S, ADC_OFF, BOD_OFF);
LowPower.powerDown(SLEEP_2S, ADC_OFF, BOD_OFF);

and:
delay(299400);
// LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF);
// LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF);
// LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF);
// LowPower.powerDown(SLEEP_4S, ADC_OFF, BOD_OFF);
// LowPower.powerDown(SLEEP_2S, ADC_OFF, BOD_OFF);

is approx 10ma, which is a good saving to start with, thank you

This schematic looks like it is based on a standard design for a combined W5100 ethernet controller and uSD card slot. https://dlnmh9ip6v2uc.cloudfront.net/datasheets/Dev/Arduino/Shields/PoEthernet-Shield-v11.pdf

You'll see that both the W5100 and uSD card slot require the 3.3V so you can't easily separate these at the regulator.

Arduino pin 10 is the Chip Enable pin for the W5100. Can you explicitly set this LOW (if not already so) in a sketch to see if that reduces the power consumption to a significant degree ?

But judging by the number of similar comments, the best solution may be the one to use a dedicated SD card module.

spruce_m00se:
That 20ma becomes 50ma with the bare arduino uno on the 5v output of the battery system.

with the ethernet shield it goes to 140-150ma, changes between the two, the DMM isnt great.

so yes, the main source of drain is the ethernet shield.
perhaps removing the LEDs from that would help?

Get rid of the Ethernet shield completely, hacking it to save a few mA is probably not worth the effort.

My suggestion(s) would be:

  • Go back to using your Pro Mini and SD card adaptor
  • Solder them to a piece of proto board/strip board/tripad board (my favourite) to make it robust and "non-dodgy". Use female pcb sockets if you later wish to remove the pro-mini or SD card adaptor for re-use. Depending on the headers fitted to the SD card adaptor, you may want to remove/replace them so that the SD Card adaptor can fit snugly on the pcb.
  • Power with 4xAA NiMh directly to the 5V pin of the Pro Mini, bypassing its regulator. In theory this could be over 5V when the cells are freshly charged, but in practice I find that as soon as any current is drawn, the voltage falls to 4.8~5V
  • Add a second 4xAA NiMh in parallel to the first if required to extend battery life.

ive decided that im just going to try and hide the small solar panel that comes with the battery out in the wild while the arduino is data logging, even if I cover most of it, it should sort me out with enough of a power boost during the day to give me a longer logging time window.

I may get out my pro mini in parellel and make that a bit more robust. I would rather lose a pro mini to theives than a whole solar system :slight_smile:

I documented some power saving techniques collected from various sources here. Get rid of as many LEDs as you can, get rid of the on board regulator, power things down that you aren't using with a MOSFET, put the USB controller into reset mode and put the Arduino to sleep for as much time as possible. With all of this, the best I can get is about 6.8mA in standby mode.

I will read up on that for future improvements, thanks,

as it happens, the 30 hours of data logging that I got has given me enough info on temp difference to find the correct time to go back and perform part two of the projects process.

which was successful, so im actually happy and perhaps dont need further temp logging for this project, I will continue to play around though as im sure the power saving tricks I learn along the way will come in handy in the future.

I tried a digital write on pin 10 to "power down" the ethernet and it made no difference. I guess the library powers it down if its not in use anyway? it gets mega hot though .