Go Down

Topic: Program hangs on SD.begin() (Read 889 times) previous topic - next topic


Oct 23, 2012, 01:36 pm Last Edit: Oct 23, 2012, 01:42 pm by scswift Reason: 1
I am having trouble interfacing with my SD card and I've discovered that my program is hanging right at the start, in SD.begin().  It never exits from this function even though it is supposed to error if it cannot initialize the card.

(I am using a sanguino variant that uses a 1284P)

I tried changing the MOSI pin to my onboard LED just to see if it was even trying to send data and it just remains solid.

Here's the code:

Code: [Select]

  SD card datalogger

This example shows how to log data from three analog sensors
to an SD card using the SD library.

The circuit:
* analog sensors on analog ins 0, 1, and 2
* SD card attached to SPI bus as follows:
** MOSI - pin 11
** MISO - pin 12
** CLK - pin 13
** CS - pin 4

created  24 Nov 2010
modified 9 Apr 2012
by Tom Igoe

This example code is in the public domain.


#include <SD.h>

// On the Ethernet Shield, CS is pin 4. Note that even if it's not
// used as the CS pin, the hardware CS pin (10 on most Arduino boards,
// 53 on the Mega) must be left as an output or the SD library
// functions will not work.
//const int chipSelect = 4;
int led = 13;

void setup()
   pinMode(led, OUTPUT);   
  digitalWrite(led, HIGH);
// Open serial communications and wait for port to open:
//  while (!Serial) {
//   ; // wait for serial port to connect. Needed for Leonardo only

  //Serial.print("Initializing SD card...");
  // make sure that the default chip select pin is set to
  // output, even if you don't use it:
  //pinMode(10, OUTPUT);

  // see if the card is present and can be initialized:
  if (!SD.begin(SS)) {
    digitalWrite(led, LOW);
    //Serial.println("Card failed, or not present");
    // don't do anything more:
   digitalWrite(led, LOW);
  //Serial.println("card initialized.");

void loop()
  // make a string for assembling the data to log:
  String dataString = "";

  // read three sensors and append to the string:
  for (int analogPin = 0; analogPin < 3; analogPin++) {
    int sensor = analogRead(analogPin);
    dataString += String(sensor);
    if (analogPin < 2) {
      dataString += ",";

  // open the file. note that only one file can be open at a time,
  // so you have to close this one before opening another.
  File dataFile = SD.open("datalog.txt", FILE_WRITE);

  digitalWrite(led, LOW);

  // if the file is available, write to it:
  if (dataFile) {
    // print to the serial port too:
  // if the file isn't open, pop up an error:
  else {
    //Serial.println("error opening datalog.txt");

Code: [Select]

#elif defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644__) || defined(__AVR_ATmega1284P__) || defined(__AVR_ATmega1284__)

// Sanguino

// Two Wire (aka I2C) ports
uint8_t const SDA_PIN = 17;
uint8_t const SCL_PIN = 18;

// SPI port
uint8_t const SS_PIN = 1;
uint8_t const MOSI_PIN = 9;
uint8_t const MISO_PIN = 8;
uint8_t const SCK_PIN = 0;

static const pin_map_t digitalPinMap[] = {
  {&DDRB, &PINB, &PORTB, 0},  // B0  0
  {&DDRB, &PINB, &PORTB, 1},  // B1  1
  {&DDRB, &PINB, &PORTB, 2},  // B2  2
  {&DDRB, &PINB, &PORTB, 3},  // B3  3
  {&DDRB, &PINB, &PORTB, 4},  // B4  4
  {&DDRB, &PINB, &PORTB, 5},  // B5  5
  {&DDRB, &PINB, &PORTB, 6},  // B6  6
  {&DDRB, &PINB, &PORTB, 7},  // B7  7
  {&DDRD, &PIND, &PORTD, 0},  // D0  8
  {&DDRD, &PIND, &PORTD, 1},  // D1  9
  {&DDRD, &PIND, &PORTD, 2},  // D2 10
  {&DDRD, &PIND, &PORTD, 3},  // D3 11
  {&DDRD, &PIND, &PORTD, 4},  // D4 12
  {&DDRD, &PIND, &PORTD, 5},  // D5 13
  {&DDRD, &PIND, &PORTD, 6},  // D6 14
  {&DDRD, &PIND, &PORTD, 7},  // D7 15
  {&DDRC, &PINC, &PORTC, 0},  // C0 16
  {&DDRC, &PINC, &PORTC, 1},  // C1 17
  {&DDRC, &PINC, &PORTC, 2},  // C2 18
  {&DDRC, &PINC, &PORTC, 3},  // C3 19
  {&DDRC, &PINC, &PORTC, 4},  // C4 20
  {&DDRC, &PINC, &PORTC, 5},  // C5 21
  {&DDRC, &PINC, &PORTC, 6},  // C6 22
  {&DDRC, &PINC, &PORTC, 7},  // C7 23
  {&DDRA, &PINA, &PORTA, 7},  // A7 24
  {&DDRA, &PINA, &PORTA, 6},  // A6 25
  {&DDRA, &PINA, &PORTA, 5},  // A5 26
  {&DDRA, &PINA, &PORTA, 4},  // A4 27
  {&DDRA, &PINA, &PORTA, 3},  // A3 28
  {&DDRA, &PINA, &PORTA, 2},  // A2 29
  {&DDRA, &PINA, &PORTA, 1},  // A1 30
  {&DDRA, &PINA, &PORTA, 0}   // A0 31


Well I think I found the source of my problems, though it does not explain why SD.Begin() hangs.

I had read that the USART on the 1284P could be used for another SPI but at no point was it mentioned that it uses different registers and works a bit different from the regular SPI, so I can't simply change the SPI pins to those of the USART unless perhaps I am using a soft-SPI where the pins are toggled manually instead of hardware SPI.

Anyway that means that it's likely I will have to go through all these libs and figure out how to change all the registers to make them work properly with the USART. :(

If only I'd known this would be an issue I'd have stuck my DAC on the USART and the SD card on the SPI.


If you want to use a serial port in SPI mode start with this version of SdFat SdFatBeta20121020.zip http://code.google.com/p/beta-lib/downloads/list.

It is designed to support various SPI controllers.  You just need to write the low level spi read/write functions for AVR serial ports.


Thanks, I'll check that out.  Unfortunately I also need to use the WaveHC library.  I'm gonna have to either figure out how to make that work along side this since it doesn't have write functionality, or convert it to use this.


I have no idea where to start with this.  Which functions do I need to modify in what files?

Go Up

Please enter a valid email to subscribe

Confirm your email address

We need to confirm your email address.
To complete the subscription, please click the link in the email we just sent you.

Thank you for subscribing!

via Egeo 16
Torino, 10131