hello,
I have an Arduino atmega2560 and the ethernet shield.
I uploaded a simple index file on the SDcard. it doens't load the images that are 4KB but they wont load. and I'm working in my LAN.
so if I digit 192.168.2.10:81 it loads just the text of the index.htm
can someone help me out? this is the code
#include <SPI.h>
#include <Ethernet.h>
#include <SD.h>
// MAC address from Ethernet shield sticker under board
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress ip(192, 168, 2, 10); // IP address, may need to change depending on network
EthernetServer server(81); // create a server at port 80
File webFile;
void setup()
{
Ethernet.begin(mac, ip); // initialize Ethernet device
server.begin(); // start to listen for clients
Serial.begin(9600); // for debugging
// initialize SD card
Serial.println("Initializing SD card...");
if (!SD.begin(4)) {
Serial.println("ERROR - SD card initialization failed!");
return; // init failed
}
Serial.println("SUCCESS - SD card initialized.");
// check for index.htm file
if (!SD.exists("index.htm")) {
Serial.println("ERROR - Can't find index.htm file!");
return; // can't find index file
}
Serial.println("SUCCESS - Found index.htm file.");
}
void loop()
{
EthernetClient client = server.available(); // try to get client
if (client) { // got client?
boolean currentLineIsBlank = true;
while (client.connected()) {
if (client.available()) { // client data available to read
char c = client.read(); // read 1 byte (character) from client
// last line of client request is blank and ends with \n
// respond to client only after last line received
if (c == '\n' && currentLineIsBlank) {
// send a standard http response header
client.println("HTTP/1.1 200 OK");
client.println("Content-Type: text/html");
client.println("Connection: close");
client.println();
// send web page
webFile = SD.open("index.htm"); // open web page file
if (webFile) {
while(webFile.available()) {
client.write(webFile.read()); // send web page to client
}
webFile.close();
}
break;
}
// every line of text received from the client ends with \r\n
if (c == '\n') {
// last character on line of received text
// starting new line with next character read
currentLineIsBlank = true;
}
else if (c != '\r') {
// a text character was received from client
currentLineIsBlank = false;
}
} // end if (client.available())
} // end while (client.connected())
delay(1); // give the web browser time to receive the data
client.stop(); // close the connection
} // end if (client)
}
That code only knows how to serve one file: index.html.
When you serve index.html, and it references an image, the browser asks your code for the image file. What does it get in return?
Your code must serve the contents of the image file, too, when it's requested. You'll find you need to change the Content-Type header for images to work properly.
There is code on the forum to do what you want, if you search a bit. I'd start with "web server sd card images".
billroy:
That code only knows how to serve one file: index.html.
When you serve index.html, and it references an image, the browser asks your code for the image file. What does it get in return?
Your code must serve the contents of the image file, too, when it's requested. You'll find you need to change the Content-Type header for images to work properly.
There is code on the forum to do what you want, if you search a bit. I'd start with "web server sd card images".
-br
thank you for the reply.
I thought that once I open the index file then it links the images with that file.
it doesn't load the image that should be the background (body), can you please explain how should i change my code?
thank you
if (webFile) {
while(webFile.available()) {
client.write(webFile.read()); // send web page to client
}
The reason is because each call to client.write() will send a full IP packet with only the one character in it. That's insane overhead. To make things a-m-a-z-i-n-g-l-y faster, read blocks of data from the file and then write the blocks to the buffer.
Incidentally, make your block size 512 bytes. Why? Well, when you read data with the SD library it'll read into it's own internal cache buffer and then copy that data to your passed in buffer. That's an extra memcpy step that you don't really need. If you make your buffer exactly 512 bytes, it'll bypass the internal cache, and write data directly from the card to your buffer.
512 isn't the most efficient for the TCP side of things because you have a max of about 1400 bytes in a packet, but it's not that much slower. If you want something really efficient, create two contiguous 512 byte buffers and then send them both. But that's a lot more overhead, so I wouldn't bother.
Incidentally, The W5100 has a 2k write buffer just sitting there not being used. Seems stupid that you have to allocate a 512 byte buffer in RAM to get around this issue when the library could handle all this for you without using any RAM. That's exactly what happens with the UDP library. Unfortunatly, the powers that be have decided that this is not a high priority...
zimm0who0net:
FYI: This section is crazy inefficient
if (webFile) {
while(webFile.available()) {
client.write(webFile.read()); // send web page to client
}
The reason is because each call to client.write() will send a full IP packet with only the one character in it. That's insane overhead. To make things a-m-a-z-i-n-g-l-y faster, read blocks of data from the file and then write the blocks to the buffer.
Incidentally, make your block size 512 bytes. Why? Well, when you read data with the SD library it'll read into it's own internal cache buffer and then copy that data to your passed in buffer. That's an extra memcpy step that you don't really need. If you make your buffer exactly 512 bytes, it'll bypass the internal cache, and write data directly from the card to your buffer.
512 isn't the most efficient for the TCP side of things because you have a max of about 1400 bytes in a packet, but it's not that much slower. If you want something really efficient, create two contiguous 512 byte buffers and then send them both. But that's a lot more overhead, so I wouldn't bother.
Incidentally, The W5100 has a 2k write buffer just sitting there not being used. Seems stupid that you have to allocate a 512 byte buffer in RAM to get around this issue when the library could handle all this for you without using any RAM. That's exactly what happens with the UDP library. Unfortunatly, the powers that be have decided that this is not a high priority...
I think that there is a way to let it go, because it's impossibile that it cannot load a png image of 4kb.
if it can't load that I can't understand why they call it WebServer.
It's a sample. It doesn't parse the request from the browser at all. It only sends the one file. It's a stretch to call it a web server I agree, but it's a sample.