(SOLVED) SFE microSD Breakout woes ...

I can't get this breakout to work ... kinda. I'm talking about the BOB-00544 from SFE. Here's what I've done and how it's connected. Because one shouldn't feed it high voltage, I have a level converter (BOB-08745) to translate the signals. So here goes the pin layout:

SD Breakout:
CD -> NC
DO -> TXI (CH1) on LV side -> from TXO (CH1) on HV side to MISO on Uno
GND -> GND
SCK -> RXO (CH1) on LV side -> from RXI (CH1) on HV side to SCK on Uno
VCC -> 3.3V on Uno
DI -> RXO (CH2) on LV side -> from RXI (CH2) on HV side to MOSI on Uno
CS -> TXI (CH2) on LV side -> from RXO (CH2) on HV side to pin 4 on Uno

Not sure I needed to pass the chipSelect and SCK pins through the level converter but hey, it couldn't hurt. I did also try it by connecting those two directly to the Uno.

The level converter is powered on the LV side with 3.3V and on the HV side with 5V. And a common GND with 5V (and the Uno.)

The sketch I'm using is the CardInfo sample. It correctly sets the chipSelect to pin 4. When I open the serial monitor, I get this:

Initializing SD card...Wiring is correct and a card is present.

    Card type: SD2
    Could not find FAT16/FAT32 partition.
    Make sure you've formatted the card

This happens with any card I put in. They're all formatted FAT16 with default block side. I also tried FAT32. No dice.

So what am I missing? It's worth pointing out that none of the other sample sketches work either. It immediately fails with the SD.begin() line. Whether it's set to the hardware SS (pin 10) and I connect the card's CS pin to that, or whether I set it to pin 4. It never seems to get past that line, weather I use pin 10 or any other pin.

Sounds right (yes all signals must be level converted - SDcards must never see anything above 3.6V abs max.)

post your circuit (or a photo of it) - worth double-checking every connection (one takes one fault in the hardware to stop
it working). SDcards also need a pokey 3.3V supply, perhaps the 3.3V rail is drooping? (multimeter).

Bypass capacitors, sounds like the Arduino finds the card... Perhaps reading anything else is problematical due to lack of bypass capacitors... .1 and perhaps a local 4R7 on the 3V3 side?

Bob

If I were you, I would swap which level shifter you are using for DI and CS.

Use:
DI <- TXI (ch2) <- TXO (ch2) <- MOSI
CD <- RXO (ch2) <- RXI (ch2) <- pin4

Goodness knows why Sparkfun gave the signals the names they did :roll_eyes:. Basically the mosfet shifter is bidirectional, but it will perform better than the resistor divider and is better suited to the data line, or even better still the clock line, for example:

DO -> TXI (CH1) on LV side -> TXO (CH1) on HV side -> MISO on Uno
GND -> GND
SCK <- TXI (ch2) on LV side <- TXO (ch2) on HV side <- SCK on Uno
VCC <- 3.3V on Uno
DI <- RXO (CH1) on LV side <- RXI (CH1) on HV side <- MOSI on Uno
CS <- RXO (ch2) on LV side <- RXI (ch2) on HV side <- pin 4 on Uno

Docedison:
Bypass capacitors, sounds like the Arduino finds the card... Perhaps reading anything else is problematical due to lack of bypass capacitors... .1 and perhaps a local 4R7 on the 3V3 side?

Are those needed though? Looking at the Ethernet shield schematic, there isn't a cap on the 3V3 line anywhere near the microSD, nor is there a resistor on it.

Yeah, that didn't work either. I'll post pics in the next msg.

These are from my phone, fairly large. The first picture shows the 3V3 line going to the bottom rail on the breadboard, and the 5V line going to the upper rail. Common ground between both and the Uno.
Overall: http://www.thekirchners.net/microSD/overall.jpg

SD closeup: http://www.thekirchners.net/microSD/sdcloseup.jpg

Level converter: http://www.thekirchners.net/microSD/levelconverter.jpg

Uno Closeup: http://www.thekirchners.net/microSD/unocloseup.jpg

SD & level converter: http://www.thekirchners.net/microSD/sdlevel.jpg

By the way, measuring voltages I get a steady 5.09V on the high side, and 3.294V on the low side. They don't budge when I try to access the card.

KirAsh4:
By the way, measuring voltages I get a steady 5.09V on the high side, and 3.294V on the low side. They don't budge when I try to access the card.

Can you try a different card and see if it works?

