ESP32 Data Logger Issue: RTC and SD Card Conflict

Hello everyone,

I'm working on a data logger project using an ESP32 microcontroller. I have successfully interfaced the following components:

  1. Temperature Sensor(NTC)
  2. Current Sensor
  3. Voltage Sensor
  4. RTC Module (DS1307)-->I2c
  5. SD Card Module--->SPI
  6. Bluetooth Module

Observations:

  • The SD card works fine when interfaced with the temperature, voltage, current sensors, and Bluetooth module.
  • The RTC module (DS1307) also works correctly when used with the temperature, voltage, current sensors, and Bluetooth module.

Issue:

When I use the RTC and SD card together, I encounter the following problems:

  1. The SD card gets corrupted after some time.
  2. The RTC shows incorrect date and time during operation.

Additional Details:

  • Both the SD card and RTC modules work perfectly in standalone tests.
  • The issue only arises when both components are used simultaneously.
#include <esp_task_wdt.h>
#include "Measurements.h"
#include "SDcard.h"
#include "RTClib.h"
#include "Wire.h"
#include <string.h>
DS1307 rtc;
String Date = " ";
String Time = " ";
//Pin 
#define currentSensor 33
#define voltageSensor 32
#define temperatureSensor 35
#define WDT_TIMEOUT 3
#define LED 26
#define LED2 10
#define BUILTIN_LED 2
#define timeIntervalForBT 1000
#define interrupt_pin 34
int sensorPin = 13;

// Time specific
#define timeIntervalForBT 1000
unsigned long startTime;
unsigned long lastTime;

uint64_t lastTick = 0;
uint64_t diff = 0;
// Flags
bool SDCAvailable = false;
bool logging = false;

// Global Vars
File file;
String filename = "/datalog.csv";
 int kmph =0;
// debug
bool stateL = false; 
//SWS
int td=0;
float a=0;
int present =1;
int prev =1;
int present_Time = 0;
int prev_Time=0;

//Speed 
volatile uint16_t call_counter = 0;
volatile uint16_t counter = 0;
uint32_t last_interrupt_time = 0;
uint32_t last_rising_time = 0;
uint32_t rising_diff = 0;

DateTime rtc_get_time() {
    return rtc.now();
}

// Function to check RTC connection by attempting communication
bool checkRTCConnection() {
  Wire.beginTransmission(0x68); // DS1307 RTC I2C address is 0x68
  uint8_t error = Wire.endTransmission();
  
  // If there is no error, the RTC is connected
  return (error == 0); 
}
// Function to initialize the RTC
void initializeRTC() {
  if (!rtc.begin()) {
    Serial.println("RTC initialization failed! Check connections.");
    return; // Don't halt execution; allow reconnection attempts
  }

  if (!rtc.isrunning()) {
    Serial.println("RTC is not running. Setting current time...");
    rtc.adjust(DateTime(F(__DATE__), F(__TIME__))); // Set RTC to compile time
    Serial.println("RTC time has been set.");
  }
}
void IRAM_ATTR isr(){
  //interrupt function for speed
  // delayMicroseconds(10);
//  digitalWrite(LED, LOW);
  call_counter++;
  uint32_t current_time = millis();
  uint32_t interrupt_diff = current_time - last_interrupt_time;
  last_interrupt_time = millis();
  if (interrupt_diff < 10){
    return;
  }
  delayMicroseconds(10);
  if (digitalRead(interrupt_pin) == 0){
    return;
  }
  // digitalWrite(onboard_led, !(digitalRead(onboard_led)));
  rising_diff = millis() - last_rising_time;
  counter++;
  last_rising_time = millis();
}
void setup() {
  // put your setup code here, to run once:
  esp_task_wdt_init(WDT_TIMEOUT, true);
  esp_task_wdt_add(NULL);
  Serial.begin(115200);
  Serial2.begin(9600);
  pinMode(temperatureSensor,INPUT);
  pinMode(voltageSensor,INPUT);
  pinMode(currentSensor,INPUT);
  pinMode(interrupt_pin, INPUT_PULLUP);
  pinMode(BUILTIN_LED, OUTPUT);
  pinMode(LED, OUTPUT);
  pinMode(LED2, OUTPUT);
  attachInterrupt(interrupt_pin, isr, FALLING);
  initializeRTC();
  startSD();
  // initial values
  startTime = millis();
  startLogging();
}

void startSD(){
  int e = SD_init();
  // int e = 0;
  if (e == 0) {
    SDCAvailable = true;
  } else {
    showError(e);
  }
  getFileName();
}

