Sd Card Write Issue

Hello all, wrote a program to collect data from 3 potentiometers then save them to an sd card after allowing the user to custom name the file. The code seems to be working up to the point where it actually writes to the sd card. I have an lcd screen being updated during the process to show the user where the arduino is in the code execution per say.

save = digitalRead(savebutton);
  }
  if (save == LOW) {
    lcd.clear();         //this part of the code is used to identify the users answer and save or restart
    if (num1 <= 5) {
      saveit();
    }
    else if (num1 >= 5) {
      lcd.setCursor(0, 0);
      lcd.write(filename);
      lcd.setCursor(0, 1);
      lcd.print("Saving");
      Serial.println("saving");
      delay(3000);
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print(r);
      lcd.print(",");
      lcd.print(g);
      lcd.print(",");
      lcd.print(b);
      lcd.setCursor(0, 1);
      lcd.print(" R , G , B ");
      delay(3000);
      SD.begin(10);
      dataFile = SD.open(filename, FILE_WRITE);
      delay(50);
      dataFile.flush();
      if (dataFile) {         // code seems to be getting stuck here and jumping to else statement
        dataFile.print(r);
        delay(50);
        dataFile.print(",");
        delay(50);
        dataFile.print(g);
        delay(50);
        dataFile.print(",");
        delay(50);
        dataFile.println(b);
        delay(50);
        dataFile.close();
        lcd.clear();
        lcd.setCursor(0, 0);
        lcd.print("Complete");
        lcd.setCursor(0, 1);
        lcd.print(filename);
        Serial.println("Complete");
        delay(3000);
        digitalWrite(rst, LOW);
      }
      else {
        lcd.clear();
        lcd.setCursor(0, 0);
        lcd.print("SD Write Error");
        lcd.setCursor(0, 1);
        lcd.print(filename);
        delay(3000);
        digitalWrite(rst, LOW);
      }
    }
  }
}

