Using SD card and external clock in the same sketch

I wrote myself a simple utility (a) to verify the presence and readability of an SD card and extract information from a file on it; and/or (b) to check, and if necessary re-set, the time in an external clock. Each part works on its own (if I comment out the other part), and there are no common variables.

When both parts are left operational, the program fails to read the clock time. Narrowing down which lines are causing the problem, it seems that calls to read files on the SD card somehow disable the ability to read the external clock. This puzzles me (as a helpless novice), because I thought communication with the SD card reader used SPI (via the SD library), while the clock used I2C (via the Wire library).

Can anyone help me to get going again, please?

[sarcasm]
The problem is probably in line 25 of your code that you have not posted.
[/sarcasm]

You have, of course, read Read this before posting a programming question ... - Programming Questions - Arduino Forum in particular point 6 of the first post.

Please take the hint and post your whole program or a shorter example that exhibits the problem.

HeliBob,

I assumed that since both parts work independently, the problem lies not with the code but with my misunderstanding of how the two processes might interact.

However, here is the code. To avoid confusing everyone with code that I haven't yet cleaned up, I have omitted the function declarations. They definitely work OK.

void setup()
{ 
  pinMode(CardDetect, INPUT);  // Card Detect on pin 6.
  pinMode(greenLED, OUTPUT);   // To indicate ready or error status via green LED on pin 5.
  pinMode(10, OUTPUT);         // CS (chip select) pin 10.

  Wire.begin();  //initializes  the Wire library and joins the I2C bus as master (because parameter not specified)
} 

// --------------------------------------------------------------------------------------------------------------------------------
void loop()
{
  Serial.begin(9600); // Initializes the Serial library.  
  Serial.println("Ready to check Ardulog RTC: (a) set-up and SD card, (b) clock time.");
  Serial.println("Enter a or b in the box above and press Return.");
  while(!Serial.available()) 
   {
     error();
   }    
  char aorb = Serial.read();
  
  if(aorb=='a')
  {
  //Checking set-up and SD card 
  Serial.println("Checking set-up and SD card.");
  delay(50);
   
  // Check SD card present. LOW on pin A2 (card detect pin) means a card is inserted.
  if(digitalRead(CardDetect) == HIGH) 
  {   
     Serial.println("ERROR: no SD card");
     while(digitalRead(CardDetect) == HIGH)
     {
       error();
     }
     Serial.println("SD card detected.  Checking card and contents.");
  }

  // OK, so SD card is present. Check whether card can be written to.  Returns true on success, false on failure.
  while(!SD.begin(10))   // NB the optional parameter "10" indicates which is the CS pin.  On the Ardulog, pin 10 is hard-wired to select the SD card reader.
  {
   error(); // ERROR: can't write to card.  Flash green LED in warning mode until problem rectified.
  }    


  // SD card is present and useable if we reach this line.  Now need to read config.txt file.
  // First check whether config.txt file exists on the SD card.
  if(SD.exists("config.txt"))
  {
    Serial.println("OK, config.txt file found on SD card"); 
  }
  else
  {
    Serial.println("No config.txt file found on SD card"); 
  }
  while(!SD.exists("config.txt")) 
  {
    error(); // ERROR: No config.txt file.  Flash green LED in warning mode until problem rectified.
  }
  configFile = SD.open("config.txt", FILE_READ);
  for (int c=0; c<6; c++)       // Start reading file.
  {
    char k = configFile.read(); // Read number of bytes prescribed by loop.
    if(k == '\n' || k == EOF)
    {
      error();                  // If line end or EOF is reached unexpectedly, go into ERROR mode until problem rectified.
    }
    else
    {
      siteID[c] = k;            // If not yet line end or EOF, write the next character to string.
    }
  }     
  siteID[6] = '\0';             // Write string terminator.
  Serial.print("Logger ID: ");
  Serial.println(loggerID);
  char x = configFile.read();   // Read and ignore next character (can be any white space character such as new line '\n').
  char y = configFile.read();   // Read and ignore next character (can be any white space character such as new line '\n').
  for (int j=0; j<3; j++)       // Now continue reading more bytes as prescribed by fresh loop.
  {
    char o = configFile.read(); // Read number of bytes prescribed by loop.
    if(o == '\n' || o == EOF)
    {
      error();                  // If line end or EOF is reached unexpectedly, go into ERROR mode until resolved.
    }
    else
    {
      operatorID[j] = o;        // Write the character to string.
    }
  }
  operatorID[3] = '\0';         // Write string terminator.
  Serial.print("Operator : ");
  Serial.println(operatorID);
  configFile.close();  // Close config file again immediately.

  Serial.println("Set-up and SD card OK.");
  }
  
  if(aorb=='b')
  digitalWrite(10,HIGH);
  {
  // Check clock time
  do
  {
    getRTCdata(seconds,minutes,hours,dow,days,months,years);
    getdateString(dow,days,months,years);
    gettimeString(hours,minutes,seconds);
    Serial.println(dateString + "," + timeString);
    Serial.println("Is date and time OK?  Type y or n in command box above, followed by Return");
    while(!Serial.available()) 
      {
        signal();
      }    
    char option = Serial.read();
    if(option=='n')
      {
      Serial.println("Remove SD card from Ardulog RTC to enable date/time reset");
      while(digitalRead(CardDetect) == LOW) 
      {
        error();
      }   
      Serial.println("Now enter date and time in this format: DD/MM/YY HH:MM:SS d");
      Serial.println("where d=day of the week:  Sun=1  Mon=2  Tue=3  Wed=4  Thur=5  Fri=6  Sat=7");
      Serial.println("       Don't forget to press Return!");
      do 
      {
        signal();
      } while(!Serial.available());   
      for (int z = 0; z<19; z++)
       { 
        char inByte = Serial.read();
        datetime[z] = inByte;
       }
      setDateTime(datetime); //Calls function to reset clock
      }
  } while(option == 'n');
  reps=0;
  while(reps<500)
    {
      getRTCdata(seconds,minutes,hours,dow,days,months,years);
      getdateString(dow,days,months,years);
      gettimeString(hours,minutes,seconds);
      Serial.println(dateString + "," + timeString);
      reps++;
    }
  }
} // repeat void loop()

