├── Libraries ├── SdFat │ ├── examples │ │ ├── LongFileName │ │ │ ├── testFiles │ │ │ │ ├── OK%83.TXT │ │ │ │ ├── STD_8_3.TXT │ │ │ │ ├── LFN,NAME.TXT │ │ │ │ ├── With Blank.txt │ │ │ │ ├── Not_8_3.txt │ │ │ │ ├── With.Two dots.txt │ │ │ │ ├── A long name can be 255 characters.txt │ │ │ │ ├── mixed.TXT │ │ │ │ ├── lower.txt │ │ │ │ └── MIXCASE.txt │ │ │ └── LongFileName.ino │ │ ├── LowLatencyLogger │ │ │ └── UserDataType.h │ │ ├── #attic │ │ │ ├── HelloWorld │ │ │ │ └── HelloWorld.ino │ │ │ ├── SD_Size │ │ │ │ └── SD_Size.ino │ │ │ ├── SdFatSize │ │ │ │ └── SdFatSize.ino │ │ │ ├── MiniSerial │ │ │ │ └── MiniSerial.ino │ │ │ ├── bufstream │ │ │ │ └── bufstream.ino │ │ │ ├── readme.txt │ │ │ ├── BaseExtCaseTest │ │ │ │ └── BaseExtCaseTest.ino │ │ │ ├── readlog │ │ │ │ └── readlog.ino │ │ │ ├── eventlog │ │ │ │ └── eventlog.ino │ │ │ ├── append │ │ │ │ └── append.ino │ │ │ ├── average │ │ │ │ └── average.ino │ │ │ ├── fgetsRewrite │ │ │ │ └── fgetsRewrite.ino │ │ │ ├── PrintBenchmarkSD │ │ │ │ └── PrintBenchmarkSD.ino │ │ │ ├── benchSD │ │ │ │ └── benchSD.ino │ │ │ └── AnalogLogger │ │ │ │ └── AnalogLogger.ino │ │ ├── cin_cout │ │ │ └── cin_cout.ino │ │ ├── StreamParseInt │ │ │ └── StreamParseInt.ino │ │ ├── OpenNext │ │ │ └── OpenNext.ino │ │ ├── SoftwareSpi │ │ │ └── SoftwareSpi.ino │ │ ├── AnalogBinLogger │ │ │ └── AnalogBinLogger.h │ │ ├── formatting │ │ │ └── formatting.ino │ │ ├── ReadWriteSdFat │ │ │ └── ReadWriteSdFat.ino │ │ ├── ReadWrite │ │ │ └── ReadWrite.ino │ │ ├── fgets │ │ │ └── fgets.ino │ │ ├── getline │ │ │ └── getline.ino │ │ ├── VolumeFreeSpace │ │ │ └── VolumeFreeSpace.ino │ │ ├── rename │ │ │ └── rename.ino │ │ ├── readCSV │ │ │ └── readCSV.ino │ │ ├── directoryFunctions │ │ │ └── directoryFunctions.ino │ │ ├── PrintBenchmark │ │ │ └── PrintBenchmark.ino │ │ ├── dataLogger │ │ │ └── dataLogger.ino │ │ ├── Timestamp │ │ │ └── Timestamp.ino │ │ ├── TwoCards │ │ │ └── TwoCards.ino │ │ ├── QuickStart │ │ │ └── QuickStart.ino │ │ ├── RawWrite │ │ │ └── RawWrite.ino │ │ ├── bench │ │ │ └── bench.ino │ │ └── StdioBench │ │ │ └── StdioBench.ino │ ├── readme.md │ ├── library.properties │ └── src │ │ ├── FatLib │ │ ├── FatLib.h │ │ ├── FmtNumber.h │ │ ├── FatApiConstants.h │ │ ├── ArduinoStream.h │ │ ├── iostream.h │ │ ├── bufstream.h │ │ ├── fstream.cpp │ │ ├── FatLibConfig.h │ │ └── ostream.cpp │ │ ├── FreeStack.h │ │ ├── MinimumSerial.h │ │ ├── SdFatUtil.cpp │ │ ├── MinimumSerial.cpp │ │ ├── SdFatUtil.h │ │ ├── Deprecated │ │ └── SdVolume.h │ │ ├── SdFat.cpp │ │ └── SdSpiCard │ │ └── SoftSPI.h └── SerialPort │ ├── readme.md │ └── examples │ ├── ArduinoSize │ ├── ArduinoSize.ino │ ├── ArduinoSize.pde │ └── FreeRam.h │ ├── HelloWorld │ ├── HelloWorld.ino │ └── HelloWorld.pde │ ├── BufferedSize │ ├── FreeRam.h │ ├── BufferedSize.ino │ └── BufferedSize.pde │ ├── UnbufferedSize │ ├── FreeRam.h │ ├── UnbufferedSize.pde │ └── UnbufferedSize.ino │ ├── WriteFlash │ ├── WriteFlash.pde │ └── WriteFlash.ino │ ├── ArduinoTest │ ├── ArduinoTest.ino │ └── ArduinoTest.pde │ ├── BufferedTest │ ├── BufferedTest.pde │ └── BufferedTest.ino │ ├── UnbufferedTest │ ├── UnbufferedTest.ino │ └── UnbufferedTest.pde │ ├── MegaTestArduino │ ├── MegaTestArduino.pde │ └── MegaTestArduino.ino │ ├── ReadWriteTest │ ├── ReadWriteTest.pde │ └── ReadWriteTest.ino │ └── MegaTest │ ├── MegaTest.pde │ └── MegaTest.ino ├── Binaries ├── avrdude.exe ├── readme.md └── batch_program.bat ├── Documentation ├── OpenLogFTDI.png └── OpenLogProMini.png ├── hardware ├── OpenLogSchematic.pdf └── OpenLogDimensionalDrawing.pdf ├── .gitattributes ├── ISSUE_TEMPLATE.md ├── .gitignore ├── firmware ├── README.md └── Arduino_Examples │ ├── Example2_HardwareLogging │ └── Example2_HardwareLogging.ino │ ├── Example1_SoftwareLogging │ └── Example1_SoftwareLogging.ino │ ├── Performance_Testing │ ├── CommandPrompt_Power │ │ └── CommandPrompt_Power.ino │ ├── Buffer_Overrun_Test_Binary │ │ └── Buffer_Overrun_Test_Binary.ino │ └── Buffer_Overrun_Test │ │ └── Buffer_Overrun_Test.ino │ └── Example6_GetVersionNumber │ └── Example6_GetVersionNumber.ino ├── LICENSE.md └── README.md /Libraries/SdFat/examples/LongFileName/testFiles/OK%83.TXT: -------------------------------------------------------------------------------- 1 | OK%83.TXT is a valid 8.3 name. -------------------------------------------------------------------------------- /Binaries/avrdude.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sparkfun/OpenLog/HEAD/Binaries/avrdude.exe -------------------------------------------------------------------------------- /Libraries/SdFat/examples/LongFileName/testFiles/STD_8_3.TXT: -------------------------------------------------------------------------------- 1 | STD_8_3.TXT - a vanilla 8.3 name. -------------------------------------------------------------------------------- /Libraries/SdFat/readme.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sparkfun/OpenLog/HEAD/Libraries/SdFat/readme.md -------------------------------------------------------------------------------- /Libraries/SdFat/examples/LongFileName/testFiles/LFN,NAME.TXT: -------------------------------------------------------------------------------- 1 | LFN,NAME.TXT is not 8.3 since it has a comma. -------------------------------------------------------------------------------- /Documentation/OpenLogFTDI.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sparkfun/OpenLog/HEAD/Documentation/OpenLogFTDI.png -------------------------------------------------------------------------------- /Libraries/SerialPort/readme.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sparkfun/OpenLog/HEAD/Libraries/SerialPort/readme.md -------------------------------------------------------------------------------- /hardware/OpenLogSchematic.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sparkfun/OpenLog/HEAD/hardware/OpenLogSchematic.pdf -------------------------------------------------------------------------------- /Documentation/OpenLogProMini.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sparkfun/OpenLog/HEAD/Documentation/OpenLogProMini.png -------------------------------------------------------------------------------- /Libraries/SdFat/examples/LongFileName/testFiles/With Blank.txt: -------------------------------------------------------------------------------- 1 | With Blank.txt 2 | Just another example of a Long File Name. 3 | -------------------------------------------------------------------------------- /hardware/OpenLogDimensionalDrawing.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sparkfun/OpenLog/HEAD/hardware/OpenLogDimensionalDrawing.pdf -------------------------------------------------------------------------------- /Libraries/SdFat/examples/LongFileName/testFiles/Not_8_3.txt: -------------------------------------------------------------------------------- 1 | Not_8_3.txt has a Long File Name 2 | since the basename is mixed case. -------------------------------------------------------------------------------- /Libraries/SdFat/examples/LongFileName/testFiles/With.Two dots.txt: -------------------------------------------------------------------------------- 1 | "With Two.dots.txt" 2 | Lots of reasons this is a Long File Name. 3 | -------------------------------------------------------------------------------- /Libraries/SdFat/library.properties: -------------------------------------------------------------------------------- 1 | name=SdFat 2 | version=2015.4.26 3 | author= 4 | maintainer= 5 | sentence=FAT16/FAT32 file system for SD cards. 6 | paragraph= 7 | category=Uncategorized 8 | url= 9 | architectures=* 10 | -------------------------------------------------------------------------------- /Libraries/SdFat/examples/LongFileName/testFiles/A long name can be 255 characters.txt: -------------------------------------------------------------------------------- 1 | This is "A long name can be 255 characters.txt" 2 | This file has a typical Long File Name. 3 | 4 | The maximum length of a Long File Name is 255 characters. 5 | -------------------------------------------------------------------------------- /Libraries/SdFat/examples/LongFileName/testFiles/mixed.TXT: -------------------------------------------------------------------------------- 1 | mixed.TXT does not have a Long File Name. 2 | 3 | Starting with NT, file names of this form, 4 | have the basename and extension character case 5 | encoded in two bits of the 8.3 directory entry. -------------------------------------------------------------------------------- /Libraries/SdFat/examples/LongFileName/testFiles/lower.txt: -------------------------------------------------------------------------------- 1 | lower.txt does not have a Long File Name. 2 | 3 | Starting with NT, file names of this form, 4 | have the basename and extension character case 5 | encoded in two bits of the 8.3 directory entry. 6 | -------------------------------------------------------------------------------- /Libraries/SdFat/examples/LongFileName/testFiles/MIXCASE.txt: -------------------------------------------------------------------------------- 1 | MIXCASE.txt does not have a Long File Name. 2 | 3 | Starting with NT, file names of this form, 4 | have the basename and extension character case 5 | encoded in two bits of the 8.3 directory entry. 6 | -------------------------------------------------------------------------------- /Libraries/SdFat/examples/LowLatencyLogger/UserDataType.h: -------------------------------------------------------------------------------- 1 | #ifndef UserDataType_h 2 | #define UserDataType_h 3 | const uint8_t ADC_DIM = 4; 4 | struct data_t { 5 | unsigned long time; 6 | unsigned short adc[ADC_DIM]; 7 | }; 8 | #endif // UserDataType_h 9 | -------------------------------------------------------------------------------- /Libraries/SerialPort/examples/ArduinoSize/ArduinoSize.ino: -------------------------------------------------------------------------------- 1 | // Print free RAM for Arduino HardwareSerial 2 | // 3 | #include "FreeRam.h" 4 | 5 | void setup() { 6 | Serial.begin(9600); 7 | Serial.println(FreeRam()); 8 | } 9 | void loop() { 10 | } 11 | -------------------------------------------------------------------------------- /Libraries/SerialPort/examples/ArduinoSize/ArduinoSize.pde: -------------------------------------------------------------------------------- 1 | // Print free RAM for Arduino HardwareSerial 2 | // 3 | #include "FreeRam.h" 4 | 5 | void setup() { 6 | Serial.begin(9600); 7 | Serial.println(FreeRam()); 8 | } 9 | void loop() { 10 | } 11 | -------------------------------------------------------------------------------- /Binaries/readme.md: -------------------------------------------------------------------------------- 1 | Programming OpenLog via Serial 2 | =========================================================== 3 | 4 | The SparkFun OpenLog can be updated using a USB to serial adapter and 5 jumper wires. Run batch_program.bat with a given COM port and HEX file. -------------------------------------------------------------------------------- /Libraries/SerialPort/examples/HelloWorld/HelloWorld.ino: -------------------------------------------------------------------------------- 1 | // Simple usage with buffering like Arduino 1.0. 2 | #include 3 | 4 | // use NewSerial for port 0 5 | USE_NEW_SERIAL; 6 | 7 | void setup() { 8 | NewSerial.begin(9600); 9 | NewSerial.println("Hello World!"); 10 | } 11 | void loop() {} -------------------------------------------------------------------------------- /Libraries/SerialPort/examples/HelloWorld/HelloWorld.pde: -------------------------------------------------------------------------------- 1 | // Simple usage with buffering like Arduino 1.0 2 | #include 3 | 4 | // use NewSerial for port 0 5 | USE_NEW_SERIAL; 6 | 7 | void setup() { 8 | NewSerial.begin(9600); 9 | NewSerial.println("Hello World!"); 10 | } 11 | void loop() {} -------------------------------------------------------------------------------- /Libraries/SerialPort/examples/ArduinoSize/FreeRam.h: -------------------------------------------------------------------------------- 1 | #include 2 | static inline int FreeRam() { 3 | extern char *__brkval; 4 | char top; 5 | #if defined(CORE_TEENSY) 6 | return &top - __brkval; 7 | #else // malloc type 8 | return __brkval ? &top - __brkval : &top - __malloc_heap_start; 9 | #endif // malloc type 10 | } 11 | -------------------------------------------------------------------------------- /Libraries/SerialPort/examples/BufferedSize/FreeRam.h: -------------------------------------------------------------------------------- 1 | #include 2 | static inline int FreeRam() { 3 | extern char *__brkval; 4 | char top; 5 | #if defined(CORE_TEENSY) 6 | return &top - __brkval; 7 | #else // malloc type 8 | return __brkval ? &top - __brkval : &top - __malloc_heap_start; 9 | #endif // malloc type 10 | } 11 | -------------------------------------------------------------------------------- /Libraries/SerialPort/examples/UnbufferedSize/FreeRam.h: -------------------------------------------------------------------------------- 1 | #include 2 | static inline int FreeRam() { 3 | extern char *__brkval; 4 | char top; 5 | #if defined(CORE_TEENSY) 6 | return &top - __brkval; 7 | #else // malloc type 8 | return __brkval ? &top - __brkval : &top - __malloc_heap_start; 9 | #endif // malloc type 10 | } 11 | -------------------------------------------------------------------------------- /Libraries/SdFat/examples/#attic/HelloWorld/HelloWorld.ino: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | // create a serial output stream 5 | ArduinoOutStream cout(Serial); 6 | 7 | void setup() { 8 | Serial.begin(9600); 9 | 10 | while (!Serial) {} // wait for Leonardo 11 | delay(2000); 12 | 13 | cout << "Hello, World!\n"; 14 | } 15 | 16 | void loop() {} 17 | -------------------------------------------------------------------------------- /Libraries/SerialPort/examples/BufferedSize/BufferedSize.ino: -------------------------------------------------------------------------------- 1 | // Print free RAM for Arduino 1.0 style buffering. 2 | // 3 | #include 4 | #include "FreeRam.h" 5 | 6 | SerialPort<0, 63, 63> NewSerial; 7 | 8 | // for Arduino 0022 style buffering use this 9 | //SerialPort<0, 127, 0> NewSerial; 10 | 11 | void setup() { 12 | NewSerial.begin(9600); 13 | NewSerial.println(FreeRam()); 14 | } 15 | void loop() {} -------------------------------------------------------------------------------- /Libraries/SerialPort/examples/BufferedSize/BufferedSize.pde: -------------------------------------------------------------------------------- 1 | // print free RAM for Arduino 1.0 style buffering 2 | // 3 | #include 4 | #include "FreeRam.h" 5 | 6 | SerialPort<0, 63, 63> NewSerial; 7 | 8 | // for Arduino 0022 style buffering use this 9 | //SerialPort<0, 127, 0> NewSerial; 10 | 11 | void setup() { 12 | NewSerial.begin(9600); 13 | NewSerial.println(FreeRam()); 14 | } 15 | void loop() {} -------------------------------------------------------------------------------- /Libraries/SerialPort/examples/UnbufferedSize/UnbufferedSize.pde: -------------------------------------------------------------------------------- 1 | // print free RAM for unbuffered mode 2 | // you can reduce flash and RAM use more by setting 3 | // BUFFERED_TX and BUFFERED_RX zero in SerialPort.h 4 | // 5 | #include 6 | #include "FreeRam.h" 7 | 8 | // no buffers 9 | SerialPort<0, 0, 0> NewSerial; 10 | 11 | void setup() { 12 | NewSerial.begin(9600); 13 | NewSerial.println(FreeRam()); 14 | } 15 | void loop() {} -------------------------------------------------------------------------------- /Libraries/SerialPort/examples/UnbufferedSize/UnbufferedSize.ino: -------------------------------------------------------------------------------- 1 | // Print free RAM for unbuffered mode. 2 | // 3 | // You can reduce flash and RAM use more by setting 4 | // BUFFERED_TX and BUFFERED_RX zero in SerialPort.h 5 | // to always disable buffering. 6 | // 7 | #include 8 | #include "FreeRam.h" 9 | 10 | // no buffers 11 | SerialPort<0, 0, 0> NewSerial; 12 | 13 | void setup() { 14 | NewSerial.begin(9600); 15 | NewSerial.println(FreeRam()); 16 | } 17 | void loop() {} -------------------------------------------------------------------------------- /Libraries/SerialPort/examples/WriteFlash/WriteFlash.pde: -------------------------------------------------------------------------------- 1 | // test write() for a flash string 2 | #include 3 | 4 | SerialPort<0, 0, 32> port; 5 | 6 | void setup(void) { 7 | port.begin(115200); 8 | 9 | for (int route = 0; route < 11; route++) { 10 | uint32_t start = micros(); 11 | port.writeln(F("Selecting passenger route x")); 12 | uint32_t stop = micros(); 13 | port.write(F("Message time: ")); 14 | port.print(stop - start, DEC); 15 | port.writeln(F(" us")); 16 | delay(400); 17 | } 18 | } 19 | void loop(void) {} 20 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | *.sln merge=union 7 | *.csproj merge=union 8 | *.vbproj merge=union 9 | *.fsproj merge=union 10 | *.dbproj merge=union 11 | 12 | # Standard to msysgit 13 | *.doc diff=astextplain 14 | *.DOC diff=astextplain 15 | *.docx diff=astextplain 16 | *.DOCX diff=astextplain 17 | *.dot diff=astextplain 18 | *.DOT diff=astextplain 19 | *.pdf diff=astextplain 20 | *.PDF diff=astextplain 21 | *.rtf diff=astextplain 22 | *.RTF diff=astextplain 23 | -------------------------------------------------------------------------------- /Binaries/batch_program.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | rem This batch file does not set the fuse bits. We assume you are updating a pre-existing OpenLog 3 | 4 | if [%1]==[] goto usage 5 | 6 | @echo Programming the SparkFun OpenLog 7 | @pause 8 | :loop 9 | 10 | @echo - 11 | @echo Programming binary: %1 on %2 12 | 13 | @avrdude -Cavrdude.conf -v -V -patmega328p -carduino -P %2 -b115200 -D -Uflash:w:%1:i 14 | 15 | @echo Done programming! Ready for next board. 16 | @pause 17 | 18 | goto loop 19 | 20 | :usage 21 | @echo Missing the binary file and com port arguments. Ex: batch_program.bat OpenLog_v43.hex COM3 22 | -------------------------------------------------------------------------------- /Libraries/SerialPort/examples/WriteFlash/WriteFlash.ino: -------------------------------------------------------------------------------- 1 | // Test write() time for a flash string. 2 | #include 3 | 4 | SerialPort<0, 0, 32> port; 5 | 6 | void setup(void) { 7 | port.begin(9600); 8 | 9 | for (int route = 0; route < 11; route++) { 10 | uint32_t start = micros(); 11 | port.writeln(F("Selecting passenger route x")); 12 | uint32_t stop = micros(); 13 | port.write(F("Message time: ")); 14 | port.print(stop - start, DEC); 15 | port.writeln(F(" us")); 16 | delay(400); 17 | } 18 | port.println(F("Done!")); 19 | } 20 | void loop(void) {} 21 | -------------------------------------------------------------------------------- /Libraries/SerialPort/examples/ArduinoTest/ArduinoTest.ino: -------------------------------------------------------------------------------- 1 | 2 | void setup() { 3 | Serial.begin(9600); 4 | uint32_t t = micros(); 5 | Serial.write("This string is used to measure the time to buffer data.\r\n"); 6 | t = micros() - t; 7 | Serial.write("Time: "); 8 | Serial.print(t); 9 | Serial.write(" us\r\n"); 10 | } 11 | void loop() { 12 | Serial.write("\r\nenter a string\r\n"); 13 | while (!Serial.available()) {} 14 | do { 15 | Serial.write(Serial.read()); 16 | uint32_t m = millis(); 17 | while (!Serial.available() && (millis() - m) < 3) {} 18 | } while(Serial.available()); 19 | Serial.write("\r\n"); 20 | } -------------------------------------------------------------------------------- /Libraries/SerialPort/examples/ArduinoTest/ArduinoTest.pde: -------------------------------------------------------------------------------- 1 | 2 | void setup() { 3 | Serial.begin(9600); 4 | uint32_t t = micros(); 5 | Serial.write("This string is used to measure the time to buffer data.\r\n"); 6 | t = micros() - t; 7 | Serial.write("Time: "); 8 | Serial.print(t); 9 | Serial.write(" us\r\n"); 10 | } 11 | void loop() { 12 | Serial.write("\r\nenter a string\r\n"); 13 | while (!Serial.available()) {} 14 | do { 15 | Serial.write(Serial.read()); 16 | uint32_t m = millis(); 17 | while (!Serial.available() && (millis() - m) < 3) {} 18 | } while(Serial.available()); 19 | Serial.write("\r\n"); 20 | } -------------------------------------------------------------------------------- /ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | ### Subject of the issue 2 | Describe your issue here. 3 | 4 | ### Your workbench 5 | * What platform are you using? 6 | * What version of the device are you using? Is there a firmware version? 7 | * How is the device wired to your platform? 8 | * How is everything being powered? 9 | * Are there any additional details that may help us help you? 10 | 11 | ### Steps to reproduce 12 | Tell us how to reproduce this issue. Please post stripped down example code demonstrating your issue to a gist. 13 | 14 | ### Expected behavior 15 | Tell us what should happen 16 | 17 | ### Actual behavior 18 | Tell us what happens instead 19 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Windows image file caches 2 | Thumbs.db 3 | ehthumbs.db 4 | 5 | #Eagle Backup files 6 | *.s#? 7 | *.b#? 8 | *.l#? 9 | *.lck 10 | 11 | # Folder config file 12 | Desktop.ini 13 | 14 | # Recycle Bin used on file shares 15 | $RECYCLE.BIN/ 16 | 17 | # Windows Installer files 18 | *.cab 19 | *.msi 20 | *.msm 21 | *.msp 22 | 23 | # ========================= 24 | # Operating System Files 25 | # ========================= 26 | 27 | # OSX 28 | # ========================= 29 | 30 | .DS_Store 31 | .AppleDouble 32 | .LSOverride 33 | 34 | # Icon must ends with two \r. 35 | Icon 36 | 37 | # Thumbnails 38 | ._* 39 | 40 | # Files that might appear on external disk 41 | .Spotlight-V100 42 | .Trashes 43 | -------------------------------------------------------------------------------- /Libraries/SdFat/examples/#attic/SD_Size/SD_Size.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * Program to compare size of Arduino SD library with SdFat. 3 | * See SdFatSize.ino for SdFat program. 4 | */ 5 | #include 6 | #include 7 | 8 | File file; 9 | //------------------------------------------------------------------------------ 10 | void setup() { 11 | Serial.begin(9600); 12 | while (!Serial) {} // wait for Leonardo 13 | 14 | if (!SD.begin()) { 15 | Serial.println("begin failed"); 16 | return; 17 | } 18 | file = SD.open("TEST_SD.TXT", FILE_WRITE); 19 | 20 | file.println("Hello"); 21 | 22 | file.close(); 23 | Serial.println("Done"); 24 | } 25 | //------------------------------------------------------------------------------ 26 | void loop() {} 27 | -------------------------------------------------------------------------------- /Libraries/SerialPort/examples/BufferedTest/BufferedTest.pde: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | // port zero, 63 character RX and TX buffers 4 | SerialPort<0, 63, 63> NewSerial; 5 | 6 | void setup() { 7 | NewSerial.begin(9600); 8 | uint32_t t = micros(); 9 | NewSerial.write("This string is used to measure the time to buffer data.\r\n"); 10 | t = micros() - t; 11 | NewSerial.write("Time: "); 12 | NewSerial.print(t); 13 | NewSerial.write(" us\r\n"); 14 | } 15 | void loop() { 16 | NewSerial.write("\r\nenter a string\r\n"); 17 | while (!NewSerial.available()) {} 18 | do { 19 | NewSerial.write(NewSerial.read()); 20 | uint32_t m = millis(); 21 | while (!NewSerial.available() && (millis() - m) < 3) {} 22 | } while(NewSerial.available()); 23 | NewSerial.write("\r\n"); 24 | } -------------------------------------------------------------------------------- /Libraries/SerialPort/examples/UnbufferedTest/UnbufferedTest.ino: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | // serial port zero with no RX or TX buffering 4 | SerialPort<0, 0, 0> NewSerial; 5 | 6 | void setup() { 7 | NewSerial.begin(9600); 8 | uint32_t t = micros(); 9 | NewSerial.write("This string is used to measure the time to buffer data.\r\n"); 10 | t = micros() - t; 11 | NewSerial.write("Time: "); 12 | NewSerial.print(t); 13 | NewSerial.write(" us\r\n"); 14 | } 15 | void loop() { 16 | NewSerial.write("\r\nenter a string\r\n"); 17 | while (!NewSerial.available()) {} 18 | do { 19 | NewSerial.write(NewSerial.read()); 20 | uint32_t m = millis(); 21 | while (!NewSerial.available() && (millis() - m) < 3) {} 22 | } while(NewSerial.available()); 23 | NewSerial.write("\r\n"); 24 | } -------------------------------------------------------------------------------- /Libraries/SerialPort/examples/UnbufferedTest/UnbufferedTest.pde: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | // serial port zero with no RX or TX buffering 4 | SerialPort<0, 0, 0> NewSerial; 5 | 6 | void setup() { 7 | NewSerial.begin(9600); 8 | uint32_t t = micros(); 9 | NewSerial.write("This string is used to measure the time to buffer data.\r\n"); 10 | t = micros() - t; 11 | NewSerial.write("Time: "); 12 | NewSerial.print(t); 13 | NewSerial.write(" us\r\n"); 14 | } 15 | void loop() { 16 | NewSerial.write("\r\nenter a string\r\n"); 17 | while (!NewSerial.available()) {} 18 | do { 19 | NewSerial.write(NewSerial.read()); 20 | uint32_t m = millis(); 21 | while (!NewSerial.available() && (millis() - m) < 3) {} 22 | } while(NewSerial.available()); 23 | NewSerial.write("\r\n"); 24 | } -------------------------------------------------------------------------------- /Libraries/SdFat/examples/#attic/SdFatSize/SdFatSize.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * Program to compare size of SdFat with Arduino SD library. 3 | * See SD_Size.ino for Arduino SD program. 4 | * 5 | */ 6 | #include 7 | #include 8 | 9 | SdFat sd; 10 | 11 | SdFile file; 12 | //------------------------------------------------------------------------------ 13 | void setup() { 14 | Serial.begin(9600); 15 | while (!Serial) {} // wait for Leonardo 16 | 17 | if (!sd.begin()) { 18 | Serial.println("begin failed"); 19 | return; 20 | } 21 | file.open("SizeTest.txt", O_RDWR | O_CREAT | O_AT_END); 22 | 23 | file.println("Hello"); 24 | 25 | file.close(); 26 | Serial.println("Done"); 27 | } 28 | //------------------------------------------------------------------------------ 29 | void loop() {} 30 | -------------------------------------------------------------------------------- /Libraries/SerialPort/examples/MegaTestArduino/MegaTestArduino.pde: -------------------------------------------------------------------------------- 1 | // Test all ports on the Mega 2 | // 3 | // place loopback jumpers, RX connected to TX, 4 | // on ports 1, 2, and 3. 5 | // 6 | void transfer(Stream* in, Stream* out) { 7 | while(!in->available()) {} 8 | do { 9 | out->write(in->read()); 10 | uint32_t m = millis(); 11 | while (!in->available() && (millis() - m) < 3) {} 12 | } while (in->available()); 13 | } 14 | void setup() { 15 | Serial.begin(9600); 16 | Serial1.begin(9600); 17 | Serial2.begin(9600); 18 | Serial3.begin(9600); 19 | } 20 | void loop() { 21 | Serial.write("type a string\r\n"); 22 | transfer(&Serial, &Serial1); 23 | transfer(&Serial1, &Serial2); 24 | transfer(&Serial2, &Serial3); 25 | transfer(&Serial3, &Serial); 26 | Serial.write("\r\n\r\n"); 27 | } 28 | -------------------------------------------------------------------------------- /Libraries/SerialPort/examples/BufferedTest/BufferedTest.ino: -------------------------------------------------------------------------------- 1 | // Check time to buffer data and function of available(). 2 | #include 3 | 4 | // port zero, 63 character RX and TX buffers 5 | SerialPort<0, 63, 63> NewSerial; 6 | 7 | void setup() { 8 | NewSerial.begin(9600); 9 | uint32_t t = micros(); 10 | NewSerial.write("This string is used to measure the time to buffer data.\r\n"); 11 | t = micros() - t; 12 | NewSerial.write("Time: "); 13 | NewSerial.print(t); 14 | NewSerial.write(" us\r\n"); 15 | } 16 | void loop() { 17 | NewSerial.write("\r\nenter a string\r\n"); 18 | while (!NewSerial.available()) {} 19 | do { 20 | NewSerial.write(NewSerial.read()); 21 | uint32_t m = millis(); 22 | while (!NewSerial.available() && (millis() - m) < 3) {} 23 | } while(NewSerial.available()); 24 | NewSerial.write("\r\n"); 25 | } -------------------------------------------------------------------------------- /Libraries/SdFat/examples/#attic/MiniSerial/MiniSerial.ino: -------------------------------------------------------------------------------- 1 | // This example illustrates use of SdFat's 2 | // minimal unbuffered AVR Serial support. 3 | // 4 | // This is useful for debug and saves RAM 5 | // Will not work on Due, Leonardo, or Teensy 6 | 7 | #include 8 | #include 9 | #include 10 | #ifdef UDR0 // Must be AVR with serial port zero. 11 | #include 12 | 13 | MinimumSerial MiniSerial; 14 | 15 | void setup() { 16 | MiniSerial.begin(9600); 17 | MiniSerial.println(FreeStack()); 18 | } 19 | void loop() { 20 | int c; 21 | MiniSerial.println(F("Type any Character")); 22 | while ((c = MiniSerial.read()) < 0) {} 23 | MiniSerial.print(F("Read: ")); 24 | MiniSerial.println((char)c); 25 | while (MiniSerial.read() >= 0) {} 26 | } 27 | #else // UDR0 28 | #error no AVR serial port 0 29 | #endif // UDR0 -------------------------------------------------------------------------------- /Libraries/SdFat/examples/#attic/bufstream/bufstream.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * Use of ibufsteam to parse a line and obufstream to format a line 3 | */ 4 | #include 5 | #include 6 | 7 | // create a serial output stream 8 | ArduinoOutStream cout(Serial); 9 | //------------------------------------------------------------------------------ 10 | void setup() { 11 | char buf[20]; // buffer for formatted line 12 | int i, j, k; // values from parsed line 13 | 14 | Serial.begin(9600); 15 | while (!Serial) {} // wait for Leonardo 16 | delay(2000); 17 | 18 | // initialize input string 19 | ibufstream bin("123 456 789"); 20 | 21 | // parse the string "123 456 789" 22 | bin >> i >> j >> k; 23 | 24 | // initialize output buffer 25 | obufstream bout(buf, sizeof(buf)); 26 | 27 | // format the output string 28 | bout << k << ',' << j << ',' << i << endl; 29 | 30 | // write the string to serial 31 | cout << buf; 32 | } 33 | 34 | void loop() {} 35 | -------------------------------------------------------------------------------- /Libraries/SdFat/examples/#attic/readme.txt: -------------------------------------------------------------------------------- 1 | Old and debug examples. 2 | 3 | AnalogLogger - A simple data logger for one or more analog pins. 4 | 5 | append - This sketch creates a large file by successive 6 | open/write/close operations. 7 | 8 | average - A demonstration of parsing floating point numbers. 9 | 10 | benchSD - A read/write benchmark for the standard Arduino SD.h library. 11 | 12 | bufstream - ibufsteam to parse a line and obufstream to format a line. 13 | 14 | eventlog - Append a line to a file - demo of pathnames and streams. 15 | 16 | fgetsRewrite - Demo of rewriting a line read by fgets. 17 | 18 | HelloWorld - Create a serial output stream. 19 | 20 | MiniSerial - SdFat minimal serial support for debug. 21 | 22 | PrintBenchmarkSD - Bench mark SD.h print. 23 | 24 | readlog - Read file. Demo of pathnames and current working directory. 25 | 26 | SD_Size - Determine flash used by SD.h example. 27 | 28 | SdFatSize - Determine flash used by SdFat. 29 | -------------------------------------------------------------------------------- /Libraries/SdFat/examples/cin_cout/cin_cout.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * Demo of ArduinoInStream and ArduinoOutStream 3 | */ 4 | #include 5 | #include 6 | 7 | // create serial output stream 8 | ArduinoOutStream cout(Serial); 9 | 10 | // input line buffer 11 | char cinBuf[40]; 12 | 13 | // create serial input stream 14 | ArduinoInStream cin(Serial, cinBuf, sizeof(cinBuf)); 15 | //------------------------------------------------------------------------------ 16 | void setup() { 17 | Serial.begin(9600); 18 | while (!Serial) {} // wait for Leonardo 19 | } 20 | //------------------------------------------------------------------------------ 21 | void loop() { 22 | int32_t n; 23 | 24 | cout << "\nenter an integer\n"; 25 | 26 | cin.readline(); 27 | 28 | if (cin >> n) { 29 | cout << "The number is: " << n; 30 | } else { 31 | // will fail if no digits or not in range [-2147483648, 2147483647] 32 | cout << "Invalid input: " << cinBuf; 33 | } 34 | cout << endl; 35 | } 36 | -------------------------------------------------------------------------------- /Libraries/SerialPort/examples/ReadWriteTest/ReadWriteTest.pde: -------------------------------------------------------------------------------- 1 | // test that ring buffer overrun can be detected 2 | #include 3 | // port 0, 16 byte RX and TX buffers 4 | SerialPort<0, 16, 16> port0; 5 | 6 | void setup() { 7 | port0.begin(9600); 8 | port0.write("SerialPort version: "); 9 | port0.println(SERIAL_PORT_VERSION); 10 | } 11 | void loop() { 12 | uint8_t buffer[10]; 13 | port0.writeln("Enter a string. Overrun error for more than 16 bytes."); 14 | while (!port0.available()) {} 15 | // delay so an ring buffer overrun will occur for long strings 16 | delay(50); 17 | uint32_t m = millis(); 18 | do { 19 | size_t n = port0.read(buffer, sizeof (buffer)); 20 | if (n) { 21 | m = millis(); 22 | port0.write(buffer, n); 23 | } 24 | } while ((millis() - m) < 4); 25 | port0.writeln(); 26 | uint8_t e = port0.getRxError(); 27 | if (e) { 28 | port0.write("Error: "); 29 | port0.println(e, HEX); 30 | port0.clearRxError(); 31 | } 32 | } -------------------------------------------------------------------------------- /Libraries/SerialPort/examples/ReadWriteTest/ReadWriteTest.ino: -------------------------------------------------------------------------------- 1 | // Test that ring buffer overrun can be detected. 2 | #include 3 | // port 0, 16 byte RX and TX buffers 4 | SerialPort<0, 16, 16> port0; 5 | 6 | void setup() { 7 | port0.begin(9600); 8 | port0.write("SerialPort version: "); 9 | port0.println(SERIAL_PORT_VERSION); 10 | } 11 | void loop() { 12 | uint8_t buffer[10]; 13 | port0.writeln("Enter a string. Overrun error for more than 16 bytes."); 14 | while (!port0.available()) {} 15 | // delay so an ring buffer overrun will occur for long strings 16 | delay(50); 17 | uint32_t m = millis(); 18 | do { 19 | size_t n = port0.read(buffer, sizeof (buffer)); 20 | if (n) { 21 | m = millis(); 22 | port0.write(buffer, n); 23 | } 24 | } while ((millis() - m) < 4); 25 | port0.writeln(); 26 | uint8_t e = port0.getRxError(); 27 | if (e) { 28 | port0.write("Error: "); 29 | port0.println(e, HEX); 30 | port0.clearRxError(); 31 | } 32 | } -------------------------------------------------------------------------------- /Libraries/SerialPort/examples/MegaTest/MegaTest.pde: -------------------------------------------------------------------------------- 1 | // Test all ports on the Mega 2 | // 3 | // place loopback jumpers, RX connected to TX, 4 | // on ports 1, 2, and 3. 5 | // 6 | #include 7 | // port 0 unbuffered 8 | SerialPort<0, 0, 0> port0; 9 | 10 | // port 1 buffered RX 11 | SerialPort<1, 32, 0> port1; 12 | 13 | // port 2 buffered RX and TX 14 | SerialPort<2, 32, 32> port2; 15 | 16 | // port 3 buffered RX and TX 17 | SerialPort<3, 32, 32> port3; 18 | 19 | void transfer(Stream* in, Stream* out) { 20 | while(!in->available()) {} 21 | do { 22 | out->write(in->read()); 23 | uint32_t m = millis(); 24 | while (!in->available() && (millis() -m) < 3) {} 25 | } while (in->available()); 26 | } 27 | 28 | void setup() { 29 | port0.begin(9600); 30 | port1.begin(9600); 31 | port2.begin(9600); 32 | port3.begin(9600); 33 | } 34 | void loop() { 35 | port0.write("type a string\r\n"); 36 | transfer(&port0, &port1); 37 | transfer(&port1, &port2); 38 | transfer(&port2, &port3); 39 | transfer(&port3, &port0); 40 | port0.write("\r\n\r\n"); 41 | } 42 | -------------------------------------------------------------------------------- /Libraries/SdFat/examples/#attic/BaseExtCaseTest/BaseExtCaseTest.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * Program to test Short File Name character case flags. 3 | */ 4 | #include 5 | #include 6 | 7 | SdFat sd; 8 | 9 | SdFile file; 10 | char* name[] = { 11 | "low.low", "low.Mix", "low.UP", 12 | "Mix.low", "Mix.Mix", "Mix.UP", 13 | "UP.low", "UP.Mix", "UP.UP" 14 | }; 15 | //------------------------------------------------------------------------------ 16 | void setup() { 17 | Serial.begin(9600); 18 | while (!Serial) {} // wait for Leonardo 19 | Serial.println("type any character to start"); 20 | while (Serial.read() < 0) {} 21 | if (!sd.begin()) { 22 | Serial.println("begin failed"); 23 | return; 24 | } 25 | for (uint8_t i = 0; i < 9; i++) { 26 | sd.remove(name[i]); 27 | if (!file.open(name[i], O_RDWR | O_CREAT | O_EXCL)) { 28 | sd.errorHalt(name[i]); 29 | } 30 | file.println(name[i]); 31 | 32 | file.close(); 33 | } 34 | sd.ls(LS_DATE|LS_SIZE); 35 | Serial.println("Done"); 36 | } 37 | //------------------------------------------------------------------------------ 38 | void loop() {} 39 | -------------------------------------------------------------------------------- /firmware/README.md: -------------------------------------------------------------------------------- 1 | OpenLog Firmware 2 | ================= 3 | * OpenLog_Firmware - Various versions of firmware that can be uploaded to OpenLog 4 | * OpenLog - Firmware that ships with OpenLog. '?' command will show the version loaded onto a unit. 5 | * OpenLog_Light - Used for high-speed logging. By removing the menu and command mode the receive buffer is increased. 6 | * OpenLog_Minimal - Highest speed logging. Baud rate must be set in code and uploaded. Hardest, most advanced, and best at high-speed logging. 7 | * Arduino_Examples - Arduino examples for controlling and testing OpenLog 8 | * Benchmarking - Used to test OpenLog. Sends large amounts of data at 115200bps over multiple files. 9 | * CommandTest - Example of how to create and append a file via command line control. 10 | * ReadExample - Example of how to control OpenLog via command line. 11 | * ReadExample_LargeFile - Example of how to open a large file stored on OpenLog and report it over a local bluetooth connection. 12 | * Test_Sketch - Used to test OpenLog with lots of serial data. 13 | * Test_Sketch_Binary - Used to test OpenLog with binary data and escape characters. 14 | 15 | -------------------------------------------------------------------------------- /Libraries/SerialPort/examples/MegaTestArduino/MegaTestArduino.ino: -------------------------------------------------------------------------------- 1 | // Test all ports on the Mega. 2 | // 3 | // 4 | // A string read on port zero will be sent to port one, 5 | // it will then be read from port one and sent to port 6 | // two, next it will be read from port two and sent to 7 | // port three, and finally it will be read from port 8 | // three and sent to port zero. 9 | // 10 | // Place a loopback jumper connecting 11 | // RX1 to TX1, RX2 to TX2, RX3 to TX3 on ports 1, 2, and 3. 12 | // Do not place a jumper on port zero. 13 | // 14 | void transfer(Stream* in, Stream* out) { 15 | while(!in->available()) {} 16 | do { 17 | out->write(in->read()); 18 | uint32_t m = millis(); 19 | while (!in->available() && (millis() - m) < 3) {} 20 | } while (in->available()); 21 | } 22 | void setup() { 23 | Serial.begin(9600); 24 | Serial1.begin(9600); 25 | Serial2.begin(9600); 26 | Serial3.begin(9600); 27 | } 28 | void loop() { 29 | Serial.write("type a string\r\n"); 30 | transfer(&Serial, &Serial1); 31 | transfer(&Serial1, &Serial2); 32 | transfer(&Serial2, &Serial3); 33 | transfer(&Serial3, &Serial); 34 | Serial.write("\r\n\r\n"); 35 | } 36 | -------------------------------------------------------------------------------- /Libraries/SdFat/examples/StreamParseInt/StreamParseInt.ino: -------------------------------------------------------------------------------- 1 | // Simple demo of the Stream parsInt() member function. 2 | #include 3 | // The next two lines replace #include . 4 | #include 5 | SdFat SD; 6 | 7 | // SD card chip select pin - Modify the value of csPin for your SD module. 8 | const uint8_t csPin = 10; 9 | 10 | File file; 11 | //------------------------------------------------------------------------------ 12 | void setup() { 13 | Serial.begin(9600); 14 | // Wait for USB Serial. 15 | while(!Serial) {} 16 | Serial.println(F("Type any character to start")); 17 | while (!Serial.available()) {} 18 | 19 | // Initialize the SD. 20 | if (!SD.begin(csPin)) { 21 | Serial.println(F("begin error")); 22 | return; 23 | } 24 | // Create and open the file. Use flag to truncate an existing file. 25 | file = SD.open("stream.txt", O_RDWR|O_CREAT|O_TRUNC); 26 | if (!file) { 27 | Serial.println(F("open error")); 28 | return; 29 | } 30 | // Write a test number to the file. 31 | file.println("12345"); 32 | 33 | // Rewind the file and read the number with parseInt(). 34 | file.seek(0); 35 | int i = file.parseInt(); 36 | Serial.print(F("parseInt: ")); 37 | Serial.println(i); 38 | file.close(); 39 | } 40 | 41 | void loop() {} -------------------------------------------------------------------------------- /Libraries/SdFat/src/FatLib/FatLib.h: -------------------------------------------------------------------------------- 1 | /* FatLib Library 2 | * Copyright (C) 2013 by William Greiman 3 | * 4 | * This file is part of the FatLib Library 5 | * 6 | * This Library is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This Library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with the FatLib Library. If not, see 18 | * . 19 | */ 20 | #ifndef FatLib_h 21 | #define FatLib_h 22 | #include "ArduinoFiles.h" 23 | #include "ArduinoStream.h" 24 | #include "FatFileSystem.h" 25 | #include "FatLibConfig.h" 26 | #include "FatVolume.h" 27 | #include "FatFile.h" 28 | #include "StdioStream.h" 29 | #include "fstream.h" 30 | //------------------------------------------------------------------------------ 31 | /** FatFileSystem version YYYYMMDD */ 32 | #define FAT_LIB_VERSION 20150131 33 | #endif // FatLib_h 34 | -------------------------------------------------------------------------------- /Libraries/SdFat/examples/#attic/readlog/readlog.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * Read the logfile created by the eventlog.ino example. 3 | * Demo of pathnames and working directories 4 | */ 5 | #include 6 | #include 7 | 8 | // SD chip select pin 9 | const uint8_t chipSelect = SS; 10 | 11 | // file system object 12 | SdFat sd; 13 | 14 | // define a serial output stream 15 | ArduinoOutStream cout(Serial); 16 | //------------------------------------------------------------------------------ 17 | void setup() { 18 | int c; 19 | Serial.begin(9600); 20 | while (!Serial) {} // wait for Leonardo 21 | 22 | // initialize the SD card at SPI_HALF_SPEED to avoid bus errors with 23 | // breadboards. use SPI_FULL_SPEED for better performance. 24 | if (!sd.begin(chipSelect, SPI_HALF_SPEED)) { 25 | sd.initErrorHalt(); 26 | } 27 | 28 | // set current working directory 29 | if (!sd.chdir("logs/2014/Jan/")) { 30 | sd.errorHalt("chdir failed. Did you run eventlog.ino?"); 31 | } 32 | // open file in current working directory 33 | ifstream file("logfile.txt"); 34 | 35 | if (!file.is_open()) { 36 | sd.errorHalt("open failed"); 37 | } 38 | 39 | // copy the file to Serial 40 | while ((c = file.get()) >= 0) { 41 | cout << (char)c; 42 | } 43 | 44 | cout << "Done" << endl; 45 | } 46 | //------------------------------------------------------------------------------ 47 | void loop() {} -------------------------------------------------------------------------------- /Libraries/SerialPort/examples/MegaTest/MegaTest.ino: -------------------------------------------------------------------------------- 1 | // Test all ports on the Mega. 2 | // 3 | // A string read on port zero will be sent to port one, 4 | // it will then be read from port one and sent to port 5 | // two, next it will be read from port two and sent to 6 | // port three, and finally it will be read from port 7 | // three and sent to port zero. 8 | // 9 | // Place a loopback jumper connecting 10 | // RX1 to TX1, RX2 to TX2, RX3 to TX3 on ports 1, 2, and 3. 11 | // Do not place a jumper on port zero. 12 | // 13 | #include 14 | // port 0 unbuffered 15 | SerialPort<0, 0, 0> port0; 16 | 17 | // port 1 buffered RX 18 | SerialPort<1, 32, 0> port1; 19 | 20 | // port 2 buffered RX and TX 21 | SerialPort<2, 32, 32> port2; 22 | 23 | // port 3 buffered RX and TX 24 | SerialPort<3, 32, 32> port3; 25 | 26 | void transfer(Stream* in, Stream* out) { 27 | while(!in->available()) {} 28 | do { 29 | out->write(in->read()); 30 | uint32_t m = millis(); 31 | while (!in->available() && (millis() -m) < 3) {} 32 | } while (in->available()); 33 | } 34 | 35 | void setup() { 36 | port0.begin(9600); 37 | port1.begin(9600); 38 | port2.begin(9600); 39 | port3.begin(9600); 40 | } 41 | void loop() { 42 | port0.write("type a string\r\n"); 43 | transfer(&port0, &port1); 44 | transfer(&port1, &port2); 45 | transfer(&port2, &port3); 46 | transfer(&port3, &port0); 47 | port0.write("\r\n\r\n"); 48 | } 49 | -------------------------------------------------------------------------------- /Libraries/SdFat/examples/OpenNext/OpenNext.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * Print size, modify date/time, and name for all files in root. 3 | */ 4 | #include 5 | #include 6 | 7 | // SD chip select pin 8 | const uint8_t chipSelect = SS; 9 | 10 | // file system object 11 | SdFat sd; 12 | 13 | SdFile file; 14 | //------------------------------------------------------------------------------ 15 | void setup() { 16 | Serial.begin(9600); 17 | while (!Serial) {} // wait for Leonardo 18 | delay(1000); 19 | Serial.println(); 20 | 21 | // initialize the SD card at SPI_HALF_SPEED to avoid bus errors with 22 | // breadboards. use SPI_FULL_SPEED for better performance. 23 | if (!sd.begin(chipSelect, SPI_HALF_SPEED)) { 24 | sd.initErrorHalt(); 25 | } 26 | 27 | // Open next file in root. The volume working directory, vwd, is root. 28 | // Warning, openNext starts at the current position of sd.vwd() so a 29 | // rewind may be neccessary in your application. 30 | while (file.openNext(sd.vwd(), O_READ)) { 31 | file.printFileSize(&Serial); 32 | Serial.write(' '); 33 | file.printModifyDateTime(&Serial); 34 | Serial.write(' '); 35 | file.printName(&Serial); 36 | if (file.isDir()) { 37 | // Indicate a directory. 38 | Serial.write('/'); 39 | } 40 | Serial.println(); 41 | file.close(); 42 | } 43 | Serial.println("Done!"); 44 | } 45 | //------------------------------------------------------------------------------ 46 | void loop() {} 47 | -------------------------------------------------------------------------------- /Libraries/SdFat/src/FatLib/FmtNumber.h: -------------------------------------------------------------------------------- 1 | /* FatLib Library 2 | * Copyright (C) 2013 by William Greiman 3 | * 4 | * This file is part of the FatLib Library 5 | * 6 | * This Library is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This Library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with the FatLib Library. If not, see 18 | * . 19 | */ 20 | #ifndef FmtNumber_h 21 | #define FmtNumber_h 22 | // #include 23 | inline bool isDigit(char c) { 24 | return '0' <= c && c <= '9'; 25 | } 26 | inline bool isSpace(char c) { 27 | return c == ' ' || (0X9 <= c && c <= 0XD); 28 | } 29 | #include 30 | #include 31 | char* fmtDec(uint16_t n, char* p); 32 | char* fmtDec(uint32_t n, char* p); 33 | char* fmtFloat(float value, char* p, uint8_t prec); 34 | char* fmtFloat(float value, char* ptr, uint8_t prec, char expChar); 35 | char* fmtHex(uint32_t n, char* p); 36 | float scale10(float v, int8_t n); 37 | float scanFloat(const char* str, char** ptr); 38 | #endif // FmtNumber_h 39 | -------------------------------------------------------------------------------- /Libraries/SdFat/src/FreeStack.h: -------------------------------------------------------------------------------- 1 | /* Arduino SdFat Library 2 | * Copyright (C) 2015 by William Greiman 3 | * 4 | * This file is part of the Arduino SdFat Library 5 | * 6 | * This Library is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This Library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | 16 | * You should have received a copy of the GNU General Public License 17 | * along with the Arduino SdFat Library. If not, see 18 | * . 19 | */ 20 | #ifndef FreeStack_h 21 | #define FreeStack_h 22 | /** 23 | * \file 24 | * \brief FreeStack() function. 25 | */ 26 | #ifdef __arm__ 27 | extern "C" char* sbrk(int incr); 28 | static int FreeStack() { 29 | char top; 30 | return &top - reinterpret_cast(sbrk(0)); 31 | } 32 | #else // __arm__ 33 | /** boundary between stack and heap. */ 34 | extern char *__brkval; 35 | /** End of bss section.*/ 36 | extern char __bss_end; 37 | /** Amount of free stack space. 38 | * \return The number of free bytes. 39 | */ 40 | static int FreeStack() { 41 | char top; 42 | return __brkval ? &top - __brkval : &top - &__bss_end; 43 | } 44 | #endif // __arm 45 | #endif // FreeStack_h 46 | -------------------------------------------------------------------------------- /Libraries/SdFat/examples/SoftwareSpi/SoftwareSpi.ino: -------------------------------------------------------------------------------- 1 | // An example of the SdFatSoftSpi template class. 2 | // This example is for an Adafruit Data Logging Shield on a Mega. 3 | // Software SPI is required on Mega since this shield connects to pins 10-13. 4 | // This example will also run on an Uno and other boards using software SPI. 5 | // 6 | #include 7 | #include 8 | #if SD_SPI_CONFIGURATION >= 3 // Must be set in SdFat/SdFatConfig.h 9 | // 10 | // Pin numbers in templates must be constants. 11 | const uint8_t SOFT_MISO_PIN = 12; 12 | const uint8_t SOFT_MOSI_PIN = 11; 13 | const uint8_t SOFT_SCK_PIN = 13; 14 | // 15 | // Chip select may be constant or RAM variable. 16 | const uint8_t SD_CHIP_SELECT_PIN = 10; 17 | 18 | // SdFat software SPI template 19 | SdFatSoftSpi sd; 20 | 21 | // Test file. 22 | SdFile file; 23 | 24 | void setup() { 25 | Serial.begin(9600); 26 | while (!Serial) {} // Wait for Leonardo 27 | 28 | Serial.println("Type any character to start"); 29 | while (Serial.read() <= 0) {} 30 | 31 | if (!sd.begin(SD_CHIP_SELECT_PIN)) { 32 | sd.initErrorHalt(); 33 | } 34 | 35 | if (!file.open("SoftSPI.txt", O_CREAT | O_RDWR)) { 36 | sd.errorHalt(F("open failed")); 37 | } 38 | file.println(F("This line was printed using software SPI.")); 39 | 40 | file.rewind(); 41 | 42 | while (file.available()) { 43 | Serial.write(file.read()); 44 | } 45 | 46 | file.close(); 47 | 48 | Serial.println(F("Done.")); 49 | } 50 | //------------------------------------------------------------------------------ 51 | void loop() {} 52 | #else // SD_SPI_CONFIGURATION >= 3 53 | #error SD_SPI_CONFIGURATION must be set to 3 in SdFat/SdFatConfig.h 54 | #endif //SD_SPI_CONFIGURATION >= 3 -------------------------------------------------------------------------------- /Libraries/SdFat/examples/AnalogBinLogger/AnalogBinLogger.h: -------------------------------------------------------------------------------- 1 | #ifndef AnalogBinLogger_h 2 | #define AnalogBinLogger_h 3 | //------------------------------------------------------------------------------ 4 | // First block of file. 5 | struct metadata_t { 6 | unsigned long adcFrequency; // ADC clock frequency 7 | unsigned long cpuFrequency; // CPU clock frequency 8 | unsigned long sampleInterval; // Sample interval in CPU cycles. 9 | unsigned long recordEightBits; // Size of ADC values, nonzero for 8-bits. 10 | unsigned long pinCount; // Number of analog pins in a sample. 11 | unsigned long pinNumber[123]; // List of pin numbers in a sample. 12 | }; 13 | //------------------------------------------------------------------------------ 14 | // Data block for 8-bit ADC mode. 15 | const size_t DATA_DIM8 = 508; 16 | struct block8_t { 17 | unsigned short count; // count of data values 18 | unsigned short overrun; // count of overruns since last block 19 | unsigned char data[DATA_DIM8]; 20 | }; 21 | //------------------------------------------------------------------------------ 22 | // Data block for 10-bit ADC mode. 23 | const size_t DATA_DIM16 = 254; 24 | struct block16_t { 25 | unsigned short count; // count of data values 26 | unsigned short overrun; // count of overruns since last block 27 | unsigned short data[DATA_DIM16]; 28 | }; 29 | //------------------------------------------------------------------------------ 30 | // Data block for PC use 31 | struct adcdata_t { 32 | unsigned short count; // count of data values 33 | unsigned short overrun; // count of overruns since last block 34 | union { 35 | unsigned char u8[DATA_DIM8]; 36 | unsigned short u16[DATA_DIM16]; 37 | } data; 38 | }; 39 | #endif // AnalogBinLogger_h -------------------------------------------------------------------------------- /Libraries/SdFat/src/MinimumSerial.h: -------------------------------------------------------------------------------- 1 | /* Arduino SdFat Library 2 | * Copyright (C) 2012 by William Greiman 3 | * 4 | * This file is part of the Arduino SdFat Library 5 | * 6 | * This Library is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This Library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with the Arduino SdFat Library. If not, see 18 | * . 19 | */ 20 | #ifndef MinimumSerial_h 21 | #define MinimumSerial_h 22 | #include 23 | //============================================================================== 24 | /** 25 | * \class MinimumSerial 26 | * \brief mini serial class for the %SdFat library. 27 | */ 28 | class MinimumSerial : public Print { 29 | public: 30 | /** 31 | * Set baud rate for serial port zero and enable in non interrupt mode. 32 | * Do not call this function if you use another serial library. 33 | * \param[in] baud rate 34 | */ 35 | void begin(uint32_t baud); 36 | /** 37 | * Unbuffered read 38 | * \return -1 if no character is available or an available character. 39 | */ 40 | int read(); 41 | /** 42 | * Unbuffered write 43 | * 44 | * \param[in] b byte to write. 45 | * \return 1 46 | */ 47 | size_t write(uint8_t b); 48 | using Print::write; 49 | }; 50 | #endif // MinimumSerial_h 51 | -------------------------------------------------------------------------------- /Libraries/SdFat/examples/#attic/eventlog/eventlog.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * Append a line to a file - demo of pathnames and streams 3 | */ 4 | #include 5 | #include 6 | 7 | // SD chip select pin 8 | const uint8_t chipSelect = SS; 9 | 10 | // file system object 11 | SdFat sd; 12 | 13 | // define a serial output stream 14 | ArduinoOutStream cout(Serial); 15 | //------------------------------------------------------------------------------ 16 | /* 17 | * Append a line to logfile.txt 18 | */ 19 | void logEvent(const char *msg) { 20 | // create dir if needed 21 | sd.mkdir("logs/2014/Jan"); 22 | 23 | // create or open a file for append 24 | ofstream sdlog("logs/2014/Jan/logfile.txt", ios::out | ios::app); 25 | 26 | // append a line to the file 27 | sdlog << msg << endl; 28 | 29 | // check for errors 30 | if (!sdlog) { 31 | sd.errorHalt("append failed"); 32 | } 33 | 34 | sdlog.close(); 35 | } 36 | //------------------------------------------------------------------------------ 37 | void setup() { 38 | Serial.begin(9600); 39 | while (!Serial) {} // wait for Leonardo 40 | 41 | // F() stores strings in flash to save RAM 42 | cout << F("Type any character to start\n"); 43 | while (Serial.read() <= 0) {} 44 | delay(400); // catch Due reset problem 45 | 46 | // initialize the SD card at SPI_HALF_SPEED to avoid bus errors with 47 | // breadboards. use SPI_FULL_SPEED for better performance. 48 | if (!sd.begin(chipSelect, SPI_HALF_SPEED)) { 49 | sd.initErrorHalt(); 50 | } 51 | 52 | // append a line to the logfile 53 | logEvent("Another line for the logfile"); 54 | 55 | cout << F("Done - check /logs/2014/Jan/logfile.txt on the SD") << endl; 56 | } 57 | //------------------------------------------------------------------------------ 58 | void loop() {} 59 | -------------------------------------------------------------------------------- /Libraries/SdFat/src/SdFatUtil.cpp: -------------------------------------------------------------------------------- 1 | /* Arduino SdFat Library 2 | * Copyright (C) 2015 by William Greiman 3 | * 4 | * This file is part of the Arduino SdFat Library 5 | * 6 | * This Library is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This Library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | 16 | * You should have received a copy of the GNU General Public License 17 | * along with the Arduino SdFat Library. If not, see 18 | * . 19 | */ 20 | #include 21 | #include "SdFat.h" 22 | #include "SdFatUtil.h" 23 | //------------------------------------------------------------------------------ 24 | #ifdef __arm__ 25 | extern "C" char* sbrk(int incr); 26 | int SdFatUtil::FreeRam() { 27 | char top; 28 | return &top - reinterpret_cast(sbrk(0)); 29 | } 30 | #else // __arm__ 31 | extern char *__brkval; 32 | extern char __bss_end; 33 | /** Amount of free RAM 34 | * \return The number of free bytes. 35 | */ 36 | int SdFatUtil::FreeRam() { 37 | char top; 38 | return __brkval ? &top - __brkval : &top - &__bss_end; 39 | } 40 | #endif // __arm 41 | //------------------------------------------------------------------------------ 42 | void SdFatUtil::print_P(Print* pr, PGM_P str) { 43 | for (uint8_t c; (c = pgm_read_byte(str)); str++) { 44 | pr->write(c); 45 | } 46 | } 47 | //------------------------------------------------------------------------------ 48 | void SdFatUtil::println_P(Print* pr, PGM_P str) { 49 | print_P(pr, str); 50 | pr->println(); 51 | } 52 | -------------------------------------------------------------------------------- /firmware/Arduino_Examples/Example2_HardwareLogging/Example2_HardwareLogging.ino: -------------------------------------------------------------------------------- 1 | /* 2 | Recording to OpenLog example 3 | By: Nathan Seidle 4 | SparkFun Electronics 5 | Date: February 8th, 2018 6 | License: This code is public domain but you buy me a beer if you use this and we meet someday (Beerware license). 7 | 8 | This is an example of basic recording to OpenLog using hardware serial. This example is best for users who 9 | are plugging the OpenLog directly onto the programming connector on an Arduino Pro Mini or Arduino Pro. 10 | 11 | We DON'T recommend this method for beginners. See Example 1 for an easier software serial example. 12 | The reason is if you upload a sketch to an Arduino with OpenLog attached then OpenLog will log the 13 | uploading of your sketch. This may cause the OpenLog to become reconfigured. No harm will be 14 | caused but it can corrupt the log file. 15 | 16 | Connect the following OpenLog to Arduino: 17 | RXI of OpenLog to TX on Arduino 18 | VCC to 5V 19 | GND to GND 20 | 21 | This example records whatever the user Serial.prints(). This is the easiest but NOTE: You cannot 22 | upload sketches to your Arduino with the OpenLog attached (because of bus contention). Upload this 23 | sketch first, and then connect the OpenLog to the TX pin on the Arduino. 24 | */ 25 | 26 | int statLED = 13; 27 | 28 | float dummyVoltage = 3.50; //This just shows to to write variables to OpenLog 29 | 30 | void setup() { 31 | pinMode(statLED, OUTPUT); 32 | Serial.begin(9600); 33 | 34 | Serial.println("Example print to OpenLog"); 35 | 36 | Serial.println("Anything printed to COM port gets logged!"); 37 | 38 | //Write something to OpenLog 39 | Serial.println("Hi there! How are you today?"); 40 | Serial.print("Voltage: "); 41 | Serial.println(dummyVoltage); 42 | dummyVoltage++; 43 | Serial.print("Voltage: "); 44 | Serial.println(dummyVoltage); 45 | } 46 | 47 | void loop() { 48 | digitalWrite(statLED, HIGH); 49 | delay(1000); 50 | digitalWrite(statLED, LOW); 51 | delay(1000); 52 | } 53 | 54 | -------------------------------------------------------------------------------- /Libraries/SdFat/examples/formatting/formatting.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * Print a table with various formatting options 3 | * Format dates 4 | */ 5 | #include 6 | #include 7 | 8 | // create Serial stream 9 | ArduinoOutStream cout(Serial); 10 | //------------------------------------------------------------------------------ 11 | // print a table to demonstrate format manipulators 12 | void example(void) { 13 | const int max = 10; 14 | const int width = 4; 15 | 16 | for (int row = 1; row <= max; row++) { 17 | for (int col = 1; col <= max; col++) { 18 | cout << setw(width) << row * col << (col == max ? '\n' : ' '); 19 | } 20 | } 21 | cout << endl; 22 | } 23 | //------------------------------------------------------------------------------ 24 | // print a date as mm/dd/yyyy with zero fill in mm and dd 25 | // shows how to set and restore the fill character 26 | void showDate(int m, int d, int y) { 27 | // convert two digit year 28 | if (y < 100) { 29 | y += 2000; 30 | } 31 | 32 | // set new fill to '0' save old fill character 33 | char old = cout.fill('0'); 34 | 35 | // print date 36 | cout << setw(2) << m << '/' << setw(2) << d << '/' << y << endl; 37 | 38 | // restore old fill character 39 | cout.fill(old); 40 | } 41 | //------------------------------------------------------------------------------ 42 | void setup(void) { 43 | Serial.begin(9600); 44 | 45 | while (!Serial) {} // wait for Leonardo 46 | delay(2000); 47 | 48 | cout << endl << "default formatting" << endl; 49 | example(); 50 | 51 | cout << showpos << "showpos" << endl; 52 | example(); 53 | 54 | cout << hex << left << showbase << "hex left showbase" << endl; 55 | example(); 56 | 57 | cout << internal << setfill('0') << uppercase; 58 | cout << "uppercase hex internal showbase fill('0')" < 21 | 22 | //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- 23 | //Connect RXI of OpenLog to pin 5 on Arduino 24 | SoftwareSerial OpenLog(0, 5); // 0 = Soft RX pin (not used), 5 = Soft TX pin 25 | //5 can be changed to any pin. See limitation section on https://www.arduino.cc/en/Reference/SoftwareSerial 26 | //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- 27 | 28 | int statLED = 13; 29 | 30 | float dummyVoltage = 3.50; //This just shows to to write variables to OpenLog 31 | 32 | void setup() { 33 | pinMode(statLED, OUTPUT); 34 | Serial.begin(9600); 35 | 36 | OpenLog.begin(9600); //Open software serial port at 9600bps 37 | 38 | Serial.println("This serial prints to the COM port"); 39 | OpenLog.println("This serial records to the OpenLog text file"); 40 | 41 | //Write something to OpenLog 42 | OpenLog.println("Hi there! How are you today?"); 43 | OpenLog.print("Voltage: "); 44 | OpenLog.println(dummyVoltage); 45 | dummyVoltage++; 46 | OpenLog.print("Voltage: "); 47 | OpenLog.println(dummyVoltage); 48 | 49 | Serial.println("Text written to file. Go look!"); 50 | } 51 | 52 | void loop() { 53 | digitalWrite(statLED, HIGH); 54 | delay(1000); 55 | digitalWrite(statLED, LOW); 56 | delay(1000); 57 | } 58 | 59 | 60 | -------------------------------------------------------------------------------- /Libraries/SdFat/examples/ReadWriteSdFat/ReadWriteSdFat.ino: -------------------------------------------------------------------------------- 1 | // Ported to SdFat from the native Arduino SD library example by Bill Greiman 2 | // On the Ethernet Shield, CS is pin 4. SdFat handles setting SS 3 | const int chipSelect = 4; 4 | /* 5 | SD card read/write 6 | 7 | This example shows how to read and write data to and from an SD card file 8 | The circuit: 9 | * SD card attached to SPI bus as follows: 10 | ** MOSI - pin 11 11 | ** MISO - pin 12 12 | ** CLK - pin 13 13 | ** CS - pin 4 14 | 15 | created Nov 2010 16 | by David A. Mellis 17 | updated 2 Dec 2010 18 | by Tom Igoe 19 | modified by Bill Greiman 11 Apr 2011 20 | This example code is in the public domain. 21 | 22 | */ 23 | #include 24 | #include 25 | SdFat sd; 26 | SdFile myFile; 27 | 28 | void setup() { 29 | Serial.begin(9600); 30 | while (!Serial) {} // wait for Leonardo 31 | Serial.println("Type any character to start"); 32 | while (Serial.read() <= 0) {} 33 | delay(400); // catch Due reset problem 34 | 35 | // Initialize SdFat or print a detailed error message and halt 36 | // Use half speed like the native library. 37 | // change to SPI_FULL_SPEED for more performance. 38 | if (!sd.begin(chipSelect, SPI_HALF_SPEED)) { 39 | sd.initErrorHalt(); 40 | } 41 | 42 | // open the file for write at end like the Native SD library 43 | if (!myFile.open("test.txt", O_RDWR | O_CREAT | O_AT_END)) { 44 | sd.errorHalt("opening test.txt for write failed"); 45 | } 46 | // if the file opened okay, write to it: 47 | Serial.print("Writing to test.txt..."); 48 | myFile.println("testing 1, 2, 3."); 49 | 50 | // close the file: 51 | myFile.close(); 52 | Serial.println("done."); 53 | 54 | // re-open the file for reading: 55 | if (!myFile.open("test.txt", O_READ)) { 56 | sd.errorHalt("opening test.txt for read failed"); 57 | } 58 | Serial.println("test.txt:"); 59 | 60 | // read from the file until there's nothing else in it: 61 | int data; 62 | while ((data = myFile.read()) >= 0) { 63 | Serial.write(data); 64 | } 65 | // close the file: 66 | myFile.close(); 67 | } 68 | 69 | void loop() { 70 | // nothing happens after setup 71 | } 72 | 73 | 74 | -------------------------------------------------------------------------------- /Libraries/SdFat/examples/#attic/append/append.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * Append Example 3 | * 4 | * This program shows how to use open for append. 5 | * The program will append 100 line each time it opens the file. 6 | * The program will open and close the file 100 times. 7 | */ 8 | #include 9 | #include 10 | 11 | // SD chip select pin 12 | const uint8_t chipSelect = SS; 13 | 14 | // file system object 15 | SdFat sd; 16 | 17 | // create Serial stream 18 | ArduinoOutStream cout(Serial); 19 | 20 | // store error strings in flash to save RAM 21 | #define error(s) sd.errorHalt(F(s)) 22 | //------------------------------------------------------------------------------ 23 | void setup() { 24 | // filename for this example 25 | char name[] = "append.txt"; 26 | 27 | Serial.begin(9600); 28 | while (!Serial) {} // wait for Leonardo 29 | 30 | // F() stores strings in flash to save RAM 31 | cout << endl << F("Type any character to start\n"); 32 | while (Serial.read() <= 0) {} 33 | delay(400); // Catch Due reset problem 34 | 35 | // initialize the SD card at SPI_HALF_SPEED to avoid bus errors with 36 | // breadboards. use SPI_FULL_SPEED for better performance. 37 | if (!sd.begin(chipSelect, SPI_HALF_SPEED)) { 38 | sd.initErrorHalt(); 39 | } 40 | 41 | cout << F("Appending to: ") << name; 42 | 43 | for (uint8_t i = 0; i < 100; i++) { 44 | // open stream for append 45 | ofstream sdout(name, ios::out | ios::app); 46 | if (!sdout) { 47 | error("open failed"); 48 | } 49 | 50 | // append 100 lines to the file 51 | for (uint8_t j = 0; j < 100; j++) { 52 | // use int() so byte will print as decimal number 53 | sdout << "line " << int(j) << " of pass " << int(i); 54 | sdout << " millis = " << millis() << endl; 55 | } 56 | // close the stream 57 | sdout.close(); 58 | 59 | if (!sdout) { 60 | error("append data failed"); 61 | } 62 | 63 | // output progress indicator 64 | if (i % 25 == 0) { 65 | cout << endl; 66 | } 67 | cout << '.'; 68 | } 69 | cout << endl << "Done" << endl; 70 | } 71 | //------------------------------------------------------------------------------ 72 | void loop() {} 73 | -------------------------------------------------------------------------------- /Libraries/SdFat/examples/#attic/average/average.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * Calculate the sum and average of a list of floating point numbers 3 | */ 4 | #include 5 | #include 6 | 7 | // SD chip select pin 8 | const uint8_t chipSelect = SS; 9 | 10 | // object for the SD file system 11 | SdFat sd; 12 | 13 | // define a serial output stream 14 | ArduinoOutStream cout(Serial); 15 | //------------------------------------------------------------------------------ 16 | void writeTestFile() { 17 | // open the output file 18 | ofstream sdout("AvgTest.txt"); 19 | 20 | // write a series of float numbers 21 | for (int16_t i = -1001; i < 2000; i += 13) { 22 | sdout << 0.1 * i << endl; 23 | } 24 | if (!sdout) { 25 | sd.errorHalt("sdout failed"); 26 | } 27 | 28 | sdout.close(); 29 | } 30 | //------------------------------------------------------------------------------ 31 | void calcAverage() { 32 | uint16_t n = 0; // count of input numbers 33 | double num; // current input number 34 | double sum = 0; // sum of input numbers 35 | 36 | // open the input file 37 | ifstream sdin("AvgTest.txt"); 38 | 39 | // check for an open failure 40 | if (!sdin) { 41 | sd.errorHalt("sdin failed"); 42 | } 43 | 44 | // read and sum the numbers 45 | while (sdin >> num) { 46 | n++; 47 | sum += num; 48 | } 49 | 50 | // print the results 51 | cout << "sum of " << n << " numbers = " << sum << endl; 52 | cout << "average = " << sum/n << endl; 53 | } 54 | //------------------------------------------------------------------------------ 55 | void setup() { 56 | Serial.begin(9600); 57 | while (!Serial) {} // wait for Leonardo 58 | 59 | // F() stores strings in flash to save RAM 60 | cout << F("Type any character to start\n"); 61 | while (Serial.read() <= 0) {} 62 | delay(400); // Catch Due reset problem 63 | 64 | // initialize the SD card at SPI_HALF_SPEED to avoid bus errors with 65 | // breadboards. use SPI_FULL_SPEED for better performance. 66 | if (!sd.begin(chipSelect, SPI_HALF_SPEED)) { 67 | sd.initErrorHalt(); 68 | } 69 | 70 | // write the test file 71 | writeTestFile(); 72 | 73 | // read the test file and calculate the average 74 | calcAverage(); 75 | } 76 | //------------------------------------------------------------------------------ 77 | void loop() {} 78 | -------------------------------------------------------------------------------- /Libraries/SdFat/src/MinimumSerial.cpp: -------------------------------------------------------------------------------- 1 | /* Arduino SdFat Library 2 | * Copyright (C) 2012 by William Greiman 3 | * 4 | * This file is part of the Arduino SdFat Library 5 | * 6 | * This Library is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This Library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with the Arduino SdFat Library. If not, see 18 | * . 19 | */ 20 | #include 21 | #if defined(UDR0) || defined(DOXYGEN) 22 | #include "MinimumSerial.h" 23 | const uint16_t MIN_2X_BAUD = F_CPU/(4*(2*0XFFF + 1)) + 1; 24 | //------------------------------------------------------------------------------ 25 | void MinimumSerial::begin(uint32_t baud) { 26 | uint16_t baud_setting; 27 | // don't worry, the compiler will squeeze out F_CPU != 16000000UL 28 | if ((F_CPU != 16000000UL || baud != 57600) && baud > MIN_2X_BAUD) { 29 | // Double the USART Transmission Speed 30 | UCSR0A = 1 << U2X0; 31 | baud_setting = (F_CPU / 4 / baud - 1) / 2; 32 | } else { 33 | // hardcoded exception for compatibility with the bootloader shipped 34 | // with the Duemilanove and previous boards and the firmware on the 8U2 35 | // on the Uno and Mega 2560. 36 | UCSR0A = 0; 37 | baud_setting = (F_CPU / 8 / baud - 1) / 2; 38 | } 39 | // assign the baud_setting 40 | UBRR0H = baud_setting >> 8; 41 | UBRR0L = baud_setting; 42 | // enable transmit and receive 43 | UCSR0B |= (1 << TXEN0) | (1 << RXEN0); 44 | } 45 | //------------------------------------------------------------------------------ 46 | int MinimumSerial::read() { 47 | if (UCSR0A & (1 << RXC0)) { 48 | return UDR0; 49 | } 50 | return -1; 51 | } 52 | //------------------------------------------------------------------------------ 53 | size_t MinimumSerial::write(uint8_t b) { 54 | while (((1 << UDRIE0) & UCSR0B) || !(UCSR0A & (1 << UDRE0))) {} 55 | UDR0 = b; 56 | return 1; 57 | } 58 | #endif // defined(UDR0) || defined(DOXYGEN) 59 | -------------------------------------------------------------------------------- /Libraries/SdFat/examples/ReadWrite/ReadWrite.ino: -------------------------------------------------------------------------------- 1 | /* 2 | SD card read/write 3 | 4 | This example shows how to read and write data to and from an SD card file 5 | The circuit: 6 | * SD card attached to SPI bus as follows: 7 | ** MOSI - pin 11 8 | ** MISO - pin 12 9 | ** CLK - pin 13 10 | ** CS - pin 4 11 | 12 | created Nov 2010 13 | by David A. Mellis 14 | modified 9 Apr 2012 15 | by Tom Igoe 16 | 17 | This example code is in the public domain. 18 | 19 | */ 20 | #define SD_CS_PIN SS 21 | #include 22 | //#include 23 | #include 24 | SdFat SD; 25 | 26 | File myFile; 27 | 28 | void setup() 29 | { 30 | // Open serial communications and wait for port to open: 31 | Serial.begin(9600); 32 | while (!Serial) { 33 | ; // wait for serial port to connect. Needed for Leonardo only 34 | } 35 | 36 | 37 | Serial.print("Initializing SD card..."); 38 | // On the Ethernet Shield, CS is pin 4. It's set as an output by default. 39 | // Note that even if it's not used as the CS pin, the hardware SS pin 40 | // (10 on most Arduino boards, 53 on the Mega) must be left as an output 41 | // or the SD library functions will not work. 42 | pinMode(10, OUTPUT); 43 | 44 | if (!SD.begin(SD_CS_PIN)) { 45 | Serial.println("initialization failed!"); 46 | return; 47 | } 48 | Serial.println("initialization done."); 49 | 50 | // open the file. note that only one file can be open at a time, 51 | // so you have to close this one before opening another. 52 | myFile = SD.open("test.txt", FILE_WRITE); 53 | 54 | // if the file opened okay, write to it: 55 | if (myFile) { 56 | Serial.print("Writing to test.txt..."); 57 | myFile.println("testing 1, 2, 3."); 58 | // close the file: 59 | myFile.close(); 60 | Serial.println("done."); 61 | } else { 62 | // if the file didn't open, print an error: 63 | Serial.println("error opening test.txt"); 64 | } 65 | 66 | // re-open the file for reading: 67 | myFile = SD.open("test.txt"); 68 | if (myFile) { 69 | Serial.println("test.txt:"); 70 | 71 | // read from the file until there's nothing else in it: 72 | while (myFile.available()) { 73 | Serial.write(myFile.read()); 74 | } 75 | // close the file: 76 | myFile.close(); 77 | } else { 78 | // if the file didn't open, print an error: 79 | Serial.println("error opening test.txt"); 80 | } 81 | } 82 | 83 | void loop() 84 | { 85 | // nothing happens after setup 86 | } 87 | 88 | 89 | -------------------------------------------------------------------------------- /Libraries/SdFat/examples/fgets/fgets.ino: -------------------------------------------------------------------------------- 1 | // Demo of fgets function to read lines from a file. 2 | #include 3 | #include 4 | 5 | // SD chip select pin 6 | const uint8_t chipSelect = SS; 7 | 8 | SdFat sd; 9 | // print stream 10 | ArduinoOutStream cout(Serial); 11 | //------------------------------------------------------------------------------ 12 | // store error strings in flash memory 13 | #define error(s) sd.errorHalt(F(s)) 14 | //------------------------------------------------------------------------------ 15 | void demoFgets() { 16 | char line[25]; 17 | int n; 18 | // open test file 19 | SdFile rdfile("fgets.txt", O_READ); 20 | 21 | // check for open error 22 | if (!rdfile.isOpen()) { 23 | error("demoFgets"); 24 | } 25 | 26 | cout << endl << F( 27 | "Lines with '>' end with a '\\n' character\n" 28 | "Lines with '#' do not end with a '\\n' character\n" 29 | "\n"); 30 | 31 | // read lines from the file 32 | while ((n = rdfile.fgets(line, sizeof(line))) > 0) { 33 | if (line[n - 1] == '\n') { 34 | cout << '>' << line; 35 | } else { 36 | cout << '#' << line << endl; 37 | } 38 | } 39 | } 40 | //------------------------------------------------------------------------------ 41 | void makeTestFile() { 42 | // create or open test file 43 | SdFile wrfile("fgets.txt", O_WRITE | O_CREAT | O_TRUNC); 44 | 45 | // check for open error 46 | if (!wrfile.isOpen()) { 47 | error("MakeTestFile"); 48 | } 49 | 50 | // write test file 51 | wrfile.print(F( 52 | "Line with CRLF\r\n" 53 | "Line with only LF\n" 54 | "Long line that will require an extra read\n" 55 | "\n" // empty line 56 | "Line at EOF without NL" 57 | )); 58 | wrfile.close(); 59 | } 60 | //------------------------------------------------------------------------------ 61 | void setup(void) { 62 | Serial.begin(9600); 63 | while (!Serial) {} // Wait for Leonardo 64 | 65 | cout << F("Type any character to start\n"); 66 | while (Serial.read() <= 0) {} 67 | delay(400); // catch Due reset problem 68 | 69 | // initialize the SD card at SPI_HALF_SPEED to avoid bus errors with 70 | // breadboards. use SPI_FULL_SPEED for better performance. 71 | if (!sd.begin(chipSelect, SPI_HALF_SPEED)) { 72 | sd.initErrorHalt(); 73 | } 74 | 75 | makeTestFile(); 76 | 77 | demoFgets(); 78 | 79 | cout << F("\nDone\n"); 80 | } 81 | void loop(void) {} 82 | -------------------------------------------------------------------------------- /Libraries/SdFat/src/SdFatUtil.h: -------------------------------------------------------------------------------- 1 | /* Arduino SdFat Library 2 | * Copyright (C) 2012 by William Greiman 3 | * 4 | * This file is part of the Arduino SdFat Library 5 | * 6 | * This Library is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This Library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with the Arduino SdFat Library. If not, see 18 | * . 19 | */ 20 | #ifndef SdFatUtil_h 21 | #define SdFatUtil_h 22 | /** 23 | * \file 24 | * \brief Useful utility functions. 25 | */ 26 | #include "SdFat.h" 27 | /** Store and print a string in flash memory.*/ 28 | #define PgmPrint(x) SerialPrint_P(PSTR(x)) 29 | /** Store and print a string in flash memory followed by a CR/LF.*/ 30 | #define PgmPrintln(x) SerialPrintln_P(PSTR(x)) 31 | 32 | namespace SdFatUtil { 33 | /** Amount of free RAM 34 | * \return The number of free bytes. 35 | */ 36 | int FreeRam(); 37 | /** %Print a string in flash memory. 38 | * 39 | * \param[in] pr Print object for output. 40 | * \param[in] str Pointer to string stored in flash memory. 41 | */ 42 | void print_P(Print* pr, PGM_P str); 43 | /** %Print a string in flash memory followed by a CR/LF. 44 | * 45 | * \param[in] pr Print object for output. 46 | * \param[in] str Pointer to string stored in flash memory. 47 | */ 48 | void println_P(Print* pr, PGM_P str); 49 | //---------------------------------------------------------------------------- 50 | /** %Print a string in flash memory to Serial. 51 | * 52 | * \param[in] str Pointer to string stored in flash memory. 53 | */ 54 | inline void SerialPrint_P(PGM_P str) { 55 | print_P(&Serial, str); 56 | } 57 | //---------------------------------------------------------------------------- 58 | /** %Print a string in flash memory to Serial followed by a CR/LF. 59 | * 60 | * \param[in] str Pointer to string stored in flash memory. 61 | */ 62 | inline void SerialPrintln_P(PGM_P str) { 63 | println_P(&Serial, str); 64 | } 65 | } // namespace SdFatUtil 66 | using namespace SdFatUtil; // NOLINT 67 | #endif // #define SdFatUtil_h 68 | -------------------------------------------------------------------------------- /Libraries/SdFat/examples/getline/getline.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * Example of getline from section 27.7.1.3 of the C++ standard 3 | * Demonstrates the behavior of getline for various exceptions. 4 | * See http://www.cplusplus.com/reference/iostream/istream/getline/ 5 | * 6 | * Note: This example is meant to demonstrate subtleties the standard and 7 | * may not the best way to read a file. 8 | */ 9 | #include 10 | #include 11 | 12 | // SD chip select pin 13 | const uint8_t chipSelect = SS; 14 | 15 | // file system object 16 | SdFat sd; 17 | 18 | // create a serial stream 19 | ArduinoOutStream cout(Serial); 20 | //------------------------------------------------------------------------------ 21 | void makeTestFile() { 22 | ofstream sdout("getline.txt"); 23 | // use flash for text to save RAM 24 | sdout << F( 25 | "short line\n" 26 | "\n" 27 | "17 character line\n" 28 | "too long for buffer\n" 29 | "line with no nl"); 30 | 31 | sdout.close(); 32 | } 33 | //------------------------------------------------------------------------------ 34 | void testGetline() { 35 | const int line_buffer_size = 18; 36 | char buffer[line_buffer_size]; 37 | ifstream sdin("getline.txt"); 38 | int line_number = 0; 39 | 40 | while (sdin.getline(buffer, line_buffer_size, '\n') || sdin.gcount()) { 41 | int count = sdin.gcount(); 42 | if (sdin.fail()) { 43 | cout << "Partial long line"; 44 | sdin.clear(sdin.rdstate() & ~ios_base::failbit); 45 | } else if (sdin.eof()) { 46 | cout << "Partial final line"; // sdin.fail() is false 47 | } else { 48 | count--; // Don’t include newline in count 49 | cout << "Line " << ++line_number; 50 | } 51 | cout << " (" << count << " chars): " << buffer << endl; 52 | } 53 | } 54 | //------------------------------------------------------------------------------ 55 | void setup(void) { 56 | Serial.begin(9600); 57 | while (!Serial) {} // wait for Leonardo 58 | 59 | // pstr stores strings in flash to save RAM 60 | cout << F("Type any character to start\n"); 61 | while (Serial.read() <= 0) {} 62 | delay(400); // catch Due reset problem 63 | 64 | // initialize the SD card at SPI_HALF_SPEED to avoid bus errors with 65 | // breadboards. use SPI_FULL_SPEED for better performance. 66 | if (!sd.begin(chipSelect, SPI_HALF_SPEED)) { 67 | sd.initErrorHalt(); 68 | } 69 | 70 | // make the test file 71 | makeTestFile(); 72 | 73 | // run the example 74 | testGetline(); 75 | cout << "\nDone!\n"; 76 | } 77 | //------------------------------------------------------------------------------ 78 | void loop(void) {} 79 | -------------------------------------------------------------------------------- /Libraries/SdFat/src/Deprecated/SdVolume.h: -------------------------------------------------------------------------------- 1 | /* Arduino SdFat Library 2 | * Copyright (C) 2012 by William Greiman 3 | * 4 | * This file is part of the Arduino SdFat Library 5 | * 6 | * This Library is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This Library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with the Arduino SdFat Library. If not, see 18 | * . 19 | */ 20 | #ifndef SdVolume_h 21 | #include "SdSpiCard.h" 22 | #include "utility/FatLib.h" 23 | #define SdVolume_h 24 | #ifndef USE_SD_VOLUME 25 | #error SdVolume is deperacated. Remove this line to continue using this class. 26 | #endif // USE_SD_VOLUME 27 | //============================================================================== 28 | /** 29 | * \class SdVolume 30 | * \brief SdVolume Soon to be removed. 31 | */ 32 | class SdVolume : public FatVolume { 33 | public: 34 | /** Initialize a FAT volume. Try partition one first then try super 35 | * floppy format. 36 | * 37 | * \param[in] dev The Sd2Card where the volume is located. 38 | * 39 | * \return true for success else false. 40 | */ 41 | bool init(Sd2Card* dev) { 42 | return init(dev, 1) ? true : init(dev, 0); 43 | } 44 | /** Initialize a FAT volume. 45 | * 46 | * \param[in] dev The Sd2Card where the volume is located. 47 | * \param[in] part the partition to use. Zero for super floppy or 1-4. 48 | * \return true for success else false. 49 | */ 50 | bool init(Sd2Card* dev, uint8_t part) { 51 | m_sdCard = dev; 52 | return FatVolume::init(part); 53 | } 54 | 55 | private: 56 | // friend class FatFile; 57 | bool readBlock(uint32_t block, uint8_t* dst) { 58 | return m_sdCard->readBlock(block, dst); 59 | } 60 | bool writeBlock(uint32_t block, const uint8_t* src) { 61 | return m_sdCard->writeBlock(block, src); 62 | } 63 | bool readBlocks(uint32_t block, uint8_t* dst, size_t n) { 64 | return m_sdCard->readBlocks(block, dst, n); 65 | } 66 | bool writeBlocks(uint32_t block, const uint8_t* src, size_t n) { 67 | return m_sdCard->writeBlocks(block, src, n); 68 | } 69 | Sd2Card* m_sdCard; // Sd2Card object for cache 70 | }; 71 | #endif // SdVolume_h 72 | -------------------------------------------------------------------------------- /Libraries/SdFat/examples/LongFileName/LongFileName.ino: -------------------------------------------------------------------------------- 1 | // Example use of lfnOpenNext and open by index. 2 | // You can use test files located in 3 | // SdFat/examples/LongFileName/testFiles. 4 | #include 5 | #include 6 | #include 7 | 8 | // SD card chip select pin. 9 | const uint8_t SD_CS_PIN = SS; 10 | 11 | SdFat sd; 12 | SdFile file; 13 | SdFile dirFile; 14 | 15 | // Number of files found. 16 | uint16_t n = 0; 17 | 18 | // Max of ten files since files are selected with a single digit. 19 | const uint16_t nMax = 10; 20 | 21 | // Position of file's directory entry. 22 | uint16_t dirIndex[nMax]; 23 | //------------------------------------------------------------------------------ 24 | void setup() { 25 | Serial.begin(9600); 26 | while (!Serial) {} 27 | delay(1000); 28 | 29 | // Print the location of some test files. 30 | Serial.println(F("\r\n" 31 | "You can use test files located in\r\n" 32 | "SdFat/examples/LongFileName/testFiles")); 33 | 34 | if (!sd.begin(SD_CS_PIN)) { 35 | sd.initErrorHalt(); 36 | } 37 | Serial.print(F("FreeStack: ")); 38 | Serial.println(FreeStack()); 39 | Serial.println(); 40 | 41 | // List files in root directory. 42 | if (!dirFile.open("/", O_READ)) { 43 | sd.errorHalt("open root failed"); 44 | } 45 | while (n < nMax && file.openNext(&dirFile, O_READ)) { 46 | 47 | // Skip directories and hidden files. 48 | if (!file.isSubDir() && !file.isHidden()) { 49 | 50 | // Save dirIndex of file in directory. 51 | dirIndex[n] = file.dirIndex(); 52 | 53 | // Print the file number and name. 54 | Serial.print(n++); 55 | Serial.write(' '); 56 | file.printName(&Serial); 57 | Serial.println(); 58 | } 59 | file.close(); 60 | } 61 | } 62 | //------------------------------------------------------------------------------ 63 | void loop() { 64 | int c; 65 | 66 | // Discard any Serial input. 67 | while (Serial.read() > 0) {} 68 | Serial.print(F("\r\nEnter File Number: ")); 69 | 70 | while ((c = Serial.read()) < 0) {}; 71 | if (!isdigit(c) || (c -= '0') >= n) { 72 | Serial.println(F("Invald number")); 73 | return; 74 | } 75 | Serial.println(c); 76 | if (!file.open(&dirFile, dirIndex[c], O_READ)) { 77 | sd.errorHalt(F("open")); 78 | } 79 | Serial.println(); 80 | 81 | char last; 82 | 83 | // Copy up to 500 characters to Serial. 84 | for (int i = 0; i < 500 && (c = file.read()) > 0; i++) { 85 | Serial.write(last = (char)c); 86 | } 87 | // Add new line if missing from last line. 88 | if (last != '\n') { 89 | Serial.println(); 90 | } 91 | file.close(); 92 | Serial.flush(); 93 | delay(100); 94 | } -------------------------------------------------------------------------------- /Libraries/SdFat/examples/VolumeFreeSpace/VolumeFreeSpace.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * This program demonstrates the freeClusterCount() call. 3 | */ 4 | #include 5 | #include 6 | /* 7 | * SD chip select pin. Common values are: 8 | * 9 | * Arduino Ethernet shield, pin 4. 10 | * SparkFun SD shield, pin 8. 11 | * Adafruit Datalogging shield, pin 10. 12 | * Default SD chip select is the SPI SS pin. 13 | */ 14 | const uint8_t chipSelect = SS; 15 | 16 | #define TEST_FILE "CLUSTER.TST" 17 | // file system 18 | SdFat sd; 19 | 20 | // test file 21 | SdFile file; 22 | 23 | // Serial output stream 24 | ArduinoOutStream cout(Serial); 25 | //------------------------------------------------------------------------------ 26 | void printFreeSpace() { 27 | cout << F("freeClusterCount() call time: "); 28 | uint32_t m = micros(); 29 | uint32_t volFree = sd.vol()->freeClusterCount(); 30 | cout << micros() - m << F(" micros\n"); 31 | cout << F("freeClusters: ") << volFree << setprecision(3) << endl; 32 | float fs = 0.000512*volFree*sd.vol()->blocksPerCluster(); 33 | cout << F("freeSpace: ") << fs << F(" MB (MB = 1,000,000 bytes)\n\n"); 34 | } 35 | //------------------------------------------------------------------------------ 36 | void setup() { 37 | Serial.begin(9600); 38 | while (!Serial) {} // wait for Leonardo 39 | 40 | if (!MAINTAIN_FREE_CLUSTER_COUNT) { 41 | cout << F("Please edit SdFatConfig.h and set\n"); 42 | cout << F("MAINTAIN_FREE_CLUSTER_COUNT nonzero for\n"); 43 | cout << F("maximum freeClusterCount() performance.\n\n"); 44 | } 45 | // pstr stores strings in flash to save RAM 46 | cout << F("Type any character to start\n"); 47 | while (Serial.read() <= 0) {} 48 | delay(400); // catch Due reset problem 49 | 50 | // initialize the SD card at SPI_HALF_SPEED to avoid bus errors with 51 | // breadboards. use SPI_FULL_SPEED for better performance. 52 | if (!sd.begin(chipSelect, SPI_HALF_SPEED)) { 53 | sd.initErrorHalt(); 54 | } 55 | // Insure no TEST_FILE. 56 | sd.remove(TEST_FILE); 57 | 58 | cout << F("\nFirst call to freeClusterCount scans the FAT.\n\n"); 59 | printFreeSpace(); 60 | 61 | cout << F("Create and write to ") << TEST_FILE << endl; 62 | if (!file.open(TEST_FILE, O_WRITE | O_CREAT)) { 63 | sd.errorHalt(F("Create failed")); 64 | } 65 | file.print(F("Cause a cluster to be allocated")); 66 | file.close(); 67 | 68 | cout << F("\nSecond freeClusterCount call is faster if\n"); 69 | cout << F("MAINTAIN_FREE_CLUSTER_COUNT is nonzero.\n\n"); 70 | 71 | printFreeSpace(); 72 | 73 | cout << F("Remove ") << TEST_FILE << endl << endl; 74 | sd.remove(TEST_FILE); 75 | printFreeSpace(); 76 | } 77 | //------------------------------------------------------------------------------ 78 | void loop() {} -------------------------------------------------------------------------------- /Libraries/SdFat/src/FatLib/FatApiConstants.h: -------------------------------------------------------------------------------- 1 | /* FatLib Library 2 | * Copyright (C) 2013 by William Greiman 3 | * 4 | * This file is part of the FatLib Library 5 | * 6 | * This Library is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This Library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with the FatLib Library. If not, see 18 | * . 19 | */ 20 | #ifndef FatApiConstants_h 21 | #define FatApiConstants_h 22 | //------------------------------------------------------------------------------ 23 | // use the gnu style oflag in open() 24 | /** open() oflag for reading */ 25 | uint8_t const O_READ = 0X01; 26 | /** open() oflag - same as O_IN */ 27 | uint8_t const O_RDONLY = O_READ; 28 | /** open() oflag for write */ 29 | uint8_t const O_WRITE = 0X02; 30 | /** open() oflag - same as O_WRITE */ 31 | uint8_t const O_WRONLY = O_WRITE; 32 | /** open() oflag for reading and writing */ 33 | uint8_t const O_RDWR = (O_READ | O_WRITE); 34 | /** open() oflag mask for access modes */ 35 | uint8_t const O_ACCMODE = (O_READ | O_WRITE); 36 | /** The file offset shall be set to the end of the file prior to each write. */ 37 | uint8_t const O_APPEND = 0X04; 38 | /** synchronous writes - call sync() after each write */ 39 | uint8_t const O_SYNC = 0X08; 40 | /** truncate the file to zero length */ 41 | uint8_t const O_TRUNC = 0X10; 42 | /** set the initial position at the end of the file */ 43 | uint8_t const O_AT_END = 0X20; 44 | /** create the file if nonexistent */ 45 | uint8_t const O_CREAT = 0X40; 46 | /** If O_CREAT and O_EXCL are set, open() shall fail if the file exists */ 47 | uint8_t const O_EXCL = 0X80; 48 | 49 | // FatFile class static and const definitions 50 | // flags for ls() 51 | /** ls() flag for list all files including hidden. */ 52 | uint8_t const LS_A = 1; 53 | /** ls() flag to print modify. date */ 54 | uint8_t const LS_DATE = 2; 55 | /** ls() flag to print file size. */ 56 | uint8_t const LS_SIZE = 4; 57 | /** ls() flag for recursive list of subdirectories */ 58 | uint8_t const LS_R = 8; 59 | 60 | // flags for timestamp 61 | /** set the file's last access date */ 62 | uint8_t const T_ACCESS = 1; 63 | /** set the file's creation date and time */ 64 | uint8_t const T_CREATE = 2; 65 | /** Set the file's write date and time */ 66 | uint8_t const T_WRITE = 4; 67 | #endif // FatApiConstants_h 68 | -------------------------------------------------------------------------------- /Libraries/SdFat/examples/#attic/fgetsRewrite/fgetsRewrite.ino: -------------------------------------------------------------------------------- 1 | // Demo of rewriting a line read by fgets 2 | #include 3 | #include 4 | 5 | // SD card chip select pin 6 | const uint8_t chipSelect = SS; 7 | 8 | // file system 9 | SdFat sd; 10 | 11 | // print stream 12 | ArduinoOutStream cout(Serial); 13 | //------------------------------------------------------------------------------ 14 | // store error strings in flash memory 15 | #define error(s) sd.errorHalt(F(s)) 16 | //------------------------------------------------------------------------------ 17 | void demoFgets() { 18 | char line[25]; 19 | int c; 20 | uint32_t pos; 21 | 22 | // open test file 23 | SdFile rdfile("fgets.txt", O_RDWR); 24 | 25 | // check for open error 26 | if (!rdfile.isOpen()) { 27 | error("demoFgets"); 28 | } 29 | 30 | // list file 31 | cout << F("-----Before Rewrite\r\n"); 32 | while ((c = rdfile.read()) >= 0) { 33 | Serial.write(c); 34 | } 35 | 36 | rdfile.rewind(); 37 | // read lines from the file to get position 38 | while (1) { 39 | pos = rdfile.curPosition(); 40 | if (rdfile.fgets(line, sizeof(line)) < 0) { 41 | error("Line not found"); 42 | } 43 | // find line that contains "Line C" 44 | if (strstr(line, "Line C")) { 45 | break; 46 | } 47 | } 48 | 49 | // rewrite line with 'C' 50 | if (!rdfile.seekSet(pos)) { 51 | error("seekSet"); 52 | } 53 | rdfile.println("Line R"); 54 | rdfile.rewind(); 55 | 56 | // list file 57 | cout << F("\r\n-----After Rewrite\r\n"); 58 | while ((c = rdfile.read()) >= 0) { 59 | Serial.write(c); 60 | } 61 | 62 | // close so rewrite is not lost 63 | rdfile.close(); 64 | } 65 | //------------------------------------------------------------------------------ 66 | void makeTestFile() { 67 | // create or open test file 68 | SdFile wrfile("fgets.txt", O_WRITE | O_CREAT | O_TRUNC); 69 | 70 | // check for open error 71 | if (!wrfile.isOpen()) { 72 | error("MakeTestFile"); 73 | } 74 | 75 | // write test file 76 | wrfile.print(F( 77 | "Line A\r\n" 78 | "Line B\r\n" 79 | "Line C\r\n" 80 | "Line D\r\n" 81 | "Line E\r\n" 82 | )); 83 | wrfile.close(); 84 | } 85 | //------------------------------------------------------------------------------ 86 | void setup(void) { 87 | Serial.begin(9600); 88 | while (!Serial) {} // wait for Leonardo 89 | 90 | cout << F("Type any character to start\n"); 91 | while (Serial.read() <= 0) {} 92 | delay(400); // catch Due reset problem 93 | 94 | // initialize the SD card at SPI_HALF_SPEED to avoid bus errors with 95 | // breadboards. use SPI_FULL_SPEED for better performance. 96 | if (!sd.begin(chipSelect, SPI_HALF_SPEED)) { 97 | sd.initErrorHalt(); 98 | } 99 | 100 | makeTestFile(); 101 | 102 | demoFgets(); 103 | 104 | cout << F("\nDone\n"); 105 | } 106 | void loop(void) {} 107 | -------------------------------------------------------------------------------- /Libraries/SdFat/examples/rename/rename.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * This program demonstrates use of SdFile::rename() 3 | * and SdFat::rename(). 4 | */ 5 | #include 6 | #include 7 | 8 | // SD chip select pin 9 | const uint8_t chipSelect = SS; 10 | 11 | // file system 12 | SdFat sd; 13 | 14 | // Serial print stream 15 | ArduinoOutStream cout(Serial); 16 | //------------------------------------------------------------------------------ 17 | // store error strings in flash to save RAM 18 | #define error(s) sd.errorHalt(F(s)) 19 | //------------------------------------------------------------------------------ 20 | void setup() { 21 | Serial.begin(9600); 22 | while (!Serial) {} // wait for Leonardo 23 | 24 | cout << F("Insert an empty SD. Type any character to start.") << endl; 25 | while (Serial.read() <= 0) {} 26 | delay(400); // catch Due reset problem 27 | 28 | // initialize the SD card at SPI_HALF_SPEED to avoid bus errors with 29 | // breadboards. use SPI_FULL_SPEED for better performance. 30 | if (!sd.begin(chipSelect, SPI_HALF_SPEED)) { 31 | sd.initErrorHalt(); 32 | } 33 | 34 | // Remove file/dirs from previous run. 35 | if (sd.exists("dir2/DIR3/NAME3.txt")) { 36 | cout << F("Removing /dir2/DIR3/NAME3.txt") << endl; 37 | if (!sd.remove("dir2/DIR3/NAME3.txt") || 38 | !sd.rmdir("dir2/DIR3/") || 39 | !sd.rmdir("dir2/")) { 40 | error("remove/rmdir failed"); 41 | } 42 | } 43 | // create a file and write one line to the file 44 | SdFile file("Name1.txt", O_WRITE | O_CREAT); 45 | if (!file.isOpen()) { 46 | error("Name1.txt"); 47 | } 48 | file.println("A test line for Name1.txt"); 49 | 50 | // rename the file name2.txt and add a line. 51 | // sd.vwd() is the volume working directory, root. 52 | if (!file.rename(sd.vwd(), "name2.txt")) { 53 | error("name2.txt"); 54 | } 55 | file.println("A test line for name2.txt"); 56 | 57 | // list files 58 | cout << F("------") << endl; 59 | sd.ls(LS_R); 60 | 61 | // make a new directory - "Dir1" 62 | if (!sd.mkdir("Dir1")) { 63 | error("Dir1"); 64 | } 65 | 66 | // move file into Dir1, rename it NAME3.txt and add a line 67 | if (!file.rename(sd.vwd(), "Dir1/NAME3.txt")) { 68 | error("NAME3.txt"); 69 | } 70 | file.println("A line for Dir1/NAME3.txt"); 71 | 72 | // list files 73 | cout << F("------") << endl; 74 | sd.ls(LS_R); 75 | 76 | // make directory "dir2" 77 | if (!sd.mkdir("dir2")) { 78 | error("dir2"); 79 | } 80 | 81 | // close file before rename(oldPath, newPath) 82 | file.close(); 83 | 84 | // move Dir1 into dir2 and rename it DIR3 85 | if (!sd.rename("Dir1", "dir2/DIR3")) { 86 | error("dir2/DIR3"); 87 | } 88 | 89 | // open file for append in new location and add a line 90 | if (!file.open("dir2/DIR3/NAME3.txt", O_WRITE | O_APPEND)) { 91 | error("dir2/DIR3/NAME3.txt"); 92 | } 93 | file.println("A line for dir2/DIR3/NAME3.txt"); 94 | file.close(); 95 | 96 | // list files 97 | cout << F("------") << endl; 98 | sd.ls(LS_R); 99 | 100 | cout << F("Done") << endl; 101 | } 102 | void loop() {} 103 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | SparkFun License Information 2 | ============================ 3 | 4 | SparkFun uses two different licenses for our files — one for hardware and one for code. 5 | 6 | Hardware 7 | --------- 8 | 9 | **SparkFun hardware is released under [Creative Commons Share-alike 4.0 International](http://creativecommons.org/licenses/by-sa/4.0/).** 10 | 11 | Note: This is a human-readable summary of (and not a substitute for) the [license](http://creativecommons.org/licenses/by-sa/4.0/legalcode). 12 | 13 | You are free to: 14 | 15 | Share — copy and redistribute the material in any medium or format 16 | Adapt — remix, transform, and build upon the material 17 | for any purpose, even commercially. 18 | The licensor cannot revoke these freedoms as long as you follow the license terms. 19 | Under the following terms: 20 | 21 | Attribution — You must give appropriate credit, provide a link to the license, and indicate if changes were made. You may do so in any reasonable manner, but not in any way that suggests the licensor endorses you or your use. 22 | ShareAlike — If you remix, transform, or build upon the material, you must distribute your contributions under the same license as the original. 23 | No additional restrictions — You may not apply legal terms or technological measures that legally restrict others from doing anything the license permits. 24 | Notices: 25 | 26 | You do not have to comply with the license for elements of the material in the public domain or where your use is permitted by an applicable exception or limitation. 27 | No warranties are given. The license may not give you all of the permissions necessary for your intended use. For example, other rights such as publicity, privacy, or moral rights may limit how you use the material. 28 | 29 | 30 | Code 31 | -------- 32 | OpenLog uses SdFatLib-beta(https://github.com/greiman/SdFat-beta) and SerialPort(https://github.com/greiman/SerialPort) written by Bill Greiman and is released under [GPL v3](http://www.gnu.org/licenses/gpl-3.0.html). 33 | 34 | **SparkFun OpenLog firmware is released under the MIT License(http://opensource.org/licenses/MIT).** 35 | 36 | The MIT License (MIT) 37 | 38 | Copyright (c) 2016 SparkFun Electronics 39 | 40 | Permission is hereby granted, free of charge, to any person obtaining a copy 41 | of this software and associated documentation files (the "Software"), to deal 42 | in the Software without restriction, including without limitation the rights 43 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 44 | copies of the Software, and to permit persons to whom the Software is 45 | furnished to do so, subject to the following conditions: 46 | 47 | The above copyright notice and this permission notice shall be included in all 48 | copies or substantial portions of the Software. 49 | 50 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 51 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 52 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 53 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 54 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 55 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 56 | SOFTWARE. 57 | -------------------------------------------------------------------------------- /Libraries/SdFat/examples/readCSV/readCSV.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * This example reads a simple CSV, comma-separated values, file. 3 | * Each line of the file has a label and three values, a long and two floats. 4 | */ 5 | #include 6 | #include 7 | 8 | // SD chip select pin 9 | const uint8_t chipSelect = SS; 10 | 11 | // file system object 12 | SdFat sd; 13 | 14 | // create Serial stream 15 | ArduinoOutStream cout(Serial); 16 | 17 | char fileName[] = "testfile.csv"; 18 | //------------------------------------------------------------------------------ 19 | // store error strings in flash to save RAM 20 | #define error(s) sd.errorHalt(F(s)) 21 | //------------------------------------------------------------------------------ 22 | // read and print CSV test file 23 | void readFile() { 24 | long lg; 25 | float f1, f2; 26 | char text[10]; 27 | char c1, c2, c3; // space for commas. 28 | 29 | // open input file 30 | ifstream sdin(fileName); 31 | 32 | // check for open error 33 | if (!sdin.is_open()) { 34 | error("open"); 35 | } 36 | 37 | // read until input fails 38 | while (1) { 39 | // Get text field. 40 | sdin.get(text, sizeof(text), ','); 41 | 42 | // Assume EOF if fail. 43 | if (sdin.fail()) { 44 | break; 45 | } 46 | 47 | // Get commas and numbers. 48 | sdin >> c1 >> lg >> c2 >> f1 >> c3 >> f2; 49 | 50 | // Skip CR/LF. 51 | sdin.skipWhite(); 52 | 53 | if (sdin.fail()) { 54 | error("bad input"); 55 | } 56 | 57 | // error in line if not commas 58 | if (c1 != ',' || c2 != ',' || c3 != ',') { 59 | error("comma"); 60 | } 61 | 62 | // print in six character wide columns 63 | cout << text << setw(6) << lg << setw(6) << f1 << setw(6) << f2 << endl; 64 | } 65 | // Error in an input line if file is not at EOF. 66 | if (!sdin.eof()) { 67 | error("readFile"); 68 | } 69 | } 70 | //------------------------------------------------------------------------------ 71 | // write test file 72 | void writeFile() { 73 | 74 | // create or open and truncate output file 75 | ofstream sdout(fileName); 76 | 77 | // write file from string stored in flash 78 | sdout << F( 79 | "Line 1,1,2.3,4.5\n" 80 | "Line 2,6,7.8,9.0\n" 81 | "Line 3,9,8.7,6.5\n" 82 | "Line 4,-4,-3.2,-1\n") << flush; 83 | 84 | // check for any errors 85 | if (!sdout) { 86 | error("writeFile"); 87 | } 88 | 89 | sdout.close(); 90 | } 91 | //------------------------------------------------------------------------------ 92 | void setup() { 93 | Serial.begin(9600); 94 | while (!Serial) {} // wait for Leonardo 95 | cout << F("Type any character to start\n"); 96 | while (Serial.read() <= 0) {} 97 | delay(400); // catch Due reset problem 98 | 99 | // initialize the SD card at SPI_HALF_SPEED to avoid bus errors with 100 | // breadboards. use SPI_FULL_SPEED for better performance 101 | if (!sd.begin(chipSelect, SPI_HALF_SPEED)) { 102 | sd.initErrorHalt(); 103 | } 104 | 105 | // create test file 106 | writeFile(); 107 | 108 | cout << endl; 109 | 110 | // read and print test 111 | readFile(); 112 | 113 | cout << "\nDone!" << endl; 114 | } 115 | void loop() {} -------------------------------------------------------------------------------- /Libraries/SdFat/examples/#attic/PrintBenchmarkSD/PrintBenchmarkSD.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * This program is a simple Print benchmark. 3 | */ 4 | #include 5 | #include 6 | 7 | // SD chip select pin 8 | const uint8_t chipSelect = SS; 9 | 10 | // number of lines to print 11 | const uint16_t N_PRINT = 20000; 12 | 13 | 14 | // test file 15 | File file; 16 | 17 | //------------------------------------------------------------------------------ 18 | void error(char* s) { 19 | Serial.println(s); 20 | while(1); 21 | } 22 | //------------------------------------------------------------------------------ 23 | void setup() { 24 | Serial.begin(9600); 25 | while (!Serial) { 26 | // wait for Leonardo 27 | } 28 | } 29 | //------------------------------------------------------------------------------ 30 | void loop() { 31 | uint32_t maxLatency; 32 | uint32_t minLatency; 33 | uint32_t totalLatency; 34 | 35 | while (Serial.read() >= 0) { 36 | } 37 | // F() stores strings in flash to save RAM 38 | Serial.println(F("Type any character to start")); 39 | while (Serial.read() <= 0) { 40 | } 41 | delay(400); // catch Due reset problem 42 | 43 | 44 | // initialize the SD card 45 | 46 | if (!SD.begin(chipSelect)) { 47 | error("begin"); 48 | } 49 | 50 | 51 | Serial.println(F("Starting print test. Please wait.\n")); 52 | 53 | // do write test 54 | for (int test = 0; test < 2; test++) { 55 | file = SD.open("bench.txt", FILE_WRITE); 56 | 57 | if (!file) { 58 | error("open failed"); 59 | } 60 | switch(test) { 61 | case 0: 62 | Serial.println(F("Test of println(uint16_t)")); 63 | break; 64 | 65 | case 1: 66 | Serial.println(F("Test of println(double)")); 67 | break; 68 | } 69 | maxLatency = 0; 70 | minLatency = 999999; 71 | totalLatency = 0; 72 | uint32_t t = millis(); 73 | for (uint16_t i = 0; i < N_PRINT; i++) { 74 | uint32_t m = micros(); 75 | 76 | switch(test) { 77 | case 0: 78 | file.println(i); 79 | break; 80 | 81 | case 1: 82 | file.println((double)0.01*i); 83 | break; 84 | } 85 | 86 | if (file.getWriteError()) { 87 | error("write failed"); 88 | } 89 | m = micros() - m; 90 | if (maxLatency < m) { 91 | maxLatency = m; 92 | } 93 | if (minLatency > m) { 94 | minLatency = m; 95 | } 96 | totalLatency += m; 97 | } 98 | file.flush(); 99 | t = millis() - t; 100 | double s = file.size(); 101 | Serial.print(F("Time ")); 102 | Serial.print(0.001*t); 103 | Serial.println(F(" sec")); 104 | Serial.print(F("File size ")); 105 | Serial.print(0.001*s); 106 | Serial.print(F(" KB\n")); 107 | Serial.print(F("Write ")); 108 | Serial.print(s/t); 109 | Serial.print(F(" KB/sec\n")); 110 | Serial.print(F("Maximum latency: ")); 111 | Serial.print(maxLatency); 112 | Serial.print(F(" usec, Minimum Latency: ")); 113 | Serial.print(minLatency); 114 | Serial.print(F(" usec, Avg Latency: ")); 115 | Serial.print(totalLatency/N_PRINT); 116 | Serial.println(F(" usec\n")); 117 | SD.remove("bench.txt"); 118 | } 119 | file.close(); 120 | Serial.println(F("Done!\n")); 121 | } -------------------------------------------------------------------------------- /firmware/Arduino_Examples/Performance_Testing/CommandPrompt_Power/CommandPrompt_Power.ino: -------------------------------------------------------------------------------- 1 | /* 2 | Example of creating a file, reading a file, and reading the disk properties on OpenLog 3 | By: Nathan Seidle 4 | SparkFun Electronics 5 | Date: September 22nd, 2013 6 | License: This code is public domain but you buy me a beer if you use this and we meet someday (Beerware license). 7 | 8 | This example puts OpenLog in command mode with and without LED so we can test current 9 | consumption during command prompt. 10 | 11 | Connect the following OpenLog to Arduino: 12 | RXI of OpenLog to pin 2 on the Arduino 13 | TXO to 3 14 | GRN to 4 15 | VCC to 5V 16 | GND to GND 17 | 18 | This example code assumes the OpenLog is set to operate at 9600bps in NewLog mode, meaning OpenLog 19 | should power up and output '12<'. This code then sends the three escape characters and then sends 20 | the commands to create a new random file called log###.txt where ### is a random number from 0 to 999. 21 | The example code will then read back the random file and print it to the serial terminal. 22 | 23 | This code assume OpenLog is in the default state of 9600bps with ASCII-26 as the esacape character. 24 | If you're unsure, make sure the config.txt file contains the following: 9600,26,3,0 25 | 26 | Be careful when sending commands to OpenLog. println() sends extra newline characters that 27 | cause problems with the command parser. The new v2.51 ignores \n commands so it should be easier to 28 | talk to on the command prompt level. This example code works with all OpenLog v2 and higher. 29 | 30 | */ 31 | 32 | #include 33 | 34 | //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- 35 | //Connect TXO of OpenLog to pin 3, RXI to pin 2 36 | SoftwareSerial OpenLog(3, 2); //Soft RX on 3, Soft TX out on 2 37 | //SoftwareSerial(rxPin, txPin) 38 | 39 | int resetOpenLog = 4; //This pin resets OpenLog. Connect pin 4 to pin GRN on OpenLog. 40 | //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- 41 | 42 | int statLED = 13; 43 | 44 | void setup() { 45 | pinMode(statLED, OUTPUT); 46 | Serial.begin(9600); 47 | 48 | setupOpenLog(); //Resets logger and waits for the '<' I'm alive character 49 | Serial.println("OpenLog online"); 50 | } 51 | 52 | void loop() { 53 | Serial.println("Going to command mode"); 54 | 55 | gotoCommandMode(); //Puts OpenLog in command mode 56 | 57 | //OpenLog will now be at ~6.7mA 58 | 59 | OpenLog.write('p'); //Send a character to get LED to turn on and stay on 60 | 61 | //OpenLog will now be at ~7.2mA 62 | 63 | while(1); //Freeze 64 | } 65 | 66 | //Setups up the software serial, resets OpenLog so we know what state it's in, and waits 67 | //for OpenLog to come online and report '<' that it is ready to receive characters to record 68 | void setupOpenLog(void) { 69 | pinMode(resetOpenLog, OUTPUT); 70 | OpenLog.begin(9600); 71 | 72 | //Reset OpenLog 73 | digitalWrite(resetOpenLog, LOW); 74 | delay(100); 75 | digitalWrite(resetOpenLog, HIGH); 76 | 77 | //Wait for OpenLog to respond with '<' to indicate it is alive and recording to a file 78 | while(1) { 79 | if(OpenLog.available()) 80 | if(OpenLog.read() == '<') break; 81 | } 82 | } 83 | 84 | //This function pushes OpenLog into command mode 85 | void gotoCommandMode(void) { 86 | //Send three control z to enter OpenLog command mode 87 | //Works with Arduino v1.0 88 | OpenLog.write(26); 89 | OpenLog.write(26); 90 | OpenLog.write(26); 91 | 92 | //Wait for OpenLog to respond with '>' to indicate we are in command mode 93 | while(1) { 94 | if(OpenLog.available()) 95 | if(OpenLog.read() == '>') break; 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /Libraries/SdFat/examples/directoryFunctions/directoryFunctions.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * Example use of chdir(), ls(), mkdir(), and rmdir(). 3 | */ 4 | #include 5 | #include 6 | // SD card chip select pin. 7 | const uint8_t SD_CHIP_SELECT = SS; 8 | //------------------------------------------------------------------------------ 9 | // Permit SD to be wiped if ALLOW_WIPE is true. 10 | const bool ALLOW_WIPE = false; 11 | 12 | // File system object. 13 | SdFat sd; 14 | 15 | // Use for file creation in folders. 16 | SdFile file; 17 | 18 | // Create a Serial output stream. 19 | ArduinoOutStream cout(Serial); 20 | 21 | // Buffer for Serial input. 22 | char cinBuf[40]; 23 | 24 | // Create a serial input stream. 25 | ArduinoInStream cin(Serial, cinBuf, sizeof(cinBuf)); 26 | //============================================================================== 27 | // Error messages stored in flash. 28 | #define error(msg) sd.errorHalt(F(msg)) 29 | //------------------------------------------------------------------------------ 30 | void setup() { 31 | Serial.begin(9600); 32 | while (!Serial) {} // wait for Leonardo 33 | delay(1000); 34 | 35 | cout << F("Type any character to start\n"); 36 | // Wait for input line and discard. 37 | cin.readline(); 38 | 39 | // Initialize the SD card at SPI_HALF_SPEED to avoid bus errors with 40 | // breadboards. use SPI_FULL_SPEED for better performance. 41 | if (!sd.begin(SD_CHIP_SELECT, SPI_HALF_SPEED)) { 42 | sd.initErrorHalt(); 43 | } 44 | 45 | // Check for empty SD. 46 | if (file.openNext(sd.vwd(), O_READ)) { 47 | cout << F("Found files/folders in the root directory.\n"); 48 | if (!ALLOW_WIPE) { 49 | error("SD not empty, use a blank SD or set ALLOW_WIPE true."); 50 | } else { 51 | cout << F("Type: 'WIPE' to delete all SD files.\n"); 52 | char buf[10]; 53 | cin.readline(); 54 | cin.get(buf, sizeof(buf)); 55 | if (cin.fail() || strncmp(buf, "WIPE", 4) || buf[4] >= ' ') { 56 | error("Invalid WIPE input"); 57 | } 58 | file.close(); 59 | if (!sd.vwd()->rmRfStar()) { 60 | error("wipe failed"); 61 | } 62 | cout << F("***SD wiped clean.***\n\n"); 63 | } 64 | } 65 | 66 | // Create a new folder. 67 | if (!sd.mkdir("Folder1")) { 68 | error("Create Folder1 failed"); 69 | } 70 | cout << F("Created Folder1\n"); 71 | 72 | // Create a file in Folder1 using a path. 73 | if (!file.open("Folder1/file1.txt", O_CREAT | O_WRITE)) { 74 | error("create Folder1/file1.txt failed"); 75 | } 76 | file.close(); 77 | cout << F("Created Folder1/file1.txt\n"); 78 | 79 | // Change volume working directory to Folder1. 80 | if (!sd.chdir("Folder1")) { 81 | error("chdir failed for Folder1.\n"); 82 | } 83 | cout << F("chdir to Folder1\n"); 84 | 85 | // Create File2.txt in current directory. 86 | if (!file.open("File2.txt", O_CREAT | O_WRITE)) { 87 | error("create File2.txt failed"); 88 | } 89 | file.close(); 90 | cout << F("Created File2.txt in current directory\n"); 91 | 92 | cout << F("List of files on the SD.\n"); 93 | sd.ls("/", LS_R); 94 | 95 | // Remove files from current directory. 96 | if (!sd.remove("file1.txt") || !sd.remove("File2.txt")) { 97 | error("remove failed"); 98 | } 99 | cout << F("\nfile1.txt and File2.txt removed.\n"); 100 | 101 | // Change current directory to root. 102 | if (!sd.chdir()) { 103 | error("chdir to root failed.\n"); 104 | } 105 | 106 | cout << F("List of files on the SD.\n"); 107 | sd.ls(LS_R); 108 | 109 | // Remove Folder1. 110 | if (!sd.rmdir("Folder1")) { 111 | error("rmdir for Folder1 failed\n"); 112 | } 113 | 114 | cout << F("\nFolder1 removed, SD empty.\n"); 115 | cout << F("Done!\n"); 116 | } 117 | //------------------------------------------------------------------------------ 118 | // Nothing happens in loop. 119 | void loop() {} -------------------------------------------------------------------------------- /Libraries/SdFat/src/FatLib/ArduinoStream.h: -------------------------------------------------------------------------------- 1 | /* FatLib Library 2 | * Copyright (C) 2013 by William Greiman 3 | * 4 | * This file is part of the FatLib Library 5 | * 6 | * This Library is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This Library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with the FatLib Library. If not, see 18 | * . 19 | */ 20 | #ifndef ArduinoStream_h 21 | #define ArduinoStream_h 22 | /** 23 | * \file 24 | * \brief ArduinoInStream and ArduinoOutStream classes 25 | */ 26 | #include "FatLibConfig.h" 27 | #if ENABLE_ARDUINO_FEATURES 28 | #include 29 | #include "bufstream.h" 30 | //============================================================================== 31 | /** 32 | * \class ArduinoInStream 33 | * \brief Input stream for Arduino Stream objects 34 | */ 35 | class ArduinoInStream : public ibufstream { 36 | public: 37 | /** 38 | * Constructor 39 | * \param[in] hws hardware stream 40 | * \param[in] buf buffer for input line 41 | * \param[in] size size of input buffer 42 | */ 43 | ArduinoInStream(Stream &hws, char* buf, size_t size) { 44 | m_hw = &hws; 45 | m_line = buf; 46 | m_size = size; 47 | } 48 | /** read a line. */ 49 | void readline() { 50 | size_t i = 0; 51 | uint32_t t; 52 | m_line[0] = '\0'; 53 | while (!m_hw->available()) {} 54 | 55 | while (1) { 56 | t = millis(); 57 | while (!m_hw->available()) { 58 | if ((millis() - t) > 10) { 59 | goto done; 60 | } 61 | } 62 | if (i >= (m_size - 1)) { 63 | setstate(failbit); 64 | return; 65 | } 66 | m_line[i++] = m_hw->read(); 67 | m_line[i] = '\0'; 68 | } 69 | done: 70 | init(m_line); 71 | } 72 | 73 | protected: 74 | /** Internal - do not use. 75 | * \param[in] off 76 | * \param[in] way 77 | * \return true/false. 78 | */ 79 | bool seekoff(off_type off, seekdir way) { 80 | return false; 81 | } 82 | /** Internal - do not use. 83 | * \param[in] pos 84 | * \return true/false. 85 | */ 86 | bool seekpos(pos_type pos) { 87 | return false; 88 | } 89 | 90 | private: 91 | char *m_line; 92 | size_t m_size; 93 | Stream* m_hw; 94 | }; 95 | //============================================================================== 96 | /** 97 | * \class ArduinoOutStream 98 | * \brief Output stream for Arduino Print objects 99 | */ 100 | class ArduinoOutStream : public ostream { 101 | public: 102 | /** constructor 103 | * 104 | * \param[in] pr Print object for this ArduinoOutStream. 105 | */ 106 | explicit ArduinoOutStream(Print& pr) : m_pr(&pr) {} 107 | 108 | protected: 109 | /// @cond SHOW_PROTECTED 110 | /** 111 | * Internal do not use 112 | * \param[in] c 113 | */ 114 | void putch(char c) { 115 | if (c == '\n') { 116 | m_pr->write('\r'); 117 | } 118 | m_pr->write(c); 119 | } 120 | void putstr(const char* str) { 121 | m_pr->write(str); 122 | } 123 | bool seekoff(off_type off, seekdir way) { 124 | return false; 125 | } 126 | bool seekpos(pos_type pos) { 127 | return false; 128 | } 129 | bool sync() { 130 | return true; 131 | } 132 | pos_type tellpos() { 133 | return 0; 134 | } 135 | /// @endcond 136 | private: 137 | ArduinoOutStream() {} 138 | Print* m_pr; 139 | }; 140 | #endif // ENABLE_ARDUINO_FEATURES 141 | #endif // ArduinoStream_h 142 | -------------------------------------------------------------------------------- /firmware/Arduino_Examples/Example6_GetVersionNumber/Example6_GetVersionNumber.ino: -------------------------------------------------------------------------------- 1 | /* 2 | Example of creating a file, reading a file, and reading the disk properties on OpenLog 3 | By: Nathan Seidle 4 | SparkFun Electronics 5 | Date: September 22nd, 2013 6 | License: This code is public domain but you buy me a beer if you use this and we meet someday (Beerware license). 7 | 8 | This example reads the firmware version of the OpenLog without the need for a USB to serial connection. 9 | The firmware version of your OpenLog is very helpful if you need tech support. 10 | 11 | Connect the following OpenLog to Arduino: 12 | RXI of OpenLog to pin 2 on the Arduino 13 | TXO to 3 14 | GRN to 4 15 | VCC to 5V 16 | GND to GND 17 | 18 | This example code assumes the OpenLog is set to operate in default mode. This is 9600bps 19 | in NewLog mode, meaning OpenLog should power up and output '12<'. This code then sends the 20 | three escape characters and then sends the commands to bring up the help menu '?' and then 21 | looks for the "OpenLog v4.0" text at the top of the menu. It will then print the version 22 | # to the serial terminal. 23 | 24 | This code assume OpenLog is in the default state of 9600bps with ASCII-26 as the esacape character. 25 | If you're unsure, make sure the config.txt file contains the following: 9600,26,3,0 26 | 27 | Be careful when sending commands to OpenLog. println() sends extra newline characters that 28 | cause problems with the command parser. v2.51 and above ignores \n commands so it should be easier to 29 | talk to on the command prompt level. This example code works with all OpenLog v2 and higher. 30 | 31 | */ 32 | 33 | #include 34 | 35 | //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- 36 | //Connect TXO of OpenLog to pin 3, RXI to pin 2 37 | SoftwareSerial OpenLog(3, 2); //Soft RX on 3, Soft TX out on 2 38 | //SoftwareSerial(rxPin, txPin) 39 | 40 | int resetOpenLog = 4; //This pin resets OpenLog. Connect pin 4 to pin GRN on OpenLog. 41 | //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- 42 | 43 | int statLED = 13; 44 | 45 | void setup() { 46 | pinMode(statLED, OUTPUT); 47 | Serial.begin(9600); 48 | 49 | Serial.println("Find OpenLog Firmware Version"); 50 | 51 | setupOpenLog(); //Resets logger and waits for the '<' I'm alive character 52 | Serial.println("OpenLog online"); 53 | 54 | gotoCommandMode(); //Puts OpenLog in command mode 55 | OpenLog.println('?'); //Send a character to get help menu 56 | delay(100); 57 | 58 | byte counter = 200; 59 | while(OpenLog.available() && counter > 0) 60 | { 61 | byte incoming = OpenLog.read(); 62 | if(incoming == 'v') counter = 4; //Get the next four characters 63 | 64 | Serial.write(incoming); 65 | counter--; 66 | } 67 | Serial.println(); 68 | } 69 | 70 | void loop() { 71 | //Do nothing 72 | } 73 | 74 | //Setups up the software serial, resets OpenLog so we know what state it's in, and waits 75 | //for OpenLog to come online and report '<' that it is ready to receive characters to record 76 | void setupOpenLog(void) { 77 | pinMode(resetOpenLog, OUTPUT); 78 | OpenLog.begin(9600); 79 | 80 | //Reset OpenLog 81 | digitalWrite(resetOpenLog, LOW); 82 | delay(100); 83 | digitalWrite(resetOpenLog, HIGH); 84 | 85 | //Wait for OpenLog to respond with '<' to indicate it is alive and recording to a file 86 | while(1) { 87 | if(OpenLog.available()) 88 | if(OpenLog.read() == '<') break; 89 | } 90 | } 91 | 92 | //This function pushes OpenLog into command mode 93 | void gotoCommandMode(void) { 94 | //Send three control z to enter OpenLog command mode 95 | //Works with Arduino v1.0 96 | OpenLog.write(26); 97 | OpenLog.write(26); 98 | OpenLog.write(26); 99 | 100 | //Wait for OpenLog to respond with '>' to indicate we are in command mode 101 | while(1) { 102 | if(OpenLog.available()) 103 | if(OpenLog.read() == '>') break; 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /Libraries/SdFat/src/SdFat.cpp: -------------------------------------------------------------------------------- 1 | /* Arduino SdFat Library 2 | * Copyright (C) 2012 by William Greiman 3 | * 4 | * This file is part of the Arduino SdFat Library 5 | * 6 | * This Library is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This Library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with the Arduino SdFat Library. If not, see 18 | * . 19 | */ 20 | #include "SdFat.h" 21 | //------------------------------------------------------------------------------ 22 | void SdFatBase::errorHalt(Print* pr) { 23 | errorPrint(pr); 24 | while (1) {} 25 | } 26 | //------------------------------------------------------------------------------ 27 | void SdFatBase::errorHalt(Print* pr, char const* msg) { 28 | errorPrint(pr, msg); 29 | while (1) {} 30 | } 31 | //------------------------------------------------------------------------------ 32 | void SdFatBase::errorHalt(Print* pr, const __FlashStringHelper* msg) { 33 | errorPrint(pr, msg); 34 | while (1) {} 35 | } 36 | //------------------------------------------------------------------------------ 37 | void SdFatBase::errorPrint(Print* pr) { 38 | if (!cardErrorCode()) { 39 | return; 40 | } 41 | pr->print(F("SD errorCode: 0X")); 42 | pr->print(cardErrorCode(), HEX); 43 | pr->print(F(",0X")); 44 | pr->println(cardErrorData(), HEX); 45 | } 46 | //------------------------------------------------------------------------------ 47 | void SdFatBase::errorPrint(Print* pr, char const* msg) { 48 | pr->print(F("error: ")); 49 | pr->println(msg); 50 | errorPrint(pr); 51 | } 52 | //------------------------------------------------------------------------------ 53 | void SdFatBase::errorPrint(Print* pr, const __FlashStringHelper* msg) { 54 | pr->print(F("error: ")); 55 | pr->println(msg); 56 | errorPrint(pr); 57 | } 58 | //------------------------------------------------------------------------------ 59 | void SdFatBase::initErrorHalt(Print* pr) { 60 | initErrorPrint(pr); 61 | while (1) {} 62 | } 63 | //------------------------------------------------------------------------------ 64 | void SdFatBase::initErrorHalt(Print* pr, char const *msg) { 65 | pr->println(msg); 66 | initErrorHalt(pr); 67 | } 68 | //------------------------------------------------------------------------------ 69 | void SdFatBase::initErrorHalt(Print* pr, const __FlashStringHelper* msg) { 70 | pr->println(msg); 71 | initErrorHalt(pr); 72 | } 73 | //------------------------------------------------------------------------------ 74 | void SdFatBase::initErrorPrint(Print* pr) { 75 | if (cardErrorCode()) { 76 | pr->println(F("Can't access SD card. Do not reformat.")); 77 | if (cardErrorCode() == SD_CARD_ERROR_CMD0) { 78 | pr->println(F("No card, wrong chip select pin, or SPI problem?")); 79 | } 80 | errorPrint(pr); 81 | } else if (vol()->fatType() == 0) { 82 | pr->println(F("Invalid format, reformat SD.")); 83 | } else if (!vwd()->isOpen()) { 84 | pr->println(F("Can't open root directory.")); 85 | } else { 86 | pr->println(F("No error found.")); 87 | } 88 | } 89 | //------------------------------------------------------------------------------ 90 | void SdFatBase::initErrorPrint(Print* pr, char const *msg) { 91 | pr->println(msg); 92 | initErrorPrint(pr); 93 | } 94 | //------------------------------------------------------------------------------ 95 | void SdFatBase::initErrorPrint(Print* pr, const __FlashStringHelper* msg) { 96 | pr->println(msg); 97 | initErrorPrint(pr); 98 | } 99 | 100 | -------------------------------------------------------------------------------- /Libraries/SdFat/examples/#attic/benchSD/benchSD.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * This program is a simple binary write/read benchmark 3 | * for the standard Arduino SD.h library. 4 | */ 5 | #include 6 | #include 7 | 8 | // SD chip select pin 9 | const uint8_t chipSelect = SS; 10 | 11 | #define FILE_SIZE_MB 5 12 | #define FILE_SIZE (1000000UL*FILE_SIZE_MB) 13 | #define BUF_SIZE 100 14 | 15 | uint8_t buf[BUF_SIZE]; 16 | 17 | // test file 18 | File file; 19 | 20 | //------------------------------------------------------------------------------ 21 | void error(char* s) { 22 | Serial.println(s); 23 | while(1); 24 | } 25 | //------------------------------------------------------------------------------ 26 | void setup() { 27 | Serial.begin(9600); 28 | while (!Serial) {} // wait for Leonardo 29 | } 30 | //------------------------------------------------------------------------------ 31 | void loop() { 32 | uint32_t maxLatency; 33 | uint32_t minLatency; 34 | uint32_t totalLatency; 35 | 36 | // discard any input 37 | while (Serial.read() >= 0) {} 38 | 39 | // F() stores strings in flash to save RAM 40 | Serial.println(F("Type any character to start")); 41 | while (Serial.read() <= 0) {} 42 | delay(400); // catch Due reset problem 43 | 44 | if (!SD.begin(chipSelect)) { 45 | error("begin"); 46 | } 47 | 48 | // open or create file - truncate existing file. 49 | file = SD.open("Bench.dat", O_RDWR | O_TRUNC | O_CREAT); 50 | if (!file) { 51 | error("open failed"); 52 | } 53 | 54 | // fill buf with known data 55 | for (uint16_t i = 0; i < (BUF_SIZE-2); i++) { 56 | buf[i] = 'A' + (i % 26); 57 | } 58 | buf[BUF_SIZE-2] = '\r'; 59 | buf[BUF_SIZE-1] = '\n'; 60 | 61 | Serial.print(F("File size ")); 62 | Serial.print(FILE_SIZE_MB); 63 | Serial.println(F("MB")); 64 | Serial.print(F("Buffer size ")); 65 | Serial.print(BUF_SIZE); 66 | Serial.println(F(" bytes")); 67 | Serial.println(F("Starting write test. Please wait up to a minute")); 68 | 69 | // do write test 70 | uint32_t n = FILE_SIZE/sizeof(buf); 71 | maxLatency = 0; 72 | minLatency = 999999; 73 | totalLatency = 0; 74 | uint32_t t = millis(); 75 | for (uint32_t i = 0; i < n; i++) { 76 | uint32_t m = micros(); 77 | if (file.write(buf, sizeof(buf)) != sizeof(buf)) { 78 | error("write failed"); 79 | } 80 | m = micros() - m; 81 | if (maxLatency < m) { 82 | maxLatency = m; 83 | } 84 | if (minLatency > m) { 85 | minLatency = m; 86 | } 87 | totalLatency += m; 88 | } 89 | file.flush(); 90 | t = millis() - t; 91 | double s = file.size(); 92 | Serial.print(F("Write ")); 93 | Serial.print(s/t); 94 | Serial.print(F(" KB/sec\n")); 95 | Serial.print(F("Maximum latency: ")); 96 | Serial.print(maxLatency); 97 | Serial.print(F(" usec, Minimum Latency: ")); 98 | Serial.print(minLatency); 99 | Serial.print(F(" usec, Avg Latency: ")); 100 | Serial.print(totalLatency/n); 101 | Serial.print(F(" usec\n\n")); 102 | Serial.println(F("Starting read test. Please wait up to a minute")); 103 | // do read test 104 | file.seek(0); 105 | maxLatency = 0; 106 | minLatency = 99999; 107 | totalLatency = 0; 108 | t = millis(); 109 | for (uint32_t i = 0; i < n; i++) { 110 | buf[BUF_SIZE-1] = 0; 111 | uint32_t m = micros(); 112 | if (file.read(buf, sizeof(buf)) != sizeof(buf)) { 113 | error("read failed"); 114 | } 115 | m = micros() - m; 116 | if (maxLatency < m) { 117 | maxLatency = m; 118 | } 119 | if (minLatency > m) { 120 | minLatency = m; 121 | } 122 | totalLatency += m; 123 | if (buf[BUF_SIZE-1] != '\n') { 124 | error("data check"); 125 | } 126 | } 127 | t = millis() - t; 128 | Serial.print(F("Read ")); 129 | Serial.print(s/t); 130 | Serial.print(F(" KB/sec\n")); 131 | Serial.print(F("Maximum latency: ")); 132 | Serial.print(maxLatency); 133 | Serial.print(F(" usec, Minimum Latency: ")); 134 | Serial.print(minLatency); 135 | Serial.print(F(" usec, Avg Latency: ")); 136 | Serial.print(totalLatency/n); 137 | Serial.print(F(" usec\n\n")); 138 | Serial.print(F("Done\n\n")); 139 | file.close(); 140 | } -------------------------------------------------------------------------------- /firmware/Arduino_Examples/Performance_Testing/Buffer_Overrun_Test_Binary/Buffer_Overrun_Test_Binary.ino: -------------------------------------------------------------------------------- 1 | /* 2 | 4-14-2010 3 | SparkFun Electronics 2012 4 | Nathan Seidle 5 | 6 | This code is public domain but you buy me a beer if you use this and we meet someday (Beerware license). 7 | 8 | This sketch is used to test the recording buffer of the OpenLog. If you send OpenLog non-stop 9 | serial data at very high data rates (like 115200bps) it can cause a buffer over-run. This sketch 10 | attempts to cause such situations by sending a large batch of characters to the serial port at 115200bps. 11 | Original test was recomended by ScottH on issue #12: 12 | http://github.com/nseidle/OpenLog/issues#issue/12 13 | 14 | Arduino TX to OpenLog RXI 15 | Arduino 5V to OpenLog VCC 16 | Arduino GND to OpenLog GND 17 | 18 | To use this sketch, attach RXI pin of OpenLog to TX pin on Arduino. Power OpenLog from 5V (or 3.3V) and GND pins from Arduino. 19 | After power up, OpenLog will start flashing (indicating it's receiving characters). It takes about 1 minute for 20 | the sketch to run to completion. This will create a file that looks like this: 21 | 22 | ... 23 | 6:abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-!# 24 | 7:abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-!# 25 | 8:abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-!# 26 | 9:abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-!# 27 | #:abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-!# 28 | 1:abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-!# 29 | 2:abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-!# 30 | ... 31 | 32 | The reason for creating these character blocks is it allows for a reader to very quickly scan the visible characters and 33 | indentify any byte errors or glitches along the way. Every 9 lines we print a 10th line that has a leading character 34 | such as # or !. These allow us to quickly see the different blocks of 10 lines. 35 | 36 | Note: Bootloading an Arduino will cause OpenLog to drop to command mode. This is because OpenLog is looking for the 37 | escape character (ctrl+z). During a bootload, all sorts of characters get sent to the Arduino and therefore ctrl+z is likely 38 | to get sent to OpenLog. v1.51 of the OpenLog firmware fixes this potential error by requiring three escape characters. 39 | 40 | */ 41 | 42 | int statLED = 13; //Status LED connected to digital pin 13 43 | 44 | void setup() 45 | { 46 | pinMode(statLED, OUTPUT); 47 | 48 | //Serial.begin(9600); //9600bps is default for OpenLog 49 | //Serial.begin(57600); //Much faster serial, used for testing buffer overruns on OpenLog 50 | Serial.begin(115200); //Much faster serial, used for testing buffer overruns on OpenLog 51 | 52 | delay(1000); //Wait a second for OpenLog to init 53 | 54 | randomSeed(analogRead(A0)); //Feed the random number generator 55 | 56 | //const char* fileHeader = "OpenLong Binary Test"; 57 | //Serial.print(fileHeader); 58 | 59 | long lastBlink = millis(); 60 | 61 | long bytesToSend = 200000; 62 | for(long x = 0 ; x < bytesToSend ; x++) 63 | { 64 | Serial.write(random(0, 256)); //Write a binary number 0 to 255 to OpenLog 65 | 66 | if(millis() - lastBlink > 2000) 67 | { 68 | lastBlink = millis(); 69 | if(digitalRead(statLED) == LOW) 70 | digitalWrite(statLED, HIGH); 71 | else 72 | digitalWrite(statLED, LOW); 73 | } 74 | } 75 | 76 | /*unsigned long totalCharacters = (long)testAmt * 100 * 110; 77 | Serial.print("Characters pushed: "); 78 | Serial.println(totalCharacters); 79 | Serial.print("Time taken (s): "); 80 | Serial.println(millis()/1000); 81 | Serial.println("Done!");*/ 82 | } 83 | 84 | void loop() 85 | { 86 | //Blink the Status LED because we're done! 87 | digitalWrite(statLED, HIGH); 88 | delay(200); 89 | digitalWrite(statLED, LOW); 90 | delay(200); 91 | } 92 | 93 | 94 | -------------------------------------------------------------------------------- /Libraries/SdFat/examples/PrintBenchmark/PrintBenchmark.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * This program is a simple Print benchmark. 3 | */ 4 | #include 5 | #include 6 | #include 7 | 8 | // SD chip select pin 9 | const uint8_t chipSelect = SS; 10 | 11 | // number of lines to print 12 | const uint16_t N_PRINT = 20000; 13 | 14 | // file system 15 | SdFat sd; 16 | 17 | // test file 18 | SdFile file; 19 | 20 | // Serial output stream 21 | ArduinoOutStream cout(Serial); 22 | //------------------------------------------------------------------------------ 23 | // store error strings in flash to save RAM 24 | #define error(s) sd.errorHalt(F(s)) 25 | //------------------------------------------------------------------------------ 26 | void setup() { 27 | Serial.begin(9600); 28 | while (!Serial) { 29 | // wait for Leonardo 30 | } 31 | } 32 | //------------------------------------------------------------------------------ 33 | void loop() { 34 | uint32_t maxLatency; 35 | uint32_t minLatency; 36 | uint32_t totalLatency; 37 | 38 | while (Serial.read() >= 0) { 39 | } 40 | // pstr stores strings in flash to save RAM 41 | cout << F("Type any character to start\n"); 42 | while (Serial.read() <= 0) { 43 | } 44 | delay(400); // catch Due reset problem 45 | 46 | cout << F("FreeStack: ") << FreeStack() << endl; 47 | 48 | // initialize the SD card at SPI_FULL_SPEED for best performance. 49 | // try SPI_HALF_SPEED if bus errors occur. 50 | if (!sd.begin(chipSelect, SPI_FULL_SPEED)) { 51 | sd.initErrorHalt(); 52 | } 53 | 54 | cout << F("Type is FAT") << int(sd.vol()->fatType()) << endl; 55 | 56 | cout << F("Starting print test. Please wait.\n\n"); 57 | 58 | // do write test 59 | for (int test = 0; test < 6; test++) { 60 | char fileName[13] = "bench0.txt"; 61 | fileName[5] = '0' + test; 62 | // open or create file - truncate existing file. 63 | if (!file.open(fileName, O_CREAT | O_TRUNC | O_RDWR)) { 64 | error("open failed"); 65 | } 66 | maxLatency = 0; 67 | minLatency = 999999; 68 | totalLatency = 0; 69 | switch(test) { 70 | case 0: 71 | cout << F("Test of println(uint16_t)\n"); 72 | break; 73 | 74 | case 1: 75 | cout << F("Test of printField(uint16_t, char)\n"); 76 | break; 77 | 78 | case 2: 79 | cout << F("Test of println(uint32_t)\n"); 80 | break; 81 | 82 | case 3: 83 | cout << F("Test of printField(uint32_t, char)\n"); 84 | break; 85 | case 4: 86 | cout << F("Test of println(float)\n"); 87 | break; 88 | 89 | case 5: 90 | cout << F("Test of printField(float, char)\n"); 91 | break; 92 | } 93 | 94 | uint32_t t = millis(); 95 | for (uint16_t i = 0; i < N_PRINT; i++) { 96 | uint32_t m = micros(); 97 | 98 | switch(test) { 99 | case 0: 100 | file.println(i); 101 | break; 102 | 103 | case 1: 104 | file.printField(i, '\n'); 105 | break; 106 | 107 | case 2: 108 | file.println(12345678UL + i); 109 | break; 110 | 111 | case 3: 112 | file.printField(12345678UL + i, '\n'); 113 | break; 114 | 115 | case 4: 116 | file.println((float)0.01*i); 117 | break; 118 | 119 | case 5: 120 | file.printField((float)0.01*i, '\n'); 121 | break; 122 | } 123 | if (file.getWriteError()) { 124 | error("write failed"); 125 | } 126 | m = micros() - m; 127 | if (maxLatency < m) { 128 | maxLatency = m; 129 | } 130 | if (minLatency > m) { 131 | minLatency = m; 132 | } 133 | totalLatency += m; 134 | } 135 | file.close(); 136 | t = millis() - t; 137 | double s = file.fileSize(); 138 | cout << F("Time ") << 0.001*t << F(" sec\n"); 139 | cout << F("File size ") << 0.001*s << F(" KB\n"); 140 | cout << F("Write ") << s/t << F(" KB/sec\n"); 141 | cout << F("Maximum latency: ") << maxLatency; 142 | cout << F(" usec, Minimum Latency: ") << minLatency; 143 | cout << F(" usec, Avg Latency: "); 144 | cout << totalLatency/N_PRINT << F(" usec\n\n"); 145 | } 146 | cout << F("Done!\n\n"); 147 | } 148 | -------------------------------------------------------------------------------- /Libraries/SdFat/src/FatLib/iostream.h: -------------------------------------------------------------------------------- 1 | /* FatLib Library 2 | * Copyright (C) 2013 by William Greiman 3 | * 4 | * This file is part of the FatLib Library 5 | * 6 | * This Library is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This Library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with the FatLib Library. If not, see 18 | * . 19 | */ 20 | #ifndef iostream_h 21 | #define iostream_h 22 | /** 23 | * \file 24 | * \brief \ref iostream class 25 | */ 26 | #include "istream.h" 27 | #include "ostream.h" 28 | /** Skip white space 29 | * \param[in] is the Stream 30 | * \return The stream 31 | */ 32 | inline istream& ws(istream& is) { 33 | is.skipWhite(); 34 | return is; 35 | } 36 | /** insert endline 37 | * \param[in] os The Stream 38 | * \return The stream 39 | */ 40 | inline ostream& endl(ostream& os) { 41 | os.put('\n'); 42 | #if ENDL_CALLS_FLUSH 43 | os.flush(); 44 | #endif // ENDL_CALLS_FLUSH 45 | return os; 46 | } 47 | /** flush manipulator 48 | * \param[in] os The stream 49 | * \return The stream 50 | */ 51 | inline ostream& flush(ostream& os) { 52 | os.flush(); 53 | return os; 54 | } 55 | /** 56 | * \struct setfill 57 | * \brief type for setfill manipulator 58 | */ 59 | struct setfill { 60 | /** fill character */ 61 | char c; 62 | /** constructor 63 | * 64 | * \param[in] arg new fill character 65 | */ 66 | explicit setfill(char arg) : c(arg) {} 67 | }; 68 | /** setfill manipulator 69 | * \param[in] os the stream 70 | * \param[in] arg set setfill object 71 | * \return the stream 72 | */ 73 | inline ostream &operator<< (ostream &os, const setfill &arg) { 74 | os.fill(arg.c); 75 | return os; 76 | } 77 | /** setfill manipulator 78 | * \param[in] obj the stream 79 | * \param[in] arg set setfill object 80 | * \return the stream 81 | */ 82 | inline istream &operator>>(istream &obj, const setfill &arg) { 83 | obj.fill(arg.c); 84 | return obj; 85 | } 86 | //------------------------------------------------------------------------------ 87 | /** \struct setprecision 88 | * \brief type for setprecision manipulator 89 | */ 90 | struct setprecision { 91 | /** precision */ 92 | unsigned int p; 93 | /** constructor 94 | * \param[in] arg new precision 95 | */ 96 | explicit setprecision(unsigned int arg) : p(arg) {} 97 | }; 98 | /** setprecision manipulator 99 | * \param[in] os the stream 100 | * \param[in] arg set setprecision object 101 | * \return the stream 102 | */ 103 | inline ostream &operator<< (ostream &os, const setprecision &arg) { 104 | os.precision(arg.p); 105 | return os; 106 | } 107 | /** setprecision manipulator 108 | * \param[in] is the stream 109 | * \param[in] arg set setprecision object 110 | * \return the stream 111 | */ 112 | inline istream &operator>>(istream &is, const setprecision &arg) { 113 | is.precision(arg.p); 114 | return is; 115 | } 116 | //------------------------------------------------------------------------------ 117 | /** \struct setw 118 | * \brief type for setw manipulator 119 | */ 120 | struct setw { 121 | /** width */ 122 | unsigned w; 123 | /** constructor 124 | * \param[in] arg new width 125 | */ 126 | explicit setw(unsigned arg) : w(arg) {} 127 | }; 128 | /** setw manipulator 129 | * \param[in] os the stream 130 | * \param[in] arg set setw object 131 | * \return the stream 132 | */ 133 | inline ostream &operator<< (ostream &os, const setw &arg) { 134 | os.width(arg.w); 135 | return os; 136 | } 137 | /** setw manipulator 138 | * \param[in] is the stream 139 | * \param[in] arg set setw object 140 | * \return the stream 141 | */ 142 | inline istream &operator>>(istream &is, const setw &arg) { 143 | is.width(arg.w); 144 | return is; 145 | } 146 | //============================================================================== 147 | /** 148 | * \class iostream 149 | * \brief Input/Output stream 150 | */ 151 | class iostream : public istream, public ostream { 152 | }; 153 | #endif // iostream_h 154 | -------------------------------------------------------------------------------- /Libraries/SdFat/src/FatLib/bufstream.h: -------------------------------------------------------------------------------- 1 | /* FatLib Library 2 | * Copyright (C) 2013 by William Greiman 3 | * 4 | * This file is part of the FatLib Library 5 | * 6 | * This Library is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This Library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with the FatLib Library. If not, see 18 | * . 19 | */ 20 | #ifndef bufstream_h 21 | #define bufstream_h 22 | /** 23 | * \file 24 | * \brief \ref ibufstream and \ref obufstream classes 25 | */ 26 | #include 27 | #include "iostream.h" 28 | //============================================================================== 29 | /** 30 | * \class ibufstream 31 | * \brief parse a char string 32 | */ 33 | class ibufstream : public istream { 34 | public: 35 | /** Constructor */ 36 | ibufstream() : m_buf(0), m_len(0) {} 37 | /** Constructor 38 | * \param[in] str pointer to string to be parsed 39 | * Warning: The string will not be copied so must stay in scope. 40 | */ 41 | explicit ibufstream(const char* str) { 42 | init(str); 43 | } 44 | /** Initialize an ibufstream 45 | * \param[in] str pointer to string to be parsed 46 | * Warning: The string will not be copied so must stay in scope. 47 | */ 48 | void init(const char* str) { 49 | m_buf = str; 50 | m_len = strlen(m_buf); 51 | m_pos = 0; 52 | clear(); 53 | } 54 | 55 | protected: 56 | /// @cond SHOW_PROTECTED 57 | int16_t getch() { 58 | if (m_pos < m_len) { 59 | return m_buf[m_pos++]; 60 | } 61 | setstate(eofbit); 62 | return -1; 63 | } 64 | void getpos(FatPos_t *pos) { 65 | pos->position = m_pos; 66 | } 67 | bool seekoff(off_type off, seekdir way) { 68 | return false; 69 | } 70 | bool seekpos(pos_type pos) { 71 | if (pos < m_len) { 72 | m_pos = pos; 73 | return true; 74 | } 75 | return false; 76 | } 77 | void setpos(FatPos_t *pos) { 78 | m_pos = pos->position; 79 | } 80 | pos_type tellpos() { 81 | return m_pos; 82 | } 83 | /// @endcond 84 | private: 85 | const char* m_buf; 86 | size_t m_len; 87 | size_t m_pos; 88 | }; 89 | //============================================================================== 90 | /** 91 | * \class obufstream 92 | * \brief format a char string 93 | */ 94 | class obufstream : public ostream { 95 | public: 96 | /** constructor */ 97 | obufstream() : m_in(0) {} 98 | /** Constructor 99 | * \param[in] buf buffer for formatted string 100 | * \param[in] size buffer size 101 | */ 102 | obufstream(char *buf, size_t size) { 103 | init(buf, size); 104 | } 105 | /** Initialize an obufstream 106 | * \param[in] buf buffer for formatted string 107 | * \param[in] size buffer size 108 | */ 109 | void init(char *buf, size_t size) { 110 | m_buf = buf; 111 | buf[0] = '\0'; 112 | m_size = size; 113 | m_in = 0; 114 | } 115 | /** \return a pointer to the buffer */ 116 | char* buf() { 117 | return m_buf; 118 | } 119 | /** \return the length of the formatted string */ 120 | size_t length() { 121 | return m_in; 122 | } 123 | 124 | protected: 125 | /// @cond SHOW_PROTECTED 126 | void putch(char c) { 127 | if (m_in >= (m_size - 1)) { 128 | setstate(badbit); 129 | return; 130 | } 131 | m_buf[m_in++] = c; 132 | m_buf[m_in] = '\0'; 133 | } 134 | void putstr(const char *str) { 135 | while (*str) { 136 | putch(*str++); 137 | } 138 | } 139 | bool seekoff(off_type off, seekdir way) { 140 | return false; 141 | } 142 | bool seekpos(pos_type pos) { 143 | if (pos > m_in) { 144 | return false; 145 | } 146 | m_in = pos; 147 | m_buf[m_in] = '\0'; 148 | return true; 149 | } 150 | bool sync() { 151 | return true; 152 | } 153 | 154 | pos_type tellpos() { 155 | return m_in; 156 | } 157 | /// @endcond 158 | private: 159 | char *m_buf; 160 | size_t m_size; 161 | size_t m_in; 162 | }; 163 | #endif // bufstream_h 164 | -------------------------------------------------------------------------------- /Libraries/SdFat/src/FatLib/fstream.cpp: -------------------------------------------------------------------------------- 1 | /* FatLib Library 2 | * Copyright (C) 2013 by William Greiman 3 | * 4 | * This file is part of the FatLib Library 5 | * 6 | * This Library is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This Library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with the FatLib Library. If not, see 18 | * . 19 | */ 20 | #include "fstream.h" 21 | //============================================================================== 22 | /// @cond SHOW_PROTECTED 23 | int16_t FatStreamBase::getch() { 24 | uint8_t c; 25 | int8_t s = read(&c, 1); 26 | if (s != 1) { 27 | if (s < 0) { 28 | setstate(badbit); 29 | } else { 30 | setstate(eofbit); 31 | } 32 | return -1; 33 | } 34 | if (c != '\r' || (getmode() & ios::binary)) { 35 | return c; 36 | } 37 | s = read(&c, 1); 38 | if (s == 1 && c == '\n') { 39 | return c; 40 | } 41 | if (s == 1) { 42 | seekCur(-1); 43 | } 44 | return '\r'; 45 | } 46 | //------------------------------------------------------------------------------ 47 | void FatStreamBase::open(const char* path, ios::openmode mode) { 48 | uint8_t flags; 49 | switch (mode & (app | in | out | trunc)) { 50 | case app | in: 51 | case app | in | out: 52 | flags = O_RDWR | O_APPEND | O_CREAT; 53 | break; 54 | 55 | case app: 56 | case app | out: 57 | flags = O_WRITE | O_APPEND | O_CREAT; 58 | break; 59 | 60 | case in: 61 | flags = O_READ; 62 | break; 63 | 64 | case in | out: 65 | flags = O_RDWR; 66 | break; 67 | 68 | case in | out | trunc: 69 | flags = O_RDWR | O_TRUNC | O_CREAT; 70 | break; 71 | 72 | case out: 73 | case out | trunc: 74 | flags = O_WRITE | O_TRUNC | O_CREAT; 75 | break; 76 | 77 | default: 78 | goto fail; 79 | } 80 | if (mode & ios::ate) { 81 | flags |= O_AT_END; 82 | } 83 | if (!FatFile::open(path, flags)) { 84 | goto fail; 85 | } 86 | setmode(mode); 87 | clear(); 88 | return; 89 | 90 | fail: 91 | FatFile::close(); 92 | setstate(failbit); 93 | return; 94 | } 95 | //------------------------------------------------------------------------------ 96 | void FatStreamBase::putch(char c) { 97 | if (c == '\n' && !(getmode() & ios::binary)) { 98 | write('\r'); 99 | } 100 | write(c); 101 | if (getWriteError()) { 102 | setstate(badbit); 103 | } 104 | } 105 | //------------------------------------------------------------------------------ 106 | void FatStreamBase::putstr(const char* str) { 107 | size_t n = 0; 108 | while (1) { 109 | char c = str[n]; 110 | if (c == '\0' || (c == '\n' && !(getmode() & ios::binary))) { 111 | if (n > 0) { 112 | write(str, n); 113 | } 114 | if (c == '\0') { 115 | break; 116 | } 117 | write('\r'); 118 | str += n; 119 | n = 0; 120 | } 121 | n++; 122 | } 123 | if (getWriteError()) { 124 | setstate(badbit); 125 | } 126 | } 127 | //------------------------------------------------------------------------------ 128 | /** Internal do not use 129 | * \param[in] off 130 | * \param[in] way 131 | */ 132 | bool FatStreamBase::seekoff(off_type off, seekdir way) { 133 | pos_type pos; 134 | switch (way) { 135 | case beg: 136 | pos = off; 137 | break; 138 | 139 | case cur: 140 | pos = curPosition() + off; 141 | break; 142 | 143 | case end: 144 | pos = fileSize() + off; 145 | break; 146 | 147 | default: 148 | return false; 149 | } 150 | return seekpos(pos); 151 | } 152 | //------------------------------------------------------------------------------ 153 | /** Internal do not use 154 | * \param[in] pos 155 | */ 156 | bool FatStreamBase::seekpos(pos_type pos) { 157 | return seekSet(pos); 158 | } 159 | //------------------------------------------------------------------------------ 160 | int FatStreamBase::write(const void* buf, size_t n) { 161 | return FatFile::write(buf, n); 162 | } 163 | //------------------------------------------------------------------------------ 164 | void FatStreamBase::write(char c) { 165 | write(&c, 1); 166 | } 167 | /// @endcond 168 | -------------------------------------------------------------------------------- /Libraries/SdFat/examples/dataLogger/dataLogger.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * Simple data logger. 3 | */ 4 | #include 5 | #include 6 | 7 | // SD chip select pin. Be sure to disable any other SPI devices such as Enet. 8 | const uint8_t chipSelect = SS; 9 | 10 | // Interval between data records in milliseconds. 11 | // The interval must be greater than the maximum SD write latency plus the 12 | // time to acquire and write data to the SD to avoid overrun errors. 13 | // Run the bench example to check the quality of your SD card. 14 | const uint32_t SAMPLE_INTERVAL_MS = 200; 15 | 16 | // Log file base name. Must be six characters or less. 17 | #define FILE_BASE_NAME "Data" 18 | //------------------------------------------------------------------------------ 19 | // File system object. 20 | SdFat sd; 21 | 22 | // Log file. 23 | SdFile file; 24 | 25 | // Time in micros for next data record. 26 | uint32_t logTime; 27 | 28 | //============================================================================== 29 | // User functions. Edit writeHeader() and logData() for your requirements. 30 | 31 | const uint8_t ANALOG_COUNT = 4; 32 | //------------------------------------------------------------------------------ 33 | // Write data header. 34 | void writeHeader() { 35 | file.print(F("micros")); 36 | for (uint8_t i = 0; i < ANALOG_COUNT; i++) { 37 | file.print(F(",adc")); 38 | file.print(i, DEC); 39 | } 40 | file.println(); 41 | } 42 | //------------------------------------------------------------------------------ 43 | // Log a data record. 44 | void logData() { 45 | uint16_t data[ANALOG_COUNT]; 46 | 47 | // Read all channels to avoid SD write latency between readings. 48 | for (uint8_t i = 0; i < ANALOG_COUNT; i++) { 49 | data[i] = analogRead(i); 50 | } 51 | // Write data to file. Start with log time in micros. 52 | file.print(logTime); 53 | 54 | // Write ADC data to CSV record. 55 | for (uint8_t i = 0; i < ANALOG_COUNT; i++) { 56 | file.write(','); 57 | file.print(data[i]); 58 | } 59 | file.println(); 60 | } 61 | //============================================================================== 62 | // Error messages stored in flash. 63 | #define error(msg) sd.errorHalt(F(msg)) 64 | //------------------------------------------------------------------------------ 65 | void setup() { 66 | const uint8_t BASE_NAME_SIZE = sizeof(FILE_BASE_NAME) - 1; 67 | char fileName[13] = FILE_BASE_NAME "00.csv"; 68 | 69 | Serial.begin(9600); 70 | while (!Serial) {} // wait for Leonardo 71 | delay(1000); 72 | 73 | Serial.println(F("Type any character to start")); 74 | while (!Serial.available()) {} 75 | 76 | // Initialize the SD card at SPI_HALF_SPEED to avoid bus errors with 77 | // breadboards. use SPI_FULL_SPEED for better performance. 78 | if (!sd.begin(chipSelect, SPI_HALF_SPEED)) { 79 | sd.initErrorHalt(); 80 | } 81 | 82 | // Find an unused file name. 83 | if (BASE_NAME_SIZE > 6) { 84 | error("FILE_BASE_NAME too long"); 85 | } 86 | while (sd.exists(fileName)) { 87 | if (fileName[BASE_NAME_SIZE + 1] != '9') { 88 | fileName[BASE_NAME_SIZE + 1]++; 89 | } else if (fileName[BASE_NAME_SIZE] != '9') { 90 | fileName[BASE_NAME_SIZE + 1] = '0'; 91 | fileName[BASE_NAME_SIZE]++; 92 | } else { 93 | error("Can't create file name"); 94 | } 95 | } 96 | if (!file.open(fileName, O_CREAT | O_WRITE | O_EXCL)) { 97 | error("file.open"); 98 | } 99 | do { 100 | delay(10); 101 | } while (Serial.read() >= 0); 102 | 103 | Serial.print(F("Logging to: ")); 104 | Serial.println(fileName); 105 | Serial.println(F("Type any character to stop")); 106 | 107 | // Write data header. 108 | writeHeader(); 109 | 110 | // Start on a multiple of the sample interval. 111 | logTime = micros()/(1000UL*SAMPLE_INTERVAL_MS) + 1; 112 | logTime *= 1000UL*SAMPLE_INTERVAL_MS; 113 | } 114 | //------------------------------------------------------------------------------ 115 | void loop() { 116 | // Time for next record. 117 | logTime += 1000UL*SAMPLE_INTERVAL_MS; 118 | 119 | // Wait for log time. 120 | int32_t diff; 121 | do { 122 | diff = micros() - logTime; 123 | } while (diff < 0); 124 | 125 | // Check for data rate too high. 126 | if (diff > 10) { 127 | error("Missed data record"); 128 | } 129 | 130 | logData(); 131 | 132 | // Force data to SD and update the directory entry to avoid data loss. 133 | if (!file.sync() || file.getWriteError()) { 134 | error("write error"); 135 | } 136 | 137 | if (Serial.available()) { 138 | // Close file and stop. 139 | file.close(); 140 | Serial.println(F("Done")); 141 | while(1) {} 142 | } 143 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | SparkFun OpenLog 2 | ================ 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 |
SparkFun OpenLogSparkFun OpenLog with Headers
SparkFun OpenLog (DEV-13712)SparkFun OpenLog with Headers (DEV-13955)
14 | 15 | OpenLog is an open source data logger that works over a simple serial connection and supports microSD cards up to 64GB. 16 | 17 | Repository Contents 18 | ------------------- 19 | * **/Documentation** - Data sheets, additional product information 20 | * **/Firmware** - Example sketches for the OpenLog, and for an Arduino connected to the OpenLog. 21 | * **/Hardware** - Hardware design files for the OpenLog PCB. These files were designed in Eagle CAD. 22 | * **/Libraries** - Libraries for use with the OpenLog. 23 | * **/Production** - Production panel files (.brd) 24 | 25 | Documentation 26 | -------------- 27 | * **[Hookup Guide](https://learn.sparkfun.com/tutorials/openlog-hookup-guide)** - Basic hookup guide for the OpenLog. 28 | * **[SparkFun Fritzing repo](https://github.com/sparkfun/Fritzing_Parts)** - Fritzing diagrams for SparkFun products. 29 | * **[SparkFun 3D Model repo](https://github.com/sparkfun/3D_Models)** - 3D models of SparkFun products. 30 | * **[SparkFun Graphical Datasheets](https://github.com/sparkfun/Graphical_Datasheets)** -Graphical Datasheets for various SparkFun products. 31 | 32 | 33 | License Information 34 | ------------------- 35 | 36 | This product is _**open source**_! 37 | 38 | Please review the LICENSE.md file for license information. 39 | 40 | If you have any questions or concerns on licensing, please contact techsupport@sparkfun.com. 41 | 42 | Distributed as-is; no warranty is given. 43 | 44 | - Your friends at SparkFun. 45 | 46 | _SDFatLib-beta and SerialPort are written by Bill Greiman, and released under GPLv3._ 47 | 48 | Version History 49 | --------------- 50 | 51 | For a full view of changes please see the [changelog](https://github.com/sparkfun/OpenLog/blob/master/CHANGELOG.md). 52 | 53 | OpenLog v4 is refactored with better RAM utilization for better performance at higher record speeds (115200/57600). 54 | 55 | OpenLog v3 is stable, supports FAT32 cards up to 64GB and supports higher record speeds (115200/57600). 56 | 57 | OpenLog v2 is a bit buggy but supports FAT32 and SD cards up to 16GB. 58 | 59 | OpenLog v1 is stable but only supports FAT16 and up to 2GB. 60 | 61 | * **v1.0** Buggy initial release 62 | * **v1.1** Small changes to system settings and EEPROM storage. 63 | * **v1.2** Added wild card to listing and remove commands. Added read file command. 64 | * **v1.3** Added auto buffer record if unit sits idle for more than 5 seconds. 65 | * **v1.4** Increase buffer size to 900 bytes. Pinning down URU errors. 66 | * **v1.5** Lowered power consumption to ~2mA avg. Added 4800 and 19200 baud rates. 67 | * **v1.51** Added configurable escape character, and escape character amount. 68 | * **v1.6** Added ability to configure via config.txt file. 69 | * **v2.0** Massive overhaul. Ported to sdfatlib. Now supports FAT16/FAT32/SD/SDHC. 70 | * **v2.1** Power save not working. Fixed issue 35. Dropping characters at 57600bps. 71 | * **v2.11** Tested with 16GB microSD. Fixed issues 30 & 34. Re-enable power save. 72 | * **v2.2** Modified append_file() to use a single buffer. Increased HardwareSerial.cpp buffer to 512 bytes. 73 | * **v2.21** ringp fork brought in. rm dir, cd .., and wildcards now work! 74 | * **v2.3** Migrated to v10.10.10 of sdfatlib. Moved to inline RX interrupt and buffer. 75 | * **v2.4** Merged ringp updates. Commands cd, rm, ls work again! 76 | * **v2.41** Power loss bug fixed. Adding support for 38400bps for testing with SparkFum 9DOF IMU logging. 77 | * **v2.5** Added software reset command. Modified the read command to print extended ASCII characters. 78 | * **v2.51** Changed command prompt control to ignore \n for easier control from microcontroller. 79 | * **v3.0** Migration to Arduino v1.0 and better recording speed at 115200bps and 57600bps. 80 | * **v3.1** Better handling of recording during power loss. 81 | * **v3.2** Freed up RAM for larger RX ring buffer. Added support for wildcards and ability to ignore emergency override. 82 | * **v3.3** Added ability to ignore escape character checking and corrected incremental log naming. 83 | * **v4.0** Re-worked to be compatible with Arduino v1.6.x. Freed RAM to increase RX buffer size. 84 | -------------------------------------------------------------------------------- /firmware/Arduino_Examples/Performance_Testing/Buffer_Overrun_Test/Buffer_Overrun_Test.ino: -------------------------------------------------------------------------------- 1 | /* 2 | 4-14-2010 3 | SparkFun Electronics 2012 4 | Nathan Seidle 5 | 6 | This code is public domain but you buy me a beer if you use this and we meet someday (Beerware license). 7 | 8 | This sketch is used to test the recording buffer of the OpenLog. If you send OpenLog non-stop 9 | serial data at very high data rates (like 115200bps) it can cause a buffer over-run. This sketch 10 | attempts to cause such situations by sending a large batch of characters to the serial port at 115200bps. 11 | Original test was recomended by ScottH on issue #12: 12 | http://github.com/nseidle/OpenLog/issues#issue/12 13 | 14 | Arduino TX to OpenLog RXI 15 | Arduino 5V to OpenLog VCC 16 | Arduino GND to OpenLog GND 17 | 18 | To use this sketch, attach RXI pin of OpenLog to TX pin on Arduino. Power OpenLog from 5V (or 3.3V) and GND pins from Arduino. 19 | After power up, OpenLog will start flashing (indicating it's receiving characters). It takes about 1 minute for 20 | the sketch to run to completion. This will create a file that looks like this: 21 | 22 | ... 23 | 6:abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-!# 24 | 7:abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-!# 25 | 8:abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-!# 26 | 9:abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-!# 27 | #:abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-!# 28 | 1:abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-!# 29 | 2:abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-!# 30 | ... 31 | 32 | The reason for creating these character blocks is it allows for a reader to very quickly scan the visible characters and 33 | indentify any byte errors or glitches along the way. Every 9 lines we print a 10th line that has a leading character 34 | such as # or !. These allow us to quickly see the different blocks of 10 lines. 35 | 36 | Note: Bootloading an Arduino will cause OpenLog to drop to command mode. This is because OpenLog is looking for the 37 | escape character (ctrl+z). During a bootload, all sorts of characters get sent to the Arduino and therefore ctrl+z is likely 38 | to get sent to OpenLog. v1.51 of the OpenLog firmware fixes this potential error by requiring three escape characters. 39 | 40 | */ 41 | 42 | int ledPin = 13; //Status LED connected to digital pin 13 43 | 44 | void setup() 45 | { 46 | pinMode(ledPin, OUTPUT); 47 | 48 | Serial.begin(9600); //9600bps is default for OpenLog 49 | //Serial.begin(57600); //Much faster serial, used for testing buffer overruns on OpenLog 50 | //Serial.begin(115200); //Much faster serial, used for testing buffer overruns on OpenLog 51 | 52 | delay(1000); //Wait a second for OpenLog to init 53 | 54 | Serial.println(); 55 | Serial.println("Run OpenLog Test"); 56 | 57 | int testAmt = 3; 58 | //At 9600, testAmt of 4 takes about 1 minute, 10 takes about 3 minutes 59 | //At 57600, testAmt of 10 takes about 1 minute, 40 takes about 5 minutes 60 | //At 115200, testAmt of 30 takes about 1 minute 61 | //testAmt of 10 will push 111,000 characters/bytes. With header and footer strings, total is 111,052 62 | 63 | //Each test is 100 lines. 10 tests is 1000 lines (11,000 characters) 64 | for(int numofTests = 0 ; numofTests < testAmt ; numofTests++) 65 | { 66 | //This loop will print 100 lines of 110 characters each 67 | for(int k = 33; k < 43 ; k++) 68 | { 69 | //Print one line of 110 characters with marker in the front (markers go from '!' to '*') 70 | Serial.write(k); //Print the ASCII value directly: ! then " then #, etc 71 | Serial.println(":abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-!#"); 72 | //delay(50); 73 | 74 | //Then print 9 lines of 110 characters with new line at the end of the line 75 | for(int i = 1 ; i < 10 ; i++) 76 | { 77 | Serial.print(i, DEC); 78 | Serial.println(":abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-!#"); 79 | //delay(50); 80 | } 81 | 82 | if(digitalRead(ledPin) == 0) //Turn the status LED on/off as we go 83 | digitalWrite(ledPin, HIGH); 84 | else 85 | digitalWrite(ledPin, LOW); 86 | } 87 | } //End numofTests loop 88 | 89 | unsigned long totalCharacters = (long)testAmt * 100 * 110; 90 | Serial.print("Characters pushed: "); 91 | Serial.println(totalCharacters); 92 | Serial.print("Time taken (s): "); 93 | Serial.println(millis()/1000); 94 | Serial.println("Done!"); 95 | } 96 | 97 | void loop() 98 | { 99 | //Blink the Status LED because we're done! 100 | digitalWrite(ledPin, HIGH); 101 | delay(100); 102 | digitalWrite(ledPin, LOW); 103 | delay(1000); 104 | } 105 | 106 | 107 | -------------------------------------------------------------------------------- /Libraries/SdFat/examples/Timestamp/Timestamp.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * This program tests the dateTimeCallback() function 3 | * and the timestamp() function. 4 | */ 5 | #include 6 | #include 7 | 8 | SdFat sd; 9 | 10 | SdFile file; 11 | 12 | // Default SD chip select is SS pin 13 | const uint8_t chipSelect = SS; 14 | 15 | // create Serial stream 16 | ArduinoOutStream cout(Serial); 17 | //------------------------------------------------------------------------------ 18 | // store error strings in flash to save RAM 19 | #define error(s) sd.errorHalt(F(s)) 20 | //------------------------------------------------------------------------------ 21 | /* 22 | * date/time values for debug 23 | * normally supplied by a real-time clock or GPS 24 | */ 25 | // date 1-Oct-14 26 | uint16_t year = 2014; 27 | uint8_t month = 10; 28 | uint8_t day = 1; 29 | 30 | // time 20:30:40 31 | uint8_t hour = 20; 32 | uint8_t minute = 30; 33 | uint8_t second = 40; 34 | //------------------------------------------------------------------------------ 35 | /* 36 | * User provided date time callback function. 37 | * See SdFile::dateTimeCallback() for usage. 38 | */ 39 | void dateTime(uint16_t* date, uint16_t* time) { 40 | // User gets date and time from GPS or real-time 41 | // clock in real callback function 42 | 43 | // return date using FAT_DATE macro to format fields 44 | *date = FAT_DATE(year, month, day); 45 | 46 | // return time using FAT_TIME macro to format fields 47 | *time = FAT_TIME(hour, minute, second); 48 | } 49 | //------------------------------------------------------------------------------ 50 | /* 51 | * Function to print all timestamps. 52 | */ 53 | void printTimestamps(SdFile& f) { 54 | dir_t d; 55 | if (!f.dirEntry(&d)) { 56 | error("f.dirEntry failed"); 57 | } 58 | 59 | cout << F("Creation: "); 60 | f.printFatDate(d.creationDate); 61 | cout << ' '; 62 | f.printFatTime(d.creationTime); 63 | cout << endl; 64 | 65 | cout << F("Modify: "); 66 | f.printFatDate(d.lastWriteDate); 67 | cout <<' '; 68 | f.printFatTime(d.lastWriteTime); 69 | cout << endl; 70 | 71 | cout << F("Access: "); 72 | f.printFatDate(d.lastAccessDate); 73 | cout << endl; 74 | } 75 | //------------------------------------------------------------------------------ 76 | void setup(void) { 77 | Serial.begin(9600); 78 | while (!Serial) {} // wait for Leonardo 79 | 80 | cout << F("Type any character to start\n"); 81 | while (!Serial.available()); 82 | delay(400); // catch Due reset problem 83 | 84 | // initialize the SD card at SPI_HALF_SPEED to avoid bus errors with 85 | // breadboards. use SPI_FULL_SPEED for better performance. 86 | if (!sd.begin(chipSelect, SPI_HALF_SPEED)) { 87 | sd.initErrorHalt(); 88 | } 89 | 90 | // remove files if they exist 91 | sd.remove("callback.txt"); 92 | sd.remove("default.txt"); 93 | sd.remove("stamp.txt"); 94 | 95 | // create a new file with default timestamps 96 | if (!file.open("default.txt", O_CREAT | O_WRITE)) { 97 | error("open default.txt failed"); 98 | } 99 | cout << F("\nOpen with default times\n"); 100 | printTimestamps(file); 101 | 102 | // close file 103 | file.close(); 104 | /* 105 | * Test the date time callback function. 106 | * 107 | * dateTimeCallback() sets the function 108 | * that is called when a file is created 109 | * or when a file's directory entry is 110 | * modified by sync(). 111 | * 112 | * The callback can be disabled by the call 113 | * SdFile::dateTimeCallbackCancel() 114 | */ 115 | // set date time callback function 116 | SdFile::dateTimeCallback(dateTime); 117 | 118 | // create a new file with callback timestamps 119 | if (!file.open("callback.txt", O_CREAT | O_WRITE)) { 120 | error("open callback.txt failed"); 121 | } 122 | cout << ("\nOpen with callback times\n"); 123 | printTimestamps(file); 124 | 125 | // change call back date 126 | day += 1; 127 | 128 | // must add two to see change since FAT second field is 5-bits 129 | second += 2; 130 | 131 | // modify file by writing a byte 132 | file.write('t'); 133 | 134 | // force dir update 135 | file.sync(); 136 | 137 | cout << F("\nTimes after write\n"); 138 | printTimestamps(file); 139 | 140 | // close file 141 | file.close(); 142 | /* 143 | * Test timestamp() function 144 | * 145 | * Cancel callback so sync will not 146 | * change access/modify timestamp 147 | */ 148 | SdFile::dateTimeCallbackCancel(); 149 | 150 | // create a new file with default timestamps 151 | if (!file.open("stamp.txt", O_CREAT | O_WRITE)) { 152 | error("open stamp.txt failed"); 153 | } 154 | // set creation date time 155 | if (!file.timestamp(T_CREATE, 2014, 11, 10, 1, 2, 3)) { 156 | error("set create time failed"); 157 | } 158 | // set write/modification date time 159 | if (!file.timestamp(T_WRITE, 2014, 11, 11, 4, 5, 6)) { 160 | error("set write time failed"); 161 | } 162 | // set access date 163 | if (!file.timestamp(T_ACCESS, 2014, 11, 12, 7, 8, 9)) { 164 | error("set access time failed"); 165 | } 166 | cout << F("\nTimes after timestamp() calls\n"); 167 | printTimestamps(file); 168 | 169 | file.close(); 170 | cout << F("\nDone\n"); 171 | } 172 | 173 | void loop(void) {} -------------------------------------------------------------------------------- /Libraries/SdFat/examples/TwoCards/TwoCards.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * Example use of two SD cards. 3 | */ 4 | #include 5 | #include 6 | #include 7 | 8 | SdFat sd1; 9 | const uint8_t SD1_CS = 10; // chip select for sd1 10 | 11 | SdFat sd2; 12 | const uint8_t SD2_CS = 4; // chip select for sd2 13 | 14 | const uint8_t BUF_DIM = 100; 15 | uint8_t buf[BUF_DIM]; 16 | 17 | const uint32_t FILE_SIZE = 1000000; 18 | const uint16_t NWRITE = FILE_SIZE/BUF_DIM; 19 | //------------------------------------------------------------------------------ 20 | // print error msg, any SD error codes, and halt. 21 | // store messages in flash 22 | #define errorExit(msg) errorHalt(F(msg)) 23 | #define initError(msg) initErrorHalt(F(msg)) 24 | //------------------------------------------------------------------------------ 25 | void setup() { 26 | Serial.begin(9600); 27 | while (!Serial) {} // wait for Leonardo 28 | Serial.print(F("FreeStack: ")); 29 | 30 | Serial.println(FreeStack()); 31 | 32 | // fill buffer with known data 33 | for (int i = 0; i < sizeof(buf); i++) { 34 | buf[i] = i; 35 | } 36 | 37 | Serial.println(F("type any character to start")); 38 | while (Serial.read() <= 0) {} 39 | delay(400); // catch Due reset problem 40 | 41 | // disable sd2 while initializing sd1 42 | pinMode(SD2_CS, OUTPUT); 43 | digitalWrite(SD2_CS, HIGH); 44 | 45 | // initialize the first card 46 | if (!sd1.begin(SD1_CS)) { 47 | sd1.initError("sd1:"); 48 | } 49 | // create Dir1 on sd1 if it does not exist 50 | if (!sd1.exists("/Dir1")) { 51 | if (!sd1.mkdir("/Dir1")) { 52 | sd1.errorExit("sd1.mkdir"); 53 | } 54 | } 55 | // initialize the second card 56 | if (!sd2.begin(SD2_CS)) { 57 | sd2.initError("sd2:"); 58 | } 59 | // create Dir2 on sd2 if it does not exist 60 | if (!sd2.exists("/Dir2")) { 61 | if (!sd2.mkdir("/Dir2")) { 62 | sd2.errorExit("sd2.mkdir"); 63 | } 64 | } 65 | // list root directory on both cards 66 | Serial.println(F("------sd1 root-------")); 67 | sd1.ls(); 68 | Serial.println(F("------sd2 root-------")); 69 | sd2.ls(); 70 | 71 | // make /Dir1 the default directory for sd1 72 | if (!sd1.chdir("/Dir1")) { 73 | sd1.errorExit("sd1.chdir"); 74 | } 75 | 76 | // make /Dir2 the default directory for sd2 77 | if (!sd2.chdir("/Dir2")) { 78 | sd2.errorExit("sd2.chdir"); 79 | } 80 | 81 | // list current directory on both cards 82 | Serial.println(F("------sd1 Dir1-------")); 83 | sd1.ls(); 84 | Serial.println(F("------sd2 Dir2-------")); 85 | sd2.ls(); 86 | Serial.println(F("---------------------")); 87 | 88 | // remove rename.bin from /Dir2 directory of sd2 89 | if (sd2.exists("rename.bin")) { 90 | if (!sd2.remove("rename.bin")) { 91 | sd2.errorExit("remove rename.bin"); 92 | } 93 | } 94 | // set the current working directory for open() to sd1 95 | sd1.chvol(); 96 | 97 | // create or open /Dir1/test.bin and truncate it to zero length 98 | SdFile file1; 99 | if (!file1.open("test.bin", O_RDWR | O_CREAT | O_TRUNC)) { 100 | sd1.errorExit("file1"); 101 | } 102 | Serial.println(F("Writing test.bin to sd1")); 103 | 104 | // write data to /Dir1/test.bin on sd1 105 | for (int i = 0; i < NWRITE; i++) { 106 | if (file1.write(buf, sizeof(buf)) != sizeof(buf)) { 107 | sd1.errorExit("sd1.write"); 108 | } 109 | } 110 | // set the current working directory for open() to sd2 111 | sd2.chvol(); 112 | 113 | // create or open /Dir2/copy.bin and truncate it to zero length 114 | SdFile file2; 115 | if (!file2.open("copy.bin", O_WRITE | O_CREAT | O_TRUNC)) { 116 | sd2.errorExit("file2"); 117 | } 118 | Serial.println(F("Copying test.bin to copy.bin")); 119 | 120 | // copy file1 to file2 121 | file1.rewind(); 122 | uint32_t t = millis(); 123 | 124 | while (1) { 125 | int n = file1.read(buf, sizeof(buf)); 126 | if (n < 0) { 127 | sd1.errorExit("read1"); 128 | } 129 | if (n == 0) { 130 | break; 131 | } 132 | if (file2.write(buf, n) != n) { 133 | sd2.errorExit("write2"); 134 | } 135 | } 136 | t = millis() - t; 137 | Serial.print(F("File size: ")); 138 | Serial.println(file2.fileSize()); 139 | Serial.print(F("Copy time: ")); 140 | Serial.print(t); 141 | Serial.println(F(" millis")); 142 | // close test.bin 143 | file1.close(); 144 | file2.close(); 145 | // list current directory on both cards 146 | Serial.println(F("------sd1 -------")); 147 | sd1.ls("/", LS_R | LS_DATE | LS_SIZE); 148 | Serial.println(F("------sd2 -------")); 149 | sd2.ls("/", LS_R | LS_DATE | LS_SIZE); 150 | Serial.println(F("---------------------")); 151 | Serial.println(F("Renaming copy.bin")); 152 | // rename the copy 153 | if (!sd2.rename("copy.bin", "rename.bin")) { 154 | sd2.errorExit("sd2.rename"); 155 | } 156 | // list current directory on both cards 157 | Serial.println(F("------sd1 -------")); 158 | sd1.ls("/", LS_R | LS_DATE | LS_SIZE); 159 | Serial.println(F("------sd2 -------")); 160 | sd2.ls("/", LS_R | LS_DATE | LS_SIZE); 161 | Serial.println(F("---------------------")); 162 | Serial.println(F("Done")); 163 | } 164 | //------------------------------------------------------------------------------ 165 | void loop() {} 166 | -------------------------------------------------------------------------------- /Libraries/SdFat/src/FatLib/FatLibConfig.h: -------------------------------------------------------------------------------- 1 | /* FatLib Library 2 | * Copyright (C) 2013 by William Greiman 3 | * 4 | * This file is part of the FatLib Library 5 | * 6 | * This Library is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This Library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with the FatLib Library. If not, see 18 | * . 19 | */ 20 | /** 21 | * \file 22 | * \brief configuration definitions 23 | */ 24 | #ifndef FatLibConfig_h 25 | #define FatLibConfig_h 26 | #include 27 | // Allow this file to override defaults. 28 | #include "../SdFatConfig.h" 29 | 30 | #ifdef __AVR__ 31 | #include 32 | #endif // __AVR__ 33 | //------------------------------------------------------------------------------ 34 | /** 35 | * Set USE_LONG_FILE_NAMES nonzero to use long file names (LFN). 36 | * Long File Name are limited to a maximum length of 255 characters. 37 | * 38 | * This implementation allows 7-bit characters in the range 39 | * 0X20 to 0X7E. The following characters are not allowed: 40 | * 41 | * < (less than) 42 | * > (greater than) 43 | * : (colon) 44 | * " (double quote) 45 | * / (forward slash) 46 | * \ (backslash) 47 | * | (vertical bar or pipe) 48 | * ? (question mark) 49 | * * (asterisk) 50 | * 51 | */ 52 | #ifndef USE_LONG_FILE_NAMES 53 | #define USE_LONG_FILE_NAMES 1 54 | #endif // USE_LONG_FILE_NAMES 55 | //------------------------------------------------------------------------------ 56 | /** 57 | * Set ARDUINO_FILE_USES_STREAM nonzero to use Stream as the base class 58 | * for the Arduino File class. If ARDUINO_FILE_USES_STREAM is zero, Print 59 | * will be used as the base class for the Arduino File class. 60 | * 61 | * You can save some flash if you do not use Stream input functions such as 62 | * find(), findUntil(), readBytesUntil(), readString(), readStringUntil(), 63 | * parseInt(), and parsefloat(). 64 | */ 65 | #ifndef ARDUINO_FILE_USES_STREAM 66 | #define ARDUINO_FILE_USES_STREAM 1 67 | #endif // ARDUINO_FILE_USES_STREAM 68 | //------------------------------------------------------------------------------ 69 | /** 70 | * Set USE_SEPARATE_FAT_CACHE non-zero to use a second 512 byte cache 71 | * for FAT table entries. Improves performance for large writes that 72 | * are not a multiple of 512 bytes. 73 | */ 74 | #ifndef USE_SEPARATE_FAT_CACHE 75 | #ifdef __arm__ 76 | #define USE_SEPARATE_FAT_CACHE 1 77 | #else // __arm__ 78 | #define USE_SEPARATE_FAT_CACHE 0 79 | #endif // __arm__ 80 | #endif // USE_SEPARATE_FAT_CACHE 81 | //------------------------------------------------------------------------------ 82 | /** 83 | * Set USE_MULTI_BLOCK_IO non-zero to use multi-block SD read/write. 84 | * 85 | * Don't use mult-block read/write on small AVR boards. 86 | */ 87 | #ifndef USE_MULTI_BLOCK_IO 88 | #if defined(RAMEND) && RAMEND < 3000 89 | #define USE_MULTI_BLOCK_IO 0 90 | #else // RAMEND 91 | #define USE_MULTI_BLOCK_IO 1 92 | #endif // RAMEND 93 | #endif // USE_MULTI_BLOCK_IO 94 | //------------------------------------------------------------------------------ 95 | /** 96 | * Set DESTRUCTOR_CLOSES_FILE non-zero to close a file in its destructor. 97 | * 98 | * Causes use of lots of heap in ARM. 99 | */ 100 | #ifndef DESTRUCTOR_CLOSES_FILE 101 | #define DESTRUCTOR_CLOSES_FILE 0 102 | #endif // DESTRUCTOR_CLOSES_FILE 103 | //------------------------------------------------------------------------------ 104 | /** 105 | * Call flush for endl if ENDL_CALLS_FLUSH is non-zero 106 | * 107 | * The standard for iostreams is to call flush. This is very costly for 108 | * SdFat. Each call to flush causes 2048 bytes of I/O to the SD. 109 | * 110 | * SdFat has a single 512 byte buffer for I/O so it must write the current 111 | * data block to the SD, read the directory block from the SD, update the 112 | * directory entry, write the directory block to the SD and read the data 113 | * block back into the buffer. 114 | * 115 | * The SD flash memory controller is not designed for this many rewrites 116 | * so performance may be reduced by more than a factor of 100. 117 | * 118 | * If ENDL_CALLS_FLUSH is zero, you must call flush and/or close to force 119 | * all data to be written to the SD. 120 | */ 121 | #ifndef ENDL_CALLS_FLUSH 122 | #define ENDL_CALLS_FLUSH 0 123 | #endif // ENDL_CALLS_FLUSH 124 | //------------------------------------------------------------------------------ 125 | /** 126 | * Allow FAT12 volumes if FAT12_SUPPORT is non-zero. 127 | * FAT12 has not been well tested. 128 | */ 129 | #ifndef FAT12_SUPPORT 130 | #define FAT12_SUPPORT 0 131 | #endif // FAT12_SUPPORT 132 | //------------------------------------------------------------------------------ 133 | /** 134 | * Enable Extra features for Arduino. 135 | */ 136 | #ifndef ENABLE_ARDUINO_FEATURES 137 | #if defined(ARDUINO) || defined(DOXYGEN) 138 | #define ENABLE_ARDUINO_FEATURES 1 139 | #else // #if defined(ARDUINO) || defined(DOXYGEN) 140 | #define ENABLE_ARDUINO_FEATURES 0 141 | #endif // defined(ARDUINO) || defined(DOXYGEN) 142 | #endif // ENABLE_ARDUINO_FEATURES 143 | #endif // FatLibConfig_h 144 | -------------------------------------------------------------------------------- /Libraries/SdFat/examples/QuickStart/QuickStart.ino: -------------------------------------------------------------------------------- 1 | // Quick hardware test. 2 | // 3 | #include 4 | #include 5 | // 6 | // Set DISABLE_CHIP_SELECT to disable a second SPI device. 7 | // For example, with the Ethernet shield, set DISABLE_CHIP_SELECT 8 | // to 10 to disable the Ethernet controller. 9 | const int8_t DISABLE_CHIP_SELECT = -1; 10 | // 11 | // Test with reduced SPI speed for breadboards. 12 | // Change spiSpeed to SPI_FULL_SPEED for better performance 13 | // Use SPI_QUARTER_SPEED for even slower SPI bus speed 14 | const uint8_t spiSpeed = SPI_HALF_SPEED; 15 | //------------------------------------------------------------------------------ 16 | // File system object. 17 | SdFat sd; 18 | 19 | // Serial streams 20 | ArduinoOutStream cout(Serial); 21 | 22 | // input buffer for line 23 | char cinBuf[40]; 24 | ArduinoInStream cin(Serial, cinBuf, sizeof(cinBuf)); 25 | 26 | // SD card chip select 27 | int chipSelect; 28 | 29 | void cardOrSpeed() { 30 | cout << F("Try another SD card or reduce the SPI bus speed.\n"); 31 | cout << F("Edit spiSpeed in this program to change it.\n"); 32 | } 33 | 34 | void reformatMsg() { 35 | cout << F("Try reformatting the card. For best results use\n"); 36 | cout << F("the SdFormatter program in SdFat/examples or download\n"); 37 | cout << F("and use SDFormatter from www.sdcard.org/downloads.\n"); 38 | } 39 | 40 | void setup() { 41 | Serial.begin(9600); 42 | while (!Serial) {} // Wait for Leonardo. 43 | 44 | cout << F("\nSPI pins:\n"); 45 | cout << F("MISO: ") << int(MISO) << endl; 46 | cout << F("MOSI: ") << int(MOSI) << endl; 47 | cout << F("SCK: ") << int(SCK) << endl; 48 | cout << F("SS: ") << int(SS) << endl; 49 | 50 | if (DISABLE_CHIP_SELECT < 0) { 51 | cout << F( 52 | "\nBe sure to edit DISABLE_CHIP_SELECT if you have\n" 53 | "a second SPI device. For example, with the Ethernet\n" 54 | "shield, DISABLE_CHIP_SELECT should be set to 10\n" 55 | "to disable the Ethernet controller.\n"); 56 | } 57 | cout << F( 58 | "\nSD chip select is the key hardware option.\n" 59 | "Common values are:\n" 60 | "Arduino Ethernet shield, pin 4\n" 61 | "Sparkfun SD shield, pin 8\n" 62 | "Adafruit SD shields and modules, pin 10\n"); 63 | } 64 | 65 | bool firstTry = true; 66 | void loop() { 67 | // read any existing Serial data 68 | while (Serial.read() >= 0) {} 69 | 70 | if (!firstTry) { 71 | cout << F("\nRestarting\n"); 72 | } 73 | firstTry = false; 74 | 75 | cout << F("\nEnter the chip select pin number: "); 76 | while (!Serial.available()) {} 77 | delay(400); // catch Due restart problem 78 | 79 | cin.readline(); 80 | if (cin >> chipSelect) { 81 | cout << chipSelect << endl; 82 | } else { 83 | cout << F("\nInvalid pin number\n"); 84 | return; 85 | } 86 | if (DISABLE_CHIP_SELECT < 0) { 87 | cout << F( 88 | "\nAssuming the SD is the only SPI device.\n" 89 | "Edit DISABLE_CHIP_SELECT to disable another device.\n"); 90 | } else { 91 | cout << F("\nDisabling SPI device on pin "); 92 | cout << int(DISABLE_CHIP_SELECT) << endl; 93 | pinMode(DISABLE_CHIP_SELECT, OUTPUT); 94 | digitalWrite(DISABLE_CHIP_SELECT, HIGH); 95 | } 96 | if (!sd.begin(chipSelect, spiSpeed)) { 97 | if (sd.card()->errorCode()) { 98 | cout << F( 99 | "\nSD initialization failed.\n" 100 | "Do not reformat the card!\n" 101 | "Is the card correctly inserted?\n" 102 | "Is chipSelect set to the correct value?\n" 103 | "Does another SPI device need to be disabled?\n" 104 | "Is there a wiring/soldering problem?\n"); 105 | cout << F("\nerrorCode: ") << hex << showbase; 106 | cout << int(sd.card()->errorCode()); 107 | cout << F(", errorData: ") << int(sd.card()->errorData()); 108 | cout << dec << noshowbase << endl; 109 | return; 110 | } 111 | cout << F("\nCard successfully initialized.\n"); 112 | if (sd.vol()->fatType() == 0) { 113 | cout << F("Can't find a valid FAT16/FAT32 partition.\n"); 114 | reformatMsg(); 115 | return; 116 | } 117 | if (!sd.vwd()->isOpen()) { 118 | cout << F("Can't open root directory.\n"); 119 | reformatMsg(); 120 | return; 121 | } 122 | cout << F("Can't determine error type\n"); 123 | return; 124 | } 125 | cout << F("\nCard successfully initialized.\n"); 126 | cout << endl; 127 | 128 | uint32_t size = sd.card()->cardSize(); 129 | if (size == 0) { 130 | cout << F("Can't determine the card size.\n"); 131 | cardOrSpeed(); 132 | return; 133 | } 134 | uint32_t sizeMB = 0.000512 * size + 0.5; 135 | cout << F("Card size: ") << sizeMB; 136 | cout << F(" MB (MB = 1,000,000 bytes)\n"); 137 | cout << endl; 138 | cout << F("Volume is FAT") << int(sd.vol()->fatType()); 139 | cout << F(", Cluster size (bytes): ") << 512L * sd.vol()->blocksPerCluster(); 140 | cout << endl << endl; 141 | 142 | cout << F("Files found (date time size name):\n"); 143 | sd.ls(LS_R | LS_DATE | LS_SIZE); 144 | 145 | if ((sizeMB > 1100 && sd.vol()->blocksPerCluster() < 64) 146 | || (sizeMB < 2200 && sd.vol()->fatType() == 32)) { 147 | cout << F("\nThis card should be reformatted for best performance.\n"); 148 | cout << F("Use a cluster size of 32 KB for cards larger than 1 GB.\n"); 149 | cout << F("Only cards larger than 2 GB should be formatted FAT32.\n"); 150 | reformatMsg(); 151 | return; 152 | } 153 | // read any existing Serial data 154 | while (Serial.read() >= 0) {} 155 | cout << F("\nSuccess! Type any character to restart.\n"); 156 | while (Serial.read() < 0) {} 157 | } -------------------------------------------------------------------------------- /Libraries/SdFat/src/FatLib/ostream.cpp: -------------------------------------------------------------------------------- 1 | /* FatLib Library 2 | * Copyright (C) 2013 by William Greiman 3 | * 4 | * This file is part of the FatLib Library 5 | * 6 | * This Library is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This Library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with the FatLib Library. If not, see 18 | * . 19 | */ 20 | #include 21 | #include "ostream.h" 22 | #ifndef PSTR 23 | #define PSTR(x) x 24 | #endif 25 | //------------------------------------------------------------------------------ 26 | void ostream::do_fill(unsigned len) { 27 | for (; len < width(); len++) { 28 | putch(fill()); 29 | } 30 | width(0); 31 | } 32 | //------------------------------------------------------------------------------ 33 | void ostream::fill_not_left(unsigned len) { 34 | if ((flags() & adjustfield) != left) { 35 | do_fill(len); 36 | } 37 | } 38 | //------------------------------------------------------------------------------ 39 | char* ostream::fmtNum(uint32_t n, char *ptr, uint8_t base) { 40 | char a = flags() & uppercase ? 'A' - 10 : 'a' - 10; 41 | do { 42 | uint32_t m = n; 43 | n /= base; 44 | char c = m - base * n; 45 | *--ptr = c < 10 ? c + '0' : c + a; 46 | } while (n); 47 | return ptr; 48 | } 49 | //------------------------------------------------------------------------------ 50 | void ostream::putBool(bool b) { 51 | if (flags() & boolalpha) { 52 | if (b) { 53 | putPgm(PSTR("true")); 54 | } else { 55 | putPgm(PSTR("false")); 56 | } 57 | } else { 58 | putChar(b ? '1' : '0'); 59 | } 60 | } 61 | //------------------------------------------------------------------------------ 62 | void ostream::putChar(char c) { 63 | fill_not_left(1); 64 | putch(c); 65 | do_fill(1); 66 | } 67 | //------------------------------------------------------------------------------ 68 | void ostream::putDouble(double n) { 69 | uint8_t nd = precision(); 70 | double round = 0.5; 71 | char sign; 72 | char buf[13]; // room for sign, 10 digits, '.', and zero byte 73 | char *end = buf + sizeof(buf) - 1; 74 | char *str = end; 75 | // terminate string 76 | *end = '\0'; 77 | 78 | // get sign and make nonnegative 79 | if (n < 0.0) { 80 | sign = '-'; 81 | n = -n; 82 | } else { 83 | sign = flags() & showpos ? '+' : '\0'; 84 | } 85 | // check for larger than uint32_t 86 | if (n > 4.0E9) { 87 | putPgm(PSTR("BIG FLT")); 88 | return; 89 | } 90 | // round up and separate int and fraction parts 91 | for (uint8_t i = 0; i < nd; ++i) { 92 | round *= 0.1; 93 | } 94 | n += round; 95 | uint32_t intPart = n; 96 | double fractionPart = n - intPart; 97 | 98 | // format intPart and decimal point 99 | if (nd || (flags() & showpoint)) { 100 | *--str = '.'; 101 | } 102 | str = fmtNum(intPart, str, 10); 103 | 104 | // calculate length for fill 105 | uint8_t len = sign ? 1 : 0; 106 | len += nd + end - str; 107 | 108 | // extract adjust field 109 | fmtflags adj = flags() & adjustfield; 110 | if (adj == internal) { 111 | if (sign) { 112 | putch(sign); 113 | } 114 | do_fill(len); 115 | } else { 116 | // do fill for internal or right 117 | fill_not_left(len); 118 | if (sign) { 119 | *--str = sign; 120 | } 121 | } 122 | putstr(str); 123 | // output fraction 124 | while (nd-- > 0) { 125 | fractionPart *= 10.0; 126 | int digit = static_cast(fractionPart); 127 | putch(digit + '0'); 128 | fractionPart -= digit; 129 | } 130 | // do fill if not done above 131 | do_fill(len); 132 | } 133 | //------------------------------------------------------------------------------ 134 | void ostream::putNum(int32_t n) { 135 | bool neg = n < 0 && flagsToBase() == 10; 136 | if (neg) { 137 | n = -n; 138 | } 139 | putNum(n, neg); 140 | } 141 | //------------------------------------------------------------------------------ 142 | void ostream::putNum(uint32_t n, bool neg) { 143 | char buf[13]; 144 | char* end = buf + sizeof(buf) - 1; 145 | char* num; 146 | char* str; 147 | uint8_t base = flagsToBase(); 148 | *end = '\0'; 149 | str = num = fmtNum(n, end, base); 150 | if (base == 10) { 151 | if (neg) { 152 | *--str = '-'; 153 | } else if (flags() & showpos) { 154 | *--str = '+'; 155 | } 156 | } else if (flags() & showbase) { 157 | if (flags() & hex) { 158 | *--str = flags() & uppercase ? 'X' : 'x'; 159 | } 160 | *--str = '0'; 161 | } 162 | uint8_t len = end - str; 163 | fmtflags adj = flags() & adjustfield; 164 | if (adj == internal) { 165 | while (str < num) { 166 | putch(*str++); 167 | } 168 | } 169 | if (adj != left) { 170 | do_fill(len); 171 | } 172 | putstr(str); 173 | do_fill(len); 174 | } 175 | //------------------------------------------------------------------------------ 176 | void ostream::putPgm(const char* str) { 177 | int n; 178 | for (n = 0; pgm_read_byte(&str[n]); n++) {} 179 | fill_not_left(n); 180 | for (uint8_t c; (c = pgm_read_byte(str)); str++) { 181 | putch(c); 182 | } 183 | do_fill(n); 184 | } 185 | //------------------------------------------------------------------------------ 186 | void ostream::putStr(const char *str) { 187 | unsigned n = strlen(str); 188 | fill_not_left(n); 189 | putstr(str); 190 | do_fill(n); 191 | } 192 | -------------------------------------------------------------------------------- /Libraries/SdFat/examples/#attic/AnalogLogger/AnalogLogger.ino: -------------------------------------------------------------------------------- 1 | // A simple data logger for the Arduino analog pins with optional DS1307 2 | // uses RTClib from https://github.com/adafruit/RTClib 3 | #include 4 | #include 5 | #include 6 | 7 | #define SD_CHIP_SELECT SS // SD chip select pin 8 | #define USE_DS1307 0 // set nonzero to use DS1307 RTC 9 | #define LOG_INTERVAL 1000 // mills between entries 10 | #define SENSOR_COUNT 3 // number of analog pins to log 11 | #define ECHO_TO_SERIAL 1 // echo data to serial port if nonzero 12 | #define WAIT_TO_START 1 // Wait for serial input in setup() 13 | #define ADC_DELAY 10 // ADC delay for high impedence sensors 14 | 15 | // file system object 16 | SdFat sd; 17 | 18 | // text file for logging 19 | ofstream logfile; 20 | 21 | // Serial print stream 22 | ArduinoOutStream cout(Serial); 23 | 24 | // buffer to format data - makes it eaiser to echo to Serial 25 | char buf[80]; 26 | //------------------------------------------------------------------------------ 27 | #if SENSOR_COUNT > 6 28 | #error SENSOR_COUNT too large 29 | #endif // SENSOR_COUNT 30 | //------------------------------------------------------------------------------ 31 | // store error strings in flash to save RAM 32 | #define error(s) sd.errorHalt(F(s)) 33 | //------------------------------------------------------------------------------ 34 | #if USE_DS1307 35 | // use RTClib from Adafruit 36 | // https://github.com/adafruit/RTClib 37 | 38 | // The Arduino IDE has a bug that causes Wire and RTClib to be loaded even 39 | // if USE_DS1307 is false. 40 | 41 | #error remove this line and uncomment the next two lines. 42 | //#include 43 | //#include 44 | RTC_DS1307 RTC; // define the Real Time Clock object 45 | //------------------------------------------------------------------------------ 46 | // call back for file timestamps 47 | void dateTime(uint16_t* date, uint16_t* time) { 48 | DateTime now = RTC.now(); 49 | 50 | // return date using FAT_DATE macro to format fields 51 | *date = FAT_DATE(now.year(), now.month(), now.day()); 52 | 53 | // return time using FAT_TIME macro to format fields 54 | *time = FAT_TIME(now.hour(), now.minute(), now.second()); 55 | } 56 | //------------------------------------------------------------------------------ 57 | // format date/time 58 | ostream& operator << (ostream& os, DateTime& dt) { 59 | os << dt.year() << '/' << int(dt.month()) << '/' << int(dt.day()) << ','; 60 | os << int(dt.hour()) << ':' << setfill('0') << setw(2) << int(dt.minute()); 61 | os << ':' << setw(2) << int(dt.second()) << setfill(' '); 62 | return os; 63 | } 64 | #endif // USE_DS1307 65 | //------------------------------------------------------------------------------ 66 | void setup() { 67 | Serial.begin(9600); 68 | while (!Serial) {} // wait for Leonardo 69 | 70 | // F() stores strings in flash to save RAM 71 | cout << endl << F("FreeStack: ") << FreeStack() << endl; 72 | 73 | #if WAIT_TO_START 74 | cout << F("Type any character to start\n"); 75 | while (Serial.read() <= 0) {} 76 | delay(400); // catch Due reset problem 77 | while (Serial.read() >= 0) {} 78 | #endif // WAIT_TO_START 79 | 80 | #if USE_DS1307 81 | // connect to RTC 82 | Wire.begin(); 83 | if (!RTC.begin()) { 84 | error("RTC failed"); 85 | } 86 | 87 | // set date time callback function 88 | SdFile::dateTimeCallback(dateTime); 89 | DateTime now = RTC.now(); 90 | cout << now << endl; 91 | #endif // USE_DS1307 92 | 93 | // initialize the SD card at SPI_HALF_SPEED to avoid bus errors with 94 | if (!sd.begin(SD_CHIP_SELECT, SPI_HALF_SPEED)) { 95 | sd.initErrorHalt(); 96 | } 97 | 98 | // create a new file in root, the current working directory 99 | char name[] = "logger00.csv"; 100 | 101 | for (uint8_t i = 0; i < 100; i++) { 102 | name[6] = i/10 + '0'; 103 | name[7] = i%10 + '0'; 104 | if (sd.exists(name)) { 105 | continue; 106 | } 107 | logfile.open(name); 108 | break; 109 | } 110 | if (!logfile.is_open()) { 111 | error("file.open"); 112 | } 113 | 114 | cout << F("Logging to: ") << name << endl; 115 | cout << F("Type any character to stop\n\n"); 116 | 117 | // format header in buffer 118 | obufstream bout(buf, sizeof(buf)); 119 | 120 | bout << F("millis"); 121 | 122 | #if USE_DS1307 123 | bout << F(",date,time"); 124 | #endif // USE_DS1307 125 | 126 | for (uint8_t i = 0; i < SENSOR_COUNT; i++) { 127 | bout << F(",sens") << int(i); 128 | } 129 | logfile << buf << endl; 130 | 131 | #if ECHO_TO_SERIAL 132 | cout << buf << endl; 133 | #endif // ECHO_TO_SERIAL 134 | } 135 | //------------------------------------------------------------------------------ 136 | void loop() { 137 | uint32_t m; 138 | 139 | // wait for time to be a multiple of interval 140 | do { 141 | m = millis(); 142 | } while (m % LOG_INTERVAL); 143 | 144 | // use buffer stream to format line 145 | obufstream bout(buf, sizeof(buf)); 146 | 147 | // start with time in millis 148 | bout << m; 149 | 150 | #if USE_DS1307 151 | DateTime now = RTC.now(); 152 | bout << ',' << now; 153 | #endif // USE_DS1307 154 | 155 | // read analog pins and format data 156 | for (uint8_t ia = 0; ia < SENSOR_COUNT; ia++) { 157 | #if ADC_DELAY 158 | analogRead(ia); 159 | delay(ADC_DELAY); 160 | #endif // ADC_DELAY 161 | bout << ',' << analogRead(ia); 162 | } 163 | bout << endl; 164 | 165 | // log data and flush to SD 166 | logfile << buf << flush; 167 | 168 | // check for error 169 | if (!logfile) { 170 | error("write data failed"); 171 | } 172 | 173 | #if ECHO_TO_SERIAL 174 | cout << buf; 175 | #endif // ECHO_TO_SERIAL 176 | 177 | // don't log two points in the same millis 178 | if (m == millis()) { 179 | delay(1); 180 | } 181 | 182 | if (!Serial.available()) { 183 | return; 184 | } 185 | logfile.close(); 186 | cout << F("Done!"); 187 | while (1); 188 | } -------------------------------------------------------------------------------- /Libraries/SdFat/examples/RawWrite/RawWrite.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * This program illustrates raw write functions in SdFat that 3 | * can be used for high speed data logging. 4 | * 5 | * This program simulates logging from a source that produces 6 | * data at a constant rate of one block every MICROS_PER_BLOCK. 7 | * 8 | * If a high quality SanDisk card is used with this program 9 | * no overruns occur and the maximum block write time is 10 | * under 2000 micros. 11 | * 12 | * Note: Apps should create a very large file then truncates it 13 | * to the length that is used for a logging. It only takes 14 | * a few seconds to erase a 500 MB file since the card only 15 | * marks the blocks as erased; no data transfer is required. 16 | */ 17 | #include 18 | #include 19 | #include 20 | 21 | // SD chip select pin 22 | const uint8_t chipSelect = SS; 23 | 24 | // number of blocks in the contiguous file 25 | const uint32_t BLOCK_COUNT = 10000UL; 26 | 27 | // time to produce a block of data 28 | const uint32_t MICROS_PER_BLOCK = 10000; 29 | 30 | // file system 31 | SdFat sd; 32 | 33 | // test file 34 | SdFile file; 35 | 36 | // file extent 37 | uint32_t bgnBlock, endBlock; 38 | 39 | // Serial output stream 40 | ArduinoOutStream cout(Serial); 41 | //------------------------------------------------------------------------------ 42 | // store error strings in flash to save RAM 43 | #define error(s) sd.errorHalt(F(s)) 44 | //------------------------------------------------------------------------------ 45 | // log of first overruns 46 | #define OVER_DIM 20 47 | struct { 48 | uint32_t block; 49 | uint32_t micros; 50 | } over[OVER_DIM]; 51 | //------------------------------------------------------------------------------ 52 | void setup(void) { 53 | Serial.begin(9600); 54 | while (!Serial) {} // wait for Leonardo 55 | } 56 | //------------------------------------------------------------------------------ 57 | void loop(void) { 58 | while (Serial.read() >= 0) {} 59 | // pstr stores strings in flash to save RAM 60 | cout << F("Type any character to start\n"); 61 | while (Serial.read() <= 0) {} 62 | delay(400); // catch Due reset problem 63 | 64 | cout << F("FreeStack: ") << FreeStack() << endl; 65 | 66 | // initialize the SD card at SPI_FULL_SPEED for best performance. 67 | // try SPI_HALF_SPEED if bus errors occur. 68 | if (!sd.begin(chipSelect, SPI_FULL_SPEED)) { 69 | sd.initErrorHalt(); 70 | } 71 | 72 | // delete possible existing file 73 | sd.remove("RawWrite.txt"); 74 | 75 | // create a contiguous file 76 | if (!file.createContiguous(sd.vwd(), "RawWrite.txt", 512UL*BLOCK_COUNT)) { 77 | error("createContiguous failed"); 78 | } 79 | // get the location of the file's blocks 80 | if (!file.contiguousRange(&bgnBlock, &endBlock)) { 81 | error("contiguousRange failed"); 82 | } 83 | //*********************NOTE************************************** 84 | // NO SdFile calls are allowed while cache is used for raw writes 85 | //*************************************************************** 86 | 87 | // clear the cache and use it as a 512 byte buffer 88 | uint8_t* pCache = (uint8_t*)sd.vol()->cacheClear(); 89 | 90 | // fill cache with eight lines of 64 bytes each 91 | memset(pCache, ' ', 512); 92 | for (uint16_t i = 0; i < 512; i += 64) { 93 | // put line number at end of line then CR/LF 94 | pCache[i + 61] = '0' + (i/64); 95 | pCache[i + 62] = '\r'; 96 | pCache[i + 63] = '\n'; 97 | } 98 | 99 | cout << F("Start raw write of ") << file.fileSize() << F(" bytes at\n"); 100 | cout << 512000000UL/MICROS_PER_BLOCK << F(" bytes per second\n"); 101 | cout << F("Please wait ") << (BLOCK_COUNT*MICROS_PER_BLOCK)/1000000UL; 102 | cout << F(" seconds\n"); 103 | 104 | // tell card to setup for multiple block write with pre-erase 105 | if (!sd.card()->writeStart(bgnBlock, BLOCK_COUNT)) { 106 | error("writeStart failed"); 107 | } 108 | // init stats 109 | uint16_t overruns = 0; 110 | uint32_t maxWriteTime = 0; 111 | uint32_t t = micros(); 112 | uint32_t tNext = t; 113 | 114 | // write data 115 | for (uint32_t b = 0; b < BLOCK_COUNT; b++) { 116 | // write must be done by this time 117 | tNext += MICROS_PER_BLOCK; 118 | 119 | // put block number at start of first line in block 120 | uint32_t n = b; 121 | for (int8_t d = 5; d >= 0; d--) { 122 | pCache[d] = n || d == 5 ? n % 10 + '0' : ' '; 123 | n /= 10; 124 | } 125 | // write a 512 byte block 126 | uint32_t tw = micros(); 127 | if (!sd.card()->writeData(pCache)) { 128 | error("writeData failed"); 129 | } 130 | tw = micros() - tw; 131 | 132 | // check for max write time 133 | if (tw > maxWriteTime) { 134 | maxWriteTime = tw; 135 | } 136 | // check for overrun 137 | if (micros() > tNext) { 138 | if (overruns < OVER_DIM) { 139 | over[overruns].block = b; 140 | over[overruns].micros = tw; 141 | } 142 | overruns++; 143 | // advance time to reflect overrun 144 | tNext = micros(); 145 | } else { 146 | // wait for time to write next block 147 | while(micros() < tNext); 148 | } 149 | } 150 | // total write time 151 | t = micros() - t; 152 | 153 | // end multiple block write mode 154 | if (!sd.card()->writeStop()) { 155 | error("writeStop failed"); 156 | } 157 | 158 | cout << F("Done\n"); 159 | cout << F("Elapsed time: ") << setprecision(3)<< 1.e-6*t; 160 | cout << F(" seconds\n"); 161 | cout << F("Max write time: ") << maxWriteTime << F(" micros\n"); 162 | cout << F("Overruns: ") << overruns << endl; 163 | if (overruns) { 164 | uint8_t n = overruns > OVER_DIM ? OVER_DIM : overruns; 165 | cout << F("fileBlock,micros") << endl; 166 | for (uint8_t i = 0; i < n; i++) { 167 | cout << over[i].block << ',' << over[i].micros << endl; 168 | } 169 | } 170 | // close file for next pass of loop 171 | file.close(); 172 | Serial.println(); 173 | } -------------------------------------------------------------------------------- /Libraries/SdFat/examples/bench/bench.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * This program is a simple binary write/read benchmark. 3 | */ 4 | #include 5 | #include 6 | #include 7 | 8 | // SD chip select pin 9 | const uint8_t chipSelect = SS; 10 | 11 | // Size of read/write. 12 | const size_t BUF_SIZE = 512; 13 | 14 | // File size in MB where MB = 1,000,000 bytes. 15 | const uint32_t FILE_SIZE_MB = 5; 16 | 17 | // Write pass count. 18 | const uint8_t WRITE_COUNT = 10; 19 | 20 | // Read pass count. 21 | const uint8_t READ_COUNT = 5; 22 | //============================================================================== 23 | // End of configuration constants. 24 | //------------------------------------------------------------------------------ 25 | // File size in bytes. 26 | const uint32_t FILE_SIZE = 1000000UL*FILE_SIZE_MB; 27 | 28 | uint8_t buf[BUF_SIZE]; 29 | 30 | // file system 31 | SdFat sd; 32 | 33 | // test file 34 | SdFile file; 35 | 36 | // Serial output stream 37 | ArduinoOutStream cout(Serial); 38 | //------------------------------------------------------------------------------ 39 | // store error strings in flash to save RAM 40 | #define error(s) sd.errorHalt(F(s)) 41 | //------------------------------------------------------------------------------ 42 | void cidDmp() { 43 | cid_t cid; 44 | if (!sd.card()->readCID(&cid)) { 45 | error("readCID failed"); 46 | } 47 | cout << F("\nManufacturer ID: "); 48 | cout << hex << int(cid.mid) << dec << endl; 49 | cout << F("OEM ID: ") << cid.oid[0] << cid.oid[1] << endl; 50 | cout << F("Product: "); 51 | for (uint8_t i = 0; i < 5; i++) { 52 | cout << cid.pnm[i]; 53 | } 54 | cout << F("\nVersion: "); 55 | cout << int(cid.prv_n) << '.' << int(cid.prv_m) << endl; 56 | cout << F("Serial number: ") << hex << cid.psn << dec << endl; 57 | cout << F("Manufacturing date: "); 58 | cout << int(cid.mdt_month) << '/'; 59 | cout << (2000 + cid.mdt_year_low + 10 * cid.mdt_year_high) << endl; 60 | cout << endl; 61 | } 62 | //------------------------------------------------------------------------------ 63 | void setup() { 64 | Serial.begin(9600); 65 | while (!Serial) {} // wait for Leonardo 66 | delay(1000); 67 | cout << F("\nUse a freshly formatted SD for best performance.\n"); 68 | 69 | // use uppercase in hex and use 0X base prefix 70 | cout << uppercase << showbase << endl; 71 | } 72 | //------------------------------------------------------------------------------ 73 | void loop() { 74 | float s; 75 | uint32_t t; 76 | uint32_t maxLatency; 77 | uint32_t minLatency; 78 | uint32_t totalLatency; 79 | 80 | // discard any input 81 | while (Serial.read() >= 0) {} 82 | 83 | // F( stores strings in flash to save RAM 84 | cout << F("Type any character to start\n"); 85 | while (Serial.read() <= 0) {} 86 | delay(400); // catch Due reset problem 87 | 88 | cout << F("FreeStack: ") << FreeStack() << endl; 89 | 90 | // initialize the SD card at SPI_FULL_SPEED for best performance. 91 | // try SPI_HALF_SPEED if bus errors occur. 92 | if (!sd.begin(chipSelect, SPI_FULL_SPEED)) { 93 | sd.initErrorHalt(); 94 | } 95 | 96 | cout << F("Type is FAT") << int(sd.vol()->fatType()) << endl; 97 | cout << F("Card size: ") << sd.card()->cardSize()*512E-9; 98 | cout << F(" GB (GB = 1E9 bytes)") << endl; 99 | 100 | cidDmp(); 101 | 102 | // open or create file - truncate existing file. 103 | if (!file.open("bench.dat", O_CREAT | O_TRUNC | O_RDWR)) { 104 | error("open failed"); 105 | } 106 | 107 | // fill buf with known data 108 | for (uint16_t i = 0; i < (BUF_SIZE-2); i++) { 109 | buf[i] = 'A' + (i % 26); 110 | } 111 | buf[BUF_SIZE-2] = '\r'; 112 | buf[BUF_SIZE-1] = '\n'; 113 | 114 | cout << F("File size ") << FILE_SIZE_MB << F(" MB\n"); 115 | cout << F("Buffer size ") << BUF_SIZE << F(" bytes\n"); 116 | cout << F("Starting write test, please wait.") << endl << endl; 117 | 118 | // do write test 119 | uint32_t n = FILE_SIZE/sizeof(buf); 120 | cout < m) { 139 | minLatency = m; 140 | } 141 | totalLatency += m; 142 | } 143 | file.sync(); 144 | t = millis() - t; 145 | s = file.fileSize(); 146 | cout << s/t <<',' << maxLatency << ',' << minLatency; 147 | cout << ',' << totalLatency/n << endl; 148 | } 149 | 150 | cout << endl << F("Starting read test, please wait.") << endl; 151 | cout << endl < m) { 172 | minLatency = m; 173 | } 174 | totalLatency += m; 175 | if (buf[BUF_SIZE-1] != '\n') { 176 | error("data check"); 177 | } 178 | } 179 | t = millis() - t; 180 | cout << s/t <<',' << maxLatency << ',' << minLatency; 181 | cout << ',' << totalLatency/n << endl; 182 | } 183 | cout << endl << F("Done") << endl; 184 | file.close(); 185 | } -------------------------------------------------------------------------------- /Libraries/SdFat/src/SdSpiCard/SoftSPI.h: -------------------------------------------------------------------------------- 1 | /* Arduino DigitalIO Library 2 | * Copyright (C) 2013 by William Greiman 3 | * 4 | * This file is part of the Arduino DigitalIO Library 5 | * 6 | * This Library is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This Library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with the Arduino DigitalIO Library. If not, see 18 | * . 19 | */ 20 | /** 21 | * @file 22 | * @brief Software SPI. 23 | * 24 | * @defgroup softSPI Software SPI 25 | * @details Software SPI Template Class. 26 | * @{ 27 | */ 28 | 29 | #ifndef SoftSPI_h 30 | #define SoftSPI_h 31 | #include "DigitalPin.h" 32 | //------------------------------------------------------------------------------ 33 | /** Nop for timing. */ 34 | #define nop asm volatile ("nop\n\t") 35 | //------------------------------------------------------------------------------ 36 | /** Pin Mode for MISO is input.*/ 37 | const bool MISO_MODE = false; 38 | /** Pullups disabled for MISO are disabled. */ 39 | const bool MISO_LEVEL = false; 40 | /** Pin Mode for MOSI is output.*/ 41 | const bool MOSI_MODE = true; 42 | /** Pin Mode for SCK is output. */ 43 | const bool SCK_MODE = true; 44 | //------------------------------------------------------------------------------ 45 | /** 46 | * @class SoftSPI 47 | * @brief Fast software SPI. 48 | */ 49 | template 50 | class SoftSPI { 51 | public: 52 | //---------------------------------------------------------------------------- 53 | /** Initialize SoftSPI pins. */ 54 | void begin() { 55 | fastPinConfig(MisoPin, MISO_MODE, MISO_LEVEL); 56 | fastPinConfig(MosiPin, MOSI_MODE, !MODE_CPHA(Mode)); 57 | fastPinConfig(SckPin, SCK_MODE, MODE_CPOL(Mode)); 58 | } 59 | //---------------------------------------------------------------------------- 60 | /** Soft SPI receive byte. 61 | * @return Data byte received. 62 | */ 63 | inline __attribute__((always_inline)) 64 | uint8_t receive() { 65 | uint8_t data = 0; 66 | receiveBit(7, &data); 67 | receiveBit(6, &data); 68 | receiveBit(5, &data); 69 | receiveBit(4, &data); 70 | receiveBit(3, &data); 71 | receiveBit(2, &data); 72 | receiveBit(1, &data); 73 | receiveBit(0, &data); 74 | return data; 75 | } 76 | //---------------------------------------------------------------------------- 77 | /** Soft SPI send byte. 78 | * @param[in] data Data byte to send. 79 | */ 80 | inline __attribute__((always_inline)) 81 | void send(uint8_t data) { 82 | sendBit(7, data); 83 | sendBit(6, data); 84 | sendBit(5, data); 85 | sendBit(4, data); 86 | sendBit(3, data); 87 | sendBit(2, data); 88 | sendBit(1, data); 89 | sendBit(0, data); 90 | } 91 | //---------------------------------------------------------------------------- 92 | /** Soft SPI transfer byte. 93 | * @param[in] txData Data byte to send. 94 | * @return Data byte received. 95 | */ 96 | inline __attribute__((always_inline)) 97 | uint8_t transfer(uint8_t txData) { 98 | uint8_t rxData = 0; 99 | transferBit(7, &rxData, txData); 100 | transferBit(6, &rxData, txData); 101 | transferBit(5, &rxData, txData); 102 | transferBit(4, &rxData, txData); 103 | transferBit(3, &rxData, txData); 104 | transferBit(2, &rxData, txData); 105 | transferBit(1, &rxData, txData); 106 | transferBit(0, &rxData, txData); 107 | return rxData; 108 | } 109 | 110 | private: 111 | //---------------------------------------------------------------------------- 112 | inline __attribute__((always_inline)) 113 | bool MODE_CPHA(uint8_t mode) { 114 | return (mode & 1) != 0; 115 | } 116 | inline __attribute__((always_inline)) 117 | bool MODE_CPOL(uint8_t mode) { 118 | return (mode & 2) != 0; 119 | } 120 | inline __attribute__((always_inline)) 121 | void receiveBit(uint8_t bit, uint8_t* data) { 122 | if (MODE_CPHA(Mode)) { 123 | fastDigitalWrite(SckPin, !MODE_CPOL(Mode)); 124 | } 125 | nop; 126 | nop; 127 | fastDigitalWrite(SckPin, 128 | MODE_CPHA(Mode) ? MODE_CPOL(Mode) : !MODE_CPOL(Mode)); 129 | if (fastDigitalRead(MisoPin)) { 130 | *data |= 1 << bit; 131 | } 132 | if (!MODE_CPHA(Mode)) { 133 | fastDigitalWrite(SckPin, MODE_CPOL(Mode)); 134 | } 135 | } 136 | //---------------------------------------------------------------------------- 137 | inline __attribute__((always_inline)) 138 | void sendBit(uint8_t bit, uint8_t data) { 139 | if (MODE_CPHA(Mode)) { 140 | fastDigitalWrite(SckPin, !MODE_CPOL(Mode)); 141 | } 142 | fastDigitalWrite(MosiPin, data & (1 << bit)); 143 | fastDigitalWrite(SckPin, 144 | MODE_CPHA(Mode) ? MODE_CPOL(Mode) : !MODE_CPOL(Mode)); 145 | nop; 146 | nop; 147 | if (!MODE_CPHA(Mode)) { 148 | fastDigitalWrite(SckPin, MODE_CPOL(Mode)); 149 | } 150 | } 151 | //---------------------------------------------------------------------------- 152 | inline __attribute__((always_inline)) 153 | void transferBit(uint8_t bit, uint8_t* rxData, uint8_t txData) { 154 | if (MODE_CPHA(Mode)) { 155 | fastDigitalWrite(SckPin, !MODE_CPOL(Mode)); 156 | } 157 | fastDigitalWrite(MosiPin, txData & (1 << bit)); 158 | fastDigitalWrite(SckPin, 159 | MODE_CPHA(Mode) ? MODE_CPOL(Mode) : !MODE_CPOL(Mode)); 160 | if (fastDigitalRead(MisoPin)) { 161 | *rxData |= 1 << bit; 162 | } 163 | if (!MODE_CPHA(Mode)) { 164 | fastDigitalWrite(SckPin, MODE_CPOL(Mode)); 165 | } 166 | } 167 | //---------------------------------------------------------------------------- 168 | }; 169 | #endif // SoftSPI_h 170 | /** @} */ 171 | -------------------------------------------------------------------------------- /Libraries/SdFat/examples/StdioBench/StdioBench.ino: -------------------------------------------------------------------------------- 1 | // Benchmark comparing SdFile and StdioStream. 2 | #include 3 | #include 4 | 5 | // Define PRINT_FIELD nonzero to use printField. 6 | #define PRINT_FIELD 0 7 | 8 | // Number of lines to list on Serial. 9 | #define STDIO_LIST_COUNT 0 10 | #define VERIFY_CONTENT 0 11 | 12 | const uint8_t SD_CS_PIN = SS; 13 | SdFat sd; 14 | 15 | SdFile printFile; 16 | StdioStream stdioFile; 17 | 18 | float f[100]; 19 | char buf[20]; 20 | char* label[] = 21 | { "uint8_t 0 to 255, 100 times ", "uint16_t 0 to 20000", 22 | "uint32_t 0 to 20000", "uint32_t 1000000000 to 1000010000", 23 | "float nnn.ffff, 10000 times" 24 | }; 25 | //------------------------------------------------------------------------------ 26 | void setup() { 27 | uint32_t m; 28 | uint32_t printSize; 29 | uint32_t stdioSize; 30 | uint32_t printTime; 31 | uint32_t stdioTime; 32 | 33 | Serial.begin(9600); 34 | while (!Serial) {} 35 | 36 | Serial.println(F("Type any character to start")); 37 | while (!Serial.available()); 38 | Serial.println(F("Starting test")); 39 | if (!sd.begin(SD_CS_PIN)) { 40 | sd.errorHalt(); 41 | } 42 | 43 | for (uint8_t i = 0; i < 100; i++) { 44 | f[i] = 123.0 + 0.1234*i; 45 | } 46 | 47 | for (uint8_t dataType = 0; dataType < 5; dataType++) { 48 | for (uint8_t fileType = 0; fileType < 2; fileType++) { 49 | if (!fileType) { 50 | if (!printFile.open("print.txt", O_CREAT | O_RDWR | O_TRUNC)) { 51 | Serial.println(F("open fail")); 52 | return; 53 | } 54 | printTime = millis(); 55 | switch (dataType) { 56 | case 0: 57 | for (uint16_t i =0; i < 100; i++) { 58 | for (uint8_t j = 0; j < 255; j++) { 59 | printFile.println(j); 60 | } 61 | } 62 | break; 63 | case 1: 64 | for (uint16_t i = 0; i < 20000; i++) { 65 | printFile.println(i); 66 | } 67 | break; 68 | 69 | case 2: 70 | for (uint32_t i = 0; i < 20000; i++) { 71 | printFile.println(i); 72 | } 73 | break; 74 | 75 | case 3: 76 | for (uint16_t i = 0; i < 10000; i++) { 77 | printFile.println(i + 1000000000UL); 78 | } 79 | break; 80 | 81 | case 4: 82 | for (int j = 0; j < 100; j++) { 83 | for (uint8_t i = 0; i < 100; i++) { 84 | printFile.println(f[i], 4); 85 | } 86 | } 87 | break; 88 | default: 89 | break; 90 | } 91 | printFile.sync(); 92 | printTime = millis() - printTime; 93 | printFile.rewind(); 94 | printSize = printFile.fileSize(); 95 | 96 | } else { 97 | if (!stdioFile.fopen("stream.txt", "w+")) { 98 | Serial.println(F("fopen fail")); 99 | return; 100 | } 101 | stdioTime = millis(); 102 | 103 | switch (dataType) { 104 | case 0: 105 | for (uint16_t i =0; i < 100; i++) { 106 | for (uint8_t j = 0; j < 255; j++) { 107 | #if PRINT_FIELD 108 | stdioFile.printField(j, '\n'); 109 | #else // PRINT_FIELD 110 | stdioFile.println(j); 111 | #endif // PRINT_FIELD 112 | } 113 | } 114 | break; 115 | case 1: 116 | for (uint16_t i = 0; i < 20000; i++) { 117 | #if PRINT_FIELD 118 | stdioFile.printField(i, '\n'); 119 | #else // PRINT_FIELD 120 | stdioFile.println(i); 121 | #endif // PRINT_FIELD 122 | } 123 | break; 124 | 125 | case 2: 126 | for (uint32_t i = 0; i < 20000; i++) { 127 | #if PRINT_FIELD 128 | stdioFile.printField(i, '\n'); 129 | #else // PRINT_FIELD 130 | stdioFile.println(i); 131 | #endif // PRINT_FIELD 132 | } 133 | break; 134 | 135 | case 3: 136 | for (uint16_t i = 0; i < 10000; i++) { 137 | #if PRINT_FIELD 138 | stdioFile.printField(i + 1000000000UL, '\n'); 139 | #else // PRINT_FIELD 140 | stdioFile.println(i + 1000000000UL); 141 | #endif // PRINT_FIELD 142 | } 143 | break; 144 | 145 | case 4: 146 | for (int j = 0; j < 100; j++) { 147 | for (uint8_t i = 0; i < 100; i++) { 148 | #if PRINT_FIELD 149 | stdioFile.printField(f[i], '\n', 4); 150 | #else // PRINT_FIELD 151 | stdioFile.println(f[i], 4); 152 | #endif // PRINT_FIELD 153 | } 154 | } 155 | break; 156 | default: 157 | break; 158 | } 159 | stdioFile.fflush(); 160 | stdioTime = millis() - stdioTime; 161 | stdioSize = stdioFile.ftell(); 162 | if (STDIO_LIST_COUNT) { 163 | size_t len; 164 | stdioFile.rewind(); 165 | for (int i = 0; i < STDIO_LIST_COUNT; i++) { 166 | stdioFile.fgets(buf, sizeof(buf), &len); 167 | Serial.print(len); 168 | Serial.print(','); 169 | Serial.print(buf); 170 | } 171 | } 172 | 173 | } 174 | 175 | } 176 | Serial.println(label[dataType]); 177 | if (VERIFY_CONTENT && printSize == stdioSize) { 178 | printFile.rewind(); 179 | stdioFile.rewind(); 180 | for (uint32_t i = 0; i < stdioSize; i++) { 181 | if (printFile.read() != stdioFile.getc()) { 182 | Serial.print(F("Files differ at pos: ")); 183 | Serial.println(i); 184 | return; 185 | } 186 | } 187 | } 188 | 189 | Serial.print(F("fileSize: ")); 190 | if (printSize != stdioSize) { 191 | Serial.print(printSize); 192 | Serial.print(F(" != ")); 193 | } 194 | Serial.println(stdioSize); 195 | Serial.print(F("print millis: ")); 196 | Serial.println(printTime); 197 | Serial.print(F("stdio millis: ")); 198 | Serial.println(stdioTime); 199 | Serial.print(F("ratio: ")); 200 | Serial.println((float)printTime/(float)stdioTime); 201 | Serial.println(); 202 | printFile.close(); 203 | stdioFile.fclose(); 204 | } 205 | Serial.println(F("Done")); 206 | } 207 | void loop() {} --------------------------------------------------------------------------------