Open an existing file when microSD is no present

Hello everybody,

I have an arduino uno and MricoSD car reader, I´m dattalogging 3 one wire DS18B20 on a 8GB micro sd.

All works perfect: the .txt creates Ok if it doesn´t exist, open .txt Ok, and write it Ok.

I included a led and routine in diferents parts of code to show any error but if I extract the microSD while sketch is running it continues logging and gives no error. If I introduce microSD again it continues logging but write nothing on microSD.

This is my code:


#include <OneWire.h>
#include <SD.h>

File SDRegTemp;
OneWire onewire(7);

#define StatusLed 6

float TEMP[4];
byte e = 0;
byte l = 0;
byte i;
byte present = 0;
byte type_s;
byte data[12];
byte addr[8];
float celsius;

void setup(void) {

pinMode(StatusLed, OUTPUT);
digitalWrite(StatusLed, LOW);
Serial.begin(9600);
Serial.print("Iniciando SD ...");

if (!SD.begin(4)) {
error();
} else {
digitalWrite(StatusLed, HIGH);
}

if (SD.exists("RegTemp.txt")) {
return;
} else {
delay(200);
SDRegTemp = SD.open("RegTemp.txt", FILE_WRITE);
SDRegTemp.close();
}
}

void loop(void) {

while (e < 4) {

regtemp();
}
delay(6000);
e = 0;
}
void regtemp() {

if ( !onewire.search(addr)) {

onewire.reset_search();
e = 4;
delay(500);
return;
}

if (OneWire::crc8(addr, 7) != addr[7]) {
error();
}

onewire.reset();
onewire.select(addr);
onewire.write(0x44, 1);

delay(1000);

present = onewire.reset();
onewire.select(addr);
onewire.write(0xBE);

for ( i = 0; i < 9; i++) {
data = onewire.read();

  • }*
  • int16_t raw = (data[1] << 8) | data[0];*
  • if (type_s) {*
  • raw = raw << 3; // 9 bit resolution default*
  • if (data[7] == 0x10) {*
  • raw = (raw & 0xFFF0) + 12 - data[6];*
  • }*
  • } else {*
  • byte cfg = (data[4] & 0x60);*
  • if (cfg == 0x00) raw = raw & ~7; // 9 bit resolution, 93.75 ms*
  • else if (cfg == 0x20) raw = raw & ~3; // 10 bit res, 187.5 ms*
  • else if (cfg == 0x40) raw = raw & ~1; // 11 bit res, 375 ms*
  • }*
  • celsius = (float)raw / 16.0;*
  • Serial.print("Temperature = ");*
  • Serial.print(celsius);*
  • Serial.print("ºC");*
  • Serial.println();*
  • TEMP[e] = celsius;*
  • Serial.println(TEMP[e]);*
  • if (SD.exists("RegTemp.txt")) {*
  • Serial.println("existe");*
  • return;*
  • } else {*
  • error();*
  • }*
  • SDRegTemp = SD.open("RegTemp.txt", FILE_WRITE); //abrimos el archivo*
  • if (SDRegTemp) {*
  • SDRegTemp.print("Sonda");*
  • SDRegTemp.print(e);*
  • SDRegTemp.print(", ");*
  • SDRegTemp.print(TEMP[e]);*
  • SDRegTemp.print("\n");*
  • SDRegTemp.close();*
  • } else {*
  • Serial.println("error");*
  • error();*
  • }*
  • e++;*
  • if (e == 3) {*
  • e = 0;*
  • }*
    }
    void error() {
  • while (true) {*
  • digitalWrite(StatusLed, HIGH);*
  • delay(100);*
  • digitalWrite(StatusLed, LOW);*
  • delay(100);*
  • }*
    }
    ---
  • if (SD.exists("RegTemp.txt")) {*
  • Serial.println("existe");*
  • return;*
  • } else {*
  • error();*
  • }*
    This function print "existe" when the microSD card is out of reader.
    Any idea? Thanks.

Goosze:
I have an arduino uno and MricoSD car reader, I´m dattalogging 3 one wire DS18B20 on a 8GB micro sd.

All works perfect:

Well, I couldn't get it to compile, so I guess it isn't. Please post your code in the proper manner, using the </> tags.

You appear to have redundant code in Setup to check the SD. If you want to use a file RegTemp and it isn't there, it will be created.

