3v3 pro mini interfacing to SD bug - SOLVED

Hi there,

I am working on a project taking an X,Y and Z reading from an adxl335 accelerometer using the onboard ADC and am storing those values to an SD card at 500 Hz. I've had the code working on a 5v pro mini but recently switched to a 3v3 pro mini do to simplicity (not needing to step up the 3.7 volts from the battery to 5v). However, the 3v3 pro mini will not recognize the SD card! It returns errors about the format.

However, if I run the SD card on 5 volts (I did this by accident) it works fine and writes to the SD card fine.

Has anyone run into this before, or have any ideas about where to look?

Below is my code though it will work fine on a 5 volt board or when the 3v3 board is powered with 5 volts:

/*
 * This sketch is a simple binary write/read benchmark.
 */
#include <SdFat.h>
#include <SdFatUtil.h>

//String r32 = "zz";
int vx = 0;
int vy = 0;
int vz = 0;
int r1 = 0;
int r2 = 0;

const int flasher = 9;
uint32_t m;
unsigned long LOG_INTERVAL;
unsigned long TWO_LOG;

char lookup32[] = 
{
  '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V'
};
// 0   1   2   3   4   5   6   7   8   9  10  11  12  13  14  15  16  17  18  19  20  21  22  23  24  25  26  27  28  29  30  31 


// SD chip select pin
const uint8_t chipSelect = SS_PIN;

// text file for logging
ofstream logfile;

#define FILE_SIZE_KB 12
//SET TO 24 before sending out


#define SAMPLES_PER_SECOND 2  // mills between entries
#define FILE_SIZE (1000UL*FILE_SIZE_KB)

#define BUF_SIZE 8

uint8_t buf[BUF_SIZE];

SdFat sd;

SdFile file;

ArduinoOutStream cout(Serial);
//------------------------------------------------------------------------------
// store error strings in flash to save RAM
#define error(s) sd.errorHalt_P(PSTR(s))
//------------------------------------------------------------------------------

void createbuffer()
{
  
  // fill buf with known data
//   delay(10);
  vx = analogRead(A2);  // 230us per line - X chan
//   delay(10);
   
  base32(vx);
  buf[BUF_SIZE-8] = lookup32[r2];
  buf[BUF_SIZE-7] = lookup32[r1];
  
//   delay(10);
  vy = analogRead(A1);  // Y read
//   delay(10);
   
  base32(vy);
  buf[BUF_SIZE-6] = lookup32[r2];
  buf[BUF_SIZE-5] = lookup32[r1];
  
//  delay(10);
  vz = analogRead(A0);  // Z read
//   delay(10);
   
  base32(vz);
  buf[BUF_SIZE-4] = lookup32[r2];
  buf[BUF_SIZE-3] = lookup32[r1];

  buf[BUF_SIZE-2] = '\r';
  buf[BUF_SIZE-1] = '\n'; 
  
  return;
}


void base32(int number)
{
  
  int n1 = int(number/32);
   r1 = number - 32 * n1;
  int n2 = int(n1/32);
   r2 = n1 - n2;

  return;
}


void setup() {
  Serial.begin(9600);
  
  pinMode(flasher, OUTPUT);
  digitalWrite(flasher, LOW); 
  
  if (!sd.init(SPI_FULL_SPEED, chipSelect)) sd.initErrorHalt();
  
  char name[] = "LOG00.TXT";

  for (uint8_t i = 0; i < 100; i++) {
    name[3] = i/10 + '0';
    name[4] = i%10 + '0';
    if (sd.exists(name)) continue;
       file.open(name, O_CREAT | O_TRUNC | O_RDWR);
    break;
  }
}
//------------------------------------------------------------------------------
void loop() 
{ 
 // do write test
  uint32_t n = FILE_SIZE/sizeof(buf);

  for (uint32_t i = 0; i < n; i++) {
    digitalWrite(flasher, HIGH); 
    createbuffer();
    digitalWrite(flasher, LOW); 
    delayMicroseconds(955); //Controls 500Hz Sampling Rate    

    
    if (file.write(buf, sizeof(buf)) != sizeof(buf)) {
      error("write failed");
    }
  }

  file.sync();
 
}

How is the SD card connected to the 3v3 pro mini?

When it does work I suspect you will drop data points. Often write takes much longer than 2 ms.

Does that matter?

Also the 3v3 pro mini is 8 MHz so writing the SD will take even longer.

To avoid dropping data points I only sync once large sets of data are collected. Though during the syncing process some data points are lost.

PIN 10 is connected directly to CS
PIN 11 is connected directly to DI
PIN 12 is connected directly to DO
PIN 13 is connected directly to SCLK

As the arduino runs on 3.3 volts these are direct connections with no pull up or pull down resistors.

Cheers

Make sure your 3.3V source has enough current capability also.

It has 100 mA with a good selection of capacitors on it (.47uF, 1uF, 47uf).

I believe this is more then enough for an SD card and an arduino (about 20 mA + 20 mA) the accelerometer uses about 60 uA i believe.

Cheers

Run the SdInfo.pde sketch using the latest version of SdFat Google Code Archive - Long-term storage for Google Code Project Hosting.. Post the output.

