You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

138 satır
4.0KB

  1. /*
  2. * Simple data logger.
  3. */
  4. #include <SdFat.h>
  5. // SD chip select pin. Be sure to disable any other SPI devices such as Enet.
  6. const uint8_t chipSelect = SS;
  7. // Interval between data records in milliseconds.
  8. // The interval must be greater than the maximum SD write latency plus the
  9. // time to acquire and write data to the SD to avoid overrun errors.
  10. // Run the bench example to check the quality of your SD card.
  11. const uint32_t SAMPLE_INTERVAL_MS = 200;
  12. // Log file base name. Must be six characters or less.
  13. #define FILE_BASE_NAME "DATA"
  14. //------------------------------------------------------------------------------
  15. // File system object.
  16. SdFat sd;
  17. // Log file.
  18. SdFile file;
  19. // Time in micros for next data record.
  20. uint32_t logTime;
  21. //==============================================================================
  22. // User functions. Edit writeHeader() and logData() for your requirements.
  23. const uint8_t ANALOG_COUNT = 4;
  24. //------------------------------------------------------------------------------
  25. // Write data header.
  26. void writeHeader() {
  27. file.print(F("micros"));
  28. for (uint8_t i = 0; i < ANALOG_COUNT; i++) {
  29. file.print(F(",adc"));
  30. file.print(i, DEC);
  31. }
  32. file.println();
  33. }
  34. //------------------------------------------------------------------------------
  35. // Log a data record.
  36. void logData() {
  37. uint16_t data[ANALOG_COUNT];
  38. // Read all channels to avoid SD write latency between readings.
  39. for (uint8_t i = 0; i < ANALOG_COUNT; i++) {
  40. data[i] = analogRead(i);
  41. }
  42. // Write data to file. Start with log time in micros.
  43. file.print(logTime);
  44. // Write ADC data to CSV record.
  45. for (uint8_t i = 0; i < ANALOG_COUNT; i++) {
  46. file.write(',');
  47. file.print(data[i]);
  48. }
  49. file.println();
  50. }
  51. //==============================================================================
  52. // Error messages stored in flash.
  53. #define error(msg) error_P(PSTR(msg))
  54. //------------------------------------------------------------------------------
  55. void error_P(const char* msg) {
  56. sd.errorHalt_P(msg);
  57. }
  58. //------------------------------------------------------------------------------
  59. void setup() {
  60. const uint8_t BASE_NAME_SIZE = sizeof(FILE_BASE_NAME) - 1;
  61. char fileName[13] = FILE_BASE_NAME "00.CSV";
  62. Serial.begin(9600);
  63. while (!Serial) {} // wait for Leonardo
  64. delay(1000);
  65. Serial.println(F("Type any character to start"));
  66. while (!Serial.available()) {}
  67. // Initialize the SD card at SPI_HALF_SPEED to avoid bus errors with
  68. // breadboards. use SPI_FULL_SPEED for better performance.
  69. if (!sd.begin(chipSelect, SPI_HALF_SPEED)) sd.initErrorHalt();
  70. // Find an unused file name.
  71. if (BASE_NAME_SIZE > 6) {
  72. error("FILE_BASE_NAME too long");
  73. }
  74. while (sd.exists(fileName)) {
  75. if (fileName[BASE_NAME_SIZE + 1] != '9') {
  76. fileName[BASE_NAME_SIZE + 1]++;
  77. } else if (fileName[BASE_NAME_SIZE] != '9') {
  78. fileName[BASE_NAME_SIZE + 1] = '0';
  79. fileName[BASE_NAME_SIZE]++;
  80. } else {
  81. error("Can't create file name");
  82. }
  83. }
  84. if (!file.open(fileName, O_CREAT | O_WRITE | O_EXCL)) error("file.open");
  85. do {
  86. delay(10);
  87. } while (Serial.read() >= 0);
  88. Serial.print(F("Logging to: "));
  89. Serial.println(fileName);
  90. Serial.println(F("Type any character to stop"));
  91. // Write data header.
  92. writeHeader();
  93. // Start on a multiple of the sample interval.
  94. logTime = micros()/(1000UL*SAMPLE_INTERVAL_MS) + 1;
  95. logTime *= 1000UL*SAMPLE_INTERVAL_MS;
  96. }
  97. //------------------------------------------------------------------------------
  98. void loop() {
  99. // Time for next record.
  100. logTime += 1000UL*SAMPLE_INTERVAL_MS;
  101. // Wait for log time.
  102. int32_t diff;
  103. do {
  104. diff = micros() - logTime;
  105. } while (diff < 0);
  106. // Check for data rate too high.
  107. if (diff > 10) error("Missed data record");
  108. logData();
  109. // Force data to SD and update the directory entry to avoid data loss.
  110. if (!file.sync() || file.getWriteError()) error("write error");
  111. if (Serial.available()) {
  112. // Close file and stop.
  113. file.close();
  114. Serial.println(F("Done"));
  115. while(1) {}
  116. }
  117. }