PlatformIO package of the Teensy core framework compatible with GCC 10 & C++20
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.

sd_datalogger.ino 9.0KB

3 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304
  1. /**********************************************************
  2. This sketch shows the use of SPI Driver used in Snooze
  3. along with the standard SD and Bounce libraries. In this
  4. example the Teensy SD Data-Logger will deepSleep until you
  5. push the button (WAKEUP_BUTTON) which will wake the Teensy
  6. and start logging data until the button is released in
  7. which the Teensy will go back into deepSleep.
  8. The SPI Driver configures the SDIO or SPI pins to minimize
  9. leakage current during deepSleep and reconfigure the pins
  10. back after wake up.
  11. Supported Micros: T-LC/3.x
  12. Teensy 4.0 hibernate wakes up with a reset so this sketch
  13. will not work.
  14. ***********************************************************/
  15. /***********************************************************
  16. SNOOZE
  17. ***********************************************************/
  18. #include <Snooze.h>
  19. // Load drivers
  20. // SnoozeUSBSerial driver does what Serial does like "print", -
  21. // "println", "prinf", etc and also handles the effects of using -
  22. // the Arduino Serial monitor and sleeping. Use it when you -
  23. // want to print to serial monitor for sleeping applications.
  24. SnoozeUSBSerial usb;
  25. SnoozeDigital digital;
  26. SnoozeSPI sdCard;
  27. SnoozeBlock config(usb, digital, sdCard);
  28. /***********************************************************
  29. SD
  30. ***********************************************************/
  31. #include <SD.h>
  32. #include <SPI.h>
  33. // set up variables using the SD utility library functions:
  34. Sd2Card card;
  35. SdVolume volume;
  36. SdFile root;
  37. const int chipSelect = BUILTIN_SDCARD;
  38. /***********************************************************
  39. BOUNCE
  40. ***********************************************************/
  41. #include <Bounce.h>
  42. const uint8_t WAKEUP_BUTTON = 7;
  43. // use bounce for pin 7, debounce of 5ms
  44. Bounce button = Bounce(WAKEUP_BUTTON, 5);
  45. /***********************************************************
  46. TIME
  47. ***********************************************************/
  48. #include <TimeLib.h>
  49. elapsedMillis rtcMilliSeconds;
  50. /***********************************************************/
  51. uint32_t dataCount;
  52. // ----------------------------------------------------------------------------------------------
  53. void setup() {
  54. //
  55. setSyncProvider(getTeensy3Time);
  56. //
  57. dataCount = 0;
  58. // Configure LED Pin
  59. pinMode(LED_BUILTIN, OUTPUT);
  60. // Configure pin 21 for bounce library
  61. pinMode(WAKEUP_BUTTON, INPUT_PULLUP);
  62. /******************Snooze Driver Config******************/
  63. // Configure pin WAKEUP_BUTTON for Snooze wakeup, also -
  64. // used by bounce but no need to reconfigure the pin -
  65. // after waking Snooze does it for you.
  66. digital.pinMode(WAKEUP_BUTTON, INPUT_PULLUP, FALLING);//pin, mode, type
  67. // Configure SD Card for Low Power operation
  68. sdCard.setClockPin( BUILTIN_SDCARD );
  69. /****************End Snooze Driver Config****************/
  70. // UNCOMMENT THESE TWO LINES FOR TEENSY AUDIO BOARD:
  71. //SPI.setMOSI(7); // Audio shield has MOSI on pin 7
  72. //SPI.setSCK(14); // Audio shield has SCK on pin 14
  73. // Wait for Serial connection to open.
  74. while (!usb);
  75. delay(100);
  76. usb.println("Snooze SD Card Push Button Hold Data-Logger Example");
  77. usb.println("---------------------------------------------------");
  78. // see if the card is present and can be initialized:
  79. SD.begin(chipSelect);
  80. if (!card.init(SPI_HALF_SPEED, chipSelect)) {
  81. // don't do anything more:
  82. while (1) {
  83. usb.println("Card failed, or not present!");
  84. blink();
  85. blink();
  86. }
  87. }
  88. elapsedMillis time = 0;
  89. while (time < 1000) {
  90. usb.print(".");
  91. delay(200);
  92. }
  93. usb.println();
  94. usb.print("-> ");
  95. usb.println("SD Card Initialized.");
  96. sdCardInfo();
  97. delay(1000);
  98. }
  99. // ------------------------------------------------------------------------
  100. void loop() {
  101. sleepDataLogger();
  102. handleButtonHold();
  103. }
  104. // ------------------------------------------------------------------------
  105. inline void sleepDataLogger() {
  106. SLEEP:
  107. digitalWriteFast(LED_BUILTIN, LOW);
  108. usb.println("Logger Will Sleep Now...");
  109. // delay to finish usb print before sleeping
  110. delay(5);
  111. // you need to update bounce before sleeping.
  112. button.update();
  113. // put Teensy into low power sleep mode
  114. Snooze.hibernate( config );
  115. digitalWriteFast(LED_BUILTIN, HIGH);
  116. // check for 300ms that the button is held
  117. bool hold = threeHundredMilliSecondHoldCheck();
  118. // if not held for 300ms go back to sleep
  119. if (hold == false) goto SLEEP;
  120. usb.println("Data Logger now awake, ready to log data.");
  121. }
  122. // ------------------------------------------------------------------
  123. // Make sure the button is help low for aleast 300ms before data logging.
  124. bool threeHundredMilliSecondHoldCheck() {
  125. button.update();
  126. // Pin is configured as PULLUP so 0 means the button has been
  127. // pushed.
  128. while (button.read() == 0) {
  129. // Monitor the pin hold duration.
  130. if (button.duration() > 300) return true;
  131. // Update bounce library.
  132. button.update();
  133. }
  134. return false;
  135. }
  136. // ------------------------------------------------------------------------
  137. void handleButtonHold() {
  138. button.update();
  139. if (button.read() == HIGH) {
  140. usb.println("No Logging of Data!!! Button released before logging could commence.");
  141. return;
  142. }
  143. usb.println("Logging data");
  144. button.update();
  145. elapsedMillis log_time = 0;
  146. while (button.read() == LOW) {
  147. if (log_time >= 99) {
  148. log_time = 0;
  149. logData(dataCount++);
  150. }
  151. button.update();
  152. }
  153. digitalWrite(LED_BUILTIN, LOW);
  154. }
  155. // ------------------------------------------------------------------------
  156. void logData(uint32_t count) {
  157. // make a string for assembling the data to log:
  158. String dataString;//"Time\tAna1\tAna2\tAna3\r\n";
  159. // read three sensors and append to the string:
  160. dataString = digitalClockDisplay(rtcMilliSeconds - 1);
  161. dataString += "\t";
  162. dataString += String(count);
  163. dataString += String("\t");
  164. for (int analogPin = 0; analogPin < 3; analogPin++) {
  165. dataString += analogRead(analogPin);
  166. if ( analogPin < 2) dataString += "\t";
  167. }
  168. dataString += "\r\n";
  169. // open the file. note that only one file can be open at a time,
  170. // so you have to close this one before opening another.
  171. File dataFile = SD.open("datalog.txt", FILE_WRITE);
  172. // if the file is available, write to it:
  173. if (dataFile) {
  174. dataFile.print(dataString);
  175. dataFile.close();
  176. // print to the serial port too:
  177. int len = dataString.length();
  178. usb.print(dataString);
  179. }
  180. // if the file isn't open, pop up an error:
  181. else {
  182. usb.println("error opening datalog.txt.");
  183. }
  184. }
  185. // ------------------------------------------------------------------------
  186. void sdCardInfo() {
  187. // print the type of card
  188. usb.print("-> Card type: ");
  189. switch (card.type()) {
  190. case SD_CARD_TYPE_SD1: {
  191. usb.println("SD1");
  192. break;
  193. }
  194. case SD_CARD_TYPE_SD2: {
  195. usb.println("SD2");
  196. break;
  197. }
  198. case SD_CARD_TYPE_SDHC: {
  199. usb.println("SDHC");
  200. break;
  201. }
  202. default: {
  203. usb.println("Unknown");
  204. break;
  205. }
  206. }
  207. // Now we will try to open the 'volume'/'partition' - it should be FAT16 or FAT32
  208. if (!volume.init(card)) {
  209. usb.println("Could not find FAT16/FAT32 partition.\nMake sure you've formatted the card");
  210. return;
  211. }
  212. // print the type and size of the first FAT-type volume
  213. uint32_t volumesize;
  214. usb.print("\nVolume type is FAT");
  215. usb.println(volume.fatType(), DEC);
  216. usb.println();
  217. // clusters are collections of blocks
  218. volumesize = volume.blocksPerCluster();
  219. // we'll have a lot of clusters
  220. volumesize *= volume.clusterCount();
  221. if (volumesize < 8388608ul) {
  222. usb.print("Volume size (bytes): ");
  223. // SD card blocks are always 512 bytes
  224. usb.println(volumesize * 512);
  225. }
  226. usb.print("Volume size (Kbytes): ");
  227. volumesize /= 2;
  228. usb.println(volumesize);
  229. usb.print("Volume size (Mbytes): ");
  230. volumesize /= 1024;
  231. usb.println(volumesize);
  232. usb.println("\nFiles found on the card (name, date and size in bytes): ");
  233. root.openRoot(volume);
  234. // list all files in the card with date and size
  235. root.ls(LS_R | LS_DATE | LS_SIZE);
  236. delay(100);
  237. }
  238. // ------------------------------------------------------------------------
  239. void rtc_seconds_isr() {
  240. // zero out millisecond counter
  241. rtcMilliSeconds = 0;
  242. }
  243. time_t getTeensy3Time() {
  244. // set rtc seconds interrupt
  245. //RTC_IER |= 0x10;
  246. rtcMilliSeconds = 0;
  247. // enable interrupt
  248. //NVIC_ENABLE_IRQ(IRQ_RTC_SECOND);
  249. return Teensy3Clock.get();
  250. }
  251. // ------------------------------------------------------------------------
  252. String digitalClockDisplay(elapsedMillis millis_t) {
  253. String time;
  254. if (hour() < 10) time += 0;
  255. //< 10 ? '0' + hour() : hour();
  256. time += hour();
  257. time += ":";
  258. if (minute() < 10) time += 0;
  259. //< 10 ? '0' + minute() : minute();
  260. time += minute();
  261. time += ":";
  262. if (second() < 10) time += 0;
  263. time += second();
  264. time += ".";
  265. if (millis_t < 100) time += 0;
  266. if (millis_t < 10) time += 0;
  267. time += (int)millis_t;
  268. return time;
  269. }
  270. // ------------------------------------------------------------------------
  271. void blink() {
  272. digitalWriteFast(LED_BUILTIN, HIGH);
  273. delay(15);
  274. digitalWriteFast(LED_BUILTIN, LOW);
  275. delay(15);
  276. }