Arduino SD card update first line

I am trying to increment a variable and write it to the SD card. My problem is how can I replace the first line with the new value to be written. I want to delete the first line of the file and write again the new value of the incremented variable. How can I achieve this?

Here is the code:

#include <SD.h>
#include <SPI.h>

File myFile;
const int CSpin = 10;

int counter;

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  pinMode(CSpin, OUTPUT);
  InitializeSDcard();
}

void loop() {
  // put your main code here, to run repeatedly:
  myFile = SD.open("KUP.txt", FILE_WRITE);
  counter++;
  String c = String(counter);
  WriteToFile(c);
  Serial.println(counter);
  delay(500);
  myFile.close();
  SD.remove("KUP.txt");
  delay(500); 
}

void InitializeSDcard(){
  Serial.println("Opening SD Card . . .");
  delay(500);
  if(SD.begin(CSpin))
  {
    Serial.println("SD Card ready to use");
  }else{
    Serial.println("Failed to open SD Card");
    return;
  }
}

int WriteToFile(String text){
  if(myFile)
  {
    myFile.println(text);
    Serial.print("Text written: ");
    Serial.println(text);
    return 1;
  }else{
    Serial.println("Failed to write");
    return 0;
  }
}

This is my trial code. I tried creating and deleting the file so that I can only write to the first line and it doesnt seem to work. Can someone help me fix this code?

Can someone help me fix this code?

Sure. You can.

Look at the source code for the SD library. Look at SD.h.

File SDClass::open(const char *filepath, uint8_t mode) {

The comments about the mode argument are instructive, but not complete.

In SdFat,h, in the utility folder:

// use the gnu style oflag in open()
/** open() oflag for reading */
uint8_t const O_READ = 0X01;
/** open() oflag - same as O_READ */
uint8_t const O_RDONLY = O_READ;
/** open() oflag for write */
uint8_t const O_WRITE = 0X02;
/** open() oflag - same as O_WRITE */
uint8_t const O_WRONLY = O_WRITE;
/** open() oflag for reading and writing */
uint8_t const O_RDWR = (O_READ | O_WRITE);
/** open() oflag mask for access modes */
uint8_t const O_ACCMODE = (O_READ | O_WRITE);
/** The file offset shall be set to the end of the file prior to each write. */
uint8_t const O_APPEND = 0X04;
/** synchronous writes - call sync() after each write */
uint8_t const O_SYNC = 0X08;
/** create the file if nonexistent */
uint8_t const O_CREAT = 0X10;
/** If O_CREAT and O_EXCL are set, open() shall fail if the file exists */
uint8_t const O_EXCL = 0X20;
/** truncate the file to zero length */
uint8_t const O_TRUNC = 0X40;

So, use the O_TRUNC flag when opening your file, and, poof!, the contents are gone.

Im having a hard time understanding the code :frowning: can you rewrite the code for me and explain the each line of code? If its mot too much to ask :slight_smile:

The only line you need to change is this one:

  myFile = SD.open("KUP.txt", FILE_WRITE);

SD.h contains:

#define FILE_WRITE (O_READ | O_WRITE | O_CREAT)

So, you should be able to see how to change the code to truncate the file when opening it.

  myFile = SD.open("KUP.txt", O_READ | O_WRITE | O_CREAT | O_TRUNC);

do I still have to remove the "SD.remove("KUP.txt")"?

@PaulS:
I did what you asked but its not writing anything to the SD card. file is always empty:

  myFile = SD.open("KUP.txt", O_READ | O_WRITE | O_CREAT | O_TRUNC);
  counter++;
  String c = String(counter);
  WriteToFile(c);
  Serial.println(counter);
  delay(500);
  myFile.close();
  SD.remove("KUP.txt");
  delay(500);

I also tried this one:

  myFile = SD.open("KUP.txt", O_READ | O_WRITE | O_CREAT | O_TRUNC);
  counter++;
  String c = String(counter);
  WriteToFile(c);
  Serial.println(counter);
  delay(500);

but I still cant write to the SD card.

I did what you asked but its not writing anything to the SD card. file is always empty:

In your
first snippet you need to delete this line. You don't want to remove the file.

  SD.remove("KUP.txt");

In your second snippet, you never use a myFile.close() which actually writes the data to the card.

You have one code that opens the file, writes to the file, closes the file, and deletes the file.

You have one code that opens the file, writes to the file, and never closes it.

Neither one of them is right.

is this right?

myFile = SD.open("KUP.txt", O_READ | O_WRITE | O_CREAT | O_TRUNC);
  counter++;
  String c = String(counter);
  WriteToFile(c);
  Serial.println(counter);
  delay(1000);
  myFile.close();

It worked!! Thank you sooo much! :smiley:

“I am using this code of yours but not getting any data in file kup.txt in SD card. The file is being creating but it’s empty. Can you explain how to solve out ??”

The code is as under :-

#include <SD.h>
#include <SPI.h>

File myFile;
const int CSpin = 10;

int counter;

void setup()
{

Serial.begin(9600);
pinMode(CSpin, OUTPUT);
InitializeSDcard();
}

void loop()
{

//myFile = SD.open(“KUP.txt”, FILE_WRITE);
myFile = SD.open(“KUP.txt”, O_READ | O_WRITE | O_CREAT | O_TRUNC);
counter++;
String c = String(counter);
WriteToFile(c);
Serial.println(counter);
delay(1000);
myFile.close();
// SD.remove(“KUP.txt”);
// delay(500);
}

void InitializeSDcard()
{
Serial.println(“Opening SD Card . . .”);
delay(500);
if(SD.begin(CSpin))
{
Serial.println(“SD Card ready to use”);
}else{
Serial.println(“Failed to open SD Card”);
return;
}
}

int WriteToFile(String text)
{
if(myFile)
{
myFile.println(text);
Serial.print("Text written: ");
Serial.println(text);
return 1;
}else{
Serial.println(“Failed to write”);
return 0;
}
}

Make sure both GND ports on the SD card module are grounded