The pro 3v3 mini works for me. I use a 3v3 FTDI to connect to it and power it.

I connect directly to SPI pins 10 -13 using this socket SparkFun microSD Transflash Breakout - BOB-00544 - SparkFun Electronics.

You will drop data points even if you don't call sync(). When a cluster needs to be added to a file a lot of I/O is done. This can take much longer than a sync() call.

That is why I developed faster data loggers. Betas are here Google Code Archive - Long-term storage for Google Code Project Hosting.

"It has 100 mA"
"I believe this is more then enough for an SD card and an arduino "

I don't believe it is. I think you need more current capability. If you look at the shields for SD cards that generate their own 3.3V, they supply higher current. Example:

http://www.ladyada.net/make/logshield/design.html

"There is a small power supply on the board for generating 3.3V @ 250mA. We don't use the 'built in' 3.3v regulator on the Arduino because its only guaranteed up to 50mA and some SD card need a lot of power when writing. This supply is nice and steady, we can use it as an analog reference too! We have two sets of bypass caps to try and keep both 5V and 3.3V supply nice and clean - the 100uF ones are for the low frequency noise and 0.1 for higher frequency"

Skyjumper did testing with his design recently, we had to increase the 3.3V regulator to a higher current part for the SD card to work correctly.

The current for SD cards varies over a huge range.

My microSD idles at about 1 ma and draws less than 20 ma max during write.

I power the a micro SD and the pro mini with a FTDI module.

What card are you using?

Hey there,

I've run SDinfo.pde and this is what I got:

type any character to start

card.init failed
SD errorCode: 0X8
SD errorData: 0X1

type any character to start

init time: 6 ms

Card type: SD2

Manufacturer ID: 0X4
OEM ID: A
Product: SMI-S
Version: 4.4
Serial number: 3
Manufacturing date: 6/2001

cardSize: 1024 (512 byte blocks)
flashEraseSize: 32 blocks
eraseSingleBlock: false
read MBR failed
SD errorCode: 0XF
SD errorData: 0XFF

I think it is really weird that the first run fails yet the following runs work!

The card is a 1GB SDmicro from sparkfun

I've played around with powering the device and it works if I supply the 4 volts raw to the arduino (on the Vcc pin) with the sd card running off the regulated 3.3volts but it doesn't work if I give the arduino 3.3 volts and the sd card power the 4 volts.

I just ran a test where I used a high quality lab power supply to supply the 3.3 volts to the arduino (vcc) and SD card. The board would not communicate and yet when the voltage was raised to 5 volts it would communicate (dropping out at 4 volts).

Therefore I have to conclude that there is some strange glitch on the arduino as it will not communicate at voltages below 4 volts even though it is a 3.3 volt board. Communication is fine if the SD card is supplied with 3.3 volts and if only the arduino is at the higher voltage. I built up a second circuit to see if this was a one off error but both boards have the same issue (maybe I bought from a bad batch, though the sketches upload fine). I am currently checking to see if uploading a new bootloader will help.

PS Those faster data loggers sound really interesting!

Any suggestions for brands of SD cards that have a good reputation?

I just tried re-burning the bootloader onto the arduino and powering the device via the FTDI breakout. No luck, though if I boost the voltage to 5 volts it works. I'm very confused at this point as I feel like I have tried almost every possibility. Would you have some example code I could examine that you use with the 3.3 volt pro mini. Right now I'm looking into if there is an issue with the SPI_FULL_SPEED writes.

I just use the SdFat examples from the SdFat/examples folder.

You shouldn't need to do anything special for the 8 MHz pro mini. Full speed SPI will be 4 MHz.

I would check the VCC pin on the pro mini. If it is more than 3.3 V something is wrong. I assume you put the 5V on the "RAW" pin.

I don't think it is the SD. SD cards are tolerant to a wide range of voltages. The OCR, operation conditions register, on cards I try have the range of 2.7-3.6 V.

The problem is logic levels expected by the CPU chip since the SD output levels will be low if the SD VDD voltage is low.

On my 3.3V and 5V pro minis the only difference I can see are black dots on the back. Maybe your 3v3 is miss marked.

So I've found a fix though it is a bit sloppy.

Basically I went to a shop and bought every 2gb microSD card they had then tested them to see if it was a card issue.

All the cards continued to fail except for a DANE-ELEC 2 gb card, which is working flawlessly.

So I didn't find or figure out what is causing the issue but fortunately I've found an acceptable work around.

So far I've used:
Jony 1gb - From sparkfun - FAILED
Unnamed 1 gb - From sparkfun - FAILED
Kingston 2gb -FAILED
NEXXTECH 2gb - FAILED
DANE-ELEC 2 gb - WORKS!! (also the cheapest card being sold)

So.... It actually looks like the issue was that I wasn't grounding the SD card! It blows my mind as the board was a revision of an earlier one so I never thought to think of it.

Programs like SDinfo were even returning information about the card, despite the fact that it wasn't grounded. I honestly can't believe that that one version of SD card was actually able to run without a ground!

Needless to say I feel like I learned a thing or two on that one :blush: