Go Down

Topic: Is there a safe "latchable" way to cut power to SD cards on a data logger? (Read 13221 times) previous topic - next topic

EKMallon

That's brilliant!

And it means that there are still huge advances to be made with my little logger builds (attached). I have been using the Rocket Scream ultra boards, and powering everything through its on-board MCP1700, but with the Pololu latching power switch (which adds 0.22-0.24mA), DS3231rtc, AT24c32, ADXL345 & SDcard all hanging on, I only get down to 0.54 mA even if I pull up those lines on the SD card. I've been using muve music uSD cards, as they seem like the only way to be sure I get authentic Sandisk on eBay.

When I have some more spare time, I will dig into the component level drains and post them. I suspect there are still much better uSD cards out there for me to find as well.

(P.S. - Yes, the high side of the voltage divider is in the wrong place in the photo. It is usually connected to Vin, but I was moving things around when I took this photo.)

EKMallon

Well fat16lib, you were right....again...

I tested two breadboard models of my loggers to get a handle on the current drawn by each individual component:

The whole logger with a ProMini clone board drew a sleep current of 0.26 mA

with:
Adxl345 accelerometer (50 hz, power save mode)         : 0.058 mA
Sandisk 256mb  uSD card                                                      : 0.061 mA
DS3231 & AT24c32 eeprom combo with (4.7k pullups)  : 0.089 mA

(*I tested a AT24c256 separately, and that eeprom draws about 0.03 mA when not being accessed)

This indicates that the ProMini clone mcu plus MIC5205 regulator needs 0.052mA when the unit is sleeping. I am guessing that about half of that due to losses on the regulator, since it's still providing power to the above components.

