SD works on Dev. Board but not on Barebones (PCB and Breadboard)

I’ve encountered this weird problem where the SD breakout board works on the dev-Board but not on barebone setup and can’t seem to find the source of the problem:

Here’s what not working on Barebone(PCB and Breadboard), when I try to turn on/off the SD board through MOSFET(N-Channel) the problem seems to exist.

CODE 1: (MOSFET/SD turned on/off)

#include <SPI.h>
#include <SD.h>

//Gate Pin for MOSFET IRF540N
int MOS_PIN = 8;

//Status LED
int LED = 4;

//SD Module CS
int CS_PIN = 10;

unsigned long previousMillis = 0;
const long interval = 10000;

void setup() {
  
Serial.begin(9600);

pinMode(MOS_PIN, OUTPUT);
pinMode(LED, OUTPUT);
pinMode(CS_PIN, OUTPUT);

digitalWrite(MOS_PIN, HIGH);

Serial.println("SD Initializing:");

if(!SD.begin(CS_PIN))
{
  Serial.println("SD ERROR");
  digitalWrite(LED, HIGH);
  return;
}

Serial.println("SD READY");

FlashLED(2, 500);

} //end setup

void FlashLED (int rep, int delayTime)
{
  for (int i = 0; i < rep; i++)
  {
    digitalWrite(LED, HIGH);
    delay(delayTime);
    digitalWrite(LED, LOW);
    delay(delayTime);
  }
} //end FlashLED

void loop() {
  
  digitalWrite(MOS_PIN, LOW);
  
  unsigned long timeStamp = millis();
  String strData = "Hello World";
  
  if (timeStamp-previousMillis >= interval)
  {
    
    SPI.begin();
    
    digitalWrite(MOS_PIN, HIGH);
    
    if(!SD.begin(CS_PIN))
    {
      Serial.println("SD ERROR _ LOOP");
      digitalWrite(LED, HIGH);
      previousMillis = timeStamp;
      return;
    }
    
    File file = SD.open("LOGTST1.csv", FILE_WRITE);
    
    if (file)
    {
            
      file.print(timeStamp);
      file.print(",");
      file.println(strData);
      file.close();
      
      Serial.print(timeStamp);
      Serial.print(",");
      Serial.println(strData);
      
      FlashLED(4,250);
      
      previousMillis = timeStamp;
    }
    else
    {
      previousMillis = timeStamp;
      digitalWrite(LED, HIGH);
      Serial.println("FILE ERROR");
    }
    SPI.end();    
  }
}//end loop

The program seems to restart on its own when it reaches this part of the code

