FAT32/SDHC library for Wave and other shields
Moderators: adafruit_support_bill, adafruit

FAT32/SDHC library for Wave and other shields

by fat16lib on Mon Feb 02, 2009 2:01 pm

I have developed a new library to support both FAT16 and FAT32 file systems on Standard SD cards and high capacity SDHC cards. Access to sub directories is supported. The library has been optimized for high performance applications like the wave shield. It is about 3K smaller than AF_Wave and runs well on 168 Arduinos. The DAC programs in this library are modified versions from Ladyada's library.

The library for the Wave shield can be downloaded at:

http://code.google.com/p/wavehc/

Try the example sketches dap_hc.pde and pispeak_hc.pde

I am interested in feedback on the use of SDHC cards on the Wave Shield.

Unfortunately most Arduino shields do not meet the minimum bus requirements for SDHC cards. The SDHC spec requires a clock rise time of under 10 ns.

SDHC cards have a 3.3 V bus so most Adruino shields, like the Wave Shield, use a resistor voltage divider to shift bus levels from 5V to 3.3V. These voltage dividers can not meet the 10 ns rise time for most SDHC cards.

Most standard, low capacity, SD cards are tolerant of the higher clock rise times and work with these shields.

About half of the SDHC cards that I have tried are flaky on the Wave shield. I would like feedback from others on their results with SDHC cards.

I have modified a Wave Shield by adding a 74LCX245 IC as the level shifter. This version of the Wave Shield works with all SDHC cards that I have tested.

It would be nice if future versions of shields with SD sockets used IC level shifters since most new SDHC cards have a 10 ns maximum clock rise time for the spi bus.

Here is the spec for low speed, under 25 MHz, use of the SDHC bus.
Attachments
SdBus.png
SDHC bus spec
SdBus.png (86.11 KiB) Viewed 18132 times
fat16lib
 
Posts: 593
Joined: Wed Dec 24, 2008 1:54 pm

Re: FAT32/SDHC library for Wave and other shields

by adafruit on Mon Feb 02, 2009 5:16 pm

awesome awesome awesome. im almost caught up with other terribleness so can redo the wave shield library this week
(i took care of the motor shield library rewrite a few days ago and its +++ better now)
thanks for your help!!!
User avatar
adafruit
 
Posts: 11745
Joined: Thu Apr 06, 2006 4:21 pm
Location: nyc

Re: FAT32/SDHC library for Wave and other shields

by acquisition on Mon Feb 09, 2009 3:07 pm

Will this allow for reading from data stored on the GPS Shield?
User avatar
acquisition
 
Posts: 14
Joined: Mon Feb 09, 2009 3:06 pm

Re: FAT32/SDHC library for Wave and other shields

by local_dani_21 on Sat Apr 25, 2009 5:47 pm

Would you mind listing the SDHC-Cards that worked with the Wave Shield? I'm very interested in being able to use lots of storage room.

The alteration with the levelshifter you did on your wave shield. Is that something you could post so I could copy it?

Thank you!
local_dani_21
 
Posts: 87
Joined: Sun Apr 19, 2009 3:10 pm
Location: Zürich, Switzerland

Re: FAT32/SDHC library for Wave and other shields

by fat16lib on Sun Apr 26, 2009 9:28 am

Dani,

Here is how I modified a Wave Shield. I will followup with comments on testing SDHC cards.

I replaced R1, R2, R3, R4, R5, R6, and D1 with a 74HC4050N. I cut half the pins (9 - 16) off and soldered wires to pins 1 - 8. I soldered the wires into holes for the replaced parts. Other ICs will work. Ladyada used a 74AHC125N in the XBee Adapter kit.

Here is a schematic and picture before the rest of the components for the Wave Shield were added.

Bill
Attachments
wave3.jpg
wave3.jpg (345.63 KiB) Viewed 17921 times
SdBuffer.png
SdBuffer.png (20.93 KiB) Viewed 17911 times
fat16lib
 
Posts: 593
Joined: Wed Dec 24, 2008 1:54 pm

Re: FAT32/SDHC library for Wave and other shields

by phil.drummond on Sun Apr 26, 2009 12:19 pm

Nice looking job! Had I not -just- completed building my GPS Logger Shield, I would have incorporated this mod into the original build. I will try this later-on after I have some code under my belt.
Thanks for the mod!

Phil

Oh, my kit worked first-try, thank you Adafruit!
phil.drummond
 
Posts: 125
Joined: Sun Feb 08, 2009 4:57 pm

Re: FAT32/SDHC library for Wave and other shields

by fat16lib on Sun Apr 26, 2009 12:22 pm

