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.

301 lines
8.9KB

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