Adapting "blink without delay" to reading sensors

Hello all. Hopefully my first post will be an interesting one. I am designing a shield to use as a sensor package in a high altitude balloon. I have four sensors I wish to read at varying intervals, as well as a microSD breakout that I am going to log the information to. Before I attempted to adapt code from the ‘blink without delay’ sketch I was able to poll two sensors and write successfully. The problem lied in the ‘delay’ function naturally. My first sensor (an accelerometer) would write followed by the 3 second delay, followed immediately by the barometric pressure sensor which would also write successfully. I only wanted to poll the pressure sensor every 30 seconds so I end up with both readings taken around 30 seconds apart. Polling an accelerometer every 30 seconds would be quite pointless, so I tried integrating blink without delay. My code compiles fine, it’s just that it initializes the SD card and then never appears to write anything. Is anyone willing to look at the loop and tell me if I’m way off target? I have been wearing out my google-fu trying to find similar topics, without much luck. Thanks in advance!

#include <Wire.h>
#include <Adafruit_BMP085.h>
#include <SD.h>

File pressure;
File ADXL;
File GPS;
File internaltemp;
Adafruit_BMP085 bmp;
const int xpin = A0; //x-axis
const int ypin = A1; //y-axis
const int zpin = A2; //z-axis
long ADXLmilli = millis(); //stores the last time the accelarometer was updated
long GPSmilli = millis(); //stores the last time the GPS was updated
long pressuremilli = millis(); //stores the last time the pressure sensor was updated
long internaltempmilli = millis(); //stores the last time the internal temp was updated
long ADXLintvl = 3333; //length of time between readings
long GPSintvl = 31546; //length of time between readings
long pressureintvl = 596661; //length of time between readings
long internalintvl = 598774; //length of time between readings

void setup()
{
  Serial.begin(9600);
  bmp.begin();
  Serial.println("Initializing SD card.");
  pinMode(10, OUTPUT);
  
  
  if (!SD.begin(10)) {
    Serial.println("Initialization failed!");
    return;
  }
  Serial.println("Initialization done.");
  
}

void loop()
{
  unsigned long currentmilli = millis();
  pressure = SD.open ("BMP085.txt", FILE_WRITE);
  ADXL = SD.open ("ADXL335.txt", FILE_WRITE); 
  
  if(currentmilli - ADXLmilli > ADXLintvl) {
    //save the last time you measured ADXL
    ADXLmilli = currentmilli;
  
  if (ADXL) {
    Serial.print("Writing to ADXL335.txt...");
    ADXL.print("x:");
    ADXL.print(analogRead(xpin));
    ADXL.print("\t");
    ADXL.print("y:");
    ADXL.print(analogRead(ypin));
    ADXL.print("\t");
    ADXL.print("z:");
    ADXL.print(analogRead(zpin));
    ADXL.println();
  
    //close the file
    ADXL.close();
    Serial.println("Done writing");
  }
  }
  
 if(currentmilli - pressuremilli > pressureintvl){
   //save the last time you measured pressure
   pressuremilli = currentmilli;
    
   //if the file opened OK, write to it:
   if (pressure) {
   Serial.print("Writing to BMP085.txt...");
   pressure.print("Temperature = ");
   pressure.print(bmp.readTemperature());
   pressure.println(" *C");
    
   pressure.print("Pressure = ");
   pressure.print(bmp.readPressure());
   pressure.println(" Pa");
    
   //Calculate Altitude assuming 'standard' pressure of 1013.25 millibar = 101325 pascals
   pressure.print("Altitude = ");
   pressure.print(bmp.readAltitude());
   pressure.println(" meters");
    
   //more accurate reading based on sea level pressure. Ex: 1015 millibars equals 101500 Pascals.
   pressure.print("Real altitude = ");
   pressure.print(bmp.readAltitude(101500));
   pressure.println(" meters");
   pressure.println();
    
   //close the file
   pressure.close();
   Serial.println("Done writing");
  }
 } 
}

Every pass through loop(), you open two files, regardless of whether it is time to write to them, or not. Why?

Which version of the IDE are you using. Depending on the version, specifically which version of the SD library, you may only be able to open one file at a time.

In any case, you only need one open file at a time. Simply wait to open the file until you know it is time to write to the file.

Your closing of the file happens only after writing to the file, not every time you open the file. Even if you are able to open multiple files at one time, you will quickly run out of file handles if the closes don’t match the opens.

I am using IDE version 1.0.1. As for the SD library it came from adafruit. I just checked the readme and it does not mention a specific version. I had not considered that multiple copies would open, that makes sense. Off to try it out!

Cheers! I am now writing to my accelerometer log file at the desired interval. I did the same for my pressure sensor but it doesn't seem to trigger.

This is how my loop looks now:

void loop()
{
  unsigned long currentmilli = millis();
  
  if(currentmilli - ADXLmilli > ADXLintvl) {
    //save the last time you measured ADXL
    ADXLmilli = currentmilli;
  ADXL = SD.open ("ADXL335.txt", FILE_WRITE);
  if (ADXL) {
    Serial.print("Writing to ADXL335.txt...");
    ADXL.print("x:");
    ADXL.print(analogRead(xpin));
    ADXL.print("\t");
    ADXL.print("y:");
    ADXL.print(analogRead(ypin));
    ADXL.print("\t");
    ADXL.print("z:");
    ADXL.print(analogRead(zpin));
    ADXL.println();
  
    //close the file
    ADXL.close();
    Serial.println("Done writing");
  }
  }
  
 if(currentmilli - pressuremilli > pressureintvl){
   //save the last time you measured pressure
   pressuremilli = currentmilli;
   pressure = SD.open ("BMP085.txt", FILE_WRITE); 
   //if the file opened OK, write to it:
   if (pressure) {
   Serial.print("Writing to BMP085.txt...");
   pressure.print("Temperature = ");
   pressure.print(bmp.readTemperature());
   pressure.println(" *C");
    
   pressure.print("Pressure = ");
   pressure.print(bmp.readPressure());
   pressure.println(" Pa");
    
   //Calculate Altitude assuming 'standard' pressure of 1013.25 millibar = 101325 pascals
   pressure.print("Altitude = ");
   pressure.print(bmp.readAltitude());
   pressure.println(" meters");
    
   //more accurate reading based on sea level pressure. Ex: 1015 millibars equals 101500 Pascals.
   pressure.print("Real altitude = ");
   pressure.print(bmp.readAltitude(101500));
   pressure.println(" meters");
   pressure.println();
    
   //close the file
   pressure.close();
   Serial.println("Done writing");
  }
 }

ik2012:
I did the same for my pressure sensor but it doesn't seem to trigger.

You really need to post a complete sketch that shows the problem (and preferably, the simplest/shortest sketch that can show the problem), because the problem may not be in the bit of code you are looking at. For example, in this case the behaviour would depend on the declaration and initialisation of pressuremilli & pressureintvl, and you haven't shown us that.

long pressureintvl = 596661; //length of time between readings
long internalintvl = 598774; //length of time between readings

Very, very strange intervals.

596 seconds and 598 seconds. Why?

I did the same for my pressure sensor but it doesn't seem to trigger.

More Serial.print() statements are needed, then.

PeterH:

ik2012:
I did the same for my pressure sensor but it doesn't seem to trigger.

You really need to post a complete sketch that shows the problem (and preferably, the simplest/shortest sketch that can show the problem), because the problem may not be in the bit of code you are looking at. For example, in this case the behaviour would depend on the declaration and initialisation of pressuremilli & pressureintvl, and you haven't shown us that.

I only changed the loop, therefore that is all I posted. In the future I will paste in the whole thing. Thanks.

PaulS:

long pressureintvl = 596661; //length of time between readings

long internalintvl = 598774; //length of time between readings



Very, very strange intervals.

596 seconds and 598 seconds. Why?



> I did the same for my pressure sensor but it doesn't seem to trigger.


More Serial.print() statements are needed, then.

Yes indeed those are strange intervals, I did not intend to go that far out. Good eye!
Not sure what you mean by more serial.print() statements, I have exactly how many I want. One when the file is written one when it closes, I am using the serial port more for debugging than anything, as the arduino will not be plugged into USB when it is up in the balloon.

Not sure what you mean by more serial.print() statements, I have exactly how many I want. One when the file is written one when it closes, I am using the serial port more for debugging than anything, as the arduino will not be plugged into USB when it is up in the balloon.

But, you could add more, to find the time, the interval till the next write, etc., to see if you got in the "it's time to write" block, etc.