RtcTimestampTest.ino 6.3 KB

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