Cannot Initialize SD Card (Teensy 3.2 + SparkFun Level Shifting microSD Breakout)

Status
Not open for further replies.

nstepp

New member
Hello!

As part of a project using ~376 WS2812b LEDs (utilizing the OctoWS2811 library), I'm working to integrate my Teensy 3.2 with Sparkfun's SparkFun Level Shifting microSD Breakout board (as to eventually read video files from the SD card and display them on the associated LEDs). So far, I have had no luck getting any microSD card to initialize.

I have triple checked my connections and they are as follows (using the following nomenclature: from TEENSY 3.2 PIN <--> to MICROSD CARD BREAKOUT PIN):

Pin 3 <--> CS
Pin 11 <--> DI
Pin 12 <--> DO
Pin 13 <--> SCK
GND <--> GND
VIN (supplied by an external regulated 5V (3A) supply) <--> VCC

For additional context I have a few additional devices connected to the Teensy 3.2 also:

- Adafruit Bluefruit LE UART Friend - Bluetooth Low Energy (BLE)

- Electret Microphone Amplifier - MAX9814 with Auto Gain Control

- An N-Channel MOSFET for controlling two 5v 30mm computer fans

The WS2812b LED's have been connected in varying combinations to the 8 Teensy 3.2 pins as specified in the OctoWS2812 library documentation.

For complete context, I had a prototype PCB made, integrating these different breakout boards / devices and integrating a few intermediate components (for signal conditioning, protecting signal integrity, ESD protection, etc.). Images of the schematic and PCB layout are attached. Specifics on wiring can be answered by referencing these images. NOTE: I have already identified one mistake on the PCB: the TX/RX lines to the Bluetooth breakout board were originally wired backwards. I have since cut these traces and corrected the connection using jumper wires soldered to the associated PCB pads.

Performing integrating testing on my setup, I have currently verified successful operation of all the individual components with the Teensy 3.2 (except the microSD card) and have tested combinations of the the components, including the LED's + Bluetooth and LED's + Mic. In attempting to test the LED's + microSD Card (using the VideoSDcard OctoWS2811 library example) I have been unable to initialize the microSD card. Consequently, I have attempted to run the cardInfo SD library example, ensuring the chip-select variable had been changed to 3 (see code below), with no luck... The card is still not initializing. During this testing all connectors for the LEDs and fan were disconnected.

Code:
/*
  SD card test 
   
 This example shows how use the utility libraries on which the'
 SD library is based in order to get info about your SD card.
 Very useful for testing a card when you're not sure whether its working or not.
 	
 The circuit:
  * SD card attached to SPI bus as follows:
 ** MOSI - pin 11 on Arduino Uno/Duemilanove/Diecimila, pin 7 on Teensy with audio board
 ** MISO - pin 12 on Arduino Uno/Duemilanove/Diecimila
 ** CLK - pin 13 on Arduino Uno/Duemilanove/Diecimila, pin 14 on Teensy with audio board
 ** CS - depends on your SD card shield or module - pin 10 on Teensy with audio board
 		Pin 4 used here for consistency with other Arduino examples
 
 created  28 Mar 2011
 by Limor Fried 
 modified 9 Apr 2012
 by Tom Igoe
 */
 // include the SD library:
#include <SD.h>
#include <SPI.h>

// set up variables using the SD utility library functions:
Sd2Card card;
SdVolume volume;
SdFile root;

// change this to match your SD shield or module;
// Arduino Ethernet shield: pin 4
// Adafruit SD shields and modules: pin 10
// Sparkfun SD shield: pin 8
// Teensy audio board: pin 10
// Teensy 3.5 & 3.6 on-board: BUILTIN_SDCARD
// Wiz820+SD board: pin 4
// Teensy 2.0: pin 0
// Teensy++ 2.0: pin 20
[B]const int chipSelect = 3; [/B]   

