SD Card filesystem poblem

GPRS module: Welcome to ELECFREAKS WIKI — ELECFREAKS WIKI

  • based on SIM900
  • uses digital pin 5 for reset and digital pin 6 for power up
  • has issues sending continuously large amounts of data
  • has power supply issues, probably responsible for the above one
  • has issues with turning on
    etc.

SD card module: http://www.lctech-inc.com/Hardware/Detail.aspx?id=0c3b6f7a-d101-4a60-8b56-3abfb7fd818d

  • SS is connected to digital pin 4
  • has 3.3v voltage regulator and supports both 3.3v and 5v vcc, connected to 3.3, no extra capacitors added... yet..

RTC module: Microbot - Real Time Clock module with DS1307

  • DS1307 based
  • 5v
  • i2c
  • using the "out" pin on digital pin 2 (interrupt 0) with 1hz clock "caught" upon RISING (once per second)

I am using pin 8 for MicroMag3 RESET pin.

Here are some screenshots of what happens to the SD card after some uptime (20-30) mins.

Maybe this caution will make sense?
http://www.elecfreaks.com/wiki/index.php?title=EFCom_GPRS/GSM_Shield#Cautions

SurferTim:
Maybe this caution will make sense?
http://www.elecfreaks.com/wiki/index.php?title=EFCom_GPRS/GSM_Shield#Cautions

I was thinking about this... I am using 1.5A 12V adapter, also tried with 2x 18650 li-ion batteries in series, from 7.4 to 8.4 v when charged... 2400 mAh, but I am not sure about the peak capacity of those batteries... should be above 1x I guess... (hope)

I was also thinking about adding one big fat capacitor after MIC 29302WU (on the GPRS board) to try to compensate some drops... I could also add one cap on the vcc of the sd card module, although its quite odd for the arduino to survive such a voltage drop that the sd wouldn't...

I don't know what type of voltage regulator the SIM has, but if it is linear, the 12V 1.5A power supply may not be enough current and too much voltage. That will cause a heat problem at the regulator.

I don't know about the li-ion batteries. I use 4S 5000ma li-po batteries for testing wifi router (6 watts - switching power supply, not linear) locations, and the voltage drops off pretty quick. Maybe a voltage check would be in order?

I am the author of SdFat which is also the base for SD.h.

I have found most bugs that result in junk file-names are due to overwriting SdFat internal memory. The SD cache often has a directory block with 16 directory entries so you get lots of junk names if it is over written.

Check loop indices, array dimensions, strings with no zero byte termination, bad pointers, and any other causes of overwriting memory.

Hello again, I have decorated my project with some capacitors last night 1000uF and 220 uF on the output and input of the voltage regulator of the gprs module, another 470 uF on the vin and another 1000uF on the 5V. It started to look like a xmas tree, but made no actual effect what so ever.

I then commented just one line of code:

//sd.remove(filename);

and yes, its a miracle, the project lived for a very long time (until I turned it off actually) and outlasted the previous record of uptime (20min) many times. If what fat16lib say is so, then I should stop working very soon, because when I don't delete the files I get a new file each 5 minutes.. 12 directory entries per hour.

None of the other libraries I use are writing on the PROGMEM so I guess that shouldn't be the problem of SdFat. I had problems with SD.h (the old and modified one) because it was pretty larger, and my rom was 29.5 kb large. After uploading it to the atmega328p-pu nothing worked, because there was not enough space on the flash for buffers/cache and etc. With the new SdFat my rom shrinked down to 26.5 kb and everything seems to be working fine. (edit: except this issue with the fat16 filesystem corruption lol)

Do you get corrupt files if you don't comment out the remove()?

If you still have the problem with remove(), is is likely something is writing over SdFat memory.

Remove() needs to do lots of writes to the SD and would likely cause file-name problems if SdFat memory is overwritten.

Unfortunately, yes.

It lasted much more though... 20mins. vs 2h 30mins. Any ideas what could have caused that..?

I have news! After disabling the file removal, the uptime was far more than before, right? Now, after I disabled data logging when the GPRS is working, the device seem to be stable, it's working for like 15 hours now. This is not the best scenario, because the sd card will get full pretty quick and mostly because of the data loss... on every 5 mins I get a blank spot of about 1.5-2 mins, while the gprs is running... Somehow, this leads me to thinking that either voltage drops or interference from the gprs tx bursts are causing the fat16 corruption. Sounds pretty hopeless...

Modern SD cards are very tolerant to voltage drops. They don't commit writes when power is failing.

The SD data blocks have very powerful ECC so hardware write errors would be detected when you read the Sd on a PC or Mac.

This is a software problem.

How do you run data logging while GPRS is working?

You can't have a file open more than once and you can't call SdFat functions in an ISR.

My gprs handling functionality does not hold the mcu control for the entire process of transfer. I don't use delay(). The handler is designed as a state machine. From state 1 (power on) to state 20 (power off), each state has entry procedure and result or time dependent procedures. The handler holds the mcu control for a very short while, but many times thru the whole process of transferring data. Therefor my application runs its loop() pretty normally, and checks the ISR flag every time, if the interrupt has occurred - runs the logger, if not, continues. If both the logger and the gprs handlers are idle (has nothing to do in the current loop()), a sleep is set, until the next interrupt. While the gprs is running sleep is disabled... here is an example...

void loop()
{
	if (interrupted) // show new time only when new interrupt signaled
	{
		interrupted = false;

                seconds++;

		idle_logger = false;

                if (seconds%GPRS_IDLE_TIME == 0)
                {
                    idle_gprs = false;
                }
                
                if (seconds%BATTERY_MONITOR_IDLE == 0)
                {
                    idle_battery_monitor = false;
                }
	}

        if (!idle_logger && idle_gprs) //test test test
            runLogger();
        
        if (!idle_gprs)
            runGPRS();
        
        if (!idle_battery_monitor)
            runBatteryMonitor();
        
        errorLog();

        if (idle_logger && idle_gprs && idle_battery_monitor)
            setSleep();
        
}

The logger resets its idle status every time, so after log is being written the system goes back to sleep, unless the gprs is doing something. The gprs holds its idle status to "false" until the final state procedure has been complete. That's how I combine both processes. You can see in my previous posts part of the code of "runLogger()".

If is not the voltage drops that cause the issue, then maybe signal interference occurs... Maybe I should wrap the arduino and the SD module in some sort of a faraday cage :smiley:

Once the data gets into an SD card there just are not undetected write errors.

Noise on the SPI bus is be the only thing left.

You can check that by enabling CRC on SPI transfers between the Arduino and SD.

I added software CRC to SdFat so edit SdFatConfig.h at about line 35 and change USE_SD_CRC to 1 or 2.

/**
 * To enable SD card CRC checking set USE_SD_CRC nonzero.
 *
 * Set USE_SD_CRC to 1 to use a smaller slower CRC-CCITT function.
 *
 * Set USE_SD_CRC to 2 to used a larger faster table driven CRC-CCITT function.
 */
#define USE_SD_CRC 0

Then all transfers on the SPI bus will be CRC protected. Calls to SdFat functions will fail with an error return.

Thank you very much, I will try this out, because since I've disabled writing while gprs is on the device worked for more than 24 hours without any faults.

Will respond back with results soon!

As a test, try running the GSM and the Arduino/SDcard on two separate batteries.

This will put to rest the problem area.

An barrier of opto isolators between the two may help your problem.

Try to write a RESET message into the SDcard.

Your memory may be getting corrupted.

Good Luck

fat16lib:
Once the data gets into an SD card there just are not undetected write errors.

Noise on the SPI bus is be the only thing left.

You can check that by enabling CRC on SPI transfers between the Arduino and SD.

I added software CRC to SdFat so edit SdFatConfig.h at about line 35 and change USE_SD_CRC to 1 or 2.

/**
  • To enable SD card CRC checking set USE_SD_CRC nonzero.
  • Set USE_SD_CRC to 1 to use a smaller slower CRC-CCITT function.
  • Set USE_SD_CRC to 2 to used a larger faster table driven CRC-CCITT function.
    */
    #define USE_SD_CRC 0



Then all transfers on the SPI bus will be CRC protected. Calls to SdFat functions will fail with an error return.

I actually failed in attempting this, because this made my rom a bit larger than before and I guess that the flash memory was not enough for SdFat buffers, everything crashed in a reset loop...