Dani,

Here are the results of testing some SDHC cards.

First testing SDHC cards on a PC or Mac does not prove they will work with an Arduino shield since the PC/Mac will access the card in "SD mode" which uses a different protocol, different clock rates (up to 50 MHz on PC/Mac) and different signals (4 bit wide for PC/Mac, 1 bit wide for the Arduino).

The Wave Shield accesses SD cards in SPI mode at a max of 8 MHz. SD cards are 3.3 V devices so signals from the Arduino must be shifted from 5 V to 3.3 V. The Wave and GPS Shields use a resistor network which causes the signals to have slower rise times than the SDHC/SPI spec. Many SPHC cards are tolerant and work with these shields.

I modified a Wave Shield, as described above, to uses a 74HC4050N level shifter. This shield works with all but one SDHC card that I have tested. The card that fails seems to have a bad block and always fails when reading that block.

Also note that manufactures change the internals of SD cards often so two cards that look the same and have the same product name/model may be different versions and not work the same.

Here are the results for seven cards. Four work on the original Wave Shield and six work on the modified shield. The seventh, an A Data card, has a bad block and fails on both when reading that block.

The test is to read 10 MB spread over the card. It takes about 23 seconds, 23000 mills, to do the read or a rate of about 400 KB/sec.

I have attached a photo of the cards. Those in the top row work with the unmodified Wave Shield.

Results for an unmodified Wave Shield:
Code: Select all | TOGGLE FULL SIZE
SanDisk Ultra II 8GB
init time: 40
OEM name: SD
Product: SD08G
Version: 8.0
Serial Number: 1015562096
Manufacture Date: 12/2008
Size: 15954944
Read 20000 blocks
Read Time mills: 22602
Success


SanDisk Ultra II 4GB
init time: 101
OEM name: SD
Product: SD04G
Version: 8.0
Serial Number: 1908630400
Manufacture Date: 12/2008
Size: 7959552
Read 20000 blocks
Read Time mills: 22582
Success

Transcend class 6 8GB
init time: 164
OEM name: SV
Product: SDC
Version: 1.0
Serial Number: 3372482560
Manufacture Date: 12/2007
Size: 15758336
Read 20000 blocks
Read Time mills: 21475
Success

SanDisk SDHC standard 4GB
init time: 164
OEM name: SD
Product: SD04G
Version: 8.0
Serial Number: 2933412448
Manufacture Date: 12/2008
Size: 7744512
Read 20000 blocks
Read Time mills: 22440
Success

Trancend Class 6 4GB
init time: 141
OEM name: SV
Product: SDC
Version: 1.0
Serial Number: 2377089089
Manufacture Date: 10/2008
Size: 7811072
Read 10293 blocks
Read Time mills: 13560
lbn: 4014270
error: Read Failure
errorCode: 10
errorData: 0

Kingston SD6/4GB
init time: 184
OEM name: 42
Product: SD4GB
Version: 2.0
Serial Number: 3493658715
Manufacture Date: 12/2008
Size: 7839744
Read 9683 blocks
Read Time mills: 11196
lbn: 3786053
error: Read Failure
errorCode: 10
errorData: FC

A Data 4GB calss6
init time: 118
OEM name: AD
Product: SD
Version: 0.0
Serial Number: 3473184768
Manufacture Date: 1/2008
Size: 7897088
Read 10157 blocks
Read Time mills: 16187
lbn: 4001858
error: Read Failure
errorCode: 10
errorData: FF


Results on the modified Wave Shield:

Code: Select all | TOGGLE FULL SIZE
SanDisk Ultra II 8GB
init time: 116
OEM name: SD
Product: SD08G
Version: 8.0
Serial Number: 1015562096
Manufacture Date: 12/2008
Size: 15954944
Read 20000 blocks
Read Time mills: 22601
Success

SanDisk Ultra II 4GB
init time: 100
OEM name: SD
Product: SD04G
Version: 8.0
Serial Number: 1908630400
Manufacture Date: 12/2008
Size: 7959552
Read 20000 blocks
Read Time mills: 22584
Success

Transcend class 6 8GB
init time: 164
OEM name: SV
Product: SDC
Version: 1.0
Serial Number: 3372482560
Manufacture Date: 12/2007
Size: 15758336
Read 20000 blocks
Read Time mills: 21471
Success

SanDisk SDHC standard 4GB
init time: 164
OEM name: SD
Product: SD04G
Version: 8.0
Serial Number: 2933412448
Manufacture Date: 12/2008
Size: 7744512
Read 20000 blocks
Read Time mills: 22441
Success

