Arduino not saving to SD correctly - arduino

I've built simple project with my daughter that takes two temp readings and writes the to a file on a Micro SD card.
The code is fairly simple (if not a bit messy) and is creating the file, but only ever seems to write the same row of data twice (from the setup()) and then never writes again, although doesn't seem to produce an error.
The code is:
#include <Wire.h> //Required for Realtime Clock
#include "RTClib.h" //Required for Realtime Clock
#include <SPI.h> //Required for SD card reader
#include <SD.h> //Required for SD card reader
#include <dht11.h> //Required for Temp/humidity reader
#define DHTPIN 4 //Pin for temp sensor
#define LEDPIN 7 //Pin for led (status)
#define DHTTYPE DHT11 //define which temp sensor we are using (DHT11)
dht11 DHT11; //Create instance of DHT11 class to read sensor values
File myFile;
String filename;
uint32_t start_min; //Store time the current loop started so we can work out how long we've been running for
RTC_DS3231 RTC; //Create instance of real Time clock class
void setup() {
Serial.begin(9600); //start serial monitor for output
Wire.begin();
//begin the rtc, let us know if it fails
if (! RTC.begin()) {
Serial.println("Couldn't find RTC");
abort();
}
Serial.print("Initializing SD card...");
if (!SD.begin(10)) {
Serial.println("initialization failed!");
while (1);
}
Serial.println("initialization done.");
//set RTC time and date to the time the app was compiled
RTC.adjust(DateTime(__DATE__, __TIME__));
//Get the current RTC time and sore it as a unix time
DateTime now = RTC.now();
start_min = now.unixtime();
//Setup Filename
String filename = String(start_min);
int start = filename.length() - 8;
int end = filename.length();
filename = filename.substring(2,10) + ".csv";
Serial.println(filename);
//Write Header row
myFile = SD.open(filename, FILE_WRITE);
if(myFile) {
myFile.println("timestamp|humidity|temperature1|temperature2");
myFile.flush();
myFile.close();
delay(1000);
}
else {
Serial.println("Error opening file");
}
}
void loop() {
//Get current RTC date and time
DateTime now = RTC.now();
//Convert to unix time
uint32_t _now = now.unixtime();
// work out if x mins have passed
if((_now - start_min) > (4*60)) {
//Turn LED on
digitalWrite(LEDPIN,HIGH);
Serial.print("Looped - ");
Serial.print(now.hour());
Serial.print(":");
Serial.println(now.minute());
int chk = DHT11.read(DHTPIN);
myFile = SD.open(filename, FILE_WRITE);
if(myFile) {
String output = String(now.getTimeStr());
output += "|";
output += String((float)DHT11.humidity,2);
output += "|";
output += String((float)DHT11.temperature, 2);
output += "|";
output += String(RTC.getTemperature());
Serial.println(output);
myFile.println(output);
myFile.close();
Serial.println("Write complete");
}
else {
Serial.println("Error opening file");
}
//reset start time
start_min = now.unixtime();
}
delay(5000);
//Turn LED off
digitalWrite(LEDPIN,0);
//wait 90 secs
delay(5000);
}
I'm using an Arduino Uno, a DHT11 for temp/humidity and a DS3231 RTC (also grabbing temp there to).
Once compiled and uploaded. this is the output:
Sketch uses 16798 bytes (52%) of program storage space. Maximum is 32256 bytes.
Global variables use 1290 bytes (62%) of dynamic memory, leaving 758 bytes for local variables. Maximum is 2048 bytes.
any help appreciate

Related

SPI Problem Arduino Mega with pressure sensor MS5803-05BA

I need your help for a project.
I have actually 2 parallel sensors of the type: MS5803-05BA, which supports I2C and SPI connection. One sensor is on I2C bus and one sensor is on SPI. They are both sending to my Arduino Mega. The I2C works perfect with short cables.
Here the datasheet of the sensor:
https://www.amsys.de/downloads/data/MS5803-05BA-AMSYS-datasheet.pdf
For some informations who wants to do the same with I2C. Here you can find a good code. (You can find the other MS580X typs there too). For the communication between the sensor and the Arduino Mega you need an logic converter like this txs0108e, which can be bought with a break out board (you need pull up resistors on the sensor side!):
https://github.com/millerlp/MS5803_05
But to my problem: I have an sensor distance for about 3-5 meters and the I2C connections doesnt work. Yes I can try to fix the pullup resistors but it doesnt worked for me (I have tried some different lower resistors between 3-10kOhm). Therefore I want to switch to the SPI bus.
I have edit the code from https://github.com/millerlp/MS5803_05, https://github.com/vic320/Arduino-MS5803-14BA and https://arduino.stackexchange.com/questions/13720/teensy-spi-and-pressure-sensor.
The File is added. (You have to put the .h and .cpp files in the folder of the arduino code (.spi).
I have problems with the code from the SPI (ccp and header). There is no right communication. I have checked my cables twice. I couldnt find a problem and the connection with the txs0108e works for parallel I2C sensor. Both sensors are working on I2C.
Here is the main code (arduino .spi) for SPI and I2C parallel:
/_____ I N C L U D E S
#include <stdio.h>
#include <math.h>
#include <SPI.h>
#include <Wire.h>
#include "MS5803_05.h"
#include "MS5803_05_SPI.h"
const int miso_port = 50; //SDI
const int mosi_port = 51; //SDO
const int sck_port = 52; //SLCK
const int slaveSelectPin = 53; // CSB
MS_5803 sensor = MS_5803(512);
MS_5803_SPI sensor_spi = MS_5803_SPI(4096, slaveSelectPin);
void setup()
{
pinMode(miso_port, INPUT);
pinMode(mosi_port, OUTPUT);
pinMode(slaveSelectPin, OUTPUT);
pinMode(sck_port, OUTPUT);
Serial.begin(9600);
//SPI BUS
if (sensor_spi.initializeMS_5803_SPI()) {
Serial.println( "MS5803 SPI CRC check OK." );
}
else {
Serial.println( "MS5803 SPI CRC check FAILED!" );
}
//I2C BUS
delay(1000);
if (sensor.initializeMS_5803()) {
Serial.println( "MS5803 I2C CRC check OK." );
}
else {
Serial.println( "MS5803 I2C CRC check FAILED!" );
}
}
void loop()
{
Serial.println("SPI Sensor first pressure [mbar], than temperature[°C]:");
sensor_spi.readSensor();
// Show pressure
Serial.print("Pressure = ");
Serial.print(sensor_spi.pressure());
Serial.println(" mbar");
// Show temperature
Serial.print("Temperature = ");
Serial.print(sensor_spi.temperature());
Serial.println("C");
////********************************************************
Serial.println("");
Serial.println("I2C Sensor first pressure [mbar], than temperature[°C]:");
sensor.readSensor();
// Show pressure
Serial.print("Pressure = ");
Serial.print(sensor.pressure());
Serial.println(" mbar");
// Show temperature
Serial.print("Temperature = ");
Serial.print(sensor.temperature());
Serial.println("C");
delay(2000);
}
}
The first connection with SPI is here (.cpp):
#include "MS5803_05_SPI.h"
#include <SPI.h>
#define CMD_RESET 0x1E // ADC reset command
#define CMD_ADC_READ 0x00 // ADC read command
#define CMD_ADC_CONV 0x40 // ADC conversion command
#define CMD_ADC_D1 0x00 // ADC D1 conversion
#define CMD_ADC_D2 0x10 // ADC D2 conversion
#define CMD_ADC_256 0x00 // ADC resolution=256
#define CMD_ADC_512 0x02 // ADC resolution=512
#define CMD_ADC_1024 0x04 // ADC resolution=1024
#define CMD_ADC_2048 0x06 // ADC resolution=2048
#define CMD_ADC_4096 0x08 // ADC resolution=4096
#define CMD_PROM_RD 0xA0 // Prom read command
#define spi_write SPI_MODE3
#define spi_write2 SPI_MODE1
// Create array to hold the 8 sensor calibration coefficients
static unsigned int sensorCoeffs[8]; // unsigned 16-bit integer (0-65535)
// D1 and D2 need to be unsigned 32-bit integers (long 0-4294967295)
static uint32_t D1 = 0; // Store uncompensated pressure value
static uint32_t D2 = 0; // Store uncompensated temperature value
// These three variables are used for the conversion steps
// They should be signed 32-bit integer initially
// i.e. signed long from -2147483648 to 2147483647
static int32_t dT = 0;
static int32_t TEMP = 0;
// These values need to be signed 64 bit integers
// (long long = int64_t)
static int64_t Offset = 0;
static int64_t Sensitivity = 0;
static int64_t T2 = 0;
static int64_t OFF2 = 0;
static int64_t Sens2 = 0;
// Some constants used in calculations below
const uint64_t POW_2_33 = 8589934592ULL; // 2^33 = 8589934592
SPISettings settings_write(500000, MSBFIRST, spi_write);
SPISettings settings_write2(500000, MSBFIRST, spi_write2);
//-------------------------------------------------
// Constructor
MS_5803_SPI::MS_5803_SPI( uint16_t Resolution, uint16_t cs) {
// The argument is the oversampling resolution, which may have values
// of 256, 512, 1024, 2048, or 4096.
_Resolution = Resolution;
//Chip Select
_cs=cs;
}
boolean MS_5803_SPI::initializeMS_5803_SPI(boolean Verbose) {
digitalWrite( _cs, HIGH );
SPI.begin();
// Reset the sensor during startup
resetSensor();
if (Verbose)
{
// Display the oversampling resolution or an error message
if (_Resolution == 256 | _Resolution == 512 | _Resolution == 1024 | _Resolution == 2048 | _Resolution == 4096){
Serial.print("Oversampling setting: ");
Serial.println(_Resolution);
} else {
Serial.println("*******************************************");
Serial.println("Error: specify a valid oversampling value");
Serial.println("Choices are 256, 512, 1024, 2048, or 4096");
Serial.println("*******************************************");
}
}
// Read sensor coefficients
for (int i = 0; i < 8; i++ )
{
SPI.beginTransaction(settings_write2);
digitalWrite(_cs, LOW); //csb_lo(); // pull CSB low
unsigned int ret;
unsigned int rC = 0;
SPI.transfer(CMD_PROM_RD + i * 2); // send PROM READ command
/*
ret = SPI.transfer(0x00); // send 0 to read the MSB
rC = 256 * ret;
ret = SPI.transfer(0x00); // send 0 to read the LSB
rC = rC + ret;
*/
// send a value of 0 to read the first byte returned:
rC = SPI.transfer( 0x00 );
rC = rC << 8;
rC |= SPI.transfer( 0x00 ); // and the second byte
sensorCoeffs[i] = (rC);
digitalWrite( _cs, HIGH );
delay(3);
}
//SPI.endTransaction(); // interrupt can now be accepted
// The last 4 bits of the 7th coefficient form a CRC error checking code.
unsigned char p_crc = sensorCoeffs[7];
// Use a function to calculate the CRC value
unsigned char n_crc = MS_5803_CRC(sensorCoeffs);
if (Verbose) {
for (int i = 0; i < 8; i++ )
{
// Print out coefficients
Serial.print("C");
Serial.print(i);
Serial.print(" = ");
Serial.println(sensorCoeffs[i]);
delay(10);
}
Serial.print("p_crc: ");
Serial.println(p_crc);
Serial.print("n_crc: ");
Serial.println(n_crc);
}
// If the CRC value doesn't match the sensor's CRC value, then the
// connection can't be trusted. Check your wiring.
if (p_crc != n_crc) {
return false;
}
// Otherwise, return true when everything checks out OK.
return true;
}
// Sends a power on reset command to the sensor.
void MS_5803_SPI::resetSensor() {
SPI.beginTransaction(settings_write);
digitalWrite(_cs, LOW); //csb_lo(); // pull CSB low to start the command
SPI.transfer(CMD_RESET); // send reset sequence
delay(3); // wait for the reset sequence timing delay(3)
digitalWrite(_cs, HIGH); //csb_hi(); // pull CSB high to finish the command
SPI.endTransaction(); // interrupt can now be accepted
}
The Code can be downloaded at: https://forum.arduino.cc/index.php?topic=670661.0
There you can find the schematic and output picture too.
Thanks a lot :).

GPS receiver + Ublox NEO-6M - Having trouble making a timeout

I'm trying to write some code that will turn on the gps module and wait for data to arrive, so that I can then do things with it. I don't need a continuous stream; I only need the first lat/long received from the gps unit, then I can turn it off. I also need this to just stop if it can't find it's location within a certain amount of time (20 seconds for example)
Here is some simple code that I've tried just to get the gps to read (full code with timeout comes later)
#include <TinyGPS++.h>
#include <SoftwareSerial.h>
TinyGPSPlus gps; // The TinyGPS++ object
SoftwareSerial ss(D4, D3); // The serial connection to the GPS
float latitude , longitude;
int count = 0;
void setup()
{
Serial.begin(9600);
ss.begin(9600);
Serial.println();
Serial.print("Starting");
}
void loop()
{
while (ss.available() > 0)
if (gps.encode(ss.read()))
{
if (gps.location.isValid())
{
latitude = gps.location.lat();
lat_str = String(latitude , 6);
longitude = gps.location.lng();
lng_str = String(longitude , 6);
}
}
Serial.println(lat_str + ":" + lng_str);
delay(100);
count += 1;
String Count = String(count);
Serial.println(Count);
}
When the delay above is 100, then everything works fine, when the delay is 1000, then suddenly no data comes through.
Here is the full code I've tried that includes my timeout and breakout condition, again not working. The cutoff line is in the GPS_mode function here: while ((stoploop < 1) && (previous - startTime < TimeOut)).
#include <SoftwareSerial.h>
#include <TinyGPS++.h>
TinyGPSPlus gps; // The TinyGPS++ object
SoftwareSerial ss(D4, D3); // The serial connection to the GPS d
int stoploop = 0; //used for stopping gps once a signal lock or timeout is reached
unsigned long startTime = millis(); // timer used for gps timeout
const int gpsCutoffPin = D1;
void setup() {
//initialise the serial monitor
Serial.begin(9600);
gps_ss.begin(9600);
//initialise the transistor pins
pinMode(gpsCutoffPin, OUTPUT);
// Start the gps in an off state
digitalWrite(gpsCutoffPin, LOW);
}
void loop() {
Serial.println("Enter GPS mode");
GPS_mode();
Serial.println("Back to the main loop now...");
Serial.println(stoploop);
delay(100000);
}
void GPS_mode(){
//turn on the gps
digitalWrite(gpsCutoffPin, HIGH);
stoploop = 0;
startTime = millis();
previous = millis();
int TimeOut = 60*1000;
gps_ss.listen();
Serial.println(stoploop);
while ((stoploop < 1) && (previous - startTime < TimeOut))
{
while (gps_ss.available() > 0)
{
if (gps.encode(gps_ss.read()))
{
logInfo();
}
yield();
}
}
gpsLat = (gps.location.lat(), DEC);
gpsLon = (gps.location.lng(), DEC);
// turn off the gps
digitalWrite(gpsCutoffPin, LOW);
}
void logInfo(){
// Causes us to wait until we have satelite fix
if(!gps.location.isValid())
{
Serial.println("Not a valid location. Waiting for satelite data.");
//return;
}
else {
//url += String(gps.location.lat(), DEC);
//url += String(gps.location.lng(), DEC);
Serial.println(gps.location.lat(), DEC);
Serial.println(gps.location.lng(), DEC);
stoploop = 2;
//delay(1000);
}
previous = millis();
}
I expect to see some gps data printed to the screen, but I actually don't see anything. I know that the gps is working and is receiving data because the blinking LED tell me so.
I have no idea how to fix this. If anyone could help I'd very much appreciate it.
Thanks

Copying file bytes from SD Card to FRAM

I'm trying to copy a file from an SD card to an adafruit FRAM module. I'm wondering if I'm going about it the right way. I'm trying to read the file one byte at a time and then write that byte to a specific location on the Fram module.
I've been trying that approach using the sketch below and haven't been successful. I'm wondering if I'm approaching it the right way, and if so, where have I gone wrong with my sketch. Thanks.
#include <SD.h>
#include <SPI.h>
#include <Wire.h>
#include "Adafruit_FRAM_I2C.h"
Adafruit_FRAM_I2C fram = Adafruit_FRAM_I2C();
uint16_t framAddr = 0;
void setup() {
Serial.begin(9600);
// setup SD-card
Serial.print("Initializing SD card...");
if (!SD.begin(4)) {
Serial.println(" failed!");
while(true);
}
Serial.println(" done.");
}
void loop() {
uint16_t count = 0;
File myFile = SD.open("test.txt");
if (!myFile) {
// if the file didn't open, print an error and stop
Serial.println("error opening");
while (true);
}
const int S = 1;
byte buffer[S];
while (myFile.available()) {
// read from the file into buffer
myFile.read(buffer, sizeof(buffer));
Serial.print("0x"); Serial.print(count, HEX); Serial.print(": ");
Serial.println(buffer[count]);
//write fram (address,value)
fram.write8(count,buffer[count]);
}
myFile.close();
while (true) ;
}
I don't familiar with this FRAM, but you don't promote your address.
So the device write to the same address all the time and rewrite the memory.
Hope i help.
yoav