Because of the fact that no bug occurs when I don't write on the SD while gprs is running leads me to thinking that the problem is not with the SdFat but with some sort of electromagnetic interference that messes up the SPI bus (that runs below the gprs board). I will try isolating some how the two parts of the device, because using AC/DC adapter with larger capacity didn't change anything, which removes the possibility of power issues causing voltage drops on the SPI.

donvukovic:
As a test, try running the GSM and the Arduino/SDcard on two separate batteries.

This will put to rest the problem area.

An barrier of opto isolators between the two may help your problem.

Try to write a RESET message into the SDcard.

Your memory may be getting corrupted.

Good Luck

The memory card works perfectly in other test applications.. It's probably ok. I will do some more tests and will feed back soon...

I guess that the flash memory was not enough for SdFat buffers, everything crashed in a reset loop...

Flash use will not cause a crash in a reset loop. If you are that close to running out of RAM, you will likely have a problem if you log data and run gprs at the same time. A pin change interrupt in SoftwareSerial can cause a stack overflow while an SdFat function like remove() is executing.

If possible check the amount of free stack by adding this include:

#include <SdFatUtil.h>

And this print in setup()

  Serial.println(FreeRam());

You need 200-300 bytes of free RAM in addition to any you allocate in functions.

I looked at your SD module and these often fail.

The problem is that these modules don't use proper level shifters on MOSI, SCK, and CS. These signals should be converted from 5V to 3.3V with an IC based level shifter. Most SD cards are not designed to accept 5V signals.

Too bad you can't use CRC on the SD to check for data transfer errors. You can check for any detected SD problem like this:

if (sd.card()->errorCode()) {
  // print SD I/O error code
  Serial.println(sd.card()->errorCode(), HEX);
}

Here are typical SD modules with a level shifter in addition to a 3.3V regulator

http://www.pjrc.com/teensy/sd_adaptor.html

fat16lib:
Flash use will not cause a crash in a reset loop. If you are that close to running out of RAM, you will likely have a problem if you log data and run gprs at the same time. A pin change interrupt in SoftwareSerial can cause a stack overflow while an SdFat function like remove() is executing.

I am not using SoftwareSerial, I am using the internal Serial object to communicate with the gprs. The worst operation done in my application is one call of sprintf() over 69 chars array. I will check my ram usage with the function you provided, but I am sure there's not much left..

fat16lib:
I looked at your SD module and these often fail.

The problem is that these modules don't use proper level shifters on MOSI, SCK, and CS. These signals should be converted from 5V to 3.3V with an IC based level shifter. Most SD cards are not designed to accept 5V signals.

Thanks for the feedback, I will keep in mind replacing this.

By the way all I had time today to test was to enable writing while gprs is running again and test the application and the device with gprs module wired up away from the device, not stacked on top. The results are pretty optimistic for now, the device has been working for like 5 hours now with no fails! If it continues to work normally like that for 24 hours I will uncomment the deletion of files (to restore the original application) and test it again. If the second test is also positive, then the problem is 100% eletromagnetic interference.

Thanks for the attention last few days, you've really done an amazing job with this library and its very honorable that you support people with its usage!

Will feed back soon

I am not using SoftwareSerial, I am using the internal Serial object to communicate with the gprs.

HardwareSerial also uses lots of stack for interrupts. I assumed SoftwareSerial since many gprs libraries use it.

Are you checking all SdFat calls for error returns?

The case could be considered closed.

When the GPRS shield is detached and wired from a distance the device works perfectly with the original version of my application, which caused the most problems. I have removed all debug delays I've placed after writing, I have re-enabled writing while GPRS is working and re-enabled file deletion after successful transfer. The device is working for 48 hours now, the condition of the SD card's fat16 file system is also normal (with the GPRS shield stacked on top the device would not last 10 minutes). Beware of using Efcom's SIM900 GPRS shield, it has bad power supply, unstable firmware and... as we can all see - makes a lot of electromagnetic interference... the manufacturer didn't bother to shield against noises, which could have destroyed other peripheral devices. Not only the SD uses the SPI bus, but also very expensive sensor equipment...

Thank you very much for the attention!