However, here is the code.

Or at least part of it. So we cannot see exactly what you have done or compile the code for ourselves.

UKHelibob,

I can't stand sarcasm from those in a position of superiority, so I spent the night figuring this out.

For those who may come across this short thread later, a kindlier response from you would have been as follows:

"It's not possible for us to tell exactly what is wrong, since you haven't provided the full code; but there have been several other threads on this forum seeking help on apparent conflicts like this. You might want to broaden your search terms to find them. These problems have typically turned out to be caused by competition for SRAM. The buffer of SD library alone consumes 25% of the available SRAM on an AtMega 328, and all your global variables, arrays, heap and stack go into SRAM too. If you can't cut down on global variables, etc, one way to free up some space is to write string constants to Flash memory, as described by John Wasser in this thread. A short function to check on the amount of free SRAM at different stages within your sketch can be found in this thread."

I am glad that you found the reason for the problem.

Yes, I was sarcastic but with good reason. You had provided little or no information and when asked to post your program you didn't do so, thus leaving us in the dark as to exactly what you had written. Very often a problem is not actually in the section of code that you think it is, hence the request to post all of the code.

Your suggested reply makes mention of the use of RAM to hold variables and in particular arrays, which is correct, but did you tell us how many variables and arrays you have of what type and size ? No.

Neither did you specify which Arduino you were using, which turned out to be very pertinent to the problem, and you had obviously not read the excellent advice to which I provided a link and which is plainly in view at the top of the forum page or if you did read it you chose to ignore it.

By the way, I do not consider myself in a position of superiority and if you think that my reply was harsh then think yourself lucky not to have got replies from some of the other members here.