|
3 | 3 |
|
4 | 4 | This example demonstrates how to perform non-blocking writes
|
5 | 5 | to a file on a SD card. The file will contain the current millis()
|
6 |
| - value every 10ms. If the SD card is busy, the data will be buffered |
| 6 | + value every 10ms. If the SD card is busy, the data will be dataBuffered |
7 | 7 | in order to not block the sketch.
|
8 | 8 |
|
| 9 | + If data is successfully written, the built in LED will flash. After a few |
| 10 | + seconds, check the card for a file called datalog.txt |
| 11 | +
|
9 | 12 | NOTE: myFile.availableForWrite() will automatically sync the
|
10 | 13 | file contents as needed. You may lose some unsynced data
|
11 | 14 | still if myFile.sync() or myFile.close() is not called.
|
12 | 15 |
|
| 16 | + Pin numbers reflect the default SPI pins for Uno and Nano models |
| 17 | + Updated for clarity and uniformity with other examples |
| 18 | +
|
13 | 19 | The circuit:
|
14 |
| - - Arduino MKR Zero board |
15 |
| - - micro SD card attached |
| 20 | + analog sensors on analog ins 0, 1, and 2 |
| 21 | + SD card attached to SPI bus as follows: |
| 22 | + ** SDO - pin 11 |
| 23 | + ** SDI - pin 12 |
| 24 | + ** CLK - pin 13 |
| 25 | + ** CS - depends on your SD card shield or module. |
| 26 | + Pin 10 used here for consistency with other Arduino examples |
| 27 | + (for MKRZero SD: SDCARD_SS_PIN) |
| 28 | +
|
| 29 | + modified 24 July 2020 |
| 30 | + by Tom Igoe |
16 | 31 |
|
17 | 32 | This example code is in the public domain.
|
18 | 33 | */
|
19 |
| - |
20 | 34 | #include <SD.h>
|
21 | 35 |
|
| 36 | +const int chipSelect = 10; |
| 37 | + |
22 | 38 | // file name to use for writing
|
23 |
| -const char filename[] = "demo.txt"; |
| 39 | +const char filename[] = "datalog.txt"; |
24 | 40 |
|
25 | 41 | // File object to represent file
|
26 |
| -File txtFile; |
27 |
| - |
| 42 | +File myFile; |
28 | 43 | // string to buffer output
|
29 |
| -String buffer; |
30 |
| - |
| 44 | +String dataBuffer; |
| 45 | +// last time data was written to card: |
31 | 46 | unsigned long lastMillis = 0;
|
32 | 47 |
|
33 | 48 | void setup() {
|
| 49 | + // Open serial communications and wait for port to open: |
34 | 50 | Serial.begin(9600);
|
35 |
| - while (!Serial); |
36 |
| - |
37 |
| - // reserve 1kB for String used as a buffer |
38 |
| - buffer.reserve(1024); |
| 51 | + // reserve 1kB for String used as a dataBuffer |
| 52 | + dataBuffer.reserve(1024); |
39 | 53 |
|
40 | 54 | // set LED pin to output, used to blink when writing
|
41 | 55 | pinMode(LED_BUILTIN, OUTPUT);
|
42 | 56 |
|
43 |
| - // init the SD card |
44 |
| - if (!SD.begin()) { |
45 |
| - Serial.println("Card failed, or not present"); |
46 |
| - // don't do anything more: |
47 |
| - while (1); |
| 57 | + // wait for Serial Monitor to connect. Needed for native USB port boards only: |
| 58 | + while (!Serial); |
| 59 | + |
| 60 | + Serial.print("Initializing SD card..."); |
| 61 | + |
| 62 | + if (!SD.begin(chipSelect)) { |
| 63 | + Serial.println("initialization failed. Things to check:"); |
| 64 | + Serial.println("1. is a card inserted?"); |
| 65 | + Serial.println("2. is your wiring correct?"); |
| 66 | + Serial.println("3. did you change the chipSelect pin to match your shield or module?"); |
| 67 | + Serial.println("Note: press reset or reopen this serial monitor after fixing your issue!"); |
| 68 | + while (true); |
48 | 69 | }
|
49 | 70 |
|
| 71 | + Serial.println("initialization done."); |
| 72 | + |
50 | 73 | // If you want to start from an empty file,
|
51 | 74 | // uncomment the next line:
|
52 |
| - // SD.remove(filename); |
53 |
| - |
| 75 | + // SD.remove(filename); |
54 | 76 | // try to open the file for writing
|
55 |
| - txtFile = SD.open(filename, FILE_WRITE); |
56 |
| - if (!txtFile) { |
| 77 | + |
| 78 | + myFile = SD.open(filename, FILE_WRITE); |
| 79 | + if (!myFile) { |
57 | 80 | Serial.print("error opening ");
|
58 | 81 | Serial.println(filename);
|
59 |
| - while (1); |
| 82 | + while (true); |
60 | 83 | }
|
61 | 84 |
|
62 | 85 | // add some new lines to start
|
63 |
| - txtFile.println(); |
64 |
| - txtFile.println("Hello World!"); |
| 86 | + myFile.println(); |
| 87 | + myFile.println("Hello World!"); |
| 88 | + Serial.println("Starting to write to file..."); |
65 | 89 | }
|
66 | 90 |
|
67 | 91 | void loop() {
|
68 | 92 | // check if it's been over 10 ms since the last line added
|
69 | 93 | unsigned long now = millis();
|
70 | 94 | if ((now - lastMillis) >= 10) {
|
71 |
| - // add a new line to the buffer |
72 |
| - buffer += "Hello "; |
73 |
| - buffer += now; |
74 |
| - buffer += "\r\n"; |
75 |
| - |
| 95 | + // add a new line to the dataBuffer |
| 96 | + dataBuffer += "Hello "; |
| 97 | + dataBuffer += now; |
| 98 | + dataBuffer += "\r\n"; |
| 99 | + // print the buffer length. This will change depending on when |
| 100 | + // data is actually written to the SD card file: |
| 101 | + Serial.print("Unsaved data buffer length (in bytes): "); |
| 102 | + Serial.println(dataBuffer.length()); |
| 103 | + // note the time that the last line was added to the string |
76 | 104 | lastMillis = now;
|
77 | 105 | }
|
78 | 106 |
|
79 | 107 | // check if the SD card is available to write data without blocking
|
80 |
| - // and if the buffered data is enough for the full chunk size |
81 |
| - unsigned int chunkSize = txtFile.availableForWrite(); |
82 |
| - if (chunkSize && buffer.length() >= chunkSize) { |
| 108 | + // and if the dataBuffered data is enough for the full chunk size |
| 109 | + unsigned int chunkSize = myFile.availableForWrite(); |
| 110 | + if (chunkSize && dataBuffer.length() >= chunkSize) { |
83 | 111 | // write to file and blink LED
|
84 | 112 | digitalWrite(LED_BUILTIN, HIGH);
|
85 |
| - txtFile.write(buffer.c_str(), chunkSize); |
| 113 | + myFile.write(dataBuffer.c_str(), chunkSize); |
86 | 114 | digitalWrite(LED_BUILTIN, LOW);
|
87 |
| - |
88 |
| - // remove written data from buffer |
89 |
| - buffer.remove(0, chunkSize); |
| 115 | + // remove written data from dataBuffer |
| 116 | + dataBuffer.remove(0, chunkSize); |
90 | 117 | }
|
91 | 118 | }
|
0 commit comments