void setup()
{
  //UNCOMMENT THESE TWO LINES FOR TEENSY AUDIO BOARD:
  //SPI.setMOSI(7);  // Audio shield has MOSI on pin 7
  //SPI.setSCK(14);  // Audio shield has SCK on pin 14
  
 // Open serial communications and wait for port to open:
  Serial.begin(9600);
   while (!Serial) {
    ; // wait for serial port to connect. Needed for Leonardo only
  }


  Serial.print("\nInitializing SD card...");


  // we'll use the initialization code from the utility libraries
  // since we're just testing if the card is working!
  if (!card.init(SPI_HALF_SPEED, chipSelect)) {
    Serial.println("initialization failed. Things to check:");
    Serial.println("* is a card inserted?");
    Serial.println("* is your wiring correct?");
    Serial.println("* did you change the chipSelect pin to match your shield or module?");
    return;
  } else {
   Serial.println("Wiring is correct and a card is present."); 
  }

  // print the type of card
  Serial.print("\nCard type: ");
  switch(card.type()) {
    case SD_CARD_TYPE_SD1:
      Serial.println("SD1");
      break;
    case SD_CARD_TYPE_SD2:
      Serial.println("SD2");
      break;
    case SD_CARD_TYPE_SDHC:
      Serial.println("SDHC");
      break;
    default:
      Serial.println("Unknown");
  }

  // Now we will try to open the 'volume'/'partition' - it should be FAT16 or FAT32
  if (!volume.init(card)) {
    Serial.println("Could not find FAT16/FAT32 partition.\nMake sure you've formatted the card");
    return;
  }


  // print the type and size of the first FAT-type volume
  uint32_t volumesize;
  Serial.print("\nVolume type is FAT");
  Serial.println(volume.fatType(), DEC);
  Serial.println();
  
  volumesize = volume.blocksPerCluster();    // clusters are collections of blocks
  volumesize *= volume.clusterCount();       // we'll have a lot of clusters
  if (volumesize < 8388608ul) {
    Serial.print("Volume size (bytes): ");
    Serial.println(volumesize * 512);        // SD card blocks are always 512 bytes
  }
  Serial.print("Volume size (Kbytes): ");
  volumesize /= 2;
  Serial.println(volumesize);
  Serial.print("Volume size (Mbytes): ");
  volumesize /= 1024;
  Serial.println(volumesize);

  
  Serial.println("\nFiles found on the card (name, date and size in bytes): ");
  root.openRoot(volume);
  
  // list all files in the card with date and size
  root.ls(LS_R | LS_DATE | LS_SIZE);
}


void loop(void) {
  
}

After reading through other similar forum posts concerning SD card connection issues, I have tried the following (using the cardInfo example) in varying combinations with no success:

- Ensured the SD card library in use was indeed the Teensy version
- Formatting SD cards to both FAT16 and FAT32 filesystems (so far I have tested 4 different microSD cards: ADATA 8GB Class 4; SanDisk 16GB Class 4; SanDisk 4GB Class 2; SanDisk Ultra Plus 32GB Class 10)
- Lowered the Teensy 3.2's clock frequency to 24 Mhz
- Changed the SPI_HALF_SPEED (specified in line 60 of the cardInfo example: ) to SPI_QUARTER_SPEED and SPI_FULL_SPEED

Additionally, suspecting it might be an issue with the level-shifting performed by the microSD breakout board, I wired together a microSD card adapter, soldering jumper wires directly to the adapters connection terminals and connected to the Teensy 3.2 in the same fashion as the microSD breakout board (with the exception of microSD's VCC now connected to the Teensy 3.2's 3.3v pin). This still didn't seem to help.

Lastly, using the same aforementioned adapter, I tried using the alternative Teensy 3.2 SPI pins,making the appropriate changes to the cardInfo example:

Code:
/*
  SD card test 
   
 This example shows how use the utility libraries on which the'
 SD library is based in order to get info about your SD card.
 Very useful for testing a card when you're not sure whether its working or not.
 	
 The circuit:
  * SD card attached to SPI bus as follows:
 ** MOSI - pin 11 on Arduino Uno/Duemilanove/Diecimila, pin 7 on Teensy with audio board
 ** MISO - pin 12 on Arduino Uno/Duemilanove/Diecimila
 ** CLK - pin 13 on Arduino Uno/Duemilanove/Diecimila, pin 14 on Teensy with audio board
 ** CS - depends on your SD card shield or module - pin 10 on Teensy with audio board
 		Pin 4 used here for consistency with other Arduino examples
 
 created  28 Mar 2011
 by Limor Fried 
 modified 9 Apr 2012
 by Tom Igoe
 */
 // include the SD library:
#include <SD.h>
#include <SPI.h>

// set up variables using the SD utility library functions:
Sd2Card card;
SdVolume volume;
SdFile root;

// change this to match your SD shield or module;
// Arduino Ethernet shield: pin 4
// Adafruit SD shields and modules: pin 10
// Sparkfun SD shield: pin 8
// Teensy audio board: pin 10
// Teensy 3.5 & 3.6 on-board: BUILTIN_SDCARD
// Wiz820+SD board: pin 4
// Teensy 2.0: pin 0
// Teensy++ 2.0: pin 20
[B]const int chipSelect = 3; [/B]   