Different SD cards need different voltages. A lot of cards want 3.6V, yours might be one of them.

You're supposed to query the card and ask it how many volts it wants when you connect to it but the SD card library is a bit loose on that part of the protocol (IIRC). It assume SD card shields will all have 3.6V. If that's the problem you'll have to boost your voltage a bit...

fungus:
Can you try a different card and see if it works?

Different SD cards need different voltages. You're supposed to query the card and ask it how many volts it wants when you connect to it but the SD card library is a bit loose on that part of the protocol (IIRC).

I've tried three different ones now. 1GB, 2GB, and 4GB (class 6)

They are all formatted with FAT (default) and default allocation. I also tried FAT32 with default allocation. No dice.

KirAsh4:
I've tried three different ones now. 1GB, 2GB, and 4GB (class 6)

They are all formatted with FAT (default) and default allocation. I also tried FAT32 with default allocation. No dice.

It's the only thing I can think of that would allow the card to initialize but not read any data.

One other thing...are the cards formatted as primary partitions or extended partitions? They might have to be primary partitions.

All primaries.

A sudden thought occured

Try changing this line:

  if (!card.init(SPI_HALF_SPEED, chipSelect)) {

To:

  if (!card.init(6, chipSelect)) {

That will slow down the SPI to the slowest possible speed of FCPU/128

If that works, try decreasing the number to 5, then 4, then 3 and so on. Each time it will double the speed.

With simple level converters like these, I was never able to get it to run faster than FCPU/8 (aka SPI_QUARTER_SPEED) reliably. Once i switched to a proper level shifter like the TXB0104, I could get up to the full speed of FCPU/2 (aka SPI_FULL_SPEED).

EDIT:
Just as a side note, the card.init() call initialises the card at FCPU/128, and then at the end of the routine sets it to full speed. This means that the volume.init() call will be running on a an SPI at a much higher freqency than card.init() which could be the reason why it fails at that point.

Woah Tom, that worked! I was able to go all the way from 6 down to 2 ... and that's as far as I could go.

Now for the next issue: none of the other sketches work. They all fail at the initialization stage. They all have this check in them which fails:

Serial.print("Initializing SD card...");
pinMode(10, OUTPUT);

if (!SD.begin(4)) {
  Serial.println("initialization failed!");
  return;
}

From reading the comments in the files, pin 10 must be left as an output, even when not used ... and I'm not using it. Still have the card's CS pin connected to pin 4 (exact setup as when I running the CardInfo sketch.)

It's an instant failure, when I open the serial console, no delays (like it's trying to access it) ...

One thing I noted, this sketch doesn't have the .init() line in it as with the CardInfo one.

Aha, reading SD.cpp I see this:

boolean SDClass::begin(uint8_t csPin) {
  /*
    Performs the initialisation required by the sdfatlib library.
    Return true if initialization succeeds, false otherwise.
   */
  return card.init(SPI_HALF_SPEED, csPin) &&
         volume.init(card) &&
         root.openRoot(volume);
}

Changing that to readreturn card.init(2, csPin) &&
... instead fixed the problem.

Hey Tom, on that TXB0104 ... can you suggest a DIP equivalent? I do all of my prototyping on breadboards before I create an SMD final board ... so I need something in DIP form ... or I'll have to create a breakout for the TXB0104 ...

The begin() function calls card.init() with SPI_HALF_SPEED:

boolean SDClass::begin(uint8_t csPin) {
  /*

    Performs the initialisation required by the sdfatlib library.

    Return true if initialization succeeds, false otherwise.

   */
  return card.init(SPI_HALF_SPEED, csPin) &&
         volume.init(card) &&
         root.openRoot(volume);
}

Which means it is running too fast. In Windows, if you open the following file (it is slightly different on Mac):
/libraries/SD/SD.cpp

You will find the begin() function declaration, just change the SPI_HALF_SPEED to 2.

As for the TXB0104, there are breakout boards available ready soldered:
8-channel Bi-directional Logic Level Converter [TXB0108] : ID 395 : $7.95 : Adafruit Industries, Unique & fun DIY electronics and kits (This is actually the 8 channel version, TXB0108)
http://www.nanocore12.com/products/details/27/4/accessories/breakout-board,-level-shifter,-3v/5v,-14-pin-wide-dip.html (4 channel TXB0104)

Yeah, I changed SD.cpp, however rather than specifying 2, I changed it to SPI_QUARTER_SPEED and called it a day. It works. :slight_smile:

Thanks for the links!