SD card recording a timestamp: Error on second sync

I am building a device that converts a manual glue machine (pressing a foot pedal to run the machine) to a digital one where pressing a button runs the whole system through a cycle. The buttons, microswitches, and everything physical works correctly. However, when I run the program once everything is fine. Then when i trigger the Go button a second time, the SD bonks out “error:sync”

The program is a mishmash of code from SDFat’s append example and RTClib’s clock example.

I am trying to record a timestamp of everytime the Go button is pressed. Any idea what is going wrong?


This code is to be used with the portionator glue machine device 
which uses a push button to run a full stroke of glue as well as
record the time and date the glue stroke was requested. This is
stored to an SD card that can be used to monitor the machine usage.
#include <SdFat.h>
#include <SdFatUtil.h> // use functions to print strings from flash memory
#include <Wire.h>
#include "RTClib.h"

Sd2Card card;
SdVolume volume;
SdFile root;
SdFile file;

#define ECHO_TO_SERIAL 1 //echo data to serial

// store error strings in flash to save RAM
#define error(s) error_P(PSTR(s))

void error_P(const char* str) {
  PgmPrint("error: ");
  if (card.errorCode()) {
    PgmPrint("SD error: ");
    Serial.print(card.errorCode(), HEX);
    Serial.println(card.errorData(), HEX);
// these constants won't change:

const int RetractSwitch = 3; //the microswitch is closed when the cylinder is retracted
const int ExtendSwitch = 4; //the microswitch is closed when the cylinder is fully extended
const int RunLEDPin =5; //This is the RED LED output pin indicating the machine is running
const int TransPin = 6; //This is the pin which activates the solenoid through the transistor
const int GoSwitch = 7; //This is the push button that when closed, activates the glue dispense sequence.

// Variables will change:
// int buttonPushCounter = 0;   // counter for the number of button presses
int GobuttonState = 0;         // current state of the button
int RunState = 0;      //Indicates if the system is running 0 = off, 1 = on
int StrokeComplete = 0; // '1' Indicates that the extend of stroke micro has been pressed but the system has not fully retracted. 
int ExtendSwitchState = 0; // Extend switch = 0 if not compressed indicating not at end of stroke
int RetractSwitchState = 0; // Retract switch =0 if not compressed indicating not at start position

void setup() {
  pinMode(RetractSwitch, INPUT);
  pinMode(ExtendSwitch, INPUT);
  pinMode(RunLEDPin, OUTPUT);
  Serial.begin(9600);  // initialize serial communication:

  //This section can be activated, compiled and uploaded to set the clock.
  // if (! RTC.isrunning()) {
  //  Serial.println("RTC is NOT running!");
    // following line sets the RTC to the date & time this sketch was compiled
  //  RTC.adjust(DateTime(__DATE__, __TIME__));

              // initialize the SD card at SPI_HALF_SPEED to avoid bus errors with
                // breadboards.  use SPI_FULL_SPEED for better performance.
                if (!card.init(SPI_HALF_SPEED)) error("card.init failed");
                //                 initialize a FAT volume
                if (!volume.init(&card)) error("volume.init failed");
                // open the root directory
                if (!root.openRoot(&volume)) error("openRoot failed");
                char name[] = "GLUEUSE.TXT";
                PgmPrint("Appending to: ");
                // clear write error
                file.writeError = false;
                  // O_CREAT - create the file if it does not exist
                   // O_APPEND - seek to the end of the file prior to each write
                  // O_WRITE - open for write
                  if (!, name, O_CREAT | O_APPEND | O_WRITE)) {
                    error("open failed");
void loop() {

//The system is not running, so check to see if the button is pressed
  if(RunState == 0) { //This makes sure the system is not already activated. This is reset to 0 when the system has triggered both micros (extended and then retracted)
  GobuttonState = digitalRead(GoSwitch);
    // if the button is pressed, run the glue dispenser
      if (GobuttonState == HIGH) {
            DateTime now =;    
            RunState = 1;
            digitalWrite(RunLEDPin, HIGH); //Turns on the RED LED to indicate the machine is running
            digitalWrite(TransPin, HIGH); //Turns on the solenoid
            //Write the timestamp to the SDcard

                  // print time to file
                      file.print(now.year(), DEC);
                      file.print(now.month(), DEC);
                      file.print(, DEC);
                      file.print(' ');
                      file.print(now.hour(), DEC);
                      file.print(now.minute(), DEC);
                      file.println(now.second(), DEC);
                  if (!file.sync()) error("sync");
                  Serial.println("Done Syncing.");
                  if (file.writeError) error("write failed");
                  if (!file.close()) error("close failed");              
//The system is running and we are looking to see if we have fully extended the cylinder
  if (RunState == 1) { //If the system has been activated
      if (StrokeComplete == 0) { // This system has not already reached the end of stroke microswitch
          Serial.println("Looking for end of stroke"); 
          ExtendSwitchState = digitalRead(ExtendSwitch);
          if (ExtendSwitchState == 1) { //This indicates the system is running and has reached the end of the glue stroke
             Serial.println("End of stroke found"); 
             digitalWrite(TransPin, LOW); // Begins to retract the cylinder
             StrokeComplete = 1; //We have completed a stroke. This is set to zero when we reach the return position

// The system is running and we have reached the end of the stroke. We are looking to see if we are back in the original position  
  if (StrokeComplete == 1) { //This indicates we are in the middle of back stroke
     Serial.println("Looking for return to start"); 
     RetractSwitchState = digitalRead(RetractSwitch);
     if (RetractSwitchState == 1) { //This indicates we have reached the end of stroke and need to reset for next stroke
       digitalWrite(RunLEDPin, LOW);
       StrokeComplete = 0;
       ExtendSwitchState = 0;
       RunState = 0;
       Serial.println("Stroke Complete");

You close the file after the first sync. When you try to sync the closed file you get an error.

Move the file opening code to the beginning of the cycle instead of in setup().