SD card not reaching IDLE state

Here’s a rough draft of some code I’m working on to store variables on an SD card:

#include <SD.h>
#include <string.h>
#include <SdFile.cpp>

Sd2Card card;
SdVolume volume;
SdFile root;

/*
        ENCODING OF "TheJohnson" MUST BE UTF8!!!!!      
*/


void setup() {
  Serial.begin(9600);//Baud = 9600 for serial :)
  Serial.print(F("Total RAM available: "));
  Serial.println(FreeRam()); //this line can be placed anywhere in the code.
                             //if the number printed is less than 5% of total, we're doomed

  //the following two lines are necessary for some reason.
  pinMode(10,OUTPUT);
  //digitalWrite(10,HIGH);
  //I actually have a 10,000 v actuator tied to pin 10... so I'm gonna have to fix that library somehow 
  digitalWrite(A1,HIGH);
  digitalWrite(A0,LOW);
  
  if (!card.init(SPI_HALF_SPEED,A0)) //we're using pin A0 for the SD_CE, baby
    Serial.println(F("failure to initialize card."));
    
  if (!volume.init(&card)) //Just making sure it's fat.
    Serial.println(F("failure to initialize volume."));
    
  Serial.print(F("It's really FAT")); //in case you were wondering...
  Serial.println(volume.fatType(),DEC); //this is the fat type.
  
  
  
  //root.ls(LS_R); //Built in arduino function for printing all folders/subdirectories
  Serial.println(F("Finished with setup."));
}

//Store indecies as uint8_t. 
//The goal is to trim all my "long"s to just 1 byte each in ROM
//these will be like "reference variables" for our SD card stuff
//Here's an example var:
//int8_t dloca = 0; //10
//Here's an example file contents:
/*
,10,44,100000000,3,it's a string!,somestuff,9,0,a,
*/
//in that file, all the numbers will be accessible, but the strings will return -1.




void loop() {
  float TestVariable;
  if (!root.openRoot(&volume)) //opening root
    Serial.println(F("failure to open the root"));
  for (uint8_t i = 0; i <= 8; i++)
  {
    Serial.print("Index ");
    Serial.print(i);
    Serial.print(": ");
    TestVariable = getMyFloat(i);
    Serial.println(TestVariable);
  }
  while(true);  
}

//Trying to get variables from the SD card...
//The first character in the file will be the delimiter, so don't screw that up.
//this function is heavily dependent on careful handling of MAINCONF.ZAC, 
//  hereafter known as TheJohnson
//The argument, "offset", is the number of delimiter characters to pass before 
//  reaching the desired value (first character not included)
//The function will return the desired value, or -1 if there was a datatype error, 
//  or something else if there was a worse error
//Right now, only positive integers work.
long getMyFloat(uint8_t offset) 
{
  SdFile TheJohnson; 
  int16_t delimiter;
  uint32_t Startpos;
  uint8_t numDigits = 0;
  long ThePower;
  long desiredValue = 0;
  if (!TheJohnson.open(root, "MAINCONF.ZAC", O_READ))
    Serial.println(F("Failure to open The Johnson"));
  else 
  {
    TheJohnson.rewind();
    delimiter = TheJohnson.read();
    //Serial.print(F("Delimiter:")); Serial.println((char)delimiter); //for debugging
    int16_t c = 0;
    for (uint8_t n = 0; n < offset; n++) 
      while (((c = TheJohnson.read()) > -1 && (c != delimiter)));
    Startpos = TheJohnson.curPosition();
    //we're at the first byte of the thing we want. 
    //First we need to know how many digits it has.
    while (((c = TheJohnson.read()) > 0) && (c != delimiter))
    {
      ++numDigits;
    }
    TheJohnson.rewind(); //going back to the top of TheJohnson
    TheJohnson.seekSet(Startpos); //going back to previous spot on TheJohnson
    
    //Time to try to concatenate some single-digit numbers:
    for (uint8_t n = numDigits-1; n >= 0; n--) 
    { //n goes to zero to make powers easier to calculate
      c = TheJohnson.read();
      if ((c < 0) || (c == delimiter)) {
        Serial.println(F("Delimiter detected prematurely. Make sure text encoding is UTF8"));
        return(-1);
      }
      if ( c >= 48 && c <= 57 ) 
      {
        c = c - 48;
      }
      else 
      {
        Serial.println(F("A bad character was detected. Values MUST be positive integer."));
        return(-1);
      }
      ThePower = 1;
      for (uint8_t pow = n; pow > 0; pow--) //this is where we calculate the power
        ThePower *= 10; //i did it this way so I wouldn't have to include math.
      desiredValue = desiredValue + ((float)c * ThePower); 
    }
    return(desiredValue);
  }
  return(-1);
  
}

It’s pretty long… Sorry about that. The initialization is on top, where it should be.

I’ve got pin 10 set to output, and I’ve tried setting it high. I am using pin A0 as my CS, and it’s being driven low. I have another device on A1, which is being deselected for this code. My SD card is FAT32 with 16kb allocation, and works on Windows. I’m not using a breakout. The whole board is custom and has a little SD reader thingy on the side; I’m just using the Arduino IDE and bootloader to make programming my Atmega easier.

I get:
“Failed to initialize SD card.”
followed by multiple subsequent failures.
I put a couple error flags in Sd2Card.cpp. My SD card fails the first check for entering IDLE state. (library line ~245)

The code worked perfectly up until about an hour ago, no errors, and now it just doesn’t work. I’m really hoping I didn’t break something.

Give it to me straight, doc. Is she gonna live?

My SD card is FAT32 with 16kb allocation, and works on Windows.

But not on the Arduino. Format your card using the format example provided with the SD library. It won't be FAT32.

Thanks! I got it fixed :slight_smile: