MicroSD breakout writing limits

Breakout boards, sensors, other Adafruit kits, etc.

Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.
Locked
jtuhtan
 
Posts: 5
Joined: Sat Apr 13, 2013 12:28 pm

MicroSD breakout writing limits

Post by jtuhtan »

After going through a couple SD + Arduino combinations, I have to say that this micro SD is by far the best of the bunch! However, I have had difficulty writing out data to the card in a particular situation:

Currently I have two pressure transducers connected to the Adafruit ADS1115 breakout in differential mode. A Dallas DS18B20 and RTC are connected to get the temperature and time, and the results are read out to the micro SD in intervals of about 2-3 seconds. Since the pressure transducers are very sensitive, I am writing a series of measurements first to an array with 10 ms delay between measurements, and then writing out the average values to the SD card.

The problem arises when the sample size is greater than 40. At this point, the connection with the SD card breaks down, and the code cycles by resetting the card.

Any help on this would be greatly appreciated.

Here is the sketch:

Code: Select all

#include <OneWire.h>
#include <DallasTemperature.h>
#include <Wire.h>
#include <Adafruit_ADS1015.h>
#include <RTClib.h>
#include <SD.h>

Adafruit_ADS1115 ads1115(0x48); // Data wire TEMP is plugged into pin 2 on the Arduino
#define ONE_WIRE_BUS 2

RTC_DS1307 RTC;
 
// Setup a oneWire instance to communicate with any OneWire devices 
// (not just Maxim/Dallas temperature ICs)
OneWire oneWire(ONE_WIRE_BUS);
 
// Pass our oneWire reference to Dallas Temperature.
DallasTemperature sensors(&oneWire);
int count = 1;
int numberOfSensors;
int mVDec = 3;

// Assign pin used for SD
const int chipSelect = 10;

// Begin SETUP
void setup(void){
  // start serial port
  Serial.begin(9600);
  ads1115.begin();
  
  // Start up the TEMP library
  sensors.begin();
  
  // Start RTC
  Wire.begin();
  RTC.begin();
  if (! RTC.isrunning()) { // check RTC
  Serial.println("RTC is NOT running!");
    // following line sets the RTC to the date & time this sketch was compiled
    RTC.adjust(DateTime(__DATE__, __TIME__));
  } // end check RTC
  
  // Start SD
  pinMode(10, OUTPUT);
    // see if the card is present and can be initialized:
  if (!SD.begin(chipSelect)) {
    Serial.println("SD card failed, or not present");
    // don't do anything more:
    return;    
  }
  
  // Retrieve RTC output
  DateTime now = RTC.now();  
  Serial.print(now.year(), DEC);
  Serial.print('/');
  Serial.print(now.month(), DEC);
  SD.mkdir("/test"); // create directory on SD card

Serial.println("SD card initialized.");
Serial.println("NO. SAMPLES DELAY[ms] DATE TIME ADC01S[mV] ADC01[mV] ADC02S[mV] ADC02[mV] TEMP[C]");
File dataFile = SD.open("TEST/data.txt", FILE_WRITE); // open SD file for writing
dataFile.println("NO. SAMPLES DELAY[ms] DATE TIME ADC01S[mV] ADC01[mV] ADC02S[mV] ADC02[mV] TEMP[C]");
dataFile.close(); // close file, data is written to SD
} // end setup


// Begin LOOP 
  void loop(void){
  // variables for oversampling
  int sampleSize = 30; // no. samples per time step output
  int delaySample = 10; // sampling delay in ms
  int16_t results_01;
  int16_t results_23;
  float ADC01_sample[sampleSize];
  float ADC23_sample[sampleSize];
  float ADC01_sampleTotal = 0;
  float ADC23_sampleTotal = 0;
  float temp = 0;
  int i = 0; // sample counter
  
  sensors.requestTemperatures(); // Send the command to get temperatures
  temp = sensors.getTempCByIndex(0);
  
  for (i = 0; i < sampleSize; i++) { // loop over i sub samples
    // read ADS1115 ADC channels

    results_01 = ads1115.readADC_Differential_0_1();
    results_23 = ads1115.readADC_Differential_2_3();
    
    ADC01_sample[i] = results_01;
    ADC23_sample[i] = results_23;
    
    ADC01_sampleTotal = ADC01_sampleTotal + ADC01_sample[i];
    ADC23_sampleTotal = ADC23_sampleTotal + ADC23_sample[i];
    
    delay(delaySample); // ensured sampling interval in ms
    } // end sampling loop
    
  ADC01_sampleTotal = ADC01_sampleTotal / sampleSize;
  ADC23_sampleTotal = ADC23_sampleTotal / sampleSize;  
  
  float ADC16BitSpan = 2.000 * 0.256; // ADC full span is 2 * span(v)  
 
  // device specific settings
  float nullVNoADC = 0; // null offset reading when ADC is disconnected
  
  // Print observation number
  Serial.print(count);
  Serial.print(";");
  
  // Print samples
  Serial.print(i);
  Serial.print(";");
  
   // Print sample delay
  Serial.print(delaySample);
  Serial.print(";");
  
  // Print RTC output
  DateTime now = RTC.now();  
  Serial.print(now.year(), DEC);
  Serial.print('/');
  Serial.print(now.month(), DEC);
  Serial.print('/');
  Serial.print(now.day(), DEC);
  Serial.print(';');
  Serial.print(now.hour(), DEC);
  Serial.print(':');
  Serial.print(now.minute(), DEC);
  Serial.print(':');
  Serial.print(now.second(), DEC);
  Serial.print(";");
  
  // Print sampled outputs ADC channel 1 in mV
  Serial.print(1000.00000000 * ADC01_sampleTotal * (ADC16BitSpan / 65536.00000000),mVDec);
  Serial.print(";");
  
  // Print outputs ADC channel 1 in mV
  Serial.print(1000.00000000 * ADC01_sample[sampleSize-1] * (ADC16BitSpan / 65536.00000000),mVDec);
  Serial.print(";");
  
  // Print sampled outputs ADC channel 2 in mV
  Serial.print(1000.00000000 * ADC23_sampleTotal * (ADC16BitSpan / 65536.00000000),mVDec);
  Serial.print(";");
  
  // Print outputs ADC channel 2 in mV
  Serial.print(1000.00000000 * ADC23_sample[sampleSize-1] * (ADC16BitSpan / 65536.00000000),mVDec);
  Serial.print(";");
  
  // Print Temp
  Serial.println(temp,1); // Why "byIndex"? 
  
  //Saving to SD
  File dataFile = SD.open("TEST/data.txt", FILE_WRITE); // open SD file for writing
  
  // if the file is available, write to SD:
  if (dataFile) {
    dataFile.print(count); // obs. no.
    dataFile.print(";"); // semicolon delimited
    // Save RTC output
    DateTime now = RTC.now();  
    
    // Print samples
    dataFile.print(i);
    dataFile.print(";");
    
     // Print sample delay
    dataFile.print(delaySample);
    dataFile.print(";");
    
    // Print RTC output
    dataFile.print(now.year(), DEC);
    dataFile.print('/');
    dataFile.print(now.month(), DEC);
    dataFile.print('/');
    dataFile.print(now.day(), DEC);
    dataFile.print(';');
    dataFile.print(now.hour(), DEC);
    dataFile.print(':');
    dataFile.print(now.minute(), DEC);
    dataFile.print(':');
    dataFile.print(now.second(), DEC);
    dataFile.print(";");
    
    // Print sampled outputs ADC channel 1 in mV
    dataFile.print(1000.00000000 * ADC01_sampleTotal * (ADC16BitSpan / 65536.00000000),mVDec);
    dataFile.print(";");
    
    // Print outputs ADC channel 1 in mV
    dataFile.print(1000.00000000 * ADC01_sample[sampleSize-1] * (ADC16BitSpan / 65536.00000000),mVDec);
    dataFile.print(";");
    
    // Print sampled outputs ADC channel 2 in mV
    dataFile.print(1000.00000000 * ADC23_sampleTotal * (ADC16BitSpan / 65536.00000000),mVDec);
    dataFile.print(";");
    
    // Print outputs ADC channel 2 in mV
    dataFile.print(1000.00000000 * ADC23_sample[sampleSize-1] * (ADC16BitSpan / 65536.00000000),mVDec);
    dataFile.print(";");
    
    // Print Temp
    //sensors.requestTemperatures(); // Send the command to get temperatures
    //dataFile.println(sensors.getTempCByIndex(0)); // Why "byIndex"? 
    dataFile.println(temp,1);
    dataFile.close(); // close file, data is written to SD
  }
  
  // if the file isn't open, show an error:
  else {
    Serial.println("error opening SD data file.");
  } 
  
  // Pause in msec
  delay(0);
  count = count + 1; // update obs. no. 
} // end loop


Jeff

User avatar
adafruit_support_bill
 
Posts: 88087
Joined: Sat Feb 07, 2009 10:11 am

Re: MicroSD breakout writing limits

Post by adafruit_support_bill »

I believe you are running out of SRAM. The Uno has 2K of RAM. 512 bytes is taken up by the SD card buffer and the rest goes to stack, heap and BSS. Your 2 arrays of floating point samples will be on the stack.

From a quick look at the code, you don't appear to be using the array data - only the totals. You can probably do without the arrays.

jtuhtan
 
Posts: 5
Joined: Sat Apr 13, 2013 12:28 pm

Re: MicroSD breakout writing limits

Post by jtuhtan »

Thanks for the tip. I will try writing out the data directly without the arrays. Worst case, I can save an array of 30 values or less and write it out. Will post the final code in a couple days when I get it all figured out.

Jeff

Locked
Please be positive and constructive with your questions and comments.

Return to “Other Products from Adafruit”