void setup()
{
  //UNCOMMENT THESE TWO LINES FOR TEENSY AUDIO BOARD:
[B]  SPI.setMOSI(7);  // Audio shield has MOSI on pin 7
  SPI.setMISO(8);
  SPI.setSCK(14);  // Audio shield has SCK on pin 14[/B]
  
 // Open serial communications and wait for port to open:
  Serial.begin(9600);
   while (!Serial) {
    ; // wait for serial port to connect. Needed for Leonardo only
  }


  Serial.print("\nInitializing SD card...");


  // we'll use the initialization code from the utility libraries
  // since we're just testing if the card is working!
  if (!card.init(SPI_HALF_SPEED, chipSelect)) {
    Serial.println("initialization failed. Things to check:");
    Serial.println("* is a card inserted?");
    Serial.println("* is your wiring correct?");
    Serial.println("* did you change the chipSelect pin to match your shield or module?");
    return;
  } else {
   Serial.println("Wiring is correct and a card is present."); 
  }

  // print the type of card
  Serial.print("\nCard type: ");
  switch(card.type()) {
    case SD_CARD_TYPE_SD1:
      Serial.println("SD1");
      break;
    case SD_CARD_TYPE_SD2:
      Serial.println("SD2");
      break;
    case SD_CARD_TYPE_SDHC:
      Serial.println("SDHC");
      break;
    default:
      Serial.println("Unknown");
  }

  // Now we will try to open the 'volume'/'partition' - it should be FAT16 or FAT32
  if (!volume.init(card)) {
    Serial.println("Could not find FAT16/FAT32 partition.\nMake sure you've formatted the card");
    return;
  }


  // print the type and size of the first FAT-type volume
  uint32_t volumesize;
  Serial.print("\nVolume type is FAT");
  Serial.println(volume.fatType(), DEC);
  Serial.println();
  
  volumesize = volume.blocksPerCluster();    // clusters are collections of blocks
  volumesize *= volume.clusterCount();       // we'll have a lot of clusters
  if (volumesize < 8388608ul) {
    Serial.print("Volume size (bytes): ");
    Serial.println(volumesize * 512);        // SD card blocks are always 512 bytes
  }
  Serial.print("Volume size (Kbytes): ");
  volumesize /= 2;
  Serial.println(volumesize);
  Serial.print("Volume size (Mbytes): ");
  volumesize /= 1024;
  Serial.println(volumesize);

  
  Serial.println("\nFiles found on the card (name, date and size in bytes): ");
  root.openRoot(volume);
  
  // list all files in the card with date and size
  root.ls(LS_R | LS_DATE | LS_SIZE);
}


void loop(void) {
  
}

Like before, this didn't seem to help.

Additionally, during testing with the aforementioned adapter, I also tried using Teensy 3.2 Pin 10 as the CS pin (making the appropriate change to the chip-select variable in the cardInfo example) with no luck.

As a final check to ensure the SD cards were good, I connected the microSD breakout board (while still attached to the prototype PCB) to an Arduino UNO (using Arduino Uno Pins 10 -13) using jumper-wires and was able to successfully run the cardInfo example on each of my four microSD cards without issue. I also performed this same testing using the aformentioned microSD card adapter I made and an Arduino Due with the same success.

At this point, I'm at a loss as to what to try next. Debug testing tells me it's either an issue with the Teensy 3.2 or something else connected to it via the prototype PCB that is interfering with the successful operation of the SPI communication. Since I have already soldered the Teensy 3.2 and microSD card breakout board to the prototype PCB, I am unable to performed more isolated testing with only the two components without the headache of having to desolder (and potentially destroy) them.

Any help or insight with this issue from the user community would be immensely appreciated!

Best,
nstepp
 

Attachments

  • nstepp_Schematic.jpg
    nstepp_Schematic.jpg
    81.2 KB · Views: 92
  • nstepp_PCB.jpg
    nstepp_PCB.jpg
    82.9 KB · Views: 96
I don't understand why you are using a board designed to shift between 5V levels from the micro-controller (the Teensy 3.2 is 3.3V) to the 3.3V levels of the uSD card.
 
Thanks for the reply! Honestly, I used this board because it was what I already had on hand, the small footprint of the board integrated well with my design, and the Sparkfun documentation stated it would operate with both 3.3v and 5v logic. So I didn't see this being an issue...

I have since ordered a few of the Teensy micro SD card adapters as an alternative solution.
 
Thanks for the reply! Honestly, I used this board because it was what I already had on hand, the small footprint of the board integrated well with my design, and the Sparkfun documentation stated it would operate with both 3.3v and 5v logic. So I didn't see this being an issue...

Then you misunderstood. It is designed as an interface between the 3.3V uSD card and a 5V device. The 5V side will not work reliably with 3.3V devices. Look at the data sheet for the level shifter and you will find that for a high input to be reliably recognized, it must be greater than 0.65 * Vcc. Or 3.25V with a 5V supply.

Not something you would choose for talking to a 3.3V system.

On the plus side, the weak output drivers probably cannot induce latchup in your 3.3V device.
 
Status
Not open for further replies.
Back
Top