|
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