SD card module does not initialize sometimes

Hello everyone.
A bit of backstory before I explain my problem. I am using an Arduino Mega with an SD card and an ADC module. Since both work on SPI protocol I searched around and wrote a code that made sense in my head and it worked. I developed a PCB (which also has a GPS module, a 12-5v power supply module and 12v barrel jack for power). Now here is the problem,
When I power my board with just the usb connector connected to Mega, the code works perfectly. But when i power the board with the 12v supply and connect the usb to read from the serial monitor the sd card does no initialize. I thought i was going mad so checked several times and it still does not work. Any idea whats the problem?
The code i am using is this

//ADS1256 library developed by Curious Scientist
//A very detailed documentation can be found at: https://curiousscientist.tech/ads1256-custom-library
#include <SPI.h>
#include <ADS1256.h>
#include <SD.h>
//#include <FS.h>
#include <TinyGPS++.h>
#include <TimeLib.h>
#include <UnixTime.h>

TinyGPSPlus gps; // create gps object

UnixTime stamp(5);

#define time_offset   18000  // define a clock offset of 18000 seconds (5 hour) ==> UTC + 5

// variable definitions
char Time[]  = "00:00:00";
char Date[]  = "00-00-2000";
byte last_second, Second, Minute, Hour, Day, Month;   //For setting time to local +5hrs
int Year;
uint32_t timeStamp;
unsigned long interval;

String sat;

const char filename[] = "test.txt";
File txtFile;
float buff;
unsigned long lastMillis = 0;

//ADS1256 A(2, 0, 8, 10, 2.500); //DRDY, RESET, SYNC(PDWN), CS, VREF(float).    //Arduino Uno
ADS1256 A(2, 0, 46, 53, 2.500); //DRDY, RESET, SYNC(PDWN), CS, VREF(float).    //Arduino Mega
//ADS1256 A(44, 0, 47, 10, 2.500); //DRDY, RESET, SYNC(PDWN), CS, VREF(float).      //Arduino Due

float rmsValue = 0;

long rawConversion = 0; //24-bit raw value
float voltageValue = 0; //human-readable floating point value
float readings[8];

int singleEndedChannels[8] = {SING_0, SING_1, SING_2, SING_3, SING_4, SING_5, SING_6, SING_7}; //Array to store the single-ended channels
int differentialChannels[4] = {DIFF_0_1, DIFF_2_3, DIFF_4_5, DIFF_6_7}; //Array to store the differential channels
int inputChannel = 0; //Number used to pick the channel from the above two arrays
char inputMode = ' '; //can be 's' and 'd': single-ended and differential

int pgaValues[7] = {PGA_1, PGA_2, PGA_4, PGA_8, PGA_16, PGA_32, PGA_64}; //Array to store the PGA settings
int pgaSelection = 0; //Number used to pick the PGA value from the above array

int drateValues[16] =
{
  DRATE_30000SPS,
  DRATE_15000SPS,
  DRATE_7500SPS,
  DRATE_3750SPS,
  DRATE_2000SPS,
  DRATE_1000SPS,
  DRATE_500SPS,
  DRATE_100SPS,
  DRATE_60SPS,
  DRATE_50SPS,
  DRATE_30SPS,
  DRATE_25SPS,
  DRATE_15SPS,
  DRATE_10SPS,
  DRATE_5SPS,
  DRATE_2SPS
}; //Array to store the sampling rates

int drateSelection = 0; //Number used to pick the sampling rate from the above array

String registers[11] =
{
  "STATUS",
  "MUX",
  "ADCON",
  "DRATE",
  "IO",
  "OFC0",
  "OFC1",
  "OFC2",
  "FSC0",
  "FSC1",
  "FSC2"
};//Array to store the registers

int registerToRead = 0; //Register number to be read
int registerToWrite = 0; //Register number to be written
int registerValueToWrite = 0; //Value to be written in the selected register

//____________________________________________________________________________________________________________________________________________________________________________

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);

  Serial1.begin(9600); // connect gps sensor
  delay(10);
  //  buff.reserve(1024);
  pinMode(53, OUTPUT);
  pinMode(4, OUTPUT);
  // set LED pin to output, used to blink when writing
  //  pinMode(LED_BUILTIN, OUTPUT);
  Serial.println("Initializing SD");
//  digitalWrite(53, 1);

  digitalWrite(4, 0);
  initSDCard();
  digitalWrite(4, 1);

  Serial.println("Initializing ADC");
  //  Serial.println("ADS1256 - Custom Library Demo File by Curious Scientist - 2023-11-10");

  digitalWrite(53, 0);
  A.InitializeADC(); //See the documentation for every details
  //Setting up CS, RESET, SYNC and SPI
  //Assigning default values to: STATUS, MUX, ADCON, DRATE
  //Performing a SYSCAL

  //Below is a demonstration to change the values through the built-on functions of the library
  //Set a PGA value
  A.setPGA(PGA_1);  //0b00000000 - DEC: 0
  //--------------------------------------------

  //Set input channels
  A.setMUX(SING_1); //0b01100111 - DEC: 31
  //--------------------------------------------

  //Set DRATE
  A.setDRATE(DRATE_100SPS); //0b00010011 - DEC: 19

  //--------------------------------------------
  A.setBuffer(1);
  delay(50);
  //Read back the above 3 values to check if the writing was succesful
  //  Serial.print("PGA: ");
  //  Serial.println(A.readRegister(IO_REG));
  //  delay(100);
  //--
  //  Serial.print("MUX: ");
  //  Serial.println(A.readRegister(MUX_REG));
  //  delay(100);
  //--
  //  Serial.print("DRATE: ");
  //  Serial.println(A.readRegister(DRATE_REG));
  //  delay(100);
  //--
  //  Serial.println(A.getPGA());
  //  delay(100);
  A.getBuffer();
  delay(100);
  //--
  //Freeze the display for 3 sec
  delay(3000);
  interval = millis();

}

//________________________________________________________________________________________________________________________________________________________________________

void loop() {
  // put your main code here, to run repeatedly:

  //  rawConversion = A.readSingle();   // To read multiple channels goto end of code to see example
  //  A.stopConversion();
  //  voltageValue = A.convertToVoltage(rawConversion);
  getADC();
  rmsValue = RMS(readings[0], readings[1], readings[2]);
  getTime();

  sat = gps.satellites.value();

  //  Serial.print(Date);
  //  Serial.print(",");
  Serial.print(timeStamp);
  Serial.print(",");
  Serial.print(readings[0], 6);
  Serial.print(",");
  Serial.print(readings[1], 6);
  Serial.print(",");
  Serial.print(readings[2], 6);
  Serial.print(",");
  Serial.print(rmsValue, 6);
  Serial.println(" ");
  //  Serial.print("\t");
  //  Serial.print(sat);
  //  Serial.print("\t");
  //  Serial.println(gps.hdop.hdop());

  if (millis() - interval > 1000)
  {
    digitalWrite(53, 1);
    digitalWrite(4, 0);
    writeToSD(Date, Time, readings[0], readings[1], readings[2], rmsValue);
    Serial.println("written");
    interval = millis();
    digitalWrite(4, 1);
    digitalWrite(53, 0);
  }
}




static void smartDelay(unsigned long ms)
{
  unsigned long start = millis();
  do
  {
    while (Serial1.available())
      gps.encode(Serial1.read());
  } while (millis() - start < ms);
}


void writeToSD(char d[], char t[], float v1, float v2, float v3, float v4)
{
  digitalWrite(4, 0);
  txtFile = SD.open(filename, FILE_WRITE);
  if (!txtFile) {
    Serial.print("error opening ");
    Serial.println(filename);
//    while (1);
  }
  else
  {
    txtFile.print(d);
    txtFile.print(",");
    txtFile.print(t);
    txtFile.print(",");
    txtFile.print(v1, 6);
    txtFile.print("uT,");
    txtFile.print(v2, 6);
    txtFile.print("uT,");
    txtFile.print(v3, 6);
    txtFile.print("uT,");
    txtFile.print(v4, 6);
    txtFile.print("uT");
    txtFile.println();
    txtFile.close();
  }
  digitalWrite(4, 1);
}


void getTime()
{
  smartDelay(10);         //Serial.available, gps encode both are done inside smartDelay function.
  if (gps.time.isValid())
  {
    Minute = gps.time.minute();
    Second = gps.time.second();
    Hour   = gps.time.hour();
    //    timeStamp = gps.time.hour() + 5;
    //    timeStamp += ":";
    //    timeStamp += gps.time.minute();
    //    timeStamp += ":";
    //    timeStamp += gps.time.second();
  }
  if (gps.date.isValid())
  {
    Day   = gps.date.day();
    Month = gps.date.month();
    Year  = gps.date.year();
  }

  if (last_second != gps.time.second()) // if time has changed
  {
    last_second = gps.time.second();

    // set current UTC time
    //    setTime(Hour, Minute, Second, Day, Month, Year);
    // add the offset to get local time
    //    adjustTime(time_offset);

    // update time array
    stamp.setDateTime(Hour, Minute, Second, Day, Month, Year);
    timeStamp = stamp.getUnix();

    Time[6] = second() / 10 + '0';
    Time[7] = second() % 10 + '0';
    Time[3]  = minute() / 10 + '0';
    Time[4] = minute() % 10 + '0';
    Time[0]  = hour()   / 10 + '0';
    Time[1]  = hour()   % 10 + '0';

    // update date array
    Date[8] = (year()  / 10) % 10 + '0';
    Date[9] =  year()  % 10 + '0';
    Date[3]  =  month() / 10 + '0';
    Date[4] =  month() % 10 + '0';
    Date[0]  =  day()   / 10 + '0';
    Date[1]  =  day()   % 10 + '0';
  }
}

