File.read() prints out -1's

Hello,

I'm working with an arduino mega 2560. I have a string and 4 ints that I'm saving to my SD card. The string is an rfid card scan and the 4 ints are bools that control 4 relays. I am saving the data to a file on the card as a comma delimited string that looks like this: "1234567,0,0,1,1". When I power down the device and take out the card, the values are all stored correctly on the file. They are saving to the sd card in case of a power failure. I didn't want to use EEPROM because I need the data to be as up-to-date as possible, and every time an led comes on or a card is scanned, the file gets removed then created and re-populated with the new string.

My problem is, when I try to read the contents of the file, right now I'm just doing Serial.println(f.read()); all I get is a bunch of lines with "-1" on them.

Here is a scaled down version of the code. this should only be code for the file handling. the rest of my code just calls the sdWrite() function:

#include <Arduino.h>
#include <PLDuino.h>
#include <SimpleTimer.h>
#include <SPI.h>
#include <SD.h>
#define FILENAME "data.tmp"

bool sdInit()
{
	if (!SD.begin(PLDuino::SD_CS))
	{
		Serial.println("Failed to initialize SD card. Please check it.");
		return false;
	}
	return true;
}

bool sdWrite(bool fileCreate)// Trying to create a file
{
	Serial.println("Creating a file...");

	if(SD.exists(FILENAME))
	{
		Serial.println("remove");
		SD.remove(FILENAME);
	}

	// Opening a file for writing...
	File f = SD.open(FILENAME, FILE_WRITE);
	if (!f)
	{
		// Stop on error
		Serial.println("Failed to create " FILENAME " file. Stop.");
		f.close(); // close when done
		return false;
	}
	else
	{
		Serial.println("create");
		if(!fileCreate)
		{
			Serial.println("write file");
			f.print(RFID);
			f.print(",");

			f.print(led1);
			f.print(",");
			f.print(led2);
			f.print(",");
			f.print(led3);
			f.print(",");

			f.print(relay);
			f.println();
		}
	} 
	f.close(); // close when done
	return true;
}

String sdRead()// Trying to read a file
{
	Serial.println("Re-opening the file for reading...");

	// Trying to open our file.
	File f = SD.open(FILENAME, FILE_READ);
	if (!f)
	{
		// Stop on error
		Serial.println("Failed to open newly created file " FILENAME ". Stop.");
		f.close(); // close when done
		return "false";
	}

	Serial.println("File contents: ");
	// Read out file contents and print them to Serial.
	String fileString = "";
	int count = 0;
	while(!f.available())
	{
		//fileString += f.read();
		Serial.println(f.read());
		if(count > 100)
		{
			return "";
		}
		count++;
	}
	Serial.println("end of open");
	return fileString;
	f.close(); // close when done
}

void setup()
{
	if(initOK)
	{
		bool initOK = sdInit();
		Serial.println("initOK");
		bool writeOK = sdWrite(true);
		if(writeOK)
		{
			Serial.println("writeOK");
			String readStr = sdRead();
			if(readStr != "")
			{
				readStr.trim();
				String readParse[5] = {"","","","",""};
				int counter = 0;
				String temp = "";
				for(int x = 0; x < readStr.length(); x++)
				{
					char readChar = readStr.charAt(x);
					if(readChar == ',')
					{
						readParse[counter] = temp;
						temp = "";
						counter++;
					}
					else
					{
						temp += readChar;
					}
				}
				RFID = readParse[0];
				setVars(readParse[1].toInt(), readParse[2].toInt(), readParse[3].toInt(), readParse[4].toInt(), 0, 0);
			}
		}
	}
}
	while(!f.available())
	{
		//fileString += f.read();
		Serial.println(f.read());

The available() method does not return a boolean. Don't treat the return value like a boolean.

PaulS:

	while(!f.available())
{
	//fileString += f.read();
	Serial.println(f.read());



The available() method does not return a boolean. Don't treat the return value like a boolean.

ah, that was another piece to the puzzle. One thing I figured out since my post, thats kind of a stupid mistake, is I forgot to put an if statement around the part where I delete the file. the function that I delete the file in is called in setup(), so it was deleting before reading.

Now I'm getting data through, but its not the data that I'm expecting. this is the string I'm getting now:
5057514852504844484448444844481310

I think I got it now. I've been working a lot with serial devices lately, and I recognized the last 4 characters of that string as "\r\n". I put it into notepad++ and split it up into groups of 2 to see if there was any redundancy. this is what that looks like:
50 57 51 48 52 50 48 44 48 44 48 44 48 44 48 13 10

Converting that over to a string gives me the exact data I need. so now I just need to figure out how to implement that in arduino.

You print and read text, it is ASCII code. You can look up ascii table and pick from many, but you only need the first 128 chars, 0 to 127 for your needs.

'0' is 48, '9' is 57, '9' - '0' is 9

'A' is 65 and 'a' is 65 + 32. In bitmath, 32 is bit 5 ON.

PS

50 57 51 48 52 50 48 44 48 44 48 44 48 44 48 13 10

Converting that over to a string gives me the exact data I need. so now I just need to figure out how to implement that in arduino.

Make a char array buffer big enough to hold any line you're likely to read.

char fileText[ 80 ]; // overkill?

As you read chars from file, fill the buffer making sure not to fill past the length-1 so the end is always zeros. That makes the buffered text into a text string (not String, AVOID those).

You can then Serial.print( fileText );

50 57 51 48 52 50 48 44 48 44 48 44 48 44 48 --- is 2930420,0,0,0,0 44 is ASCII comma

I'd use a state machine to parse that as it arrives. Some people would buffer the string and then use string.h functions (like strtok() and atoi()) to parse and lex the values out. My way, it's done very shortly after the last char is read, the other way the hard part begins after the last char is read but hey, that's what they teach in school so it must be "the right way".

	while(!f.available())
	{
		Serial.println(f.read());

"While nothing is available for read, read some stuff." f.read() does not block - it returns -1 when there's nothing available.

Thanks everybody! its working great now! I'm definitely learning more and more about arduino the more I am working with them. And despite the one mistake of forgetting the if, which I blame on working for 12 hours today lol, the other ones were ones I probably wouldn't have thought of right away as I'm still not entirely familiar with some of this stuff and was going off of an example that I now know was not a good example!

Working on code when you're tired is a great way to add more bugs than you remove.

But it's the "tired's" fault.. I've known boss/managers that demanded long days but when you boss yourself do you get out of not doing it again?