DS3231 loosing time

I am using a cheap DS3231 RTC.

reading from a CT to get current
using Emon from openEnergyMonitor
using an SD card with level shifter

lost 75 seconds overnight.
been searching and only found one reference in one post that said something about reading the RTC will effect it's timing. The post said he reads once a day. I assume he uses millis() and just adjusts for any discrepancy when evaluating the data.

I would be happy to be a second a day. or even two....

my second problem is that I have no display and if the SD card fails, no joy, no notification, and pin13 keeps blinking like it is writing.

// * analog sensors on analog ins 0, 1, and 2
// * I2C bus for RTC on A4 and A5
// * SD card attached to SPI bus as follows:
// ** MOSI - pin 11
// ** MISO - pin 12
// ** CLK - pin 13
// ** CS - pin 10

// libraries
#include <SD.h>
#include <SPI.h>
#include <EmonLib.h>
EnergyMonitor emon1;    // Create an instance
// rtc initialization  *********************************
#include "Wire.h"
#define DS3231_I2C_ADDRESS 0x68

byte decToBcd(byte val) // Convert normal decimal numbers to binary coded decimal
{
  return ( (val / 10 * 16) + (val % 10) );
}
// Convert binary coded decimal to normal decimal numbers
byte bcdToDec(byte val)
{
  return ( (val / 16 * 10) + (val % 16) );
}
//  end RTC initialization ******************************

// pin assignments

// A1 is assigned by emon
int led50 = 6;
int led100 = 7;
const int chipSelect = 10;

// global variables
int amps = 0;
double Irms ;
int datalog = 0;
int old_datalog = 0;
float IrmsDisplay ;

// fixed variables

void setup()
{
  Wire.begin();
  Serial.begin(9600);  
  pinMode(10, OUTPUT);
  pinMode(13, OUTPUT);

  emon1.current(1, 30);             // 1 = pin A1. 30 = fixed, CT has internal resistor.

  Serial.print("Initializing SD card...");

  if (!SD.begin(chipSelect)) {     // see if the card is present and can be initialized:
    Serial.println("Card failed, or not present");
    digitalWrite(13, HIGH);   // turn the LED on (HIGH is the voltage level)
    delay(2000);
    return;     // don't do anything more:

  }
  Serial.println("card initialized.");
}
//  RTC stuff ********************************
void readDS3231time(
  byte *second,
  byte *minute,
  byte *hour,
  byte *dayOfWeek,
  byte *dayOfMonth,
  byte *month,
  byte *year)
{
  Wire.beginTransmission(DS3231_I2C_ADDRESS);
  Wire.write(0); // set DS3231 register pointer to 00h
  Wire.endTransmission();
  Wire.requestFrom(DS3231_I2C_ADDRESS, 7);
  // request seven bytes of data from DS3231 starting from register 00h
  *second = bcdToDec(Wire.read() & 0x7f);
  *minute = bcdToDec(Wire.read());
  *hour = bcdToDec(Wire.read() & 0x3f);
  *dayOfWeek = bcdToDec(Wire.read());
  *dayOfMonth = bcdToDec(Wire.read());
  *month = bcdToDec(Wire.read());
  *year = bcdToDec(Wire.read());
}
void displayTime()
{
  byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;
  // retrieve data from DS3231
  readDS3231time(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month,
                 &year);
  // concatenate it for writing to SD card
  String dataString = "";   // make a string for assembling the data to log:

  dataString += String(hour, DEC );
  dataString += String(":");
  if (minute < 10) dataString += String(0);
  dataString += String(minute, DEC);
  dataString += String(":");
  if (second < 10) dataString += String(0);
  dataString += String(second, DEC);
  dataString += String(" " );
  dataString += String(dayOfMonth, DEC );
  dataString += String("/" );
  dataString += String(month, DEC );
  dataString += String( "/");
  dataString += String( year, DEC);
  dataString += String(", - " );
   //  add value from CT sensor
  dataString += (IrmsDisplay);
  dataString += " amps,";

  File dataFile = SD.open("datalog.txt", FILE_WRITE);

  // if the file is available, write to it:
  if (dataFile) {
    dataFile.println(dataString);
    dataFile.close();
    // print to the serial port too:
    Serial.println(dataString);
  }

}



// end  RTC stuff ********************************

void loop() {

  // ***** EMON
  //  double Irms = emon1.calcIrms(1480);  // Calculate Irms only // declared in inilitalization
  Irms = emon1.calcIrms(1480);  // Calculate Irms only
  IrmsDisplay = Irms;
  if (Irms <= .25) {                 // added for zero dropout
    IrmsDisplay = 0;
  }


  // ******************************************************************************************

  //  the following is how to pick a time to create a flag on when to write to the SD card.


  if (amps >= 50) {
    datalog = HIGH;
    digitalWrite(led50, LOW);
  }
  if (amps <= 40) {
    datalog = LOW;
    digitalWrite(led50, HIGH);
  }
  if (amps >= 100) {
    datalog = HIGH;
    digitalWrite(led100, LOW);
  }
  if (amps <= 80) {
    datalog = LOW;
    digitalWrite(led100, HIGH);
  }

  if (datalog != old_datalog)
    // do data log routine
    //  final bits of code go here

    old_datalog = datalog;

  // ****** end EMON *************************************************

  displayTime(); // display the real-time clock data on the Serial Monitor,
  delay(1000); // every second
  Serial.println();


  //  end RTC =======================================================


}

You probably bought either a fake DS3231, or an out of spec reject.
The genuine ones keep time to 1-2 seconds/month.

Sounds like you got a faulty DS3231. It should be accurate to about 63 seconds a YEAR (2 parts per million, 31.5 million seconds a year).

Your second problem is because of this:

    return;     // don't do anything more:

When you return from setup(), your code immediately starts going through the loop().
If you want the code to stop here, change "return;" to "while(1);"

Pete

lost 75 seconds overnight.
been searching and only found one reference in one post that said something about reading the RTC will effect it's timing.

That happens when the time between "start" of I2C transaction for reading the RTC and "stop" is longer than 1 second. That is an abnormal situation, of course..
Double check your 3V backup battery..