Show Posts
Pages: 1 ... 68 69 [70] 71 72 ... 112
1036  Using Arduino / Storage / Re: SdFat - card detection via CS support on: July 30, 2012, 03:41:31 pm

Yes I know what the SanDisk manual says.

It's just doesn't work for AVR with level shifters.

SS may already be in output mode due to other libraries.  It's just too messy to be worth doing in Arduino libraries.
1037  Using Arduino / Storage / Re: SdFat - card detection via CS support on: July 30, 2012, 03:11:20 pm

It is not a good idea for Arduino. 

Arduino is 5V and SD is 3.3V so all good shields/modules have a level shifter.  You can't tell if a card is in the module because of the level shifter.

The Card Presence Switch on SD sockets is the correct way.

I now remember that ACMD42 connects or disconnects the 50K pullup on CS.  The problem is you can't send ACMD42 until the card is in SPI mode but CMD0 to put the card in SPI mode will fail if the card is not present.

So you can't toggle the pullup to make sure you seeing the card's 50K.

Since SS must be an output for SPI to work on AVR, other SPI libraries enable it so if SS is also CS (pin 10 on a 328) you should not make SS an input so you can't use the pullup idea.
1038  Using Arduino / Storage / Re: Is my sd card compatible with SD.h on: July 30, 2012, 01:30:39 pm
SdFat and SD.h accept FAT16 and FAT32 if formatted to the SD format standard.

A card may work in a MAC/PC but not work with Arduino.

If you formatted it with an OS utility it may not work with an Arduino since many OS utilities do no comply with the SD format standard.  Use this formatter to insure the format complies with the SD standard

In a PC, MAC, or camera the SD is accessed using the 4-bit SDIO bus.  In the Arduino the SD is accessed using the SPI bus.  It is possible that SPI access fails but you can access it via a PC/MAC.

The most common formatting problem is that the SD has a GUID Partition Table.  The SD standard require a MBR Partition Table and SD.h/ SdFat only accepts MBR.  Windows and OS X accept GUID Partition tables.  The above formatter will fix this problem.
1039  Using Arduino / Storage / Re: SDFat - pulling out the card on: July 30, 2012, 09:43:29 am
The pullup is not a good idea.  CS is in output mode while the SD is in use.

If you are writing once every five minutes just init the card each time you write.

With the latest version of SdFat,

