RtcTimestampTest.ino 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  1. // Test of time-stamp callback.
  2. // Set the callback with this statement.
  3. // FsDateTime::setCallback(dateTime);
  4. #include "SdFat.h"
  5. // https://github.com/adafruit/RTClib
  6. #include "RTClib.h"
  7. // Set RTC_TYPE for file timestamps.
  8. // 0 - millis()
  9. // 1 - DS1307
  10. // 2 - DS3231
  11. // 3 - PCF8523
  12. #define RTC_TYPE 3
  13. // SD_FAT_TYPE = 0 for SdFat/File as defined in SdFatConfig.h,
  14. // 1 for FAT16/FAT32, 2 for exFAT, 3 for FAT16/FAT32 and exFAT.
  15. #define SD_FAT_TYPE 0
  16. /*
  17. Change the value of SD_CS_PIN if you are using SPI and
  18. your hardware does not use the default value, SS.
  19. Common values are:
  20. Arduino Ethernet shield: pin 4
  21. Sparkfun SD shield: pin 8
  22. Adafruit SD shields and modules: pin 10
  23. */
  24. // SDCARD_SS_PIN is defined for the built-in SD on some boards.
  25. #ifndef SDCARD_SS_PIN
  26. const uint8_t SD_CS_PIN = SS;
  27. #else // SDCARD_SS_PIN
  28. // Assume built-in SD is used.
  29. const uint8_t SD_CS_PIN = SDCARD_SS_PIN;
  30. #endif // SDCARD_SS_PIN
  31. // Try max SPI clock for an SD. Reduce SPI_CLOCK if errors occur.
  32. #define SPI_CLOCK SD_SCK_MHZ(50)
  33. // Try to select the best SD card configuration.
  34. #if HAS_SDIO_CLASS
  35. #define SD_CONFIG SdioConfig(FIFO_SDIO)
  36. #elif ENABLE_DEDICATED_SPI
  37. #define SD_CONFIG SdSpiConfig(SD_CS_PIN, DEDICATED_SPI, SPI_CLOCK)
  38. #else // HAS_SDIO_CLASS
  39. #define SD_CONFIG SdSpiConfig(SD_CS_PIN, SHARED_SPI, SPI_CLOCK)
  40. #endif // HAS_SDIO_CLASS
  41. #if SD_FAT_TYPE == 0
  42. SdFat sd;
  43. File file;
  44. #elif SD_FAT_TYPE == 1
  45. SdFat32 sd;
  46. File32 file;
  47. #elif SD_FAT_TYPE == 2
  48. SdExFat sd;
  49. ExFile file;
  50. #elif SD_FAT_TYPE == 3
  51. SdFs sd;
  52. FsFile file;
  53. #else // SD_FAT_TYPE
  54. #error Invalid SD_FAT_TYPE
  55. #endif // SD_FAT_TYPE
  56. #if RTC_TYPE == 0
  57. RTC_Millis rtc;
  58. #elif RTC_TYPE == 1
  59. RTC_DS1307 rtc;
  60. #elif RTC_TYPE == 2
  61. RTC_DS3231 rtc;
  62. #elif RTC_TYPE == 3
  63. RTC_PCF8523 rtc;
  64. #else // RTC_TYPE == type
  65. #error RTC_TYPE type not implemented.
  66. #endif // RTC_TYPE == type
  67. //------------------------------------------------------------------------------
  68. // Call back for file timestamps. Only called for file create and sync().
  69. void dateTime(uint16_t* date, uint16_t* time, uint8_t* ms10) {
  70. DateTime now = rtc.now();
  71. // Return date using FS_DATE macro to format fields.
  72. *date = FS_DATE(now.year(), now.month(), now.day());
  73. // Return time using FS_TIME macro to format fields.
  74. *time = FS_TIME(now.hour(), now.minute(), now.second());
  75. // Return low time bits in units of 10 ms, 0 <= ms10 <= 199.
  76. *ms10 = now.second() & 1 ? 100 : 0;
  77. }
  78. //------------------------------------------------------------------------------
  79. #define error(msg) (Serial.println(F("error " msg)), false)
  80. //------------------------------------------------------------------------------
  81. void clearSerialInput() {
  82. uint32_t m = micros();
  83. do {
  84. if (Serial.read() >= 0) {
  85. m = micros();
  86. }
  87. } while (micros() - m < 10000);
  88. }
  89. //------------------------------------------------------------------------------
  90. void getLine(char* line, size_t size) {
  91. size_t i = 0;
  92. uint32_t t;
  93. line[0] = '\0';
  94. while (!Serial.available()) {
  95. yield();
  96. }
  97. while (true) {
  98. t = millis() + 10;
  99. while (!Serial.available()) {
  100. if (millis() > t) {
  101. return;
  102. }
  103. }
  104. int c = Serial.read();
  105. if (i >= (size - 1) || c == '\r' || c == '\n') {
  106. return;
  107. }
  108. line[i++] = c;
  109. line[i] = '\0';
  110. }
  111. }
  112. //------------------------------------------------------------------------------
  113. void printField(Print* pr, char sep, uint8_t v) {
  114. if (sep) {
  115. pr->write(sep);
  116. }
  117. if (v < 10) {
  118. pr->write('0');
  119. }
  120. pr->print(v);
  121. }
  122. //------------------------------------------------------------------------------
  123. void printNow(Print* pr) {
  124. DateTime now = rtc.now();
  125. pr->print(now.year());
  126. printField(pr, '-', now.month());
  127. printField(pr, '-', now.day());
  128. printField(pr, ' ', now.hour());
  129. printField(pr, ':', now.minute());
  130. printField(pr, ':', now.second());
  131. }
  132. //------------------------------------------------------------------------------
  133. bool setRtc() {
  134. uint16_t y;
  135. uint8_t m, d, hh, mm, ss;
  136. char line[30];
  137. char* ptr;
  138. clearSerialInput();
  139. Serial.println(F("Enter: YYYY-MM-DD hh:mm:ss"));
  140. getLine(line, sizeof(line));
  141. Serial.print(F("Input: "));
  142. Serial.println(line);
  143. y = strtol(line, &ptr, 10);
  144. if (*ptr++ != '-' || y < 2000 || y > 2099) return error("year");
  145. m = strtol(ptr, &ptr, 10);
  146. if (*ptr++ != '-' || m < 1 || m > 12) return error("month");
  147. d = strtol(ptr, &ptr, 10);
  148. if (d < 1 || d > 31) return error("day");
  149. hh = strtol(ptr, &ptr, 10);
  150. if (*ptr++ != ':' || hh > 23) return error("hour");
  151. mm = strtol(ptr, &ptr, 10);
  152. if (*ptr++ != ':' || mm > 59) return error("minute");
  153. ss = strtol(ptr, &ptr, 10);
  154. if (ss > 59) return error("second");
  155. rtc.adjust(DateTime(y, m, d, hh, mm, ss));
  156. Serial.print(F("RTC set to "));
  157. printNow(&Serial);
  158. Serial.println();
  159. return true;
  160. }
  161. //------------------------------------------------------------------------------
  162. void setup() {
  163. Serial.begin(9600);
  164. while (!Serial) {
  165. yield();
  166. }
  167. #if RTC_TYPE == 0
  168. rtc.begin(DateTime(F(__DATE__), F(__TIME__)));
  169. #else // RTC_TYPE
  170. if (!rtc.begin()) {
  171. Serial.println(F("rtc.begin failed"));
  172. return;
  173. }
  174. if (!rtc.isrunning()) {
  175. Serial.println(F("RTC is NOT running!"));
  176. return;
  177. // following line sets the RTC to the date & time this sketch was compiled
  178. // rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
  179. // This line sets the RTC with an explicit date & time, for example to set
  180. // January 21, 2014 at 3am you would call:
  181. // rtc.adjust(DateTime(2014, 1, 21, 3, 0, 0));
  182. }
  183. #endif // RTC_TYPE
  184. while (true) {
  185. Serial.print(F("DateTime::now "));
  186. printNow(&Serial);
  187. Serial.println();
  188. clearSerialInput();
  189. Serial.println(F("Type Y to set RTC, any other character to continue"));
  190. while (!Serial.available()) {
  191. }
  192. if (Serial.read() != 'Y') break;
  193. if (setRtc()) break;
  194. }
  195. Serial.println();
  196. // Set callback
  197. FsDateTime::setCallback(dateTime);
  198. if (!sd.begin(SD_CONFIG)) {
  199. sd.initErrorHalt(&Serial);
  200. }
  201. // Remove old version to set create time.
  202. if (sd.exists("RtcTest.txt")) {
  203. sd.remove("RtcTest.txt");
  204. }
  205. if (!file.open("RtcTest.txt", FILE_WRITE)) {
  206. Serial.println(F("file.open failed"));
  207. return;
  208. }
  209. // Print current date time to file.
  210. file.print(F("Test file at: "));
  211. printNow(&file);
  212. file.println();
  213. file.close();
  214. // List files in SD root.
  215. sd.ls(LS_DATE | LS_SIZE);
  216. Serial.println(F("Done"));
  217. }
  218. //------------------------------------------------------------------------------
  219. void loop() {}