SPI and SD libraries take up 69% of RAM!

using the cardinfo example i see
Sketch uses 10660 bytes (34%) of program storage space. Maximum is 30720 bytes.
Global variables use 1422 bytes (69%) of dynamic memory, leaving 626 bytes for local variables. Maximum is 2048 bytes.
that's a lot of memory use

is there a lower overhead version out there someplace?

BTW, i'm only interested in SD card write, never read, and i only write 8 byte blocks every 10Hz

Oh!!! i replaced all the constant strings with F("string") and its down to
Global variables use 884 bytes (43%) of dynamic memory
still, a good chunk of available memory

Try SdFat to see if it has a smaller RAM footprint. If not, you may have to look for alternative filesystem drivers like PetitFS (though not sure if it has to do with SD cards); or create your own knowing how the MBR partition table and the FAT filesystem works.

But in any case, at least 512 bytes are mandatory for the sake of performance and longevitiy of the card.

steveh2112:
is there a lower overhead version out there someplace?

Its a question that gets asked often.

I dont recall anyone pointing out an better (lower memory) library.

If you find one, do tell us.

steveh2112:
Global variables use 1422 bytes (69%) of dynamic memory, leaving 626 bytes for local variables.

and stack. How deeply do your calls nest?

BTW, i'm only interested in SD card write, never read, and i only write 8 byte blocks every 10Hz

The library code you use to write, writes to a default 512 bytes (DOSFAT) buffer that gets written at burst speed to the controller in the SD card that changes the flash bits a block at a time.

I look at the ATmega1284P as more more suited to SD use. 16K RAM, 4K EEPROM, 128K flash, 32 IO pins, DIP not expensive even at Mouser (vs eBay or AliX) but more than two ATmega328P-PU's.

Look for "Atmega1284P minimal board". Gammon Forum : Electronics : Microprocessors : How to make an Arduino-compatible minimal board

The 644P DIP with 4K RAM was not much less than the 1284P DIP last time I saw. Size costs.

thanks, i only use the SD card for data logging and i have 8 byte blocks every 10Hz, which i flush every second in case or power loss, so i only use 80 bytes to buffer anyhow

i wonder if there is a way to reduce buffer size in the library?

i'll look into the other library suggestions too

in sdfat config i noticed this

/**
 * Call flush for endl if ENDL_CALLS_FLUSH is nonzero
 *
 * The standard for iostreams is to call flush.  This is very costly for
 * SdFat.  Each call to flush causes 2048 bytes of I/O to the SD.
 *
 * SdFat has a single 512 byte buffer for SD I/O so it must write the current
 * data block to the SD, read the directory block from the SD, update the
 * directory entry, write the directory block to the SD and read the data
 * block back into the buffer.
 *
 * The SD flash memory controller is not designed for this many rewrites
 * so performance may be reduced by more than a factor of 100.
 *
 * If ENDL_CALLS_FLUSH is zero, you must call flush and/or close to force
 * all data to be written to the SD.
 */

i looked thru the source and block size of 512 is not a single define someplace you can easily change, it seems to be hard coded into the source in hundreds of places. i suspect it would take weeks of work to change it to something like 128

i'll have a play with this when i have time

actually 512 is pretty hard coded into that one too

union cache16_t {
          /** Used to access cached file data blocks. */
  uint8_t data[512];
          /** Used to access cached FAT entries. */
  fat_t   fat[256];
          /** Used to access cached directory entries. */
  dir_t   dir[16];
          /** Used to access a cached Master Boot Record. */
  mbr_t   mbr;
          /** Used to access to a cached FAT16 boot sector. */
  fat_boot_t   fbs;
};

static cache16_t cacheBuffer_;      // 512 byte cache for raw blocks

and fat[256] is 512 bytes anyhow, not sure how big dir or mbr is but kinda looks like i'm screwed.
my only other thought is leave the library alone but use cacheBuffer as a temp 512 byte buffer when i'm not doing SD card writes, which is most of the time.

no idea if that will work but not hard to test

You don't want a smaller buffer for writing because it will cause the card to wear out sooner. In your case, VERY MUCH sooner.

  • The SD flash memory controller is not designed for this many rewrites
  • so performance may be reduced by more than a factor of 100.

also VERY MUCH slower.

That union lets the same buffer be used for different things.

fat_t fat[256]; // so what is fat_t defined as?


How about you put a battery backup on your project to prevent power loss from happening quick enough that you can't close the file to update the FAT and not lose your data?

GoForSmoke:
How about you put a battery backup on your project to prevent power loss from happening quick enough that you can't close the file to update the FAT and not lose your data?

its a RC airplane project, every gram counts, so battery backup not an option

i can probably live with the 512 bytes anyhow, just trying to think of ways to optimize the situation should i run into memory issues

Is it possible that you could wifi those 80 bytes/sec to a device that you hold? Even cheap wifi has good LOS range.

GoForSmoke:
Is it possible that you could wifi those 80 bytes/sec to a device that you hold? Even cheap wifi has good LOS range.

too complicated. my system is complicated enough already.

anyhow, not a big deal as i said, i have enough ram right now but some future ideas i have may need more

my idea is find out how much of that 512 byte buffer is actually used for writing 80 byte blocks. if it turns out a large part of it is not used, i can 'borrow' it for something else to use between SD writes

I thought that I explained that. You can force 80 bytes to be written at a time with flush(). Doing that will burn your SD card out early.

Wifi, you connect to serial at both ends then print at one and read at the other. It doesn't need SPI or SD libraries and doesn't use as much power as an SD write.

GoForSmoke:
I thought that I explained that. You can force 80 bytes to be written at a time. Doing that will EAT YOUR SD CARD QUICKLY at 10 writes per second.

its a FDR type function, important to save the last second or 2 before power loss and i don't have space for a battery backup

and its 1 write per second, 8bytes at 10Hz with a flush every 1 sec

also, i thought the SD card library was smart enough to move writes around on the physical device so it doesn't wear out one sector more than others

steveh2112:
its a FDR type function, important to save the last second or 2 before power loss and i don't have space for a battery backup

and its 1 write per second, 8bytes at 10Hz with a flush every 1 sec

also, i thought the SD card library was smart enough to move writes around on the physical device so it doesn't wear out one sector more than others

Yes, SD wear-levels and there are a lot of blocks on even a 2G card. There's only 3600 seconds in an hour but at 100,000 writes per block and millions of blocks you have card to waste.

the other thing is this is for an RC plane with typical flight times of a few minutes, not hours or continuous operation. i don't think Boeing or Airbus is going to be replacing their black boxes with my nano project any time soon

but i am impressed with how easy to use the SD library is and how well it works. i'm testing now (in my office, not in flight) but it seems to work great. i have a FDR playback program i wrote using the Unity game engine which works great.

SD is like a miracle for these boards as far as stretching what they can do.

Battery backup for the controller could be as light as a coin cell and transistor (to switch it ON/OFF) as all it would do is power a file close and turn off.

Other way would be to watch the battery V and when it drops below a value the prop and servos stop and the log file closes before the battery gets too low.

Do you have an Arduino board in there or did you go with a stand-alone chip?
https://make.kosakalab.com/arduino/obaka/project-2/index_en.html

I still think you should wifi the data back to a ground unit with storage, an Arduino and laptop for example would let you examine data during the flight. You could send a lot more data using cheap nRF24xx radio modules, you code Serial and the modules handle the magic in between each other all by themselves. There's actually less to it than there is to SD.

I was trying to make a project with I2C display and SD-card and didn't really succeed because of the memory overload.

There is this library: Petit FatFs - pf_lseek

But it seems it doesn't work with Arduino IDE, anyway I don't know to make it work. Also I found this one https://github.com/greiman/SdFat/blob/master/examples/ReadWrite/ReadWrite.ino

I takes a bit less memory.

Tofer:
Also I found this one https://github.com/greiman/SdFat/blob/master/examples/ReadWrite/ReadWrite.ino
I takes a bit less memory.

I think you are just nibbling at the edges, and the real answer is to get a Mega, or perhaps something using ESP8266.

GoForSmoke:
I look at the ATmega1284P as more more suited to SD use. 16K RAM, 4K EEPROM, 128K flash, 32 IO pins, DIP not expensive even at Mouser (vs eBay or AliX) but more than two ATmega328P-PU's.

Look for "Atmega1284P minimal board". Gammon Forum : Electronics : Microprocessors : How to make an Arduino-compatible minimal board

Last time I bought any was 2016 when I got 4 for $5.50 ea from Mouser. Price may have dropped some by now.

You can breadboard one for well under $10 and know every part, choose clock speed and source. Even get or make a PCB.

The 2560, 1280, 640 family are all surface mount and incredible, they support direct-address external SRAM and have 4 serial ports.

Cross Roads (a different member here I am not affiliated with but like his work) Electronics sells ATmega2560 all-the-pins breakouts btw. They are small and flat.

They also have the Bobweeny, a small board/socket for 40 pin 1284P chips, fits the 164, 324, and 644 as well. The 324 is a big Uno chip with 32 IO pins if only a dozen more pins or some open 8 bit ports are needed.

Atmega1284P On Top (a.k.a. Bobweeny)
Modeled after the Solarbotics Ardweeny, but adapted to have the 1284P on wirewrap socket headers instead of sitting under a board and having to
solder all the legs to something. Killed your chip? Pop in a new one!

http://www.crossroadsfencing.com/BobuinoRev17/