Pages: [1]   Go Down
Author Topic: Missing samples when writing to SD card  (Read 341 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 4
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I am trying a accomplish a fairly simple task of using the UNO (rev.3) to continuously log data from an accelerometer at a sampling rate of 1kHz.

Once I apply power, the UNO reads the data and begins writing the sampled data to the SDHC card.

The problem I am running into is the UNO is missing 2-3 samples ever ~143 ms. I am monitoring the sampling rate by strobing pin 8 (PCINT0). I've attached a screen capture of pin 8 which shows the missing samples along with an input signal of 100 Hz (as a test) into A0.

I can't figure out why I am missing samples. Any info is gladly appreciated as I am a beginner to the programming world.

Code:
//
// file: accel_log -- Arduino sketch to sample A/D on pin 8 and log
//
// SD card attached to SPI bus as follows:
// MOSI - pin 11
// MISO - pin 12
// CLK - pin 13
// CS - pin 10
//

#include <SD.h>

int AD1pin = A0;      // input pin
int AD2pin = A2;      // input pin
int AD1val = 0;       // value read
int AD2val = 0;       // value read
int in1;              // input pin 1
int in2;              // input pin 2

char buf[24];         // output buffer
char buf1[24];        // temp buffer
char fn[24];          // filename
int cnt = 0;          // used to decimate serial output
File fd;              // file descriptor for log file

const int chipSelect = 10;

void setup(){
        int fileNum = 0;
 
        Serial.begin(9600);      // open the serial port

 
        pinMode(10, OUTPUT);        // SD card chip select
        pinMode(8, OUTPUT);         // strobe line for debug
        pinMode(6, INPUT);          // DIO 1
        pinMode(7, INPUT);          // DIO 2

        
        //
        // inintialize SD card
        //
        Serial.print("Initializing SD card...");

        if (!SD.begin(chipSelect)) {
                Serial.println("Card failed, or not present");
                // don't do anything more:
                return;
        }
        Serial.println("card initialized.");
 
        do {
                sprintf(fn, "log_%03d.dat", fileNum++);
        } while (SD.exists(fn));

        fd = SD.open(fn, FILE_WRITE);
        if (!fd) {
                sprintf(buf1, "data file: %s opened failed\n", fn);
                Serial.print(buf1);
                return;
         }
                          
        sprintf(buf1, "data file: %s opened\n", fn);
        Serial.print(buf1);
        
        //
        // configure timer 1 for 1kHz
        //
        cli();        // disable interrupts

        //set timer0 interrupt at 1kHz
        TCCR0A = 0;                                 // set entire TCCR2A register to 0
        TCCR0B = 0;                                 // same for TCCR2B
        TCNT0  = 0;                                 // initialize counter value to 0
        
        // set compare match register for 1khz increments
        OCR0A = 248;// = (16*10^6) / (1000*64) - 1 (must be <256)  
        
        TCCR0A |= (1 << WGM01);                     // turn on CTC mode      
        TCCR0B |= (1 << CS11) | (1 << CS10);        // Set CS11 and CS10 bits for 64 prescaler    
        TIMSK0 |= (1 << OCIE0A);                    // enable timer compare interrupt
        
        sei();        //enable interrupts
      
        delay(2000);
 }

ISR(TIMER0_COMPA_vect){    //timer0 interrupt routine
        digitalWrite(8,HIGH);           // test strobe high
        
        AD1val = analogRead(AD1pin);    
        
        sprintf(buf, "%d\n", AD1val);
        
        if (fd) {
                fd.print(buf);
        }

#undef SERIAL_OUT
#ifdef SERIAL_OUT
        if (cnt % 250 == 0) {        // only output @ 4 Hz
               Serial.print(buf);
               }
        }
#endif
        if (cnt++ % 5000 == 0) {
               if (fd) {
                      fd.flush();
                }
        }
        digitalWrite(8,LOW);          // test strobe low
}


void loop(){
}


* PRINT_00.TIF (36.04 KB, 512x349 - viewed 41 times.)
« Last Edit: March 11, 2013, 11:29:56 am by jbirdthe3rd » Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 601
Posts: 48543
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

When you "write to the SD card", you are actually writing to a buffer. When the buffer gets full, the data is actually transferred to the SD card. Depending on how full the card is, that can take a non insignificant amount of time. While the transfer of data to the SD card is happening, data collection is not, unless the data collection is interrupt driven.

I'd be willing to guess that it isn't, although that isn't clear from the code you posted, since, apparently you chose a 0 point font for the code.
Logged

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

This is my first post, I hit post instead of preview. The code should be visible now.
Logged

UK
Offline Offline
Shannon Member
****
Karma: 223
Posts: 12577
-
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

While the transfer of data to the SD card is happening, data collection is not, unless the data collection is interrupt driven.

I'd be willing to guess that it isn't, although that isn't clear from the code you posted

It is interrupt-based, but writes to the SD and does serial output within the interrupt.
Logged

I only provide help via the forum - please do not contact me for private consultancy.

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

Are there and suggestions for an alternative to make this Uno not miss any samples? Take a look at the scope capture to see what pin 8 looks like when I miss the 2-3 samples.

Any code help would greatly help.
Logged

Pages: [1]   Go Up
Jump to: