I'm trying to store some sensor values on an SD card, which I believe I'm able to do. I'd just like some help on understanding what the stock example code actually means.
Here are my questions:
In the create file section of my code, is it correct to say that I can create a text file "on the fly" with any name?
If so, is there a way I can write this at the top of my code, and then reference it, like a 'const int', but a 'const string', if that makes sense...?
Can I create several text files on the same card?
Here is my code
/*
SD card datalogger
The circuit:
*SONAR
pin 2 - sonar / Trigger
pin 3 - sonar / Echo
*SD card attached to SPI bus
pin 4 - SD card / CS
pin 11 - MOSI
pin 12 - MISO
pin 13 - CLK
*/
#include <SPI.h>
#include <SD.h>
#include <NewPing.h> // sonar library
const int chipSelect = 4;
int i = 0; // initialize loop counter
int a = 0; // void loop counter, it should run only once
int b = 0; // 1st element of array
int c = 0; // counter for printing array elements
// Sonar set up
#define TRIGGER_PIN 2 // Arduino trigger pin on sonar
#define ECHO_PIN 3 // Arduino echo pin on sonar
#define MAX_DISTANCE 200 /* Maximum distance we want to ping for (in centimeters).
Maximum sensor distance is rated at 400-500cm.
*/
// SONAR
NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE); // NewPing setup of pins and maximum distance.
// STRING
/* Make a string to log data */
String dataString = "";
// ARRAY
/* Make an array to log data */
const int array_size = 5;
double dataArray[array_size] = {}; // set array to size
void setup()
{
// Open serial communications and wait for port to open:
Serial.begin(9600);
while (!Serial)
{
; // wait for serial port to connect. Needed for native USB port only
}
Serial.print("Initializing SD card...");
// see if the card is present and can be initialized:
if (!SD.begin(chipSelect))
{
Serial.println("Card failed, or not present");
// don't do anything more:
return;
}
Serial.println("card initialized.");
}
void loop()
{
// run entire loop only once
for (a; a<1; a++)
{
// read and write sensor values for each conected pin per sensor
// record 5 readings of the sensors, so that there are 5 string lines
for (i; i<array_size; i++)
{
// read sensor values
// SONAR
delay(50); // Wait 50ms between pings (~ 20 pings/sec). 29ms should be min delay between pings
// initially, these types were 'unsigned int', but seemed to be no difference
int uS = sonar.ping(); // Send ping, get ping time in microseconds (uS)
double distance = (uS / US_ROUNDTRIP_CM) / 2.54; // Convert ping time to distance, 0 = outside set distance range
// units are converted from cm to inches
double sensor_value = distance;
// print to serial monitor
Serial.print("Distance: ");
Serial.print(distance); // units are in inches
Serial.println("in");
// add sonar values to string
dataString += String(sensor_value);
if (i < 4)
{
dataString += ",";
}
// add sonar values to array
if (b<array_size)
{
dataArray[b] = sensor_value;
b++;
}
}
// OPEN FILE
/* microSD card
Note that only one file can be open at a time,
so you have to close this one before opening another.
(But if you only have 1 card, no worries.)
*/
// CREATE FILE
File dataFile = SD.open("datalog.txt", FILE_WRITE);
//(file name, function)
// WRITE TO FILE
// if the file is available, write to it:
if (dataFile)
{
// CLOSE FILE
dataFile.println(dataString); //print to microSD card
dataFile.close();
// print string to serial monitor
Serial.println("\nString printed to microSD card:");
Serial.println(dataString);
// print array to serial monitor
Serial.println("\nArray printed to microSD card:");
for (c; c < array_size; c++)
{
Serial.print(dataArray[c]); // print value at current element position
// add a comma between elements, but not after last one
if (c < array_size - 1)
{
Serial.print(",");
}
}
// test: print only 1 element of array to serial monitor
Serial.println("\n");
Serial.print("3rd element in array: ");
Serial.println(dataArray[2]);
}
// if the file isn't open, pop up an error:
else
{
Serial.println("error opening datalog.txt");
}
}
}
This code is only questionable if the file was not in the 'root' directory of the SDcard.
for each File object you have open, there is an associated sector buffer, since a 512 byte sector is 1/4 of an Arduino's RAM realistically TWO files can be opened as once. If you use a Mega (8k RAM) more files can be concurrently accessed.
You can reuse (open/close) the File object as many times as you wish. But, you are limited by your RAM size the number of concurrently 'open' files.
Essentially, yes to both. You seem to be making things more difficult than they need be. There is a useful example included in the SD section of the IDE examples that should be all you need.
It need be no more than a matter of collecting the data files as you go round the loop, and printing them
myFile.print(var);
myFile print(",");
with a println for the last.
This gives you a comma separated set of data for later analysis.
You can have multiple files but only one open at a time. Open the file, print your stuff, and close the file - each trip round the loop. I think it is the safest, even if you only have one.