Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.

AnalogLogger.ino 4.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. // A simple data logger for the Arduino analog pins with optional DS1307
  2. // uses RTClib from https://github.com/adafruit/RTClib
  3. #include <SPI.h>
  4. #include <SdFat.h>
  5. #include <FreeStack.h>
  6. #define SD_CHIP_SELECT SS // SD chip select pin
  7. #define USE_DS1307 0 // set nonzero to use DS1307 RTC
  8. #define LOG_INTERVAL 1000 // mills between entries
  9. #define SENSOR_COUNT 3 // number of analog pins to log
  10. #define ECHO_TO_SERIAL 1 // echo data to serial port if nonzero
  11. #define WAIT_TO_START 1 // Wait for serial input in setup()
  12. #define ADC_DELAY 10 // ADC delay for high impedence sensors
  13. // file system object
  14. SdFat sd;
  15. // text file for logging
  16. ofstream logfile;
  17. // Serial print stream
  18. ArduinoOutStream cout(Serial);
  19. // buffer to format data - makes it eaiser to echo to Serial
  20. char buf[80];
  21. //------------------------------------------------------------------------------
  22. #if SENSOR_COUNT > 6
  23. #error SENSOR_COUNT too large
  24. #endif // SENSOR_COUNT
  25. //------------------------------------------------------------------------------
  26. // store error strings in flash to save RAM
  27. #define error(s) sd.errorHalt(F(s))
  28. //------------------------------------------------------------------------------
  29. #if USE_DS1307
  30. // use RTClib from Adafruit
  31. // https://github.com/adafruit/RTClib
  32. // The Arduino IDE has a bug that causes Wire and RTClib to be loaded even
  33. // if USE_DS1307 is false.
  34. #error remove this line and uncomment the next two lines.
  35. //#include <Wire.h>
  36. //#include <RTClib.h>
  37. RTC_DS1307 RTC; // define the Real Time Clock object
  38. //------------------------------------------------------------------------------
  39. // call back for file timestamps
  40. void dateTime(uint16_t* date, uint16_t* time) {
  41. DateTime now = RTC.now();
  42. // return date using FAT_DATE macro to format fields
  43. *date = FAT_DATE(now.year(), now.month(), now.day());
  44. // return time using FAT_TIME macro to format fields
  45. *time = FAT_TIME(now.hour(), now.minute(), now.second());
  46. }
  47. //------------------------------------------------------------------------------
  48. // format date/time
  49. ostream& operator << (ostream& os, DateTime& dt) {
  50. os << dt.year() << '/' << int(dt.month()) << '/' << int(dt.day()) << ',';
  51. os << int(dt.hour()) << ':' << setfill('0') << setw(2) << int(dt.minute());
  52. os << ':' << setw(2) << int(dt.second()) << setfill(' ');
  53. return os;
  54. }
  55. #endif // USE_DS1307
  56. //------------------------------------------------------------------------------
  57. void setup() {
  58. Serial.begin(9600);
  59. while (!Serial) {} // wait for Leonardo
  60. // F() stores strings in flash to save RAM
  61. cout << endl << F("FreeStack: ") << FreeStack() << endl;
  62. #if WAIT_TO_START
  63. cout << F("Type any character to start\n");
  64. while (Serial.read() <= 0) {}
  65. delay(400); // catch Due reset problem
  66. while (Serial.read() >= 0) {}
  67. #endif // WAIT_TO_START
  68. #if USE_DS1307
  69. // connect to RTC
  70. Wire.begin();
  71. if (!RTC.begin()) {
  72. error("RTC failed");
  73. }
  74. // set date time callback function
  75. SdFile::dateTimeCallback(dateTime);
  76. DateTime now = RTC.now();
  77. cout << now << endl;
  78. #endif // USE_DS1307
  79. // initialize the SD card at SPI_HALF_SPEED to avoid bus errors with
  80. if (!sd.begin(SD_CHIP_SELECT, SPI_HALF_SPEED)) {
  81. sd.initErrorHalt();
  82. }
  83. // create a new file in root, the current working directory
  84. char name[] = "logger00.csv";
  85. for (uint8_t i = 0; i < 100; i++) {
  86. name[6] = i/10 + '0';
  87. name[7] = i%10 + '0';
  88. if (sd.exists(name)) {
  89. continue;
  90. }
  91. logfile.open(name);
  92. break;
  93. }
  94. if (!logfile.is_open()) {
  95. error("file.open");
  96. }
  97. cout << F("Logging to: ") << name << endl;
  98. cout << F("Type any character to stop\n\n");
  99. // format header in buffer
  100. obufstream bout(buf, sizeof(buf));
  101. bout << F("millis");
  102. #if USE_DS1307
  103. bout << F(",date,time");
  104. #endif // USE_DS1307
  105. for (uint8_t i = 0; i < SENSOR_COUNT; i++) {
  106. bout << F(",sens") << int(i);
  107. }
  108. logfile << buf << endl;
  109. #if ECHO_TO_SERIAL
  110. cout << buf << endl;
  111. #endif // ECHO_TO_SERIAL
  112. }
  113. //------------------------------------------------------------------------------
  114. void loop() {
  115. uint32_t m;
  116. // wait for time to be a multiple of interval
  117. do {
  118. m = millis();
  119. } while (m % LOG_INTERVAL);
  120. // use buffer stream to format line
  121. obufstream bout(buf, sizeof(buf));
  122. // start with time in millis
  123. bout << m;
  124. #if USE_DS1307
  125. DateTime now = RTC.now();
  126. bout << ',' << now;
  127. #endif // USE_DS1307
  128. // read analog pins and format data
  129. for (uint8_t ia = 0; ia < SENSOR_COUNT; ia++) {
  130. #if ADC_DELAY
  131. analogRead(ia);
  132. delay(ADC_DELAY);
  133. #endif // ADC_DELAY
  134. bout << ',' << analogRead(ia);
  135. }
  136. bout << endl;
  137. // log data and flush to SD
  138. logfile << buf << flush;
  139. // check for error
  140. if (!logfile) {
  141. error("write data failed");
  142. }
  143. #if ECHO_TO_SERIAL
  144. cout << buf;
  145. #endif // ECHO_TO_SERIAL
  146. // don't log two points in the same millis
  147. if (m == millis()) {
  148. delay(1);
  149. }
  150. if (!Serial.available()) {
  151. return;
  152. }
  153. logfile.close();
  154. cout << F("Done!");
  155. while (1);
  156. }