I would do something like this:
#include <SdFat.h>
SdFat sd;
SdFile myFile;
// LED to flash just after write
const uint8_t LED_PIN = 3;
const uint8_t chipSelect = 10;
void setup() {
  pinMode(LED_PIN, OUTPUT);

void loop() {
  if (!sd.begin(chipSelect)) sd.initErrorHalt();

  // open the file for write at end like the Native SD library
  if (!"test.txt", O_WRITE | O_CREAT | O_AT_END)) {
    sd.errorHalt("opening test.txt for write failed");
  // write your data
  // close the file:
  // delay five minutes
  digitalWrite(LED_PIN, HIGH);
  digitalWrite(LED_PIN, LOW);
You can pull the card after the LED flash.
1040  Using Arduino / Storage / Re: Which SD library to create file with date? on: July 30, 2012, 09:21:24 am
The version of SdFat used in 1.0 and 1.01 is the same old version used in 022 and before.  Only the SD.h wrapper has changed so this is still the best way.

If you had access to the SdFat API for files you could use the timestamp function to set all date/time fields on a per file basis.
bool SdBaseFile::timestamp    (    uint8_t     flags,
      uint16_t     year,
      uint8_t     month,
      uint8_t     day,
      uint8_t     hour,
      uint8_t     minute,
      uint8_t     second

Set a file's timestamps in its directory entry.

    [in]   flags   Values for flags are constructed by a bitwise-inclusive OR of flags from the following list

T_ACCESS - Set the file's last access date.

T_CREATE - Set the file's creation date and time.

T_WRITE - Set the file's last write/modification date and time.

    [in]   year   Valid range 1980 - 2107 inclusive.
    [in]   month   Valid range 1 - 12 inclusive.
    [in]   day   Valid range 1 - 31 inclusive.
    [in]   hour   Valid range 0 - 23 inclusive.
    [in]   minute   Valid range 0 - 59 inclusive.
    [in]   second   Valid range 0 - 59 inclusive

    It is possible to set an invalid date since there is no check for the number of days in a month.
    Modify and access timestamps may be overwritten if a date time callback function has been set by dateTimeCallback().

    The value one, true, is returned for success and the value zero, false, is returned for failure.

Or copy timestamps from another file:
bool SdBaseFile::timestamp    (    SdBaseFile *     file   )    

Copy a file's timestamps

    [in]   file   File to copy timestamps from.

    Modify and access timestamps may be overwritten if a date time callback function has been set by dateTimeCallback().

    The value one, true, is returned for success and the value zero, false, is returned for failure.

1041  Using Arduino / Storage / Re: SdFat - card detection via CS support on: July 30, 2012, 09:11:38 am
Card Present is done in a number of ways.  A pullup, the card present switch,...

It is almost always easier to read the pin before calling the SD begin/init function than tell SdFat how Card Present is done and then have the result of a digitalRead() returned.

Some of the most popular shields have a 10K pullup on CS and CS is always high in input mode.

Sometime resistor voltage dividers are used and the CS is always low in input mode.

In general pulling CS high is better than pulling CS weakly low and hoping all SD cards pull CS high.  This will cause fewer problems when the SPI bus is shared and another device is initialize before the SD.

Since Arduino is 5V, a level shifter is used on CS and you can't read the SD CS pin anyhow.
1042  Using Arduino / Storage / Re: Micro-SD Card not formatted on: July 29, 2012, 01:30:45 pm
pito's advice is better than mine on caps since he is running SD cards on very fast systems.

I really like a pullup between 3.3V and MISO on the card.  This holds MISO high when there is no card and insures there won't be a false acceptance of CMD0, the first initialization command.  This can happen due to noise on MISO since I do thousands of retries waiting for the card to go ready.  Success for this command is a status of 0X01 which can easily happen with noise and no CRC. 

0XFF is busy so if MISO is held high, commands fails with a busy timeout.
1043  Using Arduino / Storage / Re: Micro-SD Card not formatted on: July 29, 2012, 10:26:48 am
The SD status, errorData, has too many one bits to make sense.

For read CID the status 0X1F, would be:
• In idle state: The card is in idle state and running the initializing process.
• Erase reset: An erase sequence was cleared before executing because an out of erase sequence
command was received.
• Illegal command: An illegal command code was detected.
• Communication CRC error: The CRC check of the last command failed.
• Erase sequence error: An error in the sequence of erase commands occurred
This just can't be.  That's why I suspect MISO.
1044  Using Arduino / Storage / Re: Micro-SD Card not formatted on: July 29, 2012, 09:17:23 am
It's definitely an SPI problem.  It appears to nearly work.  This may because SdFat does retries during initialization.

Arduino does not support hardware CRC but SdFat has software CRC which is normally disabled.

Could you please edit SdFatConfig.h at about line 35 and enable CRC like this:
#define USE_SD_CRC 2

Then run SdInfo again.  This may give a better indication of where the problem is.

It would be great if there was a way to connect MISO directly without the level shifter.  Most SD shields connect MISO directly.  This works even though a high level of 3.3V seem marginal as an input to the ATmega.  

The spec says the Min high input is 0.6Vcc.  Guess it works since the Max low input is 0.3Vcc.


I checked some posting on AVR Freaks and the claim is:
The AVR clearly has much better specification, as at 5V vilmax is 0.42*Vcc=2.1V and vihmin is 0.52*Vcc=2.6V.
I guess this is why commercial shields work well.
1045  Using Arduino / Storage / Re: undocumented classes Sd2Card, SdVolume and SdFile on: July 28, 2012, 04:32:37 pm
I am not part of the Arduino company so I can only guess about the company's policy.

I believe the reason for the success of Arduino is that the company has targeted beginners and to do this simplicity is key. 

SD.h provides beginners with adequate functionality so from the Arduino company's point of view it "gets the job done".

This appears to be an excellent business policy but can be frustrating for more advanced users.

There is plenty of third party software but don't expect the Arduino group to support advanced users.
1046  Development / Suggestions for the Arduino Project / Re: How about adding digitalToggle(pin)? on: July 28, 2012, 04:13:59 pm
Guess I didn't make my case for toggle very well.  Here is an example where toggle is very useful.

In protocols like SPI, clock can have a polarity and signals have a phase.  This leads to the four SPI modes and makes handling clock messy in a general software SPI library.

There were lot of hard to understand lines like this where all I really wanted to do was toggle clock:
  fastDigitalWrite(SckPin, MODE_CPHA(Mode) ? MODE_CPOL(Mode) : !MODE_CPOL(Mode));
The code is much cleaner when write is replaced with toggle:
I am finding far more cases than I expected like the above where toggle is useful.

There was no speedup in the above case since all arguments are constant but in many cases you get a speedup and simpler code.
1047  Using Arduino / Storage / Re: Micro-SD Card not formatted on: July 28, 2012, 02:24:10 pm
Most likely it is not a format problem.  The only sure way to format an SD card to the SD standard is to use SDformatter

Other utilities do not comply with the standard and won't help solve your problem.

Most likely you have a low level I/O problems. 

It would be helpful if you ran two example from the SdFat library.  SdFat is located here

Run the SdInfo and QuickStart examples and post the error messages with error codes.

If you get a message like this with an errorCode, you have a basic SPI I/O problem.

From SdInfo:
card.init failed
SD errorCode: 0X1
SD errorData: 0XFF

From QuickStart:
SD initialization failed.
Do not reformat the card!
Is the card correctly inserted?
Is chipSelect set to the correct value?
Is there a wiring/soldering problem?
errorCode: 0x1, errorData: 0xff
1048  Development / Suggestions for the Arduino Project / Re: How about adding digitalToggle(pin)? on: July 28, 2012, 01:30:22 pm

Of course the case of fast write for a constant pin number has been around for years.  I have posted several versions based on classes and static functions that compile to a single sbi or cbi.  I like using static const arrays which the compiler optimizes out.  I did that in December 2009 for software SPI in SdFat but didn't post it until I saw your macros. 

For classes I use templates which forces a constant pin number without the gcc __builtin_constant_p(pin).

Toggle is useful for a constant pin number since it will toggle a pin in 125 ns.  You don't need to know the state of a pin to toggle it.

For a variable pin number it is fast since you don't need to do the atomic stuff.  You just write the bit you want to toggle to the PIN register.

As for digital I/O on SAM3X or ARM Cortex M in general, I hope I am not limited to the least common subset between AVR and ARM.  This is another reason I can't believe in AVR/ARM compatibility.

I don't expect to see toggle In the Arduino core but I added it to my digital libraries and was surprised how useful it can be.  I will be posting a new version of these libraries soon.
1049  Development / Suggestions for the Arduino Project / How about adding digitalToggle(pin)? on: July 28, 2012, 10:45:37 am
Here is a neat feature of AVR I/O ports:
The Port Input Pins I/O location is read only. However, writing a logic one to a bit in the PINx Register, will result in a toggle in the corresponding bit in the Data Register
This means that you could implement an efficient atomic digitalToggle(pin) function.  It should be faster than digitalWrite().  

It would be handy when you need to pulse a pin.  You just call digitalToggle(pin) twice.

I implemented toggle() like this as an inline function in a digital I/O class:
 void toggle() {*pinReg_ = bit_;}
This function executes in 8 cycles or 500 ns on a 16 MHz CPU.  This allows generation of a 500 ns pulse.

Not as good as the 125 ns that is possible when a pin number is a constant but is about 8 times faster than digitalWrite() which takes about 4 us.
1050  Using Arduino / Storage / Serious bug affects SD.h and String on: July 28, 2012, 09:59:38 am
There is a serious bug in 1.01 and some earlier Arduino versions that may cause crashes when you use SD.h and/or String.

The bug is in the function free() which deallocates memory.  

SD.h calls free() when you close a file.  

String may call free() when the size of a string changes or in destructors.

Frequent opening and closing of files, especially multiple file, may cause a crash in SD.h.

See this for an example of the String problem,115552.0.html.

The above topic also describes two fixes for the free() bug.

The SdFat library does not call free().  The bug is in the Arduino SD.h wrapper for SdFat.
Pages: 1 ... 68 69 [70] 71 72 ... 112