The OP has likely solved this problem by now, but I know that others will be in the same position, so I am answering for them.
I routinely record ten channels of biological sensors including one of 16-bit sound at 8 kHz (plus the associated FFT data) to an SD card using arduino-compatible systems, so I doubt very much that the SD card writing per se is the problem.
Throughput to an SD card is a function of several variables.
- To maximize write throughput you need to write full blocks of data at
the correct block size, since partial blocks take the same amount of
time as full blocks.
- You also need to be ready with more data as soon as the SD card is
ready to take more, otherwise precious cycles slip away from you.
- You need to ensure that your writes are non-blocking (don't try to
write more than the buffer can receive) so your loop can process and
queue up new data while the SD card is doing its thing.
- You need to read any timing-sensitive sensors using interrupt service
routines that write their data either to a circular buffer or to one
of a group of two or three buffers that are cycled between being
filled and being emptied.
Printing debug statements to the serial port can take many tens of milliseconds in a loop that otherwise may take only a few microseconds. If you write more than the serial port buffer can hold, the call will be blocking and you will be at the mercy of the PC that's reading the serial port. This will always be bad enough to mess up the program you're trying to debug... I've encountered situations where this introduced delays of up to 10 seconds (the PC was misbehaving, but still...).
A quick improvement to printing debug statements is to maintain a loop counter and only print a debug statement every N loops.
The program in the original question uses a naive strategy in the sense that it acquires some amount of data and then immediately tries to write it to the SD card, waiting until the write is complete before trying to acquire new data. This will never work at high data rates for the reasons given above. If you use this approach, you are likely wasting 90% of your program cycles in waiting for the SD write and the Serial port write. If either one takes too long, you will miss the next data acquisition window.
My advice: your first step is to research and find or write a circular buffer library.
Then set a timer to call an interrupt service routine that acquires data and puts it into the circular buffer.
Write a loop routine that checks to see whether the SD card is available for writing, and then takes just enough data out of the circular buffer to fit in a single block write for your SD card (look at the documentation for the card adaptor and the card).
At that point you will know whether your system can keep up with your needs.
It's possible that your SD card writing itself is OK but your Arduino is having trouble keeping up either because it's too slow or because you don't have enough room for a sufficiently large circular buffer. I doubt this because I've recorded and played back audio at 8 KHz on the Uno, but then I don't know what else you need to accomplish in your program.
If you do determine that the Arduino itself is too slow or has insufficient memory, take a look at the Teensy series of boards [https://www.pjrc.com/teensy/index.html]. They are entirely compatible with Arduino libraries and IDE but they run hundreds of times faster than the Uno at a larger data width, plus they have oodles of RAM and a gazillion pins. They're also much smaller than the Arduino form factor and the community that uses them is very knowledgeable.
If it turns out that SD card write throughput is OK but that it requires more buffering than you have on-board, you can add an SPI ram breakout board for more fast buffering space.
Finally, if the amount of data you need to collect is so large and so continuous that you simply can't buffer it long enough to get it written out to SD, or if the SD card truly can't keep up, or if the data is larger than any available SD card, you may consider sending your data off the board in near-real-time. I send 10 hours of nightly data from a Teensy over a USB virtual serial port to the PC at about 3Mbps, and others have done better. Ethernet output is also available and can be at least an order of magnitude greater.