I'm currently trying to read data from the serial monitor and write it to a file on the SD card using the rough structure below:
// setup everything
// main program
// -- read string from serial monitor byte by byte until we get cr or nl
// -- once our string is finished, echo to serial
// -- open sd card file and append the string to the end (and close the file)
Everything works fine if I initialise the file from within the setup loop:
File dataFile
void setup() {
<snip ...>
dataFile = SD.open("log0.txt", FILE_WRITE);
}
and then write to it in the main loop:
void loop() {
<snip ...>
dataFile.println("string");
dataFile.flush();
}
However if I try initialising the file within the main loop (as in the examples) I end up with weird ascii characters at the end of my character array.
void loop() {
<snip ...>
File dataFile = SD.open("log0.txt", FILE_WRITE);
// if the file is available then write to it
if (dataFile) {
dataFile.println(str);
dataFile.close();
}
// if the file isn't open then pop up an error
else {
Serial.println("error opening datalog.txt");
}
}
Could anybody explain this behaviour to me? At the moment I am working around it by not closing the file and instead calling flush() after I have tried to write the string to the file to ensure all the data is written. However, I know this isn't best practice and I am sure this will come back to bite me ...
I have provided the complete programs below for reference.
Thanks,
Alex
Working:
#include <SD.h>
// chip select is pin 4 on the ethernet shield
const int chipSelect = 4;
// the maximum data buffer is 1024 bytes
const int dataSize = 256;
// initialise data buffer
byte buff[dataSize];
int ix;
byte cr = 13; // carriage return
byte nl = 10; // new line
File dataFile;
void setup() {
// setup serial port
Serial.begin(9600);
Serial.println("serial comms working ...");
// initialise ...
ix = 0;
pinMode(10, OUTPUT);
// see if the card is present and can be initialized
if (!SD.begin(chipSelect)) {
return;
}
Serial.println("card initialized ...");
// for some reason opening the sd card file in the main loop goes weird.
// characters in the serial monitor are strange
dataFile = SD.open("log0.txt", FILE_WRITE);
}
void loop() {
// check that the serial port has data waiting to be read
while (Serial.available() > 0) {
// read a byte and, if it's not the line ending character,
// add it to the buffer
byte inByte = Serial.read();
if (inByte != cr && inByte != nl) {
buff[ix] = inByte;
ix++;
}
else {
// string conversion
char str[ix-1];
for(int i = 0; i < ix; i++) {
str = (char)buff;
}
// Serial output
Serial.print("echo >>> ");
Serial.println(str);
// if the file is available then write to it
if (dataFile) {
dataFile.println(str);
dataFile.flush();
}
// if the file isn't open then pop up an error
else {
Serial.println("error opening datalog.txt");
}
// reset the index
ix = 0;
}
}
}
Producing weirdness:
#include <SD.h>
// chip select is pin 4 on the ethernet shield
const int chipSelect = 4;
// the maximum data buffer is 1024 bytes
const int dataSize = 256;
// initialise data buffer
byte buff[dataSize];
int ix;
byte cr = 13; // carriage return
byte nl = 10; // new line
void setup() {
// setup serial port
Serial.begin(9600);
Serial.println("serial comms working ...");
// initialise ...
ix = 0;
pinMode(10, OUTPUT);
// see if the card is present and can be initialized
if (!SD.begin(chipSelect)) {
return;
}
Serial.println("card initialized ...");
}
void loop() {
// check that the serial port has data waiting to be read
while (Serial.available() > 0) {
// read a byte and, if it's not the line ending character,
// add it to the buffer
byte inByte = Serial.read();
if (inByte != cr && inByte != nl) {
buff[ix] = inByte;
ix++;
}
else {
// string conversion
char str[ix-1];
for(int i = 0; i < ix; i++) {
str = (char)buff;
}
// Serial output
Serial.print("echo >>> ");
Serial.println(str);
// open the file. note that only one file can be open
// at a time so you have to close this one before
// opening another.
File dataFile = SD.open("log0.txt", FILE_WRITE);
// if the file is available then write to it
if (dataFile) {
dataFile.println(str);
dataFile.close();
}
// if the file isn't open then pop up an error
else {
Serial.println("error opening datalog.txt");
}
// reset the index
ix = 0;
}
}
}