RFID (SoftwareSerial) influences/breaks connection with SD (SPI)

I'm creating a RFID logger with Arduino. I connected a RFID scanner, RTC module and a SD card reader. All parts are working fine together but when i started combining different sketches a problem occured.
Reading files and writing to files on the SD card is no problem as long as i don't scan a RFID card. When input is received from the RFID scanner it is no longer possible to read or write to the sd card. The connection seems to be "disconnected" as soon as RFID input is received.
I tried using different pins for the RFID scanner, another sequence of initializing in the setup but it doesn't make a difference.
Is this a limitation of the Arduino or am I doing something wrong?
I'm using a ATS125KRW RFID shield and a Catalex MicroSD card adpater in combination with a Arduino Mega.
// SD
#include <SD.h>
File myFile;
char idArray[100][11];
char nameArray[100][11];
// RTC
#include <Wire.h>
#include "RTClib.h"
RTC_DS1307 rtc;
// RFID
#include <SoftwareSerial.h>
SoftwareSerial rfid = SoftwareSerial(A8 , A9); //(RX,TX)
String cardID; //string to store card id
char c;
char cardArray[11];
int incomingByte = 0; // for incoming serial data
String rfidInput;
boolean logtosd;
void setup()
{
Serial.begin(9600);
initializeRFID();
initializeSD();
initializeRTC();
readfromSD();
}
void loop()
{
while(rfid.available()>0)
{
c = rfid.read();
rfidInput += c;
}
if(rfidInput.length() >=12)
{
Serial.print("SCanned: ");
Serial.println(rfidInput);
//writetoSD(rfidInput);
writetoSD("kaart");
rfidInput = "";
}
while(Serial.available()>0)
{
c = Serial.read();
cardID += c;
}
if(cardID.length() >= 2)
{
writetoSD(cardID);
cardID = "";
}
}
void initializeSD()
{
// GND en VCC aansluiting via pin 48 en 49
pinMode(48, OUTPUT); // set pin to output
digitalWrite(48, LOW); // GND pin dus LOW
pinMode(49, OUTPUT); // set pin to output
digitalWrite(49, HIGH); // VCC pin dus HIGH
pinMode(53, OUTPUT);
if (!SD.begin(53))
{
Serial.println("SD initialization failed");
return;
}
Serial.println("SD initialized");
}
void readfromSD()
{
//open the file for reading:
myFile = SD.open("db.txt");
if (myFile)
{
char line[25]; //Array to store entire line
int linenumber = 0;
int arrayPlace = 0;
while (myFile.available())
{
char ch = myFile.read();
if(ch != '\n')
{
line[arrayPlace] = ch;
arrayPlace ++;
}
else
{
char id[11];
char name[11];
//get ID from entire line
for(int x = 0; x <= 10 ; x++)
{
id[x] = line[x];
}
//Get NAME from entire line
for(int x = 11; x <= 19 ; x++)
{
if (line[x] != ';')
{
name[x-11] = line[x];
}
else
{
// NULL TERMINATE THE ARRAY
name[x-11] = '\0';
//STOP
x = 20;
}
}
// save name to nameArray
for(int x = 0; x <= 11 ; x++)
{
nameArray[linenumber][x] = name[x];
}
// NULL TERMINATE THE ARRAY
id[10] = '\0';
// save id to idArray
for(int x = 0; x <= 11 ; x++)
{
idArray[linenumber][x] = id[x];
}
linenumber +=1;
arrayPlace = 0;
} //else
} //while
// close the file:
myFile.close();
}
else
{
// if the file didn't open, print an error:
Serial.println("error opening db.txt");
}
}
void writetoSD(String cardID)
{
//open file for writing
myFile = SD.open("test.txt", FILE_WRITE);
// if the file opened okay, write to it:
if (myFile)
{
Serial.println("Writing time to test.txt...");
DateTime now = rtc.now();
myFile.print(now.day(), DEC);
myFile.print('/');
myFile.print(now.month(), DEC);
myFile.print('/');
myFile.print(now.year(), DEC);
myFile.print(' ');
myFile.print(now.hour(), DEC);
myFile.print(':');
myFile.print(now.minute(), DEC);
myFile.print(':');
myFile.print(now.second(), DEC);
myFile.print('\t');
Serial.println("Writing string to test.txt...");
myFile.println(cardID);
// close the file:
myFile.flush();
Serial.println("done.");
}
else
{
// if the file didn't open, print an error:
Serial.println("error opening test.txt");
}
}
void initializeRTC()
{
// GND en VCC aansluiting via pin 18 en 19
pinMode(18, OUTPUT); // set pin to output
digitalWrite(18, LOW); // GND pin dus LOW
pinMode(19, OUTPUT); // set pin to output
digitalWrite(19, HIGH); // VCC pin dus HIGH
#ifdef AVR
Wire.begin();
#else
Wire1.begin(); // Shield I2C pins connect to alt I2C bus on Arduino Due
#endif
rtc.begin();
Serial.print("RTC Initialized: ");
DateTime now = rtc.now();
Serial.print(now.day(), DEC);
Serial.print('/');
Serial.print(now.month(), DEC);
Serial.print('/');
Serial.print(now.year(), DEC);
Serial.print(' ');
Serial.print(now.hour(), DEC);
Serial.print(':');
Serial.print(now.minute(), DEC);
Serial.print(':');
Serial.print(now.second(), DEC);
Serial.println();
}
void initializeRFID()
{
rfid.begin(9600);
Serial.println("RFID initialized");
}
I think you are running out of RAM ,i have done a lot of data logging on SD card with Arduino and its a very resources taking job for the minial 2kb ram on the UNO (assuming u using UNO).
Try using MemoryFree() library before every place you see there might be problem to see if you are running outta memory?

Arduino: how to switch off SD card module right

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?
Thanks
1. Edit
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 got 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.hlibrary 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.

Resources