Removing the card while the programme is running can't be a good idea. Why would you do that?

Thank for your prompt response, sorry for the code is my first time.

Here is:

#include <OneWire.h>
#include <SD.h>

File SDRegTemp;
OneWire  onewire(7);

#define StatusLed 6

float TEMP[4];
byte e = 0;
byte l = 0;
byte i;
byte present = 0;
byte type_s;
byte data[12];
byte addr[8];
float celsius;

void setup(void) {

  pinMode(StatusLed, OUTPUT);
  digitalWrite(StatusLed, LOW);
  Serial.begin(9600);
  Serial.print("Iniciando SD ...");
  
  if (!SD.begin(4)) {
    error();
  } else {
    digitalWrite(StatusLed, HIGH);
  }

  if (SD.exists("RegTemp.txt")) {
    return;
  } else {
    delay(200);
    SDRegTemp = SD.open("RegTemp.txt", FILE_WRITE);
    SDRegTemp.close();
  }
}

void loop(void) {

  while (e < 4) {

    regtemp();
  }
  delay(6000);
  e = 0;
}
void regtemp() {

  if ( !onewire.search(addr)) {

    onewire.reset_search();
    e = 4;
    delay(500);
    return;
  }

  if (OneWire::crc8(addr, 7) != addr[7]) {
    error();
  }
 
  onewire.reset();
  onewire.select(addr);
  onewire.write(0x44, 1);  

  delay(1000); 

  present = onewire.reset();
  onewire.select(addr);
  onewire.write(0xBE);      

  for ( i = 0; i < 9; i++) {           
    data[i] = onewire.read();
  }

  int16_t raw = (data[1] << 8) | data[0];
  if (type_s) {
    raw = raw << 3; // 9 bit resolution default
    if (data[7] == 0x10) {
      raw = (raw & 0xFFF0) + 12 - data[6];
    }
  } else {
    byte cfg = (data[4] & 0x60);
    if (cfg == 0x00) raw = raw & ~7;  // 9 bit resolution, 93.75 ms
    else if (cfg == 0x20) raw = raw & ~3; // 10 bit res, 187.5 ms
    else if (cfg == 0x40) raw = raw & ~1; // 11 bit res, 375 ms
  }
  celsius = (float)raw / 16.0;
  Serial.print("Temperature = ");
  Serial.print(celsius);
  Serial.print("ºC");
  Serial.println();
  TEMP[e] = celsius;
  Serial.println(TEMP[e]);

  if (SD.exists("RegTemp.txt")) {
    Serial.println("existe");
    return;
  } else {
    error();
  }

  SDRegTemp = SD.open("RegTemp.txt", FILE_WRITE); //abrimos  el archivo
  if (SDRegTemp) {
    SDRegTemp.print("Sonda");
    SDRegTemp.print(e);
    SDRegTemp.print(", ");
    SDRegTemp.print(TEMP[e]);
    SDRegTemp.print("\n");
    SDRegTemp.close();
  } else {
    Serial.println("error");
    error();
  }

  e++;
  if (e == 3) {
    e = 0;
  }
}
void error() {

  while (true) {
    digitalWrite(StatusLed, HIGH);
    delay(100);
    digitalWrite(StatusLed, LOW);
    delay(100);
  }
}

In setup I check that SD is present an then check if RegTemp.txt is present if not, create it.

I want to implement a security for microSD, if it´s removed during normal work goes to "error".

I think that some register flag is activated when check first time if TXT exist, when I check it second time I only read the flag.

I have seen cases where it appears you can open a file with the SD removed since the directory entry for the file is in the cache or the file is not closed due to an error in close().

Unfortunately close() is void in the SD.h wrapper and does not return the success/fail value from the underlying SdFat close() function.

setWriteError() is not called reliably in SD.h so you can't depend on getWriteError().

So you are out of luck. I wrote the SdFat base for SD.h in 2009 but do not maintain the code used with SD.h.

  1. and that's why we insist on code tags.

I've got this to work but only by modifying the underlying library to actually close the SD card and delete the cache. I started from the SD.h library as it existed a few years ago. I haven't looked at the current version to see if it fixes this problem.

Thanks for replys,

I have installed SD bluit-in by arduino, sparkfun V1.1.1 library.