void getADC ()
{
  digitalWrite(53, 0);
  //  rawConversion = A.readSingle();   // To read multiple channels goto end of code to see example
  //  A.stopConversion();
  //  voltageValue = A.convertToVoltage(rawConversion);
  for (int i = 0; i < 8; i++)       // Convert all single channels and store in array
  {
    readings[i] = A.convertToVoltage(A.cycleSingle());
    //            Serial.print(A.convertToVoltage(A.cycleSingle()), 4); //print the converted single-ended results with 4 digits
    //            Serial.print("\t");//tab separator to separate the 4 conversions shown in the same line
    readings[i] = mapF(readings[i], -3.7, 3.7, -100, 100);

  }
  A.stopConversion();

  //          Serial.print(readings[0], 6);   //prints only the desired channels
  //          Serial.print("\t");
  //          Serial.print(readings[1], 6);
  //          Serial.print("\t");
  //          Serial.print(readings[2], 6);
  //          Serial.println();
  digitalWrite(53, 1);
}


void initSDCard() {

  if (!SD.begin(4)) {
    Serial.println("Card Mount Failed");
    return;
  }
  else {
    Serial.println("Initialized SD card");
  }
}


float mapF(float x, float in_min, float in_max, float out_min, float out_max)
{
  return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}


float RMS (float x, float y, float z)
{
  return (sqrt((x * x) + (y * y) + (z * z)));
}

Missing common ground?

All grounds are checked and accounted for. However I had a hunch that the problem was with the module itself as it sometimes worked and sometimes didnt so i found an ethernet shield which has a built in sd card and attached it to the arduino Mega and it worked. But since i need the module to put in my pcb i have to get a new module. Hopefully the new module works.

Turns out it was the module after all. The new module works perfectly. So the problem that I thought was related to power was just a faulty board.

And now the new module is also not working so maybe it has something to do with my code attached above. Please take a look at it.
Since i have 2 modules based on SPI I tried using enabling and disabling the cs pins whenever i wanted to use one of them but so far no luck.

Maybe start with sharing a schematic of your circuit and a photo of how everything is connected.

Where's the fun in doing so?

Attached below is the circuit picture and schematic.

OK, I see; I'm sorry, this didn't sink in with me, I should have read more carefully. Have you tried temporarily removing the ADC to see if the SD card works if it's the only thing connected to the SPI?

You'd have to verify in the datasheet of the ADS1256 as well as the breakout board you're using that the SPI pins are indeed floating/tri-stated if there's no SPI communication going on.

Yes i did remove the ADC to see if that worked but still no luck. the sd card module would sometimes initialize and sometimes wouldn't.
I also bought a new sd card module and that worked but the next day it started having the same problems.
I then, on a hunch, took an ethernet shield which has a built in sd card reader and connected everything else (gps and adc) and it worked perfectly everytime.
This makes me think that either the pcb connections are the problem since the sd card module is new

Maybe, but it's hard to tell without illustrations. A good photograph of the bottom side of the PCB may help.

If you connect the same 'problematic' SD module directly to an Arduino board without your own PCB getting in the way, does it work?

Sorry for the late reply. If i connect the module without the pcb, it still doesnt work most of the times. only when i take out the mega's cable and reconnect it then it works. but when i press the reset buttona few times it stops working

Try a different SD module.

When you set the pinMode of the SPI ss pins in setup(), also set them HIGH (disabled).

  pinMode(53, OUTPUT);
  digitalWrite(53,HIGH);  
  pinMode(4, OUTPUT);
  digitalWrite(4,HIGH);

Already tried that but still doesnt work reliably

I have another version of this using an ESP32. should I post the problems I am facing in that here as well or do i create another topic?
PS. i am also having the same sd card problems except its on esp32 HSPI

I have a Mega2560 with an ethernet shield. It has an SD card also.
Both W5100 and SD work reliably with that.

Edit: My W5100 ss is on D10 instead of D53.

Read the posts above. I have already said it works perfectly with the ethernet shield. Only problem is I can't use the shield in the pcb. so i have to use the module

Here it is

Don't use pin 53 as a device slave select. It determines if the SPI is a master or slave.

Edit: If you aren't using the ethernet shield, then use D10 for the ss instead of D53.