Upon further inspection, even when the program successfully writes to the sd card, the information is not actually being stored. Not sure why it is returning a write successful message.

      dataFile = SD.open(filename, FILE_WRITE);
      delay(50);
      dataFile.flush();
      if (dataFile) {         // code seems to be getting stuck here and jumping to else statement

Why are you dereferencing dataFile before checking that it is valid?

Why are you f**king around with all the delay()s writing to the file?

What do you mean by dereferencing dataFile? Is that what dataFile.flush() is doing? My understanding of that function is that it "flushes" the info to the card.

Re:delay, I was told to put this in to "give the program time to write to the card", I realize it works much faster than needing that but figured it wouldnt hurt to include?

SD.begin(10);

SD.begin() belongs in setup called once.

You do not need to use flush() if you are closing the file try

      dataFile = SD.open(filename, FILE_WRITE);
      if (dataFile) 
      {        
        dataFile.print(r);
        dataFile.print(",");    
        dataFile.print(g); 
        dataFile.print(",");
        dataFile.println(b);
        dataFile.close();
        }

So after making the changes you suggested, the files seem to be writing to the card more consistently but whether the data has been written to the file is a gamble. Seems like the part of code that is writing to the file is not working right.

So after making the changes you suggested, the files seem to be writing to the card more consistently but whether the data has been written to the file is a gamble. Seems like the part of code that is writing to the file is not working right.

Can you provide some simple piece of test code which compiles, runs, and demonstrates the problem. Using Serial.print for debugging purposes instead of the lcd will make it easier for us to check on what is going on. How do you know if data is written or not written. Is there a sequence number of time stamp as part of the data?

What do you mean by "Writing to the file"? and "Writing to the card"?

dataFile.print() places data in a 512 byte buffer which is physically written to the card when the buffer is full or if you close or flush the file before that point.

/*
  This program should allow the user to "create" a colour using the RGB potentiometers.
  Once a colour has been created, ask the user to name the colour. Scroll through letters using the red pot.
  Use save button to advance cursor. Once colour has been named save a text file to a sd card as "Colourname.txt".
  In the file store the RGB values as "R,r,G,g,B,b" ie. "R,134,G,255,B,003"
*/

/*
  The circuit:
   SD card attached to SPI bus as follows:
 ** MOSI - pin 11
 ** MISO - pin 12
 ** CLK - pin 13
 ** CS - pin 10
*/

#include <SPI.h>
#include <SD.h>
#include <LCD.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#define I2C_ADDR    0x27 // <<----- Add your address here.  Find it from I2C Scanner
#define BACKLIGHT_PIN     3
#define En_pin  2
#define Rw_pin  1
#define Rs_pin  0
#define D4_pin  4
#define D5_pin  5
#define D6_pin  6
#define D7_pin  7
LiquidCrystal_I2C  lcd(I2C_ADDR, En_pin, Rw_pin, Rs_pin, D4_pin, D5_pin, D6_pin, D7_pin);
File dataFile;

//LED Pins
int RLed = 3;
int GLed = 5;
int BLed = 6;

//Level Pots Pins
int RFad = A0;
int GFad = A1;
int BFad = A2;

//LED Level Variables
int r = 0;
int g = 0;
int b = 0;

int num1 = 0;
int savebutton = 8; //save button pin 12 -> gnd
int rst = 4;
int save = 0;
int saven = 0;
char alpha = 'a'; //set the intial letter to lower case "a"
char alphabet[65] = {"abcdefghijklmnopqrstuvwxyz0123456789-_ABCDEFGHIJKLMNOPQRSTUVWXYZ"}; //store the alphabet, lowercase and uppercase as well as some numbers and characters. obviously incorrect. Not sure how to do this
char filename[] = "FileName.txt";

const int chipSelect = 10;


void setup() {

  Serial.begin(9600);
  SD.begin(10);
  pinMode(RLed, OUTPUT);
  pinMode(GLed, OUTPUT);
  pinMode(BLed, OUTPUT);
  pinMode(RFad, INPUT);
  pinMode(GFad, INPUT);
  pinMode(BFad, INPUT);
  pinMode(savebutton, INPUT);
  digitalWrite(savebutton, HIGH);
  pinMode(rst, OUTPUT);
  digitalWrite(rst, HIGH);
  lcd.begin(16, 2);
  lcd.setBacklightPin(BACKLIGHT_PIN, POSITIVE);
  lcd.setBacklight(HIGH);



  Serial.println("setup initialized");
}

void loop() {

  save = digitalRead(savebutton);
  while (save == HIGH) {
    Serial.println(" R******G*****B");
    r = (analogRead(RFad) / 4);
    g = (analogRead(GFad) / 4);
    b = (analogRead(BFad) / 4);
    Serial.print(r);
    Serial.print(",");
    Serial.print(g);
    Serial.print(",");
    Serial.println(b);
    analogWrite(RLed, r);
    analogWrite(GLed, g);
    analogWrite(BLed, b);
    delay(33);
    save = digitalRead(savebutton);

    if (save == LOW) {
      Serial.println(" R******G*****B");
      Serial.print(r);
      Serial.print(",");
      Serial.print(g);
      Serial.print(",");
      Serial.println(b);
      Serial.println("saving");
      delay(1000);
      saveit();
    }
  }
}



void saveit() {
  save = digitalRead(savebutton);

  while (save == HIGH) {
    num1 = analogRead(RFad); //read the value from the red potentiometer
    num1 = map(num1, 0, 1023, 0, 64); //map the value read to the amount of characters in the array
    alpha = (alphabet[num1]); //put a character from the array into the variable "alpha"
    Serial.println("Name Colour");
    Serial.println(filename);
    int x = analogRead(BFad);
    x = map(x, 0, 1023, 0, 7);
    lcd.setCursor(x, 1);
    lcd.print(alpha);
    filename[x] = alpha;
    delay(150);
    save = digitalRead(savebutton);

    if (save == LOW) {
      yousure();
    }
  }
}
void yousure() {
  delay(1000);
  save = digitalRead(savebutton);
  lcd.clear();

  while (save == HIGH) {

    Serial.println(filename);
    Serial.println("Save File? ");
    num1 = analogRead(RFad); //read the value from the red potentiometer
    num1 = map(num1, 0, 1023, 0, 10); //map the value read to the amount of characters in the array
    if (num1 <= 5) {
      Serial.println("N");

    }
    else if (num1 >= 5) {
      Serial.println("Y");
    }

    save = digitalRead(savebutton);
  }
  if (save == LOW) {
    //this part of the code is used to identify the users answer and save or restart
    if (num1 <= 5) {
      saveit();
    }
    else if (num1 >= 5) {
      Serial.println(filename);
      Serial.print(r);
      Serial.print(",");
      Serial.print(g);
      Serial.print(",");
      Serial.println(b);
      Serial.println("saving");
      delay(3000);
      dataFile = SD.open(filename, FILE_WRITE);
      if (dataFile) {         // code seems to be getting stuck here and jumping to else statement
        dataFile.print(r);
        dataFile.print(",");
        dataFile.print(g);
        dataFile.print(",");
        dataFile.println(b);
        dataFile.close();
        Serial.println("Complete");
        delay(3000);
        digitalWrite(rst, LOW);
      }
      else {
        Serial.println("SD Write Error");
        Serial.println(filename);
        delay(3000);
        digitalWrite(rst, LOW);
      }
    }
  }
}

cattledog:
How do you know if data is written or not written.
-When I open the file on the sd card it contains no information.

Is there a sequence number of time stamp as part of the data?
-no just 3 values. a red value from 0-255 a blue and a green.

What do you mean by "Writing to the file"? and "Writing to the card"?
-every save to the sd card should create a new file. Every file should contain 3 values.

Can you successfully create the file names? Do you always get valid filenames and serial data printed?

else if (num1 >= 5) {
      Serial.println(filename);
      Serial.print(r);
      Serial.print(",");
      Serial.print(g);
      Serial.print(",");
      Serial.println(b);
      Serial.println("saving");
      delay(3000);
      dataFile = SD.open(filename, FILE_WRITE);
      if (dataFile) {         // code seems to be getting stuck here and jumping to else statement
        dataFile.print(r);
        dataFile.print(",");
        dataFile.print(g);
        dataFile.print(",");
        dataFile.println(b);
        dataFile.close();
        Serial.println("Complete");
        delay(3000);
        digitalWrite(rst, LOW);
      }
      else {
        Serial.println("SD Write Error");
        Serial.println(filename);
        delay(3000);
        digitalWrite(rst, LOW);
      }
    }

Is the problem that the card contains a file with the name, but no data, or the file has not been created?

  Use save button to advance cursor. Once colour has been named save a text file to a sd card as "Colourname.txt".

Are you limiting the file names to eight characters? (8.3 short file name format)? The comment makes me suspicious.

the files seem to be writing to the card more consistently but whether the data has been written to the file is a gamble

I am unclear between the "code seems to be getting stuck here and jumping to else statement" comment, and the printing of "SD Write Error" or the "its a gamble" statement and the empty file being created.

Have our tried to write a simple program which just creates a new file name for each write, and stores data without all the potentiomenter twiddling for file name creation?