Hello, I developing meteo logger - ATmega8 ("watchdog" MCU) + ATmega328 (main MCU) + temperature/humidity/pressure/leaf wetness sensors with nRF24l01 for remote downloading of data. For reducing power consumption, I'm switching power off between measurement. Everything is ok for about 15000 cycles... then file.close() starts to failing and data is not written. (For some reason SD.begin() and file.open() still returns true.) This effect doesn't appear if I don't cycle power for SD card. SD card is not always coruupted - sometimes it is.. aprox. 1 of 4 attempts ends with card corrupted. It looks like problem of SD card (RAM has 1100 B free space and I don't use strings and uart,...), MCU is powered off with card, so everything should be reset....
teslista:
Hello, I developing meteo logger - ATmega8 ("watchdog" MCU) + ATmega328 (main MCU) + temperature/humidity/pressure/leaf wetness sensors with nRF24l01 for remote downloading of data. For reducing power consumption, I'm switching power off between measurement. Everything is ok for about 15000 cycles... then file.close() starts to failing and data is not written. (For some reason SD.begin() and file.open() still returns true.) This effect doesn't appear if I don't cycle power for SD card. SD card is not always coruupted - sometimes it is.. aprox. 1 of 4 attempts ends with card corrupted. It looks like problem of SD card (RAM has 1100 B free space and I don't use strings and uart,...), MCU is powered off with card, so everything should be reset....
Do you have any advice, please?
Thanks, David
I would say you are powering off the SDcard while it is updating it's storage.
chuck: Thanks for response, but it must be something else (I power off SD card with 300ms delay after calling file.close()) and problem is even with file.close() itself - it returns false - so, card initialization returns true, file.exist() returns true, file.open() returns true and file.close() fails - in this step is data written to card, am I right?
Another strange behavior is that, when I unplug card and put it back (while power is down), then everything works again... until another +/- 15000 cycles - how the card can recognize that it was unpluged, when there was no power? Or is there any posibility, that it is ATmega328, who is senstive to unpluging card? Like if it clears some data from RAM when program is running without card? (I don't use EEPROM)... RAM is volatile - should be erased after reset, or not?
I use SdFat 2015 03 24 and arduino pro 3V3/8MHz core for atmega328. On SPI bus is NRF24L01... but it has same behavior without it. I also tried short-circuit power imidietly after turn power off (if slowly falling supply voltage doesn't matters), but without any difference.
I'm attaching source code for ATmega328, there is writing to EEPROM for debugging, no difference without it.
teslista:
chuck: Thanks for response, but it must be something else (I power off SD card with 300ms delay after calling file.close()) and problem is even with file.close() itself - it returns false - so, card initialization returns true, file.exist() returns true, file.open() returns true and file.close() fails - in this step is data written to card, am I right?
If you are getting a file.close() fail, it is detecting an error condition. One of the simplest is out of memory. The UNO only has 2k of ram, SD need ~900 for its self.
I noticed that you are creating objects in your measure() routine. In a perfect world this would be ok, but a lot of Arduino library creators assume that once an object is created it will exist forever. A lot of libraries do not have destructors for their objects.
I have not reviewed AdaFruits libraries or the oneWire library. You might want to check for memory leaks.
A question, Why are you directly manipulating the Hardware Serial port? is there a problem using Serial.read(), Serial.available()? Are you sure that no other library has referenced Serial?
SD cards are not designed to power on and off frequently. They have a 32-bit CPU and run complex algorithms to maintain the internal flash chips.
Occasionally, large blocks of data are copied in the wear-leveling procedure.
SD cards have very large flash blocks and emulate 512 byte sectors so much data is copied in this process when you open and close files. Moving data also requires erasing much flash.
There is a protocol for safely powering off SD cards when used in SDIO mode. The Arduino uses SPI mode and this protocol is not supported in SPI mode.
Also, when you call SD.begin(), the SD card's CPU is reset and you can lose data if this is done at the wrong time.
This is what the SD standard says about the way your program works:
Resetting a card (using CMD0 or CMD15) will terminate any pending or active programming operation. This may destroy the data contents on the card. It is the host's responsibility to prevent this.
If SD.begin() fails or file.close() fails, you have serious problems.
SD cards have a sleep mode to save power. SD cards draw less than 100 μA in sleep mode.
Here is a project that can log data for most of a year with three AA batteries using sleep for the Arduino and SD card.
Thanks to everyone for your help. None of advice unfortunately did't work, so... I solved problem different way... instead of using SDcard, I'm using dataFlash now and everything is ok (I did not need so much memory space)....
using <SdFat.h> I have no problem to turn the SD-card on and off via MOSFET.
if (stringComplete) {
digitalWrite(5, HIGH); //MOSFET on
if (!SD.begin(chipSelect)) { // see if the card is present and can be initialized:
Serial.println("Card failed or not present");
delay(50);
return;
}
File dataFile = SD.open("log.txt", FILE_WRITE);
dataFile.print(inputString);
dataFile.close();
Serial.print(inputString);
Serial.flush(); //takes ~100ms or something
inputString = ""; // clear the string:
stringComplete = false;
digitalWrite(5, LOW); //MOSFET off
}
However... how are you keeping the RTC connected? As soon as I once enter powerdown the connection is gone. I couldnt see any recovery code in your project? How do u do it?