1
+ /*
2
+ A small arduino program to log data from the UART port
3
+ to an SD card very quickly. Works at 115200 baud.
4
+
5
+
6
+ Files on the SD card are named LOG00000.TXT, LOG00001.TXT, etc
7
+ Each file is always 512,000 bytes, and the parts that have not been written to yet are all 0's
8
+
9
+ You can change the arduino's internal serial buffer at C:\Program Files (x86)\Arduino\hardware\arduino\cores\arduino\HardwareSerial.cpp
10
+ by changing the line "#define SERIAL_BUFFER_SIZE 64"
11
+ I had it set to 500
12
+
13
+
14
+ Adopted from the RawWrite.ino example found here:
15
+ https://github.com/greiman/FreeRTOS-Arduino/blob/master/libraries/SdFat/examples/RawWrite/RawWrite.ino
16
+
17
+ Also used code from OpenLog
18
+ https://github.com/sparkfun/OpenLog
19
+ */
20
+
21
+ #include < SdFat.h>
22
+ #include < SdFatUtil.h>
23
+
24
+ // SD chip select pin
25
+ #define chipSelect SS
26
+
27
+ // number of blocks in the contiguous file
28
+ const uint32_t BLOCK_COUNT = 1000UL ;
29
+
30
+ // make another file if the one fills up
31
+ uint32_t currBlock = 0 ;
32
+
33
+ // file system
34
+ SdFat sd;
35
+
36
+ // test file
37
+ SdFile file;
38
+
39
+ // file extent
40
+ uint32_t bgnBlock, endBlock;
41
+
42
+ // Serial output stream
43
+ ArduinoOutStream cout (Serial);
44
+ // ------------------------------------------------------------------------------
45
+ // store error strings in flash to save RAM
46
+ #define error (s ) sd.errorHalt_P(PSTR(s))
47
+ // ------------------------------------------------------------------------------
48
+
49
+
50
+ #define printn Serial.print
51
+ #define printf (...) Serial.print(F(__VA_ARGS__))
52
+
53
+
54
+ unsigned int bufferIndex;
55
+
56
+ uint8_t * pCache;
57
+
58
+
59
+ void makeFile (void )
60
+ {
61
+
62
+ // Search for next available log spot
63
+ char new_file_name[] = " LOG00000.TXT" ;
64
+ int new_file_number=0 ;
65
+ while (1 )
66
+ {
67
+ new_file_number++;
68
+
69
+ // There is a max of 65534 logs
70
+ if (new_file_number > 65533 )
71
+ {
72
+ printf ((" !Too many logs:2!" ));
73
+ return ; // Bail!
74
+ }
75
+
76
+ // Splice the new file number into this file name
77
+ sprintf (new_file_name, " LOG%05d.TXT" , new_file_number);
78
+
79
+ // Try to open file, if fail (file doesn't exist), then break
80
+ if (file.open (new_file_name, O_CREAT | O_EXCL | O_WRITE)) break ;
81
+ }
82
+
83
+ // Close the new file that was just opened
84
+ file.close ();
85
+
86
+ // delete existing file that was just created, so it can be recreated as continuous
87
+ sd.remove (new_file_name);
88
+
89
+
90
+ // create a contiguous file
91
+ if (!file.createContiguous (sd.vwd (), new_file_name, 512UL *BLOCK_COUNT)) {
92
+ error (" createContiguous failed" );
93
+ }
94
+ // get the location of the file's blocks
95
+ if (!file.contiguousRange (&bgnBlock, &endBlock)) {
96
+ error (" contiguousRange failed" );
97
+ }
98
+ // *********************NOTE**************************************
99
+ // NO SdFile calls are allowed while cache is used for raw writes
100
+ // ***************************************************************
101
+
102
+ // clear the cache and use it as a 512 byte buffer
103
+ pCache = (uint8_t *)sd.vol ()->cacheClear ();
104
+
105
+
106
+ // tell card to setup for multiple block write with pre-erase
107
+ if (!sd.card ()->erase (bgnBlock, endBlock)) error (" card.erase failed" );
108
+ if (!sd.card ()->writeStart (bgnBlock, BLOCK_COUNT)) {
109
+ error (" writeStart failed" );
110
+ }
111
+
112
+ printf (" begin:" );
113
+ printn (bgnBlock);
114
+ printf (" \n " );
115
+ printf (" end:" );
116
+ printn (endBlock);
117
+ printf (" \n " );
118
+ }
119
+
120
+
121
+ void setup (void ) {
122
+ Serial.begin (115200 );
123
+ while (!Serial) {} // wait for Leonardo
124
+
125
+
126
+ cout << pstr (" Free RAM: " ) << FreeRam () << endl;
127
+
128
+ // initialize the SD card at SPI_FULL_SPEED for best performance.
129
+ // try SPI_HALF_SPEED if bus errors occur.
130
+ if (!sd.begin (chipSelect, SPI_FULL_SPEED)) sd.initErrorHalt ();
131
+
132
+ makeFile ();
133
+
134
+ }
135
+
136
+ char chr;
137
+
138
+ // ------------------------------------------------------------------------------
139
+ void loop (void ) {
140
+
141
+
142
+ // write data
143
+ while (Serial.available ())
144
+ {
145
+
146
+ // read the data and record it in the buffer
147
+ chr=Serial.read ();
148
+
149
+ pCache[bufferIndex]=chr;
150
+ bufferIndex++;
151
+
152
+
153
+ // flush whenever the the buffer fills up, or when an 18 is recieved
154
+ if (bufferIndex==511 || chr==18 )
155
+ {
156
+
157
+ signed int t=millis ();
158
+
159
+ // write a 512 byte block
160
+ if (!sd.card ()->writeData (pCache))
161
+ {
162
+ error (" writeData failed" );
163
+ }
164
+
165
+
166
+ // log some info
167
+ printf (" flushing took " );
168
+ printn ((signed )millis ()-t);
169
+ printf (" ms\n " );
170
+ printn ((char )18 );
171
+ if (chr==18 ){
172
+ printf (" chr\n " );
173
+ }
174
+ if (bufferIndex==511 )
175
+ {
176
+ printf (" buf\n " );
177
+ }
178
+
179
+ // reset the count
180
+ bufferIndex=0 ;
181
+ currBlock++;
182
+ if (currBlock==BLOCK_COUNT){
183
+
184
+ if (!sd.card ()->writeStop ()) error (" writeStop failed" );
185
+
186
+ file.close ();
187
+ makeFile ();
188
+
189
+ currBlock=0 ;
190
+
191
+ }
192
+ }
193
+ }
194
+ }
0 commit comments