Pages: [1]   Go Down
Author Topic: Trouble writing to SD card inside Interrupt Service Routine  (Read 832 times)
0 Members and 1 Guest are viewing this topic.
Montana
Offline Offline
Newbie
*
Karma: 0
Posts: 2
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I must admit to being quite new to Arduinos (been playing for about 6 weeks).  One problem I have not been able to solve on my own or with previous forum posts:

I can't seem to write to the SD card within a Timer1 ISR().  Is this not possible?  Or am I missing something?  I am able to write to the card when inside the setup, so I don't believe it's my card or shield.

I'm using the Mega 2560 with the Adafruit Data Logger Shield.  Here is the code that is refusing to work for me smiley 

Code:
/*

Timer interrupt.  Using 16bit Timer/Counter 1 for mega 2560

*/
const int chipSelect = 10;

#include <avr/interrupt.h>
#include <avr/io.h>
#include <SdFat.h>
 
unsigned int count = 0;

SdFat sd;
SdFile aFile;

//*****************************************************************
//   setup()
//*****************************************************************
void setup()  {
 
  Serial.begin(9600);    //testing
  pinMode(10, OUTPUT);   //SD card pin

  if (!sd.init(SPI_FULL_SPEED, chipSelect)) {
     Serial.println("init error");
    sd.initErrorHalt();
  }
  //***************setting up Timer1******************
   DDRB = 0x01;    //PB0 aka pin 53
   PORTB = 0x00;  //start with all pins LOW   
  //setup Timer1 to fire every 250ms
//  TCCR1A = 0x00;    //disable Timer1 while we set it up
  TCCR1B = 0x00;    //disable Timer1 while we set it up
  //reset timer/counter1
  TCNT1  = 0x0000;        //set counter to 0, to count up to Output Compare Register     
  TCCR1A  = 0x00;   //Timer1 Control Reg A: Wave Gen Mode normal
  //TCCR1B bits 2:0 clock select bits, 011=clk(io)/64(from prescalar)
  TCCR1B  = 0x03;   //Timer1 Control Reg B: prescalar set to 64
  OCR1A = 0xF487;    //set Output Compare Reg to 62499     
  //turn on timer1 
  TIMSK1 = 0x02;        //enable output compare interrupt for OCR1A 
  sei();    //enables interrupts
}            //************** end setup()
   

//***************************************
//    main loop()
//***************************************

void loop() 
{
 
}            //*********************end main loop()


//*******************************************
//        logSD()
//*******************************************
void logSD() 
{
      if (!aFile.open("log.csv", O_RDWR | O_CREAT | O_APPEND)) 
      {
         sd.errorHalt("opening log.csv for write failed in logSD()");
      }
      aFile.println("in loop");
      aFile.close();

}            //*************end logSD()

//********************************************************
//          ISR for Timer1
//**********************************************************
ISR(TIMER1_COMPA_vect)   {
     count++;   //testing
 
    PORTB= 0x01;   //switch pin 53 to HIGH, PB0
    logSD();
    PORTB = 0x00;    //switch to low   
   
    Serial.println(count, DEC);  //testing   
    OCR1A += 0xF487;      //set output compare to next value
}            //*******************end ISR for Timer1

I have tried simply writing to SD card inside the ISR without the subroutine logSD(), but the result is the same either way for me.  Thanks in advance for any helpful suggestions or pointers to places I may have missed with my googling skills.
Logged

0
Offline Offline
Edison Member
*
Karma: 63
Posts: 1601
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

SdFat was not designed to be used in an interrupt routine.  Writing to an SD with file I/O takes too long to be reasonable in an ISR.

If you need to log data in a timer ISR see the fastLogger examples here http://code.google.com/p/beta-lib/downloads/list.
Logged

Global Moderator
Netherlands
Offline Offline
Shannon Member
*****
Karma: 211
Posts: 13478
In theory there is no difference between theory and practice, however in practice there are many...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

No definite answer but...

ISR's must be kept short as possible, accessing SDcards might take too long, and you could get some reentry problem.

It might be that for the SPI IO which is used by the SDcard the timer is needed????
Logged

Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

Montana
Offline Offline
Newbie
*
Karma: 0
Posts: 2
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thank you both.  I think you are correct robtillaart, because it has worked before, but only for one or two writes.  Thanks for the suggestion...I will try it out!
Logged

Pages: [1]   Go Up
Jump to: