Basic SD output datalogger

Hi All

I need some advise. i have a uno with a data logger sd shield. Im trying to get it so that when i trigger an input it will write to SD card with time stamp. Please help.

Thanks in advance

If pin HIGH then Read time myFile.print(time)

Have you gotten your clock to work? Have you checked the datalogger in the SD examples ?

Hi Nick

I tried the example and formatted the card. and not sure how to get the clock working.

Below is the example code im using. I cant find which pin is High. Thanks for the help.

/*

  • Simple data logger.
    */
    #include <SPI.h>
    #include “SdFat.h”

// SD chip select pin. Be sure to disable any other SPI devices such as Enet.
const uint8_t chipSelect = SS;

// Interval between data records in milliseconds.
// The interval must be greater than the maximum SD write latency plus the
// time to acquire and write data to the SD to avoid overrun errors.
// Run the bench example to check the quality of your SD card.
const uint32_t SAMPLE_INTERVAL_MS = 1000;

// Log file base name. Must be six characters or less.
#define FILE_BASE_NAME “Data”
//------------------------------------------------------------------------------
// File system object.
SdFat sd;

// Log file.
SdFile file;

// Time in micros for next data record.
uint32_t logTime;

//==============================================================================
// User functions. Edit writeHeader() and logData() for your requirements.

const uint8_t ANALOG_COUNT = 4;
//------------------------------------------------------------------------------
// Write data header.
void writeHeader() {
file.print(F(“micros”));
for (uint8_t i = 0; i < ANALOG_COUNT; i++) {
file.print(F(",adc"));
file.print(i, DEC);
}
file.println();
}
//------------------------------------------------------------------------------
// Log a data record.
void logData() {
uint16_t data[ANALOG_COUNT];

// Read all channels to avoid SD write latency between readings.
for (uint8_t i = 0; i < ANALOG_COUNT; i++) {
data = analogRead(i);

  • }*
  • // Write data to file. Start with log time in micros.*
  • file.print(logTime);*
  • // Write ADC data to CSV record.*
  • for (uint8_t i = 0; i < ANALOG_COUNT; i++) {*
  • file.write(’,’);*
    _ file.print(data*);_
    _
    }_
    _
    file.println();_
    _
    }_
    _
    //==============================================================================_
    _
    // Error messages stored in flash._
    _
    #define error(msg) sd.errorHalt(F(msg))_
    _
    //------------------------------------------------------------------------------_
    void setup() {
    const uint8_t BASE_NAME_SIZE = sizeof(FILE_BASE_NAME) - 1;
    char fileName[13] = FILE_BASE_NAME “00.csv”;
    _
    Serial.begin(9600);*_

* // Wait for USB Serial*
* while (!Serial) {*
* SysCall::yield();*
* }*
* delay(1000);*
* Serial.println(F(“Type any character to start”));*
* while (!Serial.available()) {*
* SysCall::yield();*
* }*

* // Initialize at the highest speed supported by the board that is*
* // not over 50 MHz. Try a lower speed if SPI errors occur.*
* if (!sd.begin(chipSelect, SD_SCK_MHZ(50))) {
_
sd.initErrorHalt();_
_
}_
_
// Find an unused file name._
if (BASE_NAME_SIZE > 6) {
error(“FILE_BASE_NAME too long”);
_
}_
_
while (sd.exists(fileName)) {_
if (fileName[BASE_NAME_SIZE + 1] != ‘9’) {
fileName[BASE_NAME_SIZE + 1]++;
} else if (fileName[BASE_NAME_SIZE] != ‘9’) {
fileName[BASE_NAME_SIZE + 1] = ‘0’;
fileName[BASE_NAME_SIZE]++;
_
} else {_
_
error(“Can’t create file name”);_
_
}_
_
}_
if (!file.open(fileName, O_CREAT | O_WRITE | O_EXCL)) {
_
error(“file.open”);_
_
}_
_
// Read any Serial data._
_
do {_
_
delay(10);_
_
} while (Serial.available() && Serial.read() >= 0);_
_
Serial.print(F("Logging to: "));_
_
Serial.println(fileName);_
_
Serial.println(F(“Type any character to stop”));_
_
// Write data header._
_
writeHeader();_
_
// Start on a multiple of the sample interval._
logTime = micros()/(1000ULSAMPLE_INTERVAL_MS) + 1;

logTime = 1000ULSAMPLE_INTERVAL_MS;
}
//------------------------------------------------------------------------------
void loop() {
* // Time for next record.*
logTime += 1000ULSAMPLE_INTERVAL_MS;
_
// Wait for log time._
int32_t diff;
_
do {_
_
diff = micros() - logTime;_
_
} while (diff < 0);_
_
// Check for data rate too high._
_
if (diff > 10) {_
_
error(“Missed data record”);_
_
}_
_
logData();_
_
// Force data to SD and update the directory entry to avoid data loss._
_
if (!file.sync() || file.getWriteError()) {_
_
error(“write error”);_
_
}_
_
if (Serial.available()) {_
_
// Close file and stop._
_
file.close();_
_
Serial.println(F(“Done”));_
_
SysCall::halt();_
_
}_
_
}*_

I then get this error

Arduino: 1.6.7 (Windows 7), Board: “Arduino/Genuino Uno”

Unable to find C:\Program Files (x86)\Arduino\libraries\SD\examples\Datalogger\Datalogger.ino in C:\Program Files (x86)\Arduino\libraries\SD\examples\Datalogger

Error compiling.

This report would have more information with
“Show verbose output during compilation”
enabled in File > Preferences.

Trevor1983: Unable to find C:\Program Files (x86)\Arduino\libraries\SD\examples\Datalogger\Datalogger.ino in C:\Program Files (x86)\Arduino\libraries\SD\examples\Datalogger

Wow.........that is weird. Your error message, such as it is, seems to indicate that your files are a mess. It appears that your code is confusing the standard example included in the SD section with whatever it is in SDFat. It could be that your SDFat stuff is simply in the wrong place and, bizarrely, Arduino is taking the next bet. You may be able to rectify that but, since I have never known a good reason for using SDFat, I can only suggest you scrub it altogether and use the example in the SD section, which I was alluding to in the first place. The advantage of this would be that you can be pretty confident that your SD stuff is in the right place because the Arduino fairies put it there. Another clear advantage is that the code required to do the simple job you have in mind will surely be a hell of a lot shorter than what you have now.

Hi Nick

So i have uninstalled and then re installed the arduino suite 1.8.3 I uploaded the standard example of SD datalogger (below)
I am still unable to get any info to save onto the card. Unless im using the incorrect way of triggering the input.
The way i understand it is, that i should short out pins 4 and CS to initiate the time stamp event as im only needing to monitor a potential free relay contact once it has triggered.

/*
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 (for MKRZero SD: SDCARD_SS_PIN)

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>

const int chipSelect = 4;

void setup() {
// 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.”);
}

void loop() {
// make a string for assembling the data to log:
String dataString = “”;

// read three sensors and append to the string:
for (int analogPin = 0; analogPin < 3; analogPin++) {
int sensor = analogRead(analogPin);
dataString += String(sensor);
if (analogPin < 2) {
dataString += “,”;
}
}

// 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) {
dataFile.println(dataString);
dataFile.close();
// print to the serial port too:
Serial.println(dataString);
}
// if the file isn’t open, pop up an error:
else {
Serial.println(“error opening datalog.txt”);
}
}

Trevor1983:
Unless im using the incorrect way of triggering the input.
The way i understand it is, that i should short out pins 4 and CS to initiate the time stamp event

I don’t think that is a good idea. Leave CS on Pin 4 and put the switch somewhere else.
https://www.connectedly.com/using-buttons-and-switches-arduino
also make sure you SD is formatted in the kosher manner, as detailed at the head of this forum.

Hi Nick

So I have cleaned all the gremlins out of my file directory and did a clean install. And still no success. But wait I did find my problem and that is the shield that I have for some reason is having an intermittent read fault, so I need to pull the SD card out of the socket about 1mm then it will works.

Thank You for your help really appreciate it.

So now Im reading the analogue values now and they are coming in thick and fast but I need to get the timestamp now to work do you have any ideas?

Thank You

Glad you got a result.

As for timestamping, I think you should get a clock module DS3231. DS1307 is common but I don't think there is any point in getting it - other than space problems, the DS3231 is only a dollar more and is a much better product. http://bildr.org/2011/03/ds1307-arduino/ I use it, no change required for DS3231 This enables you to 1. print time to SD just like your sensor data. 2. provide source for filenames 3. create new SD file on schedule, I make a new file at midnight.

http://homepages.ihug.com.au/~npyner/Arduino/Bluetooth_graphic_5110_with_file_retrieve_DY.ino No claims for programming elegance or subtlety, strip out what you don't need, which is probably most of it!