I try to build a data logger with SD card for saving sensor data. I need to reduce the power consumption as soon as the circuit is going to sleep. The problem is the power consumption of the SD card module of about 3mA. I read a lot about saving power and many do switch of the power to the SD card module with re-initializing the card when waking up. I can't achieve that. As soon as the SD card module is switched of only error messages are thrown. Can anybody give me a hint to put me on the right track? How do I re-initialize the SD card module right?
Everything works fine until the first wake up. Than the code error message "Card failed, or not present" is thrown and the loop will start again without writing to SD card.
Here is what I have so far:
// DHT sensor library
#include "DHT.h"
// SD card library
#include <SD.h>
// for sleep modes
#include <avr/interrupt.h>
#include <avr/power.h>
#include <avr/sleep.h>
#define DHTPIN 9
#define DHTTYPE DHT22 //DHT11, DHT21, DHT22
DHT dht(DHTPIN, DHTTYPE);
// make sure that the default chip select pin is set
const int chipSelect = 4;
int counter = 0;
int sdPower = 8;
volatile int sleepcounter = 0; // count sleep cycles
void setup() {
pinMode(sdPower, OUTPUT);
// output, even if you don't use it to ensure proper SD library working:
pinMode(10, OUTPUT);
digitalWrite(sdPower, LOW);
watchdogOn(); // switch on Watchdog timer
ADCSRA = ADCSRA & B01111111; // switch off ADC, ADEN bit7 zu 0
ACSR = B10000000; // switch off analog Comparator, ACD bit7 to 1
DIDR0 = DIDR0 | B00111111; // switch off digital input buffer, analog input pins 0-5 to 1
dht.begin();
}
// -------------------------------------- LOOP ---------------------------------
void loop() {
Serial.begin(9600);
// ------------------------- initialize SD card -------------------------
digitalWrite(sdPower, HIGH);
Serial.println("Start of recording");
delay(500);
// see if the card is present and can be initialized:
if (!SD.begin(chipSelect)) {
Serial.println("Card failed, or not present");
delay(100);
// don't do anything more:
return;
}
Serial.println("card initialized.");
// --------------------------------------------------------------------------
float humidity = dht.readHumidity(); //measure humidity
float temp = dht.readTemperature(); //measure temp
// make a string for assembling the data to log:
String dataString = "";
// ------------------------- read sensor and store in string -----------------------------
// check for valid number, throw error for NaN (not a number)
if (isnan(temp) || isnan(humidity)) {
Serial.println("no read for DHT22");
}
else {
dataString += "MP-";
dataString += String(counter);
dataString += ",";
dataString += String(temp);
dataString += ",";
dataString += String(humidity);
// ------------------------- open SD card and write values -----------------------------
// open the file. note that only one file can be open at a time,
// so you have to close this one before opening another.
delay(1000);
File dataFile = SD.open("datalog.txt", FILE_WRITE);
// if the file is available, write to it:
if (dataFile) {
dataFile.println(dataString);
dataFile.close(); //dataFile.sync() doesn't change something
delay(500);
// print to the serial port too:
Serial.println(dataString);
delay(500);
counter = counter + 1;
}
// if the file isn't open, pop up an error:
else {
Serial.println("error opening datalog.txt");
}
//-------------------------------------- sleep mode activation ----------------------------
// Stay awake for 0.5 second, then sleep.
delay(500);
digitalWrite(sdPower, LOW);
delay(500);
pwrDown(5); // go to sleep for (x) sec.
}
}
// some methods for sleep mode are not shown
The often used
SD.h
library is not able to manage powered down SD card modules. After the power is taken away the code will throw an error. The card can't get re-initialized.I used the
SdFat.h
instead and it works just perfect. SD cards draw a lot of current. To switch the SD card module a MOSFet is recommended.