Sd card logger draft (under construction)

From ArduinoInfo
Jump to: navigation, search
/*YourDuino SD Card Temperature Logger
  V1.0 02/05/2018

  This sketch will log multiupl Temperature sensors and record the data as a .CSV file onto an SD card.
  This allows easy transfer of data to a computer where it can be opened in Excel or similar programs
  and worked on. 
  
  Uses SD Card Module availabe here:http://www.yourduino.com/sunshop/index.php?l=product_detail&p=246
  Uses DS18B20 Temperature sensor here:http://www.yourduino.com/sunshop/index.php?l=product_detail&p=134
  Waterproof Version here: http://www.yourduino.com/sunshop/index.php?l=product_detail&p=151

  Wiring: SD Card Module
  (Arduino Pin) - Module Pin
  10 (SS) to CS
  11 (MOSI) to DI
  12 (MISO) to DO
  13 (SCK) to CLK
  and G to GND and + to 5V
  Switch the switch to 5V

  Wiring: Temperature Sensor
  CONNECTIONS: (Holding chip with pins down, label towards you)
  - Left  pin:  Ground
  - Right pin:  +5V
  - Center pin: Arduino Pin 9 and ALSO "Pullup Resistor":
  - Center pin: to 4700 (4.7K) or 5K resistor * (other end goes to +5V)
    NOTE: Two 10K resistors connected in parallel can be used.

  Wiring: Status LED
  Connect and LED to pin 8 (don't forget 220 reisitor between pin and LED)

  Based on YourDuino Temperature Sensor Example and SDFat dataLogger example.
*/

/*-----( Import needed libraries )-----*/
#include <SPI.h>
#include "SdFat.h"
#include <OneWire.h>
#include <DallasTemperature.h>

/*-----( Declare Constants )-----*/
#define ONE_WIRE_BUS 9
#define STATUS_LED 8
// Log file base name.  Must be six characters or less.
#define FILE_BASE_NAME "Data"


/*-----( Declare objects )-----*/
/* Set up a oneWire instance to communicate with any OneWire device*/
OneWire ourWire(ONE_WIRE_BUS);

/* Tell Dallas Temperature Library to use oneWire Library */
DallasTemperature sensors(&ourWire);

/*-----( Declare Variables )-----*/
// SD chip select pin.  Be sure to disable any other SPI devices such as Enet.
const uint8_t chipSelect = SS;

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

// Interval between data records in seconds.
// 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 = 60;

//Number of attached temperature sensors
const uint8_t SENSOR_COUNT = 2;


/*-----( SD Stuff )-----*/
// File system object.
SdFat sd;

// Log file.
SdFile file;

// Error messages stored in flash.
#define error(msg) sd.errorHalt(F(msg))

void setup() /*----( SETUP: RUNS ONCE )----*/
{
  const uint8_t BASE_NAME_SIZE = sizeof(FILE_BASE_NAME) - 1;
  char fileName[13] = FILE_BASE_NAME "00.csv";

  pinMode(STATUS_LED, OUTPUT); //Set the Status LED pin to output
  digitalWrite(STATUS_LED, HIGH); //Turn On the status LED
  Serial.begin(9600);//Start Serial communication

  // Wait for USB Serial
  while (!Serial)
  {
    SysCall::yield();
  }
  delay(1000);
  //Start Dalas Temperature Library
  sensors.begin();

  // 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(4)))
  {
    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();

  logTime = 0;
  digitalWrite(STATUS_LED, LOW); //turn off Status LED 
}/*--(end setup )---*/

void loop() /*----( LOOP: RUNS CONSTANTLY )----*/
{
  logData(); //Call the Log Data Function
  delay(SAMPLE_INTERVAL * 1000); //wait for log time (in mils)
  logTime = logTime + SAMPLE_INTERVAL; //Set the new logtime

  // Force data to SD and update the directory entry to avoid data loss.
  if (!file.sync() || file.getWriteError())
  {
    error("write error");
  }

  if (Serial.available()) //Stop Recording data if Serial Monitor detects a character.
  {
    // Close file and stop.
    file.close();
    Serial.println(F("Done"));
    SysCall::halt();
  }
} /* --(end main loop )-- */


/*-----( Functions)-----*/
// Write data header creates the first line of the CSV with the titles of each column 
void writeHeader()
{
  file.print(F("Seconds"));
  for (uint8_t i = 0; i < SENSOR_COUNT; i++) {
    file.write(',');
    file.print(F("Temp Sensor:"));
    file.print(i, DEC);
    file.print(F("( F)"));
  }
  file.println();
}


// Log a data record.
void logData()
{
  Serial.println("New Log");
  digitalWrite(STATUS_LED, HIGH); //Turn on Staus LED

  //create a one demensional matrix to hold the data from all the sensors
  uint16_t data[SENSOR_COUNT];

  // Read all sensors to avoid SD write latency between readings.
  sensors.requestTemperatures(); // Send the command to get temperatures
  for (uint8_t i = 0; i < SENSOR_COUNT; i++) //For each sensor put the data into the matrix
  {
    data[i] = sensors.getTempFByIndex(i);
    Serial.print(i);
    Serial.print(" F:");
    Serial.println(data[i]);
  }
  // Write data to file.  Start with log time in seconds.
  file.print(logTime);

  // Write data to CSV record.
  for (uint8_t i = 0; i < SENSOR_COUNT; i++)
  {
    file.write(',');
    file.print(data[i]);
  }
  file.println();
  digitalWrite(STATUS_LED, LOW);
}
//==============================================================================


/* ( THE END ) */