Files are being corrupted on my SD card, and I'm not writing to it!

Hey guys,

I'm having an issue with files being corrupted on my SD card. I powered up my board this evening, and after working flawlessly the last couple days, I suddenly started hearing static while playing this looping hum sound effect. I wiggled my audio cables to no avail, and even plugged in a speaker directly to my project just to make sure it was the audio cable going to my amp which was the issue, but I still got the static. I then remembered that a while back I had a similar issue which I'd chalked up to having stuck new files on the SD card without formatting it first, and I overwrote the files without actually checking to see if they were corrupted, which someone had suggested might be the problem. So this time I copied the files off the SD card and loaded them into my sound editing program, and lo and behold in my looping sound effect there are repeating regions of static. And not single pops and clicks here and there, but regular sections of noise, each 200ms, and spaced 400ms apart.

I can't imagine what would cause this. They don't seem spaced in such a way that it would be related to the sample buffer being filled. (it's only 512 bytes) And with my LED modules being updated at 60hz (one update where I send 72 bytes every 16ms) the gaps are much too large to be related to that either. I'm also not writing to the card, and no other files other than this one looping file that plays 90% of the time is corrupted. Also, my SD card, DAC, and LEDs are all on separate data busses and everything worked fine until this one file decided to suddenly become corrupted.

Has anyone who has used the WaveHC lib experienced anything like this?

I guess my next step will be to try to find some kind of SD card testing application to see if the card itself is broken. I would test with a new card but the problem happens so rarely it could be weeks before I see it again.

Hm, looking at the sound data more closely, I noticed something about it which may provide a clue. In the regions of static, I can see the sine wave which forms the original sound, but there are spikes. And those spikes are not random. They follow the curve of the sine wave closely. Some are small, and some are large, and they are fairly uniform in size. That indicates to me that rather than a random byte being written over a particular sample, I'm getting single bit errors.

In other words, the bytes on the card in these regions of static are unchanged, except for a single bit here and there. How could that happen? Is it possible to write a single bit to an SD card? Because it seems extremely unlikely that I might have a bug which would cause the correct sample to be written back to the card in the correct location, save for a few bits being wrong.

Here is the audio file:

Here is the relevant SD reader code:

Well I ran an SD card test program and it doesn't detect any issues with the card, so it must be something with my board or my code causing it. I don't think there's anything wrong with the hardware design, I've got a pullup on the CS pin like I should so garbage won't be written to the card but I can't see how there could be anything wrong on the software side either.

I forgot to mention that another weird thing was that when my board was playing back this file that had been corrupted somehow, something was causing my LED animation to be choppy. Like something in the SD card read code was stuck in a while loop briefly and would cause slight pauses in the LED updates, just short enough to cause the animation not to be smooth at 60fps. I suppose it could have been the wav reader code that was having issues though. But since sound force didn't seem to think the wav file was corrupted when I loaded the corrupted file, it seems unlikely that any headers were corrupted or I would expect it to have complained.

I haven't followed this thread all that closely, but I get the impression that you expect every read to take the same amount of time. That will not happen unless the file is less than 512 bytes. Is it?

This isn't about expecting reads to take the same time. I assume you are referring to the bit about the glitch with the animation speed. The issue there is that normally the animation runs smoothly. This is regardless of what sound file I play. But as soon as this file got corrupted, when it was played the animation started to be choppy. So something was causing it to take more time. A lot more time. Milliseconds. But the time to read it shouldn't have changed at all. I mean, a byte should not take longer to read if some bits in it are changed but it is still at the same location, right?

And what is this about different reads taking different amounts of time anyway? (No, my sound files are not 512 bytes long.)

You have already confirmed that the error is stored on the card and not introduced when reading from the card, so it seems clear that your SD card is being corrupted.

Since you don't write to it deliberately, I can see two possible explanations.

You might be writing to it accidentally. If you have code that writes to the card, it might be executing when you don't expect it to due to a bug. If your sketch uses the String class, it's conceivable that you have suffered memory corruption which resulted in the Arduino writing to the SD card. Not likely, but conceivable. Do you have a write protect tab on your SD card? If so (and if you have confirmed that it actually works) you could rule out the possibility that the card was being written to.

The card itself might be being damaged due to external factors - noise on the supply line, magnetic fields etc that are causing it to lose bits. Depending on the source of these errors, it is conceivable that they would tend to happen to files that were being accessed (and therefore having connections made to their memory cells).

When you say write to the card, do you mean code that writes files to the card? Or code that sends commands to the card? Becuase there is no code to write files to the card. The WaveHC lib includes only a fat reader class, no fat write class. But it does of course send data to the card to tell it to send data back.

Here's a pic showing the single bit errors I'm seeing in the sound file:

Can you post a link to the SD shield/hardware?

I use an ethernet shield with a uSD card onboard, and it is quite possible to unintentionally "write" to the SD if you do not disable the SD SPI interface when setting up the w5100. Is there another SPI device on the SPI bus?

It can also garbage up the SPI bus like you are seeing by using the SD card without disabling the w5100.

SurferTim: Can you post a link to the SD shield/hardware?

It's a custom board, but I can post the schematic:

I use an ethernet shield with a uSD card onboard, and it is quite possible to unintentionally "write" to the SD if you do not disable the SD SPI interface when setting up the w5100. Is there another SPI device on the SPI bus?

It can also garbage up the SPI bus like you are seeing by using the SD card without disabling the w5100.

The SD card is on USART0 all by itself. I've got USART0 set up to act as a second SPI bus. The first SPI bus is attached to my DAC. And I have some LED drivers on USART1.

The board is also running a custom bootloader which uses USART1 for serial communication. Not that that matters, since the CS pin is pulled high by the resistor. But just in case you thought a reset might cause data to be written to the card.

Have you compared the actual value with the expected value to see whether there is any pattern to which bits are affected?

Have you tried the 'write protect' check?

These are MicroSD cards, there is no write-protect switch.

And as for a pattern to the bits, you can see the sound file above at three different levels of magnification. Those repeating spikes when zoomed out all the way are the affected regions. You can see there is a pattern to them. And when you zoom in all the way, you can see the indvidual spikes are fairly regular in both time, and in size. (Regular in the sense that there’s only like 8 different sizes, indicating a single bit in the sample was flipped.)

I have not directly compared the two files byte for byte because that wouldn’t really provide more information that what I can see in the sound editing program. I can’t really tell where the headers are and such to see if they’re affected, and displaying the data visually like this makes it easy to see what’s been altered as far as the samples themselves go.