| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197 | // A simple data logger for the Arduino analog pins with optional DS1307// uses RTClib from https://github.com/adafruit/RTClib#include <SPI.h>#include "SdFat.h"#include "sdios.h"#include "FreeStack.h"#define SD_CHIP_SELECT  SS  // SD chip select pin#define USE_DS1307       0  // set nonzero to use DS1307 RTC#define LOG_INTERVAL  1000  // mills between entries#define SENSOR_COUNT     3  // number of analog pins to log#define ECHO_TO_SERIAL   1  // echo data to serial port if nonzero#define WAIT_TO_START    1  // Wait for serial input in setup()#define ADC_DELAY       10  // ADC delay for high impedence sensors// file system objectSdFat sd;// text file for loggingofstream logfile;// Serial print streamArduinoOutStream cout(Serial);// buffer to format data - makes it eaiser to echo to Serialchar buf[80];//------------------------------------------------------------------------------#if SENSOR_COUNT > 6#error SENSOR_COUNT too large#endif  // SENSOR_COUNT//------------------------------------------------------------------------------// store error strings in flash to save RAM#define error(s) sd.errorHalt(F(s))//------------------------------------------------------------------------------#if USE_DS1307// use RTClib from Adafruit// https://github.com/adafruit/RTClib// The Arduino IDE has a bug that causes Wire and RTClib to be loaded even// if USE_DS1307 is false.#error remove this line and uncomment the next two lines.//#include <Wire.h>//#include <RTClib.h>RTC_DS1307 RTC;  // define the Real Time Clock object//------------------------------------------------------------------------------// call back for file timestampsvoid dateTime(uint16_t* date, uint16_t* time) {  DateTime now = RTC.now();  // return date using FAT_DATE macro to format fields  *date = FAT_DATE(now.year(), now.month(), now.day());  // return time using FAT_TIME macro to format fields  *time = FAT_TIME(now.hour(), now.minute(), now.second());}//------------------------------------------------------------------------------// format date/timeostream& operator << (ostream& os, DateTime& dt) {  os << dt.year() << '/' << int(dt.month()) << '/' << int(dt.day()) << ',';  os << int(dt.hour()) << ':' << setfill('0') << setw(2) << int(dt.minute());  os << ':' << setw(2) << int(dt.second()) << setfill(' ');  return os;}#endif  // USE_DS1307//------------------------------------------------------------------------------void setup() {  Serial.begin(9600);  // Wait for USB Serial.  while (!Serial) {    yield();  }  // F() stores strings in flash to save RAM  cout << endl << F("FreeStack: ") << FreeStack() << endl;#if WAIT_TO_START  cout << F("Type any character to start\n");  while (!Serial.available()) {    yield();  }  // Discard input.  do {    delay(10);  } while(Serial.available() && Serial.read() >= 0);#endif  // WAIT_TO_START#if USE_DS1307  // connect to RTC  Wire.begin();  if (!RTC.begin()) {    error("RTC failed");  }  // set date time callback function  SdFile::dateTimeCallback(dateTime);  DateTime now = RTC.now();  cout  << now << endl;#endif  // USE_DS1307  // 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(SD_CHIP_SELECT, SD_SCK_MHZ(50))) {    sd.initErrorHalt();  }  // create a new file in root, the current working directory  char name[] = "logger00.csv";  for (uint8_t i = 0; i < 100; i++) {    name[6] = i/10 + '0';    name[7] = i%10 + '0';    if (sd.exists(name)) {      continue;    }    logfile.open(name);    break;  }  if (!logfile.is_open()) {    error("file.open");  }  cout << F("Logging to: ") << name << endl;  cout << F("Type any character to stop\n\n");  // format header in buffer  obufstream bout(buf, sizeof(buf));  bout << F("millis");#if USE_DS1307  bout << F(",date,time");#endif  // USE_DS1307  for (uint8_t i = 0; i < SENSOR_COUNT; i++) {    bout << F(",sens") << int(i);  }  logfile << buf << endl;#if ECHO_TO_SERIAL  cout << buf << endl;#endif  // ECHO_TO_SERIAL}//------------------------------------------------------------------------------void loop() {  uint32_t m;  // wait for time to be a multiple of interval  do {    m = millis();  } while (m % LOG_INTERVAL);  // use buffer stream to format line  obufstream bout(buf, sizeof(buf));  // start with time in millis  bout << m;#if USE_DS1307  DateTime now = RTC.now();  bout << ',' << now;#endif  // USE_DS1307  // read analog pins and format data  for (uint8_t ia = 0; ia < SENSOR_COUNT; ia++) {#if ADC_DELAY    analogRead(ia);    delay(ADC_DELAY);#endif  // ADC_DELAY    bout << ',' << analogRead(ia);  }  bout << endl;  // log data and flush to SD  logfile << buf << flush;  // check for error  if (!logfile) {    error("write data failed");  }#if ECHO_TO_SERIAL  cout << buf;#endif  // ECHO_TO_SERIAL  // don't log two points in the same millis  if (m == millis()) {    delay(1);  }  if (!Serial.available()) {    return;  }  logfile.close();  cout << F("Done!");  while (true) {}}
 |