SD card problem

hi all ,
i have a problem with SD card i do alot of researches before posting but i didn't find a solution
all i want is to put pictures in my webpage so i save pictures on SD card and do index.html and do the website i want with pictures
but when i open the website pictures didn't appear !! although i did add to sd library and i use sd.open and everything !!!
can anyone know why ?

Are you running your web server on the Arduino, with html pages and images stored on the SD card? It doesn't look an easy task. You may try to verify the following conditions:

  1. Have you got enough memory on the Arduino to serve html and images? It all depends on the Arduino (is it a Mega?) and on how memory-intensive is your use of the SD library, so you should post your code if you need help with that.

  2. Is your server able to serve concurrent request from your server? When a browser reads an html containing a tag it usually sends a parallel request to the server. The Ethernet library can only handle a limited number of concurrent requests. Even managing two concurrent connections, however, may be tricky. If you suspect this is the problem you should post your code.

No it is arduino uno and i want to save html code in sd card to save memory and in that html code i want to add pictures
my question is how to do that ?
thanks for your help :slight_smile:

How do you create the html files? If you create them using a PC you can store them directly on the SD card without using the Arduino. The same for the images: you probably have them on the PC. If your html is already in an arduino sketch you can just copy and paste it when you are editing it on the PC. That would simplify your task. As for including images, as you know you just need to put into the html file an tag, like this:

<img src="filename.jpg">

Now, the hard part is to use the html and images stored on the SD card with a web server running on arduino. Is this what you want to do? I don't understand if you already have a web server running on arduino or if you are planning to create one. Anyway, you need the Ethernet library and the SD library. When the server starts it listens on a TCP port for requests. Each time a client connects and makes a request the server uses the SD library to open the html or image file, read it, and send it to the client. This is the part where I am almost sure you will encounter serious memory limitations.

If you are still sure you want to do that, try dividing your project in smaller tasks: can you create a web server? check the documentation for the Ethernet library: Ethernet - Arduino Reference; can you read from an SD card? check the documentation for the SD library: http://arduino.cc/en/Reference/SD. Many people in this forum are discussing problems and solutions related to both libraries, and you should give a look at these discussions so that you know what to expect.

Good luck ;).

and in that html code i want to add pictures
my question is how to do that ?

Are you asking how to embed pictures in an html file? Or are you asking how to serve those pictures? They are two completely different issues. Which do you need help with?

Where is your code?

#include <SD.h>
#include <SPI.h>
#include <Ethernet.h>

byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; //physical mac address
byte ip[] = { 192, 168, 1, 102 }; // ip in lan
byte gateway[] = { 192, 168, 1, 1 }; // internet access via router
byte subnet[] = { 255, 255, 255, 0 }; //subnet mask
EthernetServer server(84); //server port
String readString; 
String state1="LOW";
String state2="LOW";
//////////////////////

void setup(){

  Serial.begin(9600);
pinMode(7, OUTPUT); //pin selected to control
  pinMode(8, OUTPUT); //pin selected to control
  // disable w5100 while setting up SD
  pinMode(10,OUTPUT);
  digitalWrite(10,HIGH);
  Serial.print("Starting SD..");
  if(!SD.begin(4)) Serial.println("failed");
  else Serial.println("ok");

  Ethernet.begin(mac, ip, gateway, gateway, subnet);
  digitalWrite(10,HIGH);

  //delay(2000);
  server.begin();
  Serial.println("Ready");

}

void loop(){
  // Create a client connection
  EthernetClient client = server.available();
  if (client) {
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();

        //read char by char HTTP request
        if (readString.length() < 100) {
          //store characters to string 
          readString += c; 
          //Serial.print(c);
        } 
        //if HTTP request has ended
        if (c == '\n') {

          ///////////////
          Serial.println(readString); //print to serial monitor for debuging 
          if(readString.indexOf('2') >0)//checks for 2
          {
            state1="ON";
            digitalWrite(8, HIGH);    // set pin 8 high
	

          }

          if(readString.indexOf('3') >0)//checks for 3
          {
            state1="OFF";
            digitalWrite(8, LOW);    // set pin 8 low
	
          }
          
          if(readString.indexOf('4') >0)//checks for 4
          {
            state2="ON";
            digitalWrite(7, HIGH);    // set pin 7 high
           }

          if(readString.indexOf('5') >0)//checks for 5
          {
            state2="OFF";
            digitalWrite(7, LOW);    // set pin 7 low
          }
          
          
          client.println("HTTP/1.0 ok"); //send new page
          client.println("Content-Type: text/html");
          client.println();

          client.println("<HTML>");
          client.println("<HEAD>");
          client.println("<TITLE>Smart Home Over IP</TITLE>");
          client.println("</HEAD>");
          client.println("<BODY>");

          client.println("<H1>Smart Home Over IP


</H1>");
          
          
          client.println("<H1>light 1</H1>");
            client.println("Light1 is ");
 
          client.println(state1);
 
          client.println("
");
          client.print("<input type=submit value=ON style=width:100px;height:45px onClick=location.href='/?on2'>");
          client.print("<input type=submit value=OFF style=width:100px;height:45px onClick=location.href='/?off3'>");
         
         
          client.println("<H1>light 2</H1>");
          client.println("Light1 is ");
 
          client.println(state2);
 
          client.println("
");
          client.print("<input type=submit value=ON style=width:100px;height:45px onClick=location.href='/?on4'>");
          client.print("<input type=submit value=OFF style=width:100px;height:45px onClick=location.href='/?off5'>");
        


          client.println("</BODY>");
          client.println("</HTML>");


          client.println("HTTP/1.1 200 OK"); //send new page
          //client.println("Content-Type: text/html");
          client.println("Content-Type: image/jpeg");
          //client.println("Content-Type: image/gif");
          //client.println("Content-Type: application/x-javascript");
          //client.println("Content-Type: text");
          
         

          //File myFile = SD.open("index.htm");
          File myFile = SD.open("on.jpg");
          //File myFile = SD.open("BLUEH_SL.GIF");
          //File myFile = SD.open("SERVOSLD.HTM");
          if (myFile) {
            //Serial.println("test.txt:");
            // read from the file until there's nothing else in it:
            while (myFile.available()) {
              client.write(myFile.read());
            }
            // close the file:
            myFile.close();
         
      


          }
      
    
            delay(1);
            //stopping client
            client.stop();
            readString="";
          //}
        }
      }
    }
  } 
}

i want to make picture on.jpg appear on the webpage but it appears as nothing like that

""—ñe–Y|›à˜Ù¡è¶šKU G¦ÀùÜYe—õèÇ‚Á aè¶Ô-Ƈ²þÖ‰Xù=à‡a¦§P´{{/ð¯Œi—NV¡ŒðZ87Ñlêö\¿Å7e¤ºR¶5„1á¡‹Fúnu:—/ólø' øÇ43F‡Øju8QCý˜u걕ø‡ÝP&&=KÅ/õg…#> ªHdn½-x/Ae¢c7/±ýŸÍÂR|X´—G„ D†:EάhÓS…/í:c&-wáž@BéUÂí±Pm5—xË=cDPÆ­KN”¿Á:1Rt¾<zJÓÑpP…:Ób£ÿŒJvXCÑ"­íiF¾‰·Ðï‡ðM¢äUq> F=#ú5¦6æ%è݃EBŽšÒÔp¯Ñ%^öÅO°²>x-‚ê>:‰¾‚iM ÇþÇò «#sðvë,Á/´''""

any help please

i want to make picture on.jpg appear on the webpage but it appears as nothing like that

Have you looked at the source page for a web page that includes a picture?

If you had, you would have seen something like:

<p class='vspace'></p><div><img src='http://arduino.cc/en/uploads/Main/arduino_due_in_hand.jpg' alt='' title='' /></div>

The important part is the img tag. The src part defines the name of the image file to display. The browser will get the html file, and see that it includes an img tag, and it will make a second request to get the image file. That request is satisfied differently. But, that means that you need to determine what the client is asking for before you generate a response.

i don't need scr as i used sd.open so i told the arduino to open it from the root of the sd card right ?

The problem is that if you put a tag in an html page you are telling the browser to send a new request in order to pull that image. So in your server code you should be prepared to handle a new request just for that image. An alternative is to send a response of multipart/mixed mimetype, then embed the content of the image under a heading such as:

Content-type: image/gif; name="up.gif"
Content-ID: <up.gif>
X-Attachment-Id: up.gif
Content-Disposition: Embedded; filename="up.gif"
Content-transfer-encoding: base64

See RFC1341(MIME) : 7 The Multipart content type or look for specific examples of embedding images in a response.

i solving it like 80 % here is the code just trial code to show pictures from with sd card on website

//zoomkat 1/26/13
//SD server slider test code
//open serial monitor to see what the arduino receives
//address will look like http://192.168.1.102:84/servosld.htm when submited
//for use with W5100 based ethernet shields
//put the servosld.htm, slider.js, bluev_sl.gif,
//and bluev_bg.gif on the SD card
//files at http://web.comporium.net/~shb/servoslider.htm page


#include <SD.h>
#include <SPI.h>
#include <Ethernet.h>
String readString, pos;
int sensor;
byte mac[] = { 0x90, 0xA2, 0xDA, 0x0D, 0x80, 0xA2 };
byte ip[] = { 
  192, 168, 1, 102 }; // ip in lan
byte gateway[] = { 
  192, 168, 1, 1 }; // internet access via router
byte subnet[] = { 
  255, 255, 255, 0 }; //subnet mask
EthernetServer server(84); //server port

//////////////////////

void setup(){

  Serial.begin(9600);
  pinMode(7,OUTPUT);
    pinMode(8,OUTPUT);
      pinMode(2,INPUT);
  // disable w5100 while setting up SD
  pinMode(10,OUTPUT);
  digitalWrite(10,HIGH);
  Serial.print("Starting SD..");
  if(!SD.begin(4)) Serial.println("failed");
  else Serial.println("ok");

  Ethernet.begin(mac, ip, gateway, gateway, subnet);

  //delay(2000);
  server.begin();
  Serial.println("Ready");
pinMode(7, OUTPUT); //pin selected to control
  pinMode(8, OUTPUT); //pin selected to control

}

void loop(){
  // Create a client connection
  EthernetClient client = server.available();
  if (client) {
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();

        //read char by char HTTP request
        if (readString.length() < 100) {
          //store characters to string 
          readString += c; 
          //Serial.print(c);
        } 
        //if HTTP request has ended
        if (c == '\n') {

          ///////////////
          Serial.println(readString); //print to serial monitor for debuging
         
         //select proper header for file to be sent to browser
         
          client.println("HTTP/1.1 200 OK"); //send new page
          if(readString.indexOf("index") >=0) {
          client.println("Content-Type: text/html");
          client.println(); }

        
           if(readString.indexOf("bk") >=0) {
          client.println("Content-Type: image/jpeg");
          client.println(); }
          
         
          
          if(readString.indexOf("bk") >=0) {
            File myFile = SD.open("bk.jpg");
            if (myFile) {
              while (myFile.available()) {
                client.write(myFile.read());
              }
              myFile.close();
            }
          }
          
          if(readString.indexOf("d1") >=0) {
          client.println("Content-Type: image/jpeg");
          client.println(); }
          
         
          
          if(readString.indexOf("d1") >=0) {
            File myFile = SD.open("d1.jpg");
            if (myFile) {
              while (myFile.available()) {
                client.write(myFile.read());
              }
              myFile.close();
            }
          }
          
          //select file to send to browser
          if(readString.indexOf("index") >= 0) {
            File myFile = SD.open("index.HTM");
            if (myFile) {
              while (myFile.available()) {
                client.write(myFile.read());
              }
              myFile.close();
            }
          }
          sensor=digitalRead(2);
          
   client.print(sensor);
          

         if(readString.indexOf('2') >0)//checks for 2
          {
            //state1="ON";
           
            digitalWrite(8, HIGH);    // set pin 8 high
	

          }

          if(readString.indexOf('3') >0)//checks for 3
          {
            //state1="OFF";
            digitalWrite(8, LOW);    // set pin 8 low
	
          }
          
          if(readString.indexOf('4') >0)//checks for 4
          {
            //state2="ON";
            digitalWrite(7, HIGH);    // set pin 7 high
           }

          if(readString.indexOf('5') >0)//checks for 5
          {
            //state2="OFF";
            digitalWrite(7, LOW);    // set pin 7 low
          }

          delay(1);
          //stopping client
          client.stop();
         
        
          readString="";
        }
      }
    }
  } 
}

it worked good some how but when i press on ON button it lights the led but go to empty page so i must press back to the index.html
second problem the address now is 192.168.1.102:84/index.html i think it will make problem in port forwarding as i forward to port 84 only not 84/index.html how can i solve it ?

I wouldn't worry for port forwarding, the request that the server will see will not contain the port number (for example, GET /index.htm).

Consider that a browser will send not just a GET request, but also a bunch of other HTTP parameters (host, user-agent, keep-alive, ...). You need to read them even if you don't use them, otherwise you will get them the next time you listen for a request.

Also consider that mimetypes of type image are usually sent using an encoding, because transmitting binary data can be problematic. However, if you were successful in transferring your image you may not worry about this. The fact that the browser goes to an empty page may be related to the mimetype: it may 'think' it is a file to be downloaded and not something to be displayed. You need to check all the parameters in your response header that may affect the browser's behavior.

I think that a browser will send a request using a persistent connection. It will expect to reuse the same connection for sending more requests. This is not a problem, but you should tell the client that you are maintaining the connection open (it is one of the parameters you send in the header of the response, after 200 OK). Or maybe you'll have to close the connection, I don't know, you can only try and see. In both cases, telling the client whether the connection is open or closed may improve the flow of data.

Finally, try to make your code more readable by joining the equivalent if statements (you always do a double check for each request), removing the extra instructions about sensors, and using Auto Format in the Tools menu of Arduino to correct the indentation.

You need to understand how URLs are formed. The first part is a protocol (http). Then, there is a delimiter (:), then a pair of slashes, followed by a host IP address or name (192.168.1.102). Then, there is an optional delimiter (:slight_smile: and port number to use. That is followed by the script to access on the server (/index.html).

When you set up port forwarding, the port is the only part that matters. The script name is completely irrelevant.

thanks alot for your replys and your help i understand now :slight_smile: