Failing to create SD directory and write

I am trying to create a specific directory on boot up and/or when the functions are called. it is creating the first folder structure 'log#x'
and then MISSING the second layer 'diveProfilex'
I want to create like the following >> /LOG#1/diveProfile1/dive0.txt

if there is repeat call to logProfileNameAllocation() it should create dive1.txt dive2.txt etc etc in the same directory
if there is a call to void instantiateLogNum() it should create a new log i.e LOG#2 and dive name reset. i.e /LOG#2/diveProfile1/dive0.txt

Any ideas? see code below. have inserted in the top here where its not working.. full code below.

SD.mkdir(liveDirectory);
                          Serial.println(liveDirectory);
                          

// it prints live directory .. does not create and then fails at this point.. 

                          if(SD.mkdir(liveDirectory)){
                            Serial.print("Directory Created: ");
                            Serial.print(liveDirectory);                      
                          }
// clock channel identify 0x68
// The I2C address of the DS3231 is 0x68. 0x57 is the I2C address of the AT24C32 EEPROM on your ZS-042 RTC module

// Following is for an I2C Multiplexor system.
// Arduino to LCA9548A
// 10k PULL UP RESISTORS

// Using 3 Peripheral I2C channels: 1,2,3
// NOTE: SD writing - working, BMP serial monitor displaying - working, magnetic compass function serial - working 
// INDIVIUDALLY TESTED AND WORKING PERIPHERALS
//

// MAGNETIC COMPASS
//
// magnetic compass x,y,z recordings serial print out + write to SD card
// SD_BMP180_Clock_QMC5583L

#include <SFE_BMP180.h>
#include <Wire.h>
#include <Regexp.h>
SFE_BMP180 pressure;
#define ALTITUDE 10 // Altitude of (Ajax, Ontario, Canada)

////////////////////

#include <Wire.h>
#include <RTC.h>

DS3231 RTC;
#include <SD.h>
#include <SPI.h>
File myFile;

int pinCS = 53; // chip select 53 mega >> 10 uno
int modeState = 1;

// to merge to main code below 

String liveDirectory;
String fileNameAllocation = "dive0.txt";
int logNum = 0;
String logDirectory = "/LOG#1";
int diveNumber = 0;
int logCount = 0;
String liveFullDirectory = "";

#include <QMC5883LCompass.h>
QMC5883LCompass compass;
//#define TotalSamples 100;

/////////////////////////////////////////////////////////////////////  FUNCTION CALLS

void BMP180_check();
void compassCheck();
void writeSD_compassData(int x,int y,int z,String t);
void writeSD_BMP(float temp,float absolutePressure,float computedAltitude);
void logProfileNameAllocation(); // can be created at the initiation of dive arming
void tcaSelect(uint8_t bus);
void instantiateLogNum();
void logProfileNameAllocation();

////////////////////////////////////////////////////////////////////
       
//  TCA9548 module I2C address:  0x70 >> MULTIPLEXOR

//  I2C device found at address 0x0D  ! QMC5883L >> COMPASS
//  I2C device found at address 0x68  ! DS3231 RTC >> CLOCK LINE 
//  I2C device found at address 0x77  ! BMP180 >> PRESSURE BAROMETER

#define addr1   0x68       // CLOCK device 3 (I2C bus 2)
#define addr2   0x0D       // QMC device 1 (I2C bus 1)
#define addr3   0x77       // BMP device 4 (I2C bus 2)
#define TCA_Address 0x70   // address of I2C switch module

#define bus1    1          // CLOCK
#define bus2    2          // COMPASS
#define bus3    3          // BMP



void setup() {

////////////////////////////////////////////////////////////////////////// CLOCK ACTIVATE
  
  
  pinMode(pinCS, OUTPUT); // cs pin needs to be in a low setting for SPI communication to work correctly
  digitalWrite(pinCS, HIGH);
  
  Serial.begin(38400); // serial boot
  delay(200);
  Wire.begin(); // initialize i2c comms
  delay(500);

  Serial.println("PROGRAM LIVE");
  Serial.println("***************************************");
  Serial.println();
  
  tcaSelect(bus1);               // enable I2C channel 1
  
  delay(100);
  
  if (RTC.begin()){
    Serial.println("RTC init success");
  }
  else
  {
    // Oops, something went wrong, this is usually a connection problem,
    // see the comments at the top of this sketch for the proper connections.

    Serial.println("RTC init fail\n\n");
    while(1); // Pause forever.
  }
 
//////////////////////////////////////////////////////////////////////////// COMPASS ACTIVATE

tcaSelect(bus2);               // enable I2C channel 2
    
compass.init();

Serial.println("Compass init success");

//  }
//  else
//  {
//    // Oops, something went wrong, this is usually a connection problem,
//    // see the comments at the top of this sketch for the proper connections.
//
//    Serial.println("Compass init fail\n\n");
//    while(1); // Pause forever.
//  }

  
  compass.setCalibration(-428, 656, -2357, 0, 0, 980);
  Serial.println("Compass Calibration Set");
 

//////////////////////////////////////////////////////////////////////////// BMP180 ACTIVATE - TEMP/PRESSURE

  tcaSelect(bus3);               // enable I2C channel 3
  
  if (pressure.begin()){
    Serial.println("BMP180 init success");
  }
  else
  {
    // Oops, something went wrong, this is usually a connection problem,
    // see the comments at the top of this sketch for the proper connections.

    Serial.println("BMP180 init fail\n\n");
    while(1); // Pause forever.
  }
 
  
//////////////////////////////////////////////////////////////////////////// SPI COMMS, SD INITIALIZE, CS

  
  // pinMode(pinCS, OUTPUT);
  
  // SD Card Initialization
  if (SD.begin())
  {
    Serial.println("SD card is ready to use.");
  } else
  {
    Serial.println("SD card initialization failed");
    return;
  }

////////////////////////////////////////////////// BOOT UP FUNCTIONS - SINGULAR

instantiateLogNum();

logProfileNameAllocation(); // call to scan card if file exists otherwise break and write file as the default setting dive0

} // END OF SETUP ***************************************************************************************************************************************************************

          void loop() {                          
                         
                          compassCheck();
                        
                          BMP180_check();
                        
                          delay(2000); 
          
          }


void instantiateLogNum(){

                        // created only at bootup, as root directory.
                        // traverse log folder directory until the latest can be appended

                       
                        while(SD.exists(logDirectory)) // check if folder structure/ directory exists log
                        {
                                                   
                         logCount++;
                         String logCountCastToString = String(logCount);
                         String logPrefix = "/LOG#";
                         logDirectory = logPrefix + logCountCastToString;
                         Serial.print(logDirectory);
                         
                        }                     
                        
                        SD.mkdir(logDirectory);
                        Serial.println("New Folder Log made: ");
                        Serial.print(logDirectory);
                        Serial.println();


  
}


// running program should save data to live set profile, LOG#1/dive1/dive0.txt >> dive1.txt >> dive2.txt

void logProfileNameAllocation(){ // using SPI comms - command should be called as the dive is armed moments before break-away.
                          
                       // see if the directory exists, create it if not. construct from the live dive profile denotation

                        String mScast = String(modeState); // convert into string
                        
                        liveDirectory = logDirectory + "/diveProfile" + mScast + "/"; // >> /LOG#1/diveProfile1
                                                  
                        if(!SD.exists(liveDirectory)) // check if folder structure/ directory exists
                        {

                          SD.mkdir(liveDirectory);
                          Serial.println(liveDirectory);
                          
                          if(SD.mkdir(liveDirectory)){
                            Serial.print("Directory Created: ");
                            Serial.print(liveDirectory);                      
                          }
                        }
                        else {
                                      ("path already exists, directory not created");
                                  }                        

                                 liveFullDirectory = liveDirectory + fileNameAllocation; // >> /LOG#1/diveProfile1/dive0.txt
                                 
                                 while(SD.exists(liveFullDirectory)){

                                        diveNumber++;        
                                        String diveNumberString = String(diveNumber);
                                        fileNameAllocation = "dive" + diveNumberString + ".txt"; // concatanate an iteration one up from the existing global scoped variable/existing file

                                        liveFullDirectory = liveDirectory + "/" + fileNameAllocation;
                                        
                                        }                   
                                                                              
                                                                                                                   
                                                          myFile = SD.open(liveFullDirectory, FILE_WRITE);

                                                                              if (myFile) { 

                                                                                myFile.print("\n\n"); 
                                                                                myFile.print("New File: ");
                                                                                myFile.print(fileNameAllocation);    
                                                                                Serial.println();
                                                                                Serial.println("***************************************");
                                                                                Serial.println("Success >> New Log text printed");                                    
                                                                                myFile.close(); // close the file
                                                                                
                                                                                                              }       
                                                                                                              else {
                                                                                                                            Serial.println("error opening SD file");
                                                                                                                          }
                                                                                                                                   
}



// **********************************************************************************************************************************************************************





void tcaSelect(uint8_t bus) {
  
              if (bus > 7) return;
              Wire.beginTransmission(TCA_Address);
              Wire.write(1 << bus);
              Wire.endTransmission();
              Serial.print("bus live: ");
              Serial.print(bus);
              Serial.println();
  
}


void compassCheck(){

           tcaSelect(bus1);               // enable I2C channel 1, busline switch to clockline function call
                                                                                        
                                                          String absoluteTime = ""; 
                                                         
                                                          absoluteTime = absoluteTime + RTC.getHours() + ":" +  RTC.getMinutes()+ ":" + RTC.getSeconds();
                                                          Serial.println();
                                                          Serial.print("Time: ");
                                                          Serial.println(absoluteTime);

            tcaSelect(bus2);               // enable I2C channel 2
                    
            int compass_x, compass_y, compass_z, a, b;
            char myArray[3];
          
            compass.read();
            Serial.println();
            compass_x = compass.getX();
            compass_y = compass.getY();
            compass_z = compass.getZ();
            Serial.print("X: ");
            Serial.print(",");
            Serial.print(compass_x);
            Serial.print(",");
            Serial.print(" Y: ");
            Serial.print(compass_y);
            Serial.print(",");
            Serial.print(" Z: ");
            Serial.print(compass_z);
            
            a = compass.getAzimuth();
            b = compass.getBearing(a);
            compass.getDirection(myArray, a);
            
                                                Serial.println();
                                                Serial.print("Azimuth: ");
                                                Serial.print(a);
                                                Serial.println();
                                                Serial.print("Bearing: ");
                                                Serial.print(b);
                                                Serial.println();
                                                Serial.print("Direction: ");
                                                Serial.print(myArray[0]);
                                                Serial.print(myArray[1]);
                                                Serial.print(myArray[2]);                                              
                                                Serial.println();

                                                /////////////////////////////////////////

                                                writeSD_compassData(compass_x,compass_y,compass_z,absoluteTime);
                                                                                        
}
  
  
void writeSD_compassData(int x,int y,int z,String t){

                                    Serial.print("write to directory: ");
                                    Serial.print(liveFullDirectory);
                                    Serial.println();
                                    
                                    myFile = SD.open(liveFullDirectory, FILE_WRITE);
                                    if (myFile) {  
                                      
                                                    myFile.println();
                                                    myFile.print("X: ");
                                                    myFile.print(",");
                                                    myFile.print(x);
                                                    myFile.print(",");
                                                    myFile.print(" Y: ");
                                                    myFile.print(",");
                                                    myFile.print(y);
                                                    myFile.print(" Z: ");
                                                    myFile.print(",");
                                                    myFile.print(z);
                                                    myFile.println();
                                                    myFile.print("Time: ");
                                                    myFile.print(t);
                                                    Serial.println();
                                                    
                                                    Serial.println("Success >> Compass data write to card");
                                                    
                                    myFile.close(); // close the file
                                                    }
                                                                                                              // if the file didn't open, print an error:
                                                                            else {
                                                                              Serial.println("error opening SD file");
                                                                            }


}






void BMP180_check(){

  tcaSelect(bus3);               // enable I2C channel 3
 

  char status;
  double T,P,p0,J;

  // Loop here getting pressure readings every 10 seconds.

  // If you want sea-level-compensated pressure, as used in weather reports,
  // you will need to know the altitude at which your measurements are taken.
  // We're using a constant called ALTITUDE in this sketch:
  
  Serial.println();
  Serial.print("provided altitude: ");
  Serial.print(ALTITUDE,0);
  Serial.print(" meters, ");
  Serial.print(ALTITUDE*3.28084,0);
  Serial.println(" feet");
  
  // If you want to measure altitude, and not pressure, you will instead need
  // to provide a known baseline pressure. This is shown at the end of the sketch.

  // You must first get a temperature measurement to perform a pressure reading.
  
  // Start a temperature measurement:
  // If request is successful, the number of ms to wait is returned.
  // If request is unsuccessful, 0 is returned.

  status = pressure.startTemperature();
  if (status != 0)
  {
    // Wait for the measurement to complete:
    delay(status);

    // Retrieve the completed temperature measurement:
    // Note that the measurement is stored in the variable T.
    // Function returns 1 if successful, 0 if failure.

    status = pressure.getTemperature(T);
    if (status != 0)
    {
      // Print out the measurement:
      Serial.print("temperature: ");
      Serial.print(T,2);
      Serial.print(" deg C, ");
      Serial.print((9.0/5.0)*T+32.0,2);
      Serial.println(" deg F");
      
      // Start a pressure measurement:
      // The parameter is the oversampling setting, from 0 to 3 (highest res, longest wait).
      // If request is successful, the number of ms to wait is returned.
      // If request is unsuccessful, 0 is returned.

      status = pressure.startPressure(3);
      if (status != 0)
      {
        // Wait for the measurement to complete:
        delay(status);

        // Retrieve the completed pressure measurement:
        // Note that the measurement is stored in the variable P.
        // Note also that the function requires the previous temperature measurement (T).
        // (If temperature is stable, you can do one temperature measurement for a number of pressure measurements.)
        // Function returns 1 if successful, 0 if failure.

        status = pressure.getPressure(P,T);
        if (status != 0)
        {
          // Print out the measurement:
          Serial.print("absolute pressure: ");
          Serial.print(P,2);
          Serial.print(" mb, ");
          Serial.print(P*0.0295333727,2);
          Serial.println(" inHg");

          // The pressure sensor returns abolute pressure, which varies with altitude.
          // To remove the effects of altitude, use the sealevel function and your current altitude.
          // This number is commonly used in weather reports.
          
          // Parameters: P = absolute pressure in mb, ALTITUDE = current altitude in m.
          // Result: p0 = sea-level compensated pressure in mb

          p0 = pressure.sealevel(P,ALTITUDE); // we're at 90 meters (Boulder, CO)
          Serial.print("relative (sea-level) pressure: ");
          Serial.print(p0,2);
          Serial.print(" mb, ");
          Serial.print(p0*0.0295333727,2);
          Serial.println(" inHg");

          // On the other hand, if you want to determine your altitude from the pressure reading,
          // use the altitude function along with a baseline pressure (sea-level or other).
          
          // Parameters: P = absolute pressure in mb, p0 = baseline pressure in mb.
          // Result: a = altitude in m.

          J = pressure.altitude(P,p0);
          Serial.print("computed altitude: ");
          Serial.print(J,0);
          Serial.print(" meters, ");
          Serial.print(J*3.28084,0);
          Serial.println(" feet");
        }
        else Serial.println("error retrieving pressure measurement\n");
      }
      else Serial.println("error starting pressure measurement\n");
    }
    else Serial.println("error retrieving temperature measurement\n");
  }
  else Serial.println("error starting temperature measurement\n");

writeSD_BMP(T,P,J);

}


void writeSD_BMP(float temp,float absolutePressure,float computedAltitude){

                                    myFile = SD.open(liveFullDirectory, FILE_WRITE);
                                    if (myFile) {  
                                      
                                                    myFile.println();
                                                    myFile.print("Temperature: ");
                                                    myFile.print(temp);
                                                    myFile.print(",");
                                                    myFile.print(" Absolute Pressure: ");
                                                    myFile.print(absolutePressure);
                                                    myFile.print(",");
                                                    myFile.print(" Computed Altitude: ");
                                                    myFile.print(computedAltitude);
                                                    Serial.println();
                                                    
                                                    Serial.println("Success >> BMP data write to card");
                                                    
                                    myFile.close(); // close the file
                                                    }
                                                                                                              // if the file didn't open, print an error:
                                                                            else {
                                                                              Serial.println("error opening SD file");
                                                                            }
  
}

what is the question?

why is this code not working :smiley: or for start as.. why can i not create a second layer sub directory .. in my case im using: SD.mkdir(liveDirectory);
to try and do so.. but it doesn't seem to be working..

Only use DOS 8.3 file and directory names. Your directory names are too long.

Seems like that solved the problem! thanks. I shortened the folder structure to a few characters.. would you know of another system or module which will allow larger/longer naming structure?

The SdFat library seems to support long filenames; I've never tested it. I've never had a need so haven't played with it; I'll leave the research up to you :wink:

1 Like

thank you very much!!

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.