Well... quite a general subject. That's because I just want to share my experience, so anyone who faces a similar problem can solve it quicker than I did.
All this happened with an Arduino Mega 2560, and an cheap LCD + Touch + MicroSDCard Reader shield from AliExpress. Obviously this could have happened with any other Arduino, while using poorly designed (cheap) shields, of any kind. This is just an example of what can go wrong. Here there is an image of the shield:
I was trying to read a microSD card. The tinyFat lib seemed to work almost ok, but I couldn't get sdFat lib to work properly. The example sketch CardInfo thrown the following output:
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
I tried almost everything. Anyone with this problem should first:
-Make sure the SD card works! -Format the SD card with the sdcard.org format tool. -Reduce SPI speed to QUARTER : card.init(SPI_QUARTER_SPEED, chipSelect)
In my case, the solution was a tiny fix on the board.
The problem is that this board uses the serial resistor approach to the necessary "voltage level shifter" circuitry, as you see in the image. There's a 3v3 voltage regulator for supply voltage (LCD, touch controller and SDCard), but all signal pins were interfaced with arrays of 10K resistors.
This method of level "conversion" is the cheapest, no discussion here, but usually controversial, as it could damage 3V3 devices if their inputs lack of a proper clamping protection (Do ALL SD have?). But, apart from this, there's another drawback. We are working with real components, where current leaks, parasite capacitances or inductances do exist. Interfacing with series resistors can make these non-idealities arise: sharped-edged signals became curved, speed must be reduced, voltage level bands became narrower, etc.
For example, although the minimum voltage of a high 3V3 TTL output is supposed to be correctly read as high by a 5V TLL input (isn't it?), this was not the case, at least for SPI communication (were time matters! Steady state assumptions are no longer valid). The result is that the DO(SO) pin of the SD card seemed not to be properly driving the MI pin of the Arduino.
But why is that resistor there? It makes sense to interface from 5 to 3v3... but from 3v3 to 5?? Well, it might act as a protection in case someone incorrectly sets MI pin as an output, or if you connect the shield pin to ground.. surely there was reason. But, in my project, all it does is prevent sdFat library from working. So get away with it:
Now, everything works fine.
A resistor in parallel might also be a good fix. For example... another 10K in parallel, to get a 5K interfacing resistor. The lower resistor value might be low enough to solve the problem (must be tested), and you would preserve some of its protection function.
As a general advice... choose shields or modules with more elaborated level shifters than the one shown here!
Any comments or corrections are welcomed.
Moderators: Please feel free to move this post to another section, if you think it fits better there.