void loop() {
  // Serial2.print("Current");
  // Serial2.println(calculate_Current());
  // Serial2.print("Voltage");
  // Serial2.println(calculate_Voltage());
  // Serial.print("ADC");
  // Serial2.println(analogRead(33));
  
  // Serial2.print("Temperature");
  // Serial2.println(calculate_temperature());
  Serial2.print("SWS");
  Serial2.println(calculate_speed(rising_diff));
   if (!checkRTCConnection()) {
    Date = "NA";
    Time = "NA";
//    Serial.println("RTC lost connection! Displaying NA...");
  } else {
    // If RTC is connected, fetch the current time
    DateTime now = rtc.now();

    // Format the date and time as strings
    Date = String(now.year()) + "/" + String(now.month()) + "/" + String(now.day());
    Time = String(now.hour()) + ":" + String(now.minute()) + ":" + String(now.second());
  }

   Serial2.println(Date);
   Serial2.println(Time);
  
  if(logging){
    unsigned long curTime = millis() - startTime;
    unsigned long displayCurTime = curTime / 1000; 
    if(SD_openWrite(filename, calculate_Voltage(), calculate_Current(), calculate_temperature(),  calculate_speed(rising_diff),Date,Time, curTime)){
      digitalWrite(LED, LOW);
      digitalWrite(BUILTIN_LED, HIGH);
      esp_task_wdt_reset();
    } else {
      digitalWrite(LED, HIGH);
      digitalWrite(BUILTIN_LED, LOW);
      SD_init();
    }
    if (curTime > (lastTime + timeIntervalForBT)) {

      // bluetooth
      // Serial2.printf("#data,%.2f,%.2f,%.2f,%.2f,%.2f,%lu,%lu\n", calculate_Voltage(), calculate_Current(), calculate_temperature(),  SWS(), displayCurTime);
      lastTime = curTime;
    }
    
    esp_task_wdt_reset();
  }
}

void showError(int i) {
  Serial.println(i);
}

bool setFileName(String _fn){
    Serial.println("Saving file as: " + _fn);
    if (SD_setFileName(_fn)){
      filename = "/" + _fn + ".csv";
    }
}

void getFileName(){
  String filenameFromSD = SD_getFileName();
  filename = (filenameFromSD == " ")? "/datalog.csv" : filenameFromSD;
  
}
  // put your main code here, to run repeatedly:

void startLogging(){
  Serial.println("Starting logging");
  if(SD_writeFirstLine(filename)){
    digitalWrite(LED, HIGH);
    digitalWrite(BUILTIN_LED, HIGH);
    
  } else {
    digitalWrite(LED, LOW);
    digitalWrite(BUILTIN_LED, LOW);
  }
  logging = true;
  // if (SDCAvailable) { file = SD_openFile(filename); }
  startTime = millis();
  digitalWrite(LED, LOW);

}


void stopLogging(){
  Serial.println("Stopped logging");
  logging = false;
  digitalWrite(BUILTIN_LED, LOW);
  digitalWrite(LED, LOW);
  // if (SD_closeFile(file)){ Serial.println("file closed"); }
  // else { Serial.println("unable to close file");}
}

void countPulse(){
  uint64_t tdiff = millis() - lastTick;
  if (tdiff > 100){
    diff = tdiff;
  }
  lastTick = millis();
}

give links to the various modules?
can you provide a schematic showing the wiring and power supplies?
in particular you could be having power supply problems

1 Like

Waveform on MCU 5v

Thank you for your solution
I'm working on a 0-100V system. I've converted the 0-100V input to a 14V signal, and then further to a 5V signal. The 5V signal is used to power the RTC and SD card. Here's the circuit diagram for the 14V conversion:


waveform on 14v

For 5v


Waveform on 5v

It looks like the 10uf power supply output capacitor has too much reactance to filter out the high frequency switching noise. Try adding a 1nf ceramic capacitor across each 10uf capacitor.

1 Like

Thank you for solution sir
Sir this solution haven't work please suggest me other solution

There is also a possibility that the layout of the ground connections could be the problem

1 Like

Sir i have verify the layout of the ground connection 3-4 time but the is no problem
please tell me other solution

The figures are too small for me to read. I succest you provide a proper schematic for the whole system including supplies, and a photo so we can see how the supplies- and grounds - are connected.

Did you follow my link and check the psu connections are star connected?

The waveform you are seeing on the supply should not be there. Do you have the correct value and type of capacitors connected to the 7805 AT THE PINS - as explained in the data sheet?

An input bypass capacitor should be selected to provide good high frequency characteristics to insure
stable operation under all load conditions. A 0.33 μF or larger tantalum, mylar or other capacitor having low
internal impedance at high frequencies should be chosen. The bypass capacitor should be mounted with the
shortest possible leads directly across the regulators input terminals. Normally good construction techniques
should be used to minimize ground loops and lead resistance drops since the regulator has no external sense
lead.

1 Like

Thank you so much sir for you ideas
I figure out issue there was issue with sd card when i replace sd card issue has been solved

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.