/********************************************************** This sketch shows the use of SPI Driver used in Snooze along with the standard SD and Bounce libraries. In this example the Teensy SD Data-Logger will deepSleep until you push the button (WAKEUP_BUTTON) which will wake the Teensy and start logging data until the button is released in which the Teensy will go back into deepSleep. The SPI Driver configures the SDIO or SPI pins to minimize leakage current during deepSleep and reconfigure the pins back after wake up. Supported Micros: T-LC/3.x Teensy 4.0 hibernate wakes up with a reset so this sketch will not work. ***********************************************************/ /*********************************************************** SNOOZE ***********************************************************/ #include // Load drivers // SnoozeUSBSerial driver does what Serial does like "print", - // "println", "prinf", etc and also handles the effects of using - // the Arduino Serial monitor and sleeping. Use it when you - // want to print to serial monitor for sleeping applications. SnoozeUSBSerial usb; SnoozeDigital digital; SnoozeSPI sdCard; SnoozeBlock config(usb, digital, sdCard); /*********************************************************** SD ***********************************************************/ #include #include // set up variables using the SD utility library functions: Sd2Card card; SdVolume volume; SdFile root; const int chipSelect = BUILTIN_SDCARD; /*********************************************************** BOUNCE ***********************************************************/ #include const uint8_t WAKEUP_BUTTON = 7; // use bounce for pin 7, debounce of 5ms Bounce button = Bounce(WAKEUP_BUTTON, 5); /*********************************************************** TIME ***********************************************************/ #include elapsedMillis rtcMilliSeconds; /***********************************************************/ uint32_t dataCount; // ---------------------------------------------------------------------------------------------- void setup() { // setSyncProvider(getTeensy3Time); // dataCount = 0; // Configure LED Pin pinMode(LED_BUILTIN, OUTPUT); // Configure pin 21 for bounce library pinMode(WAKEUP_BUTTON, INPUT_PULLUP); /******************Snooze Driver Config******************/ // Configure pin WAKEUP_BUTTON for Snooze wakeup, also - // used by bounce but no need to reconfigure the pin - // after waking Snooze does it for you. digital.pinMode(WAKEUP_BUTTON, INPUT_PULLUP, FALLING);//pin, mode, type // Configure SD Card for Low Power operation sdCard.setClockPin( BUILTIN_SDCARD ); /****************End Snooze Driver Config****************/ // UNCOMMENT THESE TWO LINES FOR TEENSY AUDIO BOARD: //SPI.setMOSI(7); // Audio shield has MOSI on pin 7 //SPI.setSCK(14); // Audio shield has SCK on pin 14 // Wait for Serial connection to open. while (!usb); delay(100); usb.println("Snooze SD Card Push Button Hold Data-Logger Example"); usb.println("---------------------------------------------------"); // see if the card is present and can be initialized: SD.begin(chipSelect); if (!card.init(SPI_HALF_SPEED, chipSelect)) { // don't do anything more: while (1) { usb.println("Card failed, or not present!"); blink(); blink(); } } elapsedMillis time = 0; while (time < 1000) { usb.print("."); delay(200); } usb.println(); usb.print("-> "); usb.println("SD Card Initialized."); sdCardInfo(); delay(1000); } // ------------------------------------------------------------------------ void loop() { sleepDataLogger(); handleButtonHold(); } // ------------------------------------------------------------------------ inline void sleepDataLogger() { SLEEP: digitalWriteFast(LED_BUILTIN, LOW); usb.println("Logger Will Sleep Now..."); // delay to finish usb print before sleeping delay(5); // you need to update bounce before sleeping. button.update(); // put Teensy into low power sleep mode Snooze.hibernate( config ); digitalWriteFast(LED_BUILTIN, HIGH); // check for 300ms that the button is held bool hold = threeHundredMilliSecondHoldCheck(); // if not held for 300ms go back to sleep if (hold == false) goto SLEEP; usb.println("Data Logger now awake, ready to log data."); } // ------------------------------------------------------------------ // Make sure the button is help low for aleast 300ms before data logging. bool threeHundredMilliSecondHoldCheck() { button.update(); // Pin is configured as PULLUP so 0 means the button has been // pushed. while (button.read() == 0) { // Monitor the pin hold duration. if (button.duration() > 300) return true; // Update bounce library. button.update(); } return false; } // ------------------------------------------------------------------------ void handleButtonHold() { button.update(); if (button.read() == HIGH) { usb.println("No Logging of Data!!! Button released before logging could commence."); return; } usb.println("Logging data"); button.update(); elapsedMillis log_time = 0; while (button.read() == LOW) { if (log_time >= 99) { log_time = 0; logData(dataCount++); } button.update(); } digitalWrite(LED_BUILTIN, LOW); } // ------------------------------------------------------------------------ void logData(uint32_t count) { // make a string for assembling the data to log: String dataString;//"Time\tAna1\tAna2\tAna3\r\n"; // read three sensors and append to the string: dataString = digitalClockDisplay(rtcMilliSeconds - 1); dataString += "\t"; dataString += String(count); dataString += String("\t"); for (int analogPin = 0; analogPin < 3; analogPin++) { dataString += analogRead(analogPin); if ( analogPin < 2) dataString += "\t"; } dataString += "\r\n"; // open the file. note that only one file can be open at a time, // so you have to close this one before opening another. File dataFile = SD.open("datalog.txt", FILE_WRITE); // if the file is available, write to it: if (dataFile) { dataFile.print(dataString); dataFile.close(); // print to the serial port too: int len = dataString.length(); usb.print(dataString); } // if the file isn't open, pop up an error: else { usb.println("error opening datalog.txt."); } } // ------------------------------------------------------------------------ void sdCardInfo() { // print the type of card usb.print("-> Card type: "); switch (card.type()) { case SD_CARD_TYPE_SD1: { usb.println("SD1"); break; } case SD_CARD_TYPE_SD2: { usb.println("SD2"); break; } case SD_CARD_TYPE_SDHC: { usb.println("SDHC"); break; } default: { usb.println("Unknown"); break; } } // Now we will try to open the 'volume'/'partition' - it should be FAT16 or FAT32 if (!volume.init(card)) { usb.println("Could not find FAT16/FAT32 partition.\nMake sure you've formatted the card"); return; } // print the type and size of the first FAT-type volume uint32_t volumesize; usb.print("\nVolume type is FAT"); usb.println(volume.fatType(), DEC); usb.println(); // clusters are collections of blocks volumesize = volume.blocksPerCluster(); // we'll have a lot of clusters volumesize *= volume.clusterCount(); if (volumesize < 8388608ul) { usb.print("Volume size (bytes): "); // SD card blocks are always 512 bytes usb.println(volumesize * 512); } usb.print("Volume size (Kbytes): "); volumesize /= 2; usb.println(volumesize); usb.print("Volume size (Mbytes): "); volumesize /= 1024; usb.println(volumesize); usb.println("\nFiles found on the card (name, date and size in bytes): "); root.openRoot(volume); // list all files in the card with date and size root.ls(LS_R | LS_DATE | LS_SIZE); delay(100); } // ------------------------------------------------------------------------ void rtc_seconds_isr() { // zero out millisecond counter rtcMilliSeconds = 0; } time_t getTeensy3Time() { // set rtc seconds interrupt //RTC_IER |= 0x10; rtcMilliSeconds = 0; // enable interrupt //NVIC_ENABLE_IRQ(IRQ_RTC_SECOND); return Teensy3Clock.get(); } // ------------------------------------------------------------------------ String digitalClockDisplay(elapsedMillis millis_t) { String time; if (hour() < 10) time += 0; //< 10 ? '0' + hour() : hour(); time += hour(); time += ":"; if (minute() < 10) time += 0; //< 10 ? '0' + minute() : minute(); time += minute(); time += ":"; if (second() < 10) time += 0; time += second(); time += "."; if (millis_t < 100) time += 0; if (millis_t < 10) time += 0; time += (int)millis_t; return time; } // ------------------------------------------------------------------------ void blink() { digitalWriteFast(LED_BUILTIN, HIGH); delay(15); digitalWriteFast(LED_BUILTIN, LOW); delay(15); }