Trancend Class 6 4GB
init time: 141
OEM name: SV
Product: SDC
Version: 1.0
Serial Number: 2377089089
Manufacture Date: 10/2008
Size: 7811072
Read 20000 blocks
Read Time mills: 26739
Success

Kingston SD6/4GB
init time: 182
OEM name: 42
Product: SD4GB
Version: 2.0
Serial Number: 3493658715
Manufacture Date: 12/2008
Size: 7839744
Read 20000 blocks
Read Time mills: 23101
Success

A Data 4GB calss6
init time: 117
OEM name: AD
Product: SD
Version: 0.0
Serial Number: 3473184768
Manufacture Date: 1/2008
Size: 7897088
Read 10157 blocks
Read Time mills: 16188
lbn: 4001858
error: Read Failure
errorCode: 10
errorData: FF
Attachments
SdCards.jpg
SdCards.jpg (168.88 KiB) Viewed 17908 times
fat16lib
 
Posts: 593
Joined: Wed Dec 24, 2008 1:54 pm

Re: FAT32/SDHC library for Wave and other shields

by local_dani_21 on Mon Apr 27, 2009 2:31 pm

Bill

Great! Thank you for the instructions. I'll first try one of the successfully tested SDHC cards on my unmodified WaveShield and if it doesn't work, I'll get to the chip-modding! Looking forward to doing this (well, at least a bit :)!

Dani
local_dani_21
 
Posts: 87
Joined: Sun Apr 19, 2009 3:10 pm
Location: Zürich, Switzerland

Re: FAT32/SDHC library for Wave and other shields

by fat16lib on Thu Apr 30, 2009 10:39 am

I am posting this sketch to help diagnose SD card problems when using the WaveHC library with a Wave Shield.

This sketch checks for problems with low level access to SD cards. The Wave Shield accesses the SD card in SPI mode. Cards that work on a Mac or PC can be marginal in SPI mode (see above posts).

Please run the following sketch which does a read stress test. It takes about 20 seconds to run and reads 10 MB at about 500 KB/second. Run it several times.

You must set SD_CARD_SIZE_SUPPORT to 1 in SdCard.h and delete all the .o files in the WaveHC library.

Bill

Code: Select all | TOGGLE FULL SIZE
// this sketch wiil do a read stress test on a SD card.
// set SD_CARD_SIZE_SUPPORT to 1 in SdCard.h
// delete all .o files in the WaveHC library to force a rebuild.

#include <avr/pgmspace.h>
#include "SdCard.h"
#include "WaveUtil.h"
SdCard card;

uint8_t cidDmp(void)
{
  cid_t cid;
  if (!card.readCID(cid)) {
    putstring("readCID failed");
    sdError();
    return 0;
  }
  putstring("\nManufacturer ID: ");
  Serial.println(cid.mid, HEX);
  putstring("OEM ID: ");
  Serial.print(cid.oid[0]);
  Serial.println(cid.oid[1]);
  putstring("Product: ");
  for (uint8_t i = 0; i < 5; i++)Serial.print(cid.pnm[i]);
  putstring("\nVersion: ");
  Serial.print(cid.prv_n, DEC);
  Serial.print('.');
  Serial.println(cid.prv_m, DEC);
  putstring("Serial number: ");
  Serial.println(cid.psn);
  putstring("Manufacturing date: ");
  Serial.print(cid.mdt_month);
  Serial.print('/');
  Serial.println(2000 + cid.mdt_year_low + (cid.mdt_year_high <<4));
  Serial.println();
  return 1;
}
void sdError(void)
{
  putstring_nl("SD error");
  putstring("errorCode: ");Serial.println(card.errorCode(), HEX);
  putstring("errorData: ");Serial.println(card.errorData(), HEX); 
  return;
}
void setup(void)
{
  Serial.begin(9600);
}

void loop(void)
{
  putstring_nl("\ntype any character to start");
  while (!Serial.available());
  Serial.flush();
  uint32_t t0 = millis();
  uint8_t r = card.init(0);
  uint32_t d = millis()- t0;
  if (!r) {
    putstring_nl("\ncard.init failed");
    sdError();
    return;
  }
  putstring("\ninit time: ");Serial.println(d);
    putstring("\nCard type: ");
  switch(card.type()) {
    case SD_CARD_TYPE_SD1:
      putstring_nl("SD1");
      break;
    case SD_CARD_TYPE_SD2:
      putstring_nl("SD2");
      break;
    case SD_CARD_TYPE_SDHC:
      putstring_nl("SDHC");
      break;
    default:
      putstring_nl("Unknown");
  }
 
  if(!cidDmp()) return;
  uint32_t size = card.cardSize();
  if (size == 0) {
    putstring("cardSize failed");
    sdError();
    return;
  }
  putstring("card size: ");
  Serial.print(size);
  putstring(" (512 byte blocks)\n");
  uint16_t nTest = 20000;
  uint16_t nRead = 0;
  uint8_t buf[2];
  d = size/nTest;
  uint32_t b;
  uint32_t m0 = millis();
  for (nRead = 0; nRead < nTest; nRead++){
    b = nRead*d;
    if (!(r = card.readData(b, 510, buf, 2))) break;
    if (nRead == 0 && (buf[0] != 0X55 || buf[1] != 0XAA)) {
      putstring("Invalid block zero signature: ");
      Serial.print(buf[0], HEX);
      Serial.print(',');
      Serial.println(buf[1], HEX);
    }
  }
  uint32_t m1 = millis();
  putstring("\nRead ");
  Serial.print(nRead);putstring_nl(" blocks");
  putstring("mills: ");Serial.println(m1 - m0);
  if(r) {
    putstring_nl("\nDone");
  }
  else {
    putstring_nl("\nRead Failure");
    putstring("lbn: ");Serial.println(b); 
    sdError();
  }
}
fat16lib
 
Posts: 593
Joined: Wed Dec 24, 2008 1:54 pm

Re: FAT32/SDHC library for Wave and other shields

by local_dani_21 on Sun May 10, 2009 9:31 am

I bought (www.digitec.ch, 22 CHF) two Sandisk 4GB Standard SDHC-Cards (see picture above) and they work fine with the unaltered arduino/waveshield!
Thanks for the tip, Bill!

Dani
local_dani_21
 
Posts: 87
Joined: Sun Apr 19, 2009 3:10 pm
Location: Zürich, Switzerland

Re: FAT32/SDHC library for Wave and other shields

by LiveRock on Wed May 20, 2009 2:03 am

Hi

Looking at the picture of the 74HC4050, I can't tell everything component has been replaced by it.
for example, it seems to me that the diode is omitted? Not used?
Does the addition of the 74HC4050 eliminate some components?

Please help me. I am halfway thru soldering and discovered this observation and wonder how to continue....

Thanks!
LiveRock
 
Posts: 26
Joined: Sun May 17, 2009 10:33 pm

Re: FAT32/SDHC library for Wave and other shields

by fat16lib on Wed May 20, 2009 4:49 am

The instructions above the picture state R1, R2, R3, R4, R5, R6, and D1 are replaced.

The pins of the IC are connected to the holes for R1, R3, and R5 as follows. Pins 6 and 7 to the holes for R1. Pins 2 and 3 to the holes for R5. Pins 4 and 5 to the holes for R3.

Pin 8 of the IC is connected to the GND end of R2 and pin 1 to the hole for +3.3 as shown in the picture.
fat16lib
 
Posts: 593
Joined: Wed Dec 24, 2008 1:54 pm

Re: FAT32/SDHC library for Wave and other shields

by LiveRock on Wed May 20, 2009 5:37 am

Pardon me but does that mean R2, R4, R6 and D1 will be empty? (not used)
or
R2, R4, R6, D1 are used, 74HC4050 is replacing only R1,R3,R5.

"Pin 8 of the IC is connected to the GND end of R2"
Not sure what you mean...
Sorry, I am not very clear... thanks for your patience...
LiveRock
 
Posts: 26
Joined: Sun May 17, 2009 10:33 pm

Re: FAT32/SDHC library for Wave and other shields

by LiveRock on Wed May 20, 2009 11:02 pm

Hi

Thanks for the detailed info.

Here is mine PCB:

Image

Thanks!
Last edited by LiveRock on Fri May 22, 2009 11:35 pm, edited 1 time in total.
LiveRock
 
Posts: 26
Joined: Sun May 17, 2009 10:33 pm

Re: FAT32/SDHC library for Wave and other shields

by zachtos on Wed May 20, 2009 11:26 pm

Anyone care to post a simple example on how to call a wave file using this library? I'm not familiar with classes or what special procedures are required for this library. I do have it working for the original library, but want the pause/resume function of this one so I can finish my laser tag project.

>>>>>>>
OK, I give up. What code do I need to have at the start of my program to call a simple Play() command?

IE, give an example, as your examples are too confusing for me to interpret. I just want to open the file, and play it, pause/resume, and close when I'm done. What are the steps to accomplish this easily?
zachtos
 
Posts: 77
Joined: Sun May 03, 2009 8:18 pm