I then swapped the MCU for a RocketScream Ultra board, and the logger drew 0.22 mA with the same SD card used above, indicating that its sleep current for the MCP1700 regulator & MCU is around 0.012 mA  (sleeping powerdown mode for all tests using RocketScreams Low power library, ADC & BOD off:  https://github.com/rocketscream/Low-Power )

I then tested that Rocket ultra unit with the Pololu power switch, and sleep current went up to 0.53 mA with the Pololu power switch back in the circuit, indicating that the Pololu power switch is adding 0.32 mA to the sleep current for this design (even after I removed it's power LED). Just to be sure about this I measured the current on the other side of the Pololu switch, and the logger unit was still drawing 0.22mA in total, so it was not noise, or some other weird side effect keeping the SD card from sleeping.

fat16lib

I have started looking at the DS3231.  I am powering it with a digital pin and a battery.  I found that the interrupt to wake the powered down Arduino works on battery power.  I set the digital pin low and input mode before powering down.

Looks like the DS3231 only draws a about a mirco-amp from the battery.  This is a real puzzle.  Why such a huge difference?

I will do more tests after I update an old DS3231 library I wrote a few years ago.  It needs some new features for alarms.  I wrote the library to be able to synchronize the DS3231 with a GPS one second pulse.   I wanted time accurate to a ms, the GSP pulse is good to the microsecond level.
Quote
GPS PPS signals have an accuracy ranging from 100 ns to a few microseconds per second..

EKMallon

I was quite surprised by the numbers for the RTC as well. But I am using a somewhat crude method to measure the currents so for all I know my little sparkfun meter is messing with the numbers a bit.  Also, those cheap RTC boards are not exactly the highest quality, and I have always been a bit dubious whether or not they have genuine chips on them. So multiple factors could be at play. When I get the chance I will look at the chronodot in more detail, as I trust that to be authentic

But on first bounce, I wonder if it is a similar issue to the SD cards? where I have left some pins floating and that is causing excessive current? If your battery power results look simmilar to the coin cell draws, then I will go digging. If all it takes is a couple of pullups to save power I would be happy about that.

I knew about the register setting to force the alarms to continue on battery, but I did not know how long the little coin cell could sustain something like a 5 minute alarm schedule (a typical field logger setting), and I am running from AA's most of the time, so I am not operating down in micro power territory.


fat16lib

Quote
I knew about the register setting to force the alarms to continue on battery, but I did not know how long the little coin cell could sustain something like a 5 minute alarm schedule (a typical field logger setting), and I am running from AA's most of the time, so I am not operating down in micro power territory.


I don't enable the 32kHz output with battery power.  The same settings work for alarms with power from battery or VCC.  I powered the DS3231 with only power on the battery pin and measured the current with a very high end DMM.  The current is less than a micro-amp while waiting for an alarm..  There is a larger current draw when temperature adjustments are done about once a minute.  The datasheet specifies that the average battery current is less than 3.0 mico-amps.  A CR2032 is good for about 200 mAh.  You can draw 3 micro-amps for about seven years.

Accessing the DS3231 with I2C does result in a large current on battery but I2C is not active while waiting for an interrupt.

I just don't understand the difference in current between waiting for an interrupt on battery power, less than 3.0 micro-amps, and with vcc, about 80 micro-amps.  Using vcc takes about 30 times as much current.  Maybe I2C is always active with VCC.  The datasheet says I2C is not active on battery if SDA and SCL are both at zero volts or both are at Vbat volts.

fat16lib

I have put together a low power logger with a Pro Mini, DS3231, and SD that only draws 68 micro-amps while sleeping.

I connected the DS3231 battery pin to 3.3V and left the DS3231 Vcc pin floating.  The alarm interrupt works fine.

I wrote this file using the DS3231 to wake every 10 seconds.  The total current into the 3.3 V regulator for the Pro Mini, SD card and DS3231 was about 68 micro-amps during the 10 second sleep periods.
Quote

2014-10-11 02:28:24
2014-10-11 02:28:34
2014-10-11 02:28:44
2014-10-11 02:28:54
2014-10-11 02:29:04
2014-10-11 02:29:14
2014-10-11 02:29:24
2014-10-11 02:29:34
2014-10-11 02:29:44
2014-10-11 02:29:54
2014-10-11 02:30:04
2014-10-11 02:30:14
2014-10-11 02:30:24
2014-10-11 02:30:34
2014-10-11 02:30:44
2014-10-11 02:30:54
2014-10-11 02:31:04
2014-10-11 02:31:14
2014-10-11 02:31:24
2014-10-11 02:31:34
2014-10-11 02:31:44

Here is the test program:
Code: [Select]

#include <Wire.h>
#include <DsRtc.h>
#include <SdFat.h>
#include <LowPower.h>
SdFat sd;
SdFile file;
DsRtc rtc;
time_t t;
//------------------------------------------------------------------------------
void rtcInterrupt() {
detachInterrupt(0);
}
//------------------------------------------------------------------------------
void sleepUntil(time_t t) {
  if (!rtc.setAlarm1(t) ||
      !rtc.modify(DS3231_CONTROL_ADDRESS, 0XFF,
                  DS3231_CONTROL_INTCN | DS3231_CONTROL_A1IE) ||
      !rtc.modify(DS3231_CONTROL_STATUS_ADDRESS,
                  DS3231_CONTROL_STATUS_A1F, 0)) {
    while(1);
  }
  attachInterrupt(0, rtcInterrupt, FALLING);
  LowPower.powerDown(SLEEP_FOREVER, ADC_OFF, BOD_OFF);
}
//------------------------------------------------------------------------------
void setup() {
  if (!sd.begin(SS) || !file.open("LOWPWR.TXT", O_RDWR | O_CREAT)){
    while(1) {}
  }
  Wire.begin();
  t = rtc.getTime();
  pinMode(2, INPUT);
  digitalWrite(2, 0);
}
//------------------------------------------------------------------------------
void loop() {
  t += 10;
  sleepUntil(t);
  rtc.printDateTime(&file);
  file.println();
  file.sync(); 
}


EKMallon

I tried shutting down 32khz via the register, and it did not change the sleep current, nor did putting a pullup on 32khz line. Just thought that might have been a possible source of current drain.

From the datasheet:

"There are several modes of operation that affect the amount of VBAT current that is drawn. While the device is powered by VBAT and the serial interface is active, active battery current, IBATA (70μA at 3.3v - pg3 of datasheet), is drawn.

When the serial interface is inactive, timekeeping current IBATT (3.0μA at 3.3v), which includes the averaged temperature conversion current, IBATTC, is used.

Temperature conversion current, IBATTC (575μA at 3.3v), is specified since the system must be able to support the periodic higher current pulse and still maintain a valid voltage level. (refer to Application Note 3644: Power Considerations for Accurate Real-Time Clocks for details - for details on extending the time between temperature conversions to save power)."

If I assume that the eeprom is drawing 20μA, then 70μA for the rtc in active mode would explain my high current draw. But the mcu is sleeping in power down mode, so I have to find out why the clock thinks that I2C is still active while the units are sleeping. I did not find anything about I2C being forced active on Vcc in the data sheet...but I think your suggestion is a real possibility.

Or perhaps my ADXL or Eeprom is sending things along the I2C line, even when the mcu is asleep? and this keeps telling the rtc that the serial interface has to stay active?

Because of the way these boards are soldered, I would have to clip a pin on the IC to force the RTC to run on Vbat because I am using the vcc line as a pass through to power the other I2c devices. Will try that experiment and report back later.

EKMallon

Yep, if I simply cut the Vcc line to the RTC forcing it to run on Vbat , the logger draws 70uA less during sleep, but alarm functions and I2C comms still seem to be working.

So the question is, can I do this same thing less dramatically in software...

fat16lib

I connected Vcc to an Arduino pin and set that pin low during sleep.  That way I can use a battery on Vbat.  The DS3231 only draws high current, 78 μA, while the Arduino is awake.

Quote
I tried shutting down 32khz via the register, and it did not change the sleep current, nor did putting a pullup on 32khz line. Just thought that might have been a possible source of current drain.
I checked and the 32kHz doesn't change the DS3231 battery current.

Quote
When the serial interface is inactive, timekeeping current IBATT (3.0μA at 3.3v), which includes the averaged temperature conversion current, IBATTC, is used.
My DS3231 is on a ChronDot board.  It draws 0.85 μA except for the Temperature Conversion Current.  I see the Temperature Conversion Current but can't measure it since it is for a very short time period once every 64 seconds.

The datasheet claims the Temperature Conversion Time is typically 125 ms and draws 575 μA

The average Temperature Conversion Current is (0.125*575)/64 = 1.12 μA so my average DS3231 current is about 2 μA while sleeping.

If I power the DS3231 on Vcc while sleeping, it draws 78.8 μA.  

This is my low power test program. I logs the date, time and one analog pin. It still draws 68 μA while sleeping.

Code: [Select]

#include <Wire.h>
#include <DsRtc.h>
#include <SdFat.h>
#include <LowPower.h>
//
// SD card chip select pin.
const uint8_t SD_CS_PIN = 10;
//
// RTC INT/SQW pin.
const uint8_t RTC_INT_PIN = 2;
//
// RTC primary power pin.
const uint8_t RTC_VCC_PIN = 3;

SdFat sd;

SdFile file;

DsRtc rtc;

// Time to wake from sleep.
time_t t;
//------------------------------------------------------------------------------
#define SERIAL_DEBUG 0
#if SERIAL_DEBUG
#define dbgMsg(msg) {Serial.println(msg); Serial.flush();}
#define error(msg) {Serial.print(msg); while(1);}
#else
#define dbgMsg(msg)
#define error(msg) while(1)
#endif
//------------------------------------------------------------------------------
void rtcInterrupt() {
 detachInterrupt(0);
}
//------------------------------------------------------------------------------
void sleepUntil(time_t t) {
  uint8_t r[2];
  
  // Enable interrupt for alarm one.
  r[0] = DS3231_CONTROL_INTCN | DS3231_CONTROL_A1IE;
  
  // Clear status bits and disable 32 kHz output.
  r[1] = 0;
  if (!rtc.setAlarm1(t) || !rtc.write(DS3231_CONTROL_ADDRESS, r, 2)) {
    error("sleepUntil");
  }
  // RTC to low power battery mode.
  digitalWrite(RTC_VCC_PIN, LOW);
  
  attachInterrupt(0, rtcInterrupt, FALLING);
  LowPower.powerDown(SLEEP_FOREVER, ADC_OFF, BOD_OFF);
  digitalWrite(RTC_VCC_PIN, HIGH);
}
//------------------------------------------------------------------------------
void setup() {
#if SERIAL_DEBUG
  Serial.begin(9600);
#endif

  // Power RTC with digital pin while not sleeping.
  pinMode(RTC_VCC_PIN, OUTPUT);
  digitalWrite(RTC_VCC_PIN, HIGH);
  
  if (!sd.begin(SS) || !file.open("LOWPWR.TXT", O_RDWR | O_CREAT | O_TRUNC)){
    error("SD setup");
  }
  Wire.begin();
  t = rtc.getTime();
  // should check for error
}
//------------------------------------------------------------------------------
void loop() {
  dbgMsg("loop");
  t += 10;
  sleepUntil(t);
  rtc.printDateTime(&file);
  file.write(',');
  file.println(analogRead(1));
  file.sync();  
}


EKMallon

Nick Gammon gives an example of powering a 1307 from a pin at:
http://www.gammon.com.au/forum/?id=11497   (about 1/2 way down)

But he uses a decoupling capacitor and a limit resistor.  Did you get stable operation without those?

I will have to check on my battery current when the power pin is low. I still have an I2C accelerometer running even when the logger is asleep (providing interrupts), and am wondering if that would be generating enough noise to make the RTC think it still has to keep the I2C interface active this might mean that the battery is providing 70uA, instead of the <3uA when Vcc is low

And

Since my loggers are in caves, and the temperature does not change very quickly in that environment, I am setting the temp conversion time to 512sec as per application note 3644

  i2c_writeRegBits(DS3231_ADDRESS,DS3231_STATUS_REG,1,Bit4_MASK);
  i2c_writeRegBits(DS3231_ADDRESS,DS3231_STATUS_REG,1,Bit5_MASK);


fat16lib

Quote
But he uses a decoupling capacitor and a limit resistor.  Did you get stable operation without those?
I get stable operation.  I have not had a problem with noise.  But the datasheet says you should use a 0.1μF to 1.0μF decoupling cap.

Quote
I am setting the temp conversion time to 512sec as per application note 3644
I thought only the DS3232/DS3234 allowed setting the "Temperature Update Time".

The app note is not very clear.  It states:
Quote
The DS3232/DS3234 provide a bit field in a user-programmable register that allows the time between temperature updates to be increased, thus reducing the average current requirement. Both devices provide the C_Rate bit field in the Control/Status Register, which provides four different periods between temperature updates. This register is detailed in Table 1.
My Rev 9; 1/13 version of the DS3231 datasheet just shows zeros for the C_Rate field.

EKMallon

I tested this pin -> VCC idea, and monitored the battery current. No funny power spikes on the battery to 70uA, and as expected, battery current dropped to zero whenever the Arduino was awake, and driving the pin supplying Vcc high.  So no problems for powering the RTC with this method, even with some interference from an always on I2C sensor.

Ooops... I did not catch the DS3232/4 distinction in that app note. Have not seen any problems trying to write the registers though on the DS3231 so its probably just ignoring the write attempts.


pito

When powering the DS3231 via its Vcc the current might be easily 70uA as you power the internal circuitry related to the Vcc / Vbat switching. Not sure they use simple diodes for Vcc/Vbat switching, but rather a mosfet stuff. So powering it via Vcc does not guarantee the ~1-2uA current you would expect.

Go Up