Ethernet Shield speed slowed down by SD card?

Hello everyone,

I am working on a project which has an Arduino Uno board, an Ethernet Shield, and an SD Card which is mounted on the Shield.

It’s a basic SD card web server. When I type it’s IP address in the browser, then the Arduino fetches the HTML page (.htm) from the SD card and writes it to the browser. It works fine, but here is a problem.

The htm webpage on the SD card is about 64kb in size, and it takes about 16 seconds to load it on the browser. It means that the Arduino writes the page at a rate of 4kbps. This is too slow if it is to load a 64kb page.
And I can literally see the Ethernet Shield struggling as the webpage loads.

I tried it with both SD library and SDfat library. (SDfat was said to be faster than SD) but both gave the same result.

What I think now, is that the Ethernet Shield and SD both use the SPi bus. How it works is that Arduino reads one char at a time from the htm file and write()s it on the Ethernet client. So I think, that this is too complicated and switching the Ethernet and SD on the SPI bus just for one char is very time consuming.
I think that the alternation of the Ethernet and SD on the bus is causing time.

Please can anyone tell if this is actually the problem, or its anything else? And please tell if I can use the SD and Ethernet on two separate SPI buses.

And yes, I forgot to mention that my Arduino sketch uses 75℅ ram, leaving 512 bytes for local variables.

So actually I don’t think that this would cause the problem as my function only needs one byte of char at a time, but keep a note of this low memory.

I am not a beginner, I have worked with Arduino for 3 years.

try to add buffering

Thank You I will try it.

But can I connect the SD to a separate SPI bus to make things simpler?

I don’t think so this will work because the SD’s SPI bus is hard connected to the Ethernet’s SPI. So I don’t think this is possible.

And also, is there a way to optimize SPI, or increasing clock rate? Please tell.

buffering optimizes SPI and network transfer

Thank you, I will definitely try this method.

Also, can I increase the SPI clock speed?
Or will it cause data corruption?

both libraries use max available speed. they use SPI transitions to set the bus speed for the specific device before communicating with it

And lastly, should I use SDfat or should I use the default SD library?

It was said on GitHub that SDfat is way faster than SD. But when I tested, It gave the same result.

Which one should I use?

I never tested SDFat. SD is old version of SDFat wrapped in Arduino API. the network is much slower then the SD card

No where in your discussion of the SD card do you account for the fact that the data is ONLY read from the card in 512 byte segments and the library must block until all the 512 bytes have been read.
Paul

Paul, we can’t do anything about that, but I am sure there is room for big improvement with SPI and network transfer.

But some local variables also exist in my sketch, so it’s not always 512 bytes free.

SD libraries always have their own 512 byte buffer to read SD card data into or write SD card data from. When you read one or more bytes, the library only moves that number of bytes from it’s buffer to your variable. When the library has moved 512 bytes, total, it will physically read another 512 bytes into it’s buffer and that takes time!
Paul

code.ino (1.5 KB)

My code.

I used a 64 byte char buffer.

I tested it but it gave same result. 16 seconds.
What’s the problem now…

you still read and write by one byte. how should the libraries use optimized read and write?

I linked an example above
here is the file download part

        char buff[RESPONSE_BUFFER_SIZE];
        BufferedPrint response(client, buff, sizeof(buff));
        response.println(F("HTTP/1.1 200 OK"));
        response.println(F("Connection: close"));
        response.print(F("Content-Length: "));
        response.println(file.size());
        response.println();
        response.copyAvailableFrom(file);
        response.flush();
        file.close();
        client.close();

It worked, thanks for your help #Juraj.

Now I am getting better speeds.