void loop() {
  
  digitalWrite(MOS_PIN, LOW);
  
  unsigned long timeStamp = millis();
  String strData = "Hello World";
  
  if (timeStamp-previousMillis >= interval)
  {
    
    SPI.begin();
    
    digitalWrite(MOS_PIN, HIGH);
    
    if(!SD.begin(CS_PIN))
    {
      Serial.println("SD ERROR _ LOOP");
      digitalWrite(LED, HIGH);
      previousMillis = timeStamp;
      return;
    }

Working codes for the barebones:

CODE 2 (MOSFET/SD always ON):

#include <SPI.h>
#include <SD.h>

//Gate Pin for MOSFET IRF540N
int MOS_PIN = 8;

//Status LED
int LED = 4;

//SD Module CS
int CS_PIN = 10;

unsigned long previousMillis = 0;
const long interval = 10000;

void setup() {
  
Serial.begin(9600);

pinMode(MOS_PIN, OUTPUT);
pinMode(LED, OUTPUT);
pinMode(CS_PIN, OUTPUT);

digitalWrite(MOS_PIN, HIGH);

Serial.println("SD Initializing:");

if(!SD.begin(CS_PIN))
{
  Serial.println("SD ERROR");
  digitalWrite(LED, HIGH);
  return;
}

Serial.println("SD READY");

FlashLED(2, 500);

} //end setup

void FlashLED (int rep, int delayTime)
{
  for (int i = 0; i < rep; i++)
  {
    digitalWrite(LED, HIGH);
    delay(delayTime);
    digitalWrite(LED, LOW);
    delay(delayTime);
  }
} //end FlashLED

void loop() {
  
  unsigned long timeStamp = millis();
  String strData = "Hello World";
  
  if (timeStamp-previousMillis >= interval)
  {
    
    SPI.begin();
    
    if(!SD.begin(CS_PIN))
    {
      Serial.println("SD ERROR _ LOOP");
      digitalWrite(LED, HIGH);
      previousMillis = timeStamp;
      return;
    }
    
    File file = SD.open("LOGTST1.csv", FILE_WRITE);
    
    if (file)
    {
            
      file.print(timeStamp);
      file.print(",");
      file.println(strData);
      file.close();
      
      Serial.print(timeStamp);
      Serial.print(",");
      Serial.println(strData);
      
      FlashLED(4,250);
      
      previousMillis = timeStamp;
    }
    else
    {
      previousMillis = timeStamp;
      digitalWrite(LED, HIGH);
      Serial.println("FILE ERROR");
    }
    SPI.end();    
  }
}//end loop

But both codes work on the Dev. board

I’ve attached some files (BRD Layout, Breadboard, etc) related to the project:

AnitoLabs:
I've encountered this weird problem where the SD breakout board works on the dev-Board but not on barebone setup and can't seem to find the source of the problem:

Here's what not working on Barebone(PCB and Breadboard), when I try to turn on/off the SD board through MOSFET(N-Channel) the problem seems to exist.

CODE 1: (MOSFET/SD turned on/off)

You need to add some time delay after you write, before you powerdown the SDcard. The microprocessor in the SDCard has housekeeping to do after you send it data.

I question your Low side MOSFET switch. I have never used a low side switch for digital electronics.
I would change to a P-MOSFET and switch the VCC line.

I have heard that the poweron cycle for SDCards can require 200mA for a couple of milliseconds. It has cause much heartache due to subpar power regulators. I see you are directly using 1.25V NiMH batteries(4.8..5V full charge.). Depending on the overhead of the 3.3V regulator on the SDCard module you could need between 4.0 and 4.25V for successful operation. This should be acceptable, NiMH discharge to 1.1V.

When you disconnect the GND at the SDCard, if any of the digital pins are low (MOSI,SCK,) you might be seeing current inflow from the SDCard. The protection diodes inside the level translation IC's would see negative voltages in reference to the disconnected ground, this current might upset the AVR chip (atmega328p)?

I would recommend changing the circuit.

Chuck.

Thanks for the help chuck, :slight_smile:

You need to add some time delay after you write, before you powerdown the SDcard. The microprocessor in the SDCard has housekeeping to do after you send it data.

How long does the card needs to stay ON after the write sequence to guarantee proper operation?

I question your Low side MOSFET switch. I have never used a low side switch for digital electronics.
I would change to a P-MOSFET and switch the VCC line.

When you disconnect the GND at the SDCard, if any of the digital pins are low (MOSI,SCK,) you might be seeing current inflow from the SDCard. The protection diodes inside the level translation IC's would see negative voltages in reference to the disconnected ground, this current might upset the AVR chip (atmega328p)?

Will definitely change the circuit to High-side switch thanks for the suggestion and pointing-out the problem on using the current setup.

Anito.

AnitoLabs:
Thanks for the help chuck, :slight_smile:
How long does the card needs to stay ON after the write sequence to guarantee proper operation?

Here is a spec sheet for a Transcend 2gb card.
SDCardStandardv1.9.pdf

I could not find a 'hard' time. The spec sheet describes a 'Busy' register bit that should be polled to identify when the card has completed it's last command.

The spec sheet also describes the power on max current at 10ma, but the Read and Write currents can be up to 100mA(read) or 200mA(write). The actual amounts required are card specific. Each card has a 3 bit value that describes its current requirement for Read and Write Operations. I don't know if the Arduino library exposes these values.

I would hope the file.close() or file.flush() would actually uses this 'busy' flag. I have not studied the SD Library so, I cannot give you a authoritative answer.

AnitoLabs:
Will definitely change the circuit to High-side switch thanks for the suggestion and pointing-out the problem on using the current setup.
Anito.

After you power down the SD card, and SPI.end() set the pinMode on SCK,MOSI,MISO,SS to INPUT and turn off the pullup resistors (pinMode(pin,INPUT); digitalWrite(pin,low); that will minimize any potential current losses to the 'powered Down' SDcard.

Also, you might want to review this project on Nick Gammon's website
A temperature and Humidity Logger

Chuck.