Go Down

Topic: Using the Arduino Uno R3 and Eithernet & SD sheild as a Webserver (Read 962 times) previous topic - next topic

BigMrTong

Hope someone can help. I have an Uno R3 and Eithernet / Sd Card Sheild.

I have had it working wth the example scripts, and loading Hello workd to the browser etc, and also I have found a script that loads a htm file from the SD card.

I want to put a small site (understand the 8.3 limitations) that has htm file and pictures in it.  Can I use folders ?

The scripts I have found refer to specific htm files in the scripts, or I have found some pretty short and neat ones that claim to load any htm / lpg files from the Sd card based on the browsers request.

The latter sounds good for me, but all the examples I find from googleing (and boy have I googled) are from 2011 and early 2012.  If I use these Sketches cut and paste, I get errors about lots of commands now being renaimed etc.

Can anyone link me to anything please ?

pylon

Did you try TinyWebServer? https://github.com/ovidiucp/TinyWebServer

The examples compile with a current IDE (1.0.3) without any problems.

zoomkat

Some server code that supplies some small images to a browser.

Code: [Select]

//zoomkat 2/26/13
//SD server slider test code
//open serial monitor to see what the arduino receives
//browser 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
//download flies at:
// http://web.comporium.net/~shb/pix/servosld.htm
// http://web.comporium.net/~shb/pix/slider.js
// http://web.comporium.net/~shb/pix/bluev_bg.gif
// http://web.comporium.net/~shb/pix/bluev_sl.gif
//

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

#include <Servo.h>
Servo myservoa, myservob, myservoc, myservod;  // create servo object to control a servo
Servo myservoe, myservof, myservog; // myservoh not used due to lack of another free pin
String readString, pos;

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

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

void setup(){

  Serial.begin(9600);

  // 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");

  myservoa.attach(2);  //the pin for the servoa control
  myservob.attach(3);  //the pin for the servob control
  myservoc.attach(5);  //the pin for the servoc control
  myservod.attach(6);  //the pin for the servod control
  myservoe.attach(7);  //the pin for the servoa control
  myservof.attach(8);  //the pin for the servob control
  myservog.attach(9);  //the pin for the servoc control
  //myservoh.attach(10);  //the pin for the servod 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("servosld") >=0) {
            client.println("Content-Type: text/html");
            client.println();
          }

          if(readString.indexOf("slider") >=0) {
            client.println("Content-Type: application/x-javascript");
            client.println();
          }

          if(readString.indexOf("bluev") >=0) {
            client.println("Content-Type: image/gif");
            client.println();
          }

          //select file to send to browser
          if(readString.indexOf("servosld") >=0) {
            File myFile = SD.open("SERVOSLD.HTM");
            if (myFile) {

              byte clientBuf[64];
              int clientCount = 0;             

              while (myFile.available())
              {
                clientBuf[clientCount] = myFile.read();
                clientCount++;

                if(clientCount > 63)
                {
                  client.write(clientBuf,64);
                  clientCount = 0;
                }               
              }
              if(clientCount > 0) client.write(clientBuf,clientCount);           
              myFile.close();
            }
          }

          if(readString.indexOf("slider") >=0) {
            File myFile = SD.open("slider.js");
            if (myFile) {

              byte clientBuf[64];
              int clientCount = 0;             

              while (myFile.available())
              {
                clientBuf[clientCount] = myFile.read();
                clientCount++;

                if(clientCount > 63)
                {
                  client.write(clientBuf,64);
                  clientCount = 0;
                }               
              }
              if(clientCount > 0) client.write(clientBuf,clientCount);
              myFile.close();
            }
          }

          if(readString.indexOf("bluev_sl") >=0) {
            File myFile = SD.open("bluev_sl.gif");
            if (myFile) {

              byte clientBuf[64];
              int clientCount = 0;             

              while (myFile.available())
              {
                clientBuf[clientCount] = myFile.read();
                clientCount++;

                if(clientCount > 63)
                {
                  client.write(clientBuf,64);
                  clientCount = 0;
                }               
              }
              if(clientCount > 0) client.write(clientBuf,clientCount);
              myFile.close();
            }
          }

          if(readString.indexOf("bluev_bg") >=0) {
            File myFile = SD.open("bluev_bg.gif");
            if (myFile) {

              byte clientBuf[64];
              int clientCount = 0;             

              while (myFile.available())
              {
                clientBuf[clientCount] = myFile.read();
                clientCount++;

                if(clientCount > 63)
                {
                  client.write(clientBuf,64);
                  clientCount = 0;
                }               
              }
              if(clientCount > 0) client.write(clientBuf,clientCount);
              myFile.close();
            }
          }

          delay(1);
          //stopping client
          client.stop();

          //process GET string request from client and and position servo

          pos = readString.substring(8, 12); //get the first four characters         
          //Serial.println(pos);
          int n = pos.toInt();  //convert readString into a number   
          Serial.println(n);
          Serial.println();

          if(readString.indexOf("?0") >0) myservoa.writeMicroseconds(n);
          if(readString.indexOf("?1") >0) myservob.writeMicroseconds(n);
          if(readString.indexOf("?2") >0) myservoc.writeMicroseconds(n);
          if(readString.indexOf("?3") >0) myservod.writeMicroseconds(n);
          if(readString.indexOf("?4") >0) myservoe.writeMicroseconds(n);
          if(readString.indexOf("?5") >0) myservof.writeMicroseconds(n);
          if(readString.indexOf("?6") >0) myservog.writeMicroseconds(n);
          //only seven servo pins, so back to myservoa for testing
          if(readString.indexOf("?7") >0) myservoa.writeMicroseconds(n);

          //clearing string for next read
          readString="";
          pos="";
        }
      }
    }
  }
}


Google forum search: Use Google Advanced Search and use Http://forum.arduino.cc/index in the "site or domain:" box.

BigMrTong


Thanks Guys.  I had tried the above two and whilst some complied in 1.0.3 they still would not work, or did not work I I required.   I ended up cobling together 3 different scripts I found on line and editing a little.

This is what I ended up with.  It will server a full website from the SD card.


Code: [Select]
#include <SPI.h>
#include <SdFat.h>
#include <SdFatUtil.h>
#include <Ethernet.h>

byte mac[] = {
  0x90,0xA2,0xDA,0x00,0x26,0xEB};
IPAddress ip(192, 168, 1, 76);
char rootFileName[] = "index.htm";
EthernetServer server(80);

Sd2Card card;
SdVolume volume;
SdFile root;
SdFile file;

#define error(s) error_P(PSTR(s))
void error_P(const char* str) {
  PgmPrint("error: ");
  SerialPrintln_P(str);
  if (card.errorCode()) {
    PgmPrint("SD error: ");
    Serial.print(card.errorCode(), HEX);
    Serial.print(',');
    Serial.println(card.errorData(), HEX);
  }
  while(1);
}

void setup() {
  Serial.begin(9600);
  PgmPrint("Free RAM: ");
  Serial.println(FreeRam());
  pinMode(10, OUTPUT);
  digitalWrite(10, HIGH);
  if (!card.init(SPI_FULL_SPEED, 4)) error("card.init failed!");
  if (!volume.init(&card)) error("vol.init failed!");
  PgmPrint("Volume is FAT");
  Serial.println(volume.fatType(),DEC);
  Serial.println();
  if (!root.openRoot(&volume)) error("openRoot failed");
  PgmPrintln("Files found in root:");
  root.ls(LS_DATE | LS_SIZE);
  Serial.println();
  PgmPrintln("Files found in all dirs:");
  root.ls(LS_R);
  Serial.println();
  PgmPrintln("Done");
  Ethernet.begin(mac, ip);
  server.begin();
}
#define BUFSIZ 100

void loop()
{
  char clientline[BUFSIZ];
  char *filename;
  int index = 0;
  int image = 0;
EthernetClient client = server.available();
  if (client) {
    boolean current_line_is_blank = true;
    index = 0;
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();
        if (c != '\n' && c != '\r') {
          clientline[index] = c;
          index++;
          if (index >= BUFSIZ)
            index = BUFSIZ -1;
          continue;
        }
        clientline[index] = 0;
        filename = 0;
        Serial.println(clientline);
        if (strstr(clientline, "GET / ") != 0) {
          filename = rootFileName;
        }
        if (strstr(clientline, "GET /") != 0) {
          if (!filename) filename = clientline + 5;
          (strstr(clientline, " HTTP"))[0] = 0;
          Serial.println(filename);
          if (! file.open(&root, filename, O_READ)) {
            client.println("HTTP/1.1 404 Not Found");
            client.println("Content-Type: text/html");
            client.println();
            file.open(&root,"404error.htm",O_READ);  //Opens the file 404error.htm from the root directory.  This is if the file doesn't exist
            int16_t c;
            while((c=file.read())>=0){  //sends file (yes it is the slow way, but if you don't have a picture, thats ok
              client.write((char)c);
            }
            file.close();
            break;
          }
          Serial.println("Opened!");
          client.println("HTTP/1.1 200 OK");
          if (strstr(filename, ".htm") != 0)
            client.println("Content-Type: text/html");
          else if (strstr(filename, ".css") != 0)
            client.println("Content-Type: text/css");
          else if (strstr(filename, ".png") != 0)
            client.println("Content-Type: image/png");
          else if (strstr(filename, ".jpg") != 0)
            client.println("Content-Type: image/jpeg");
          else if (strstr(filename, ".gif") != 0)
            client.println("Content-Type: image/gif");
          else if (strstr(filename, ".3gp") != 0)
            client.println("Content-Type: video/mpeg");
          else if (strstr(filename, ".pdf") != 0)
            client.println("Content-Type: application/pdf");
          else if (strstr(filename, ".js") != 0)
            client.println("Content-Type: application/x-javascript");
          else if (strstr(filename, ".xml") != 0)
            client.println("Content-Type: application/xml");
          else
            client.println("Content-Type: text");
          client.println();
          int16_t c;
          while ((c = file.read()) >= 0) {
            client.write((char)c);
          }
          file.close();
        }
        else {
          client.println("HTTP/1.1 404 Not Found");
          client.println("Content-Type: text/html");
          client.println();
          file.open(&root,"404error.htm",O_READ);  //this is if the "GET /" fails to retrieve data
          int16_t c;
          while((c=file.read())>=0){  //sends file.  still not fast.
            client.write((char)c);
          }
          file.close();
        }
        break;
      }
    }
    delay(1);
    client.stop();
  }
}

BigMrTong


Just an update guys. I made a slight change to the code.  It worked fine internally on the network, but when  I tried to use it on the internet and set up some port forwarding on my router, it did not.

After a little scratching I figured out I had not set up a Subnet mask or default gateway.  Works fine now.

Updated code below.  90% of my help has been form searching these forums !


Code: [Select]
#include <SPI.h>
#include <SdFat.h>
#include <SdFatUtil.h>
#include <Ethernet.h>

byte mac[] = {0x90,0xA2,0xDA,0x00,0x26,0xEB};
IPAddress ip(192, 168, 1, 76);
byte gateway[] = { 192, 168, 1, 254 };
byte subnet[] = { 255, 255, 255, 0 };
EthernetServer server(80);

char rootFileName[] = "index.htm";


Sd2Card card;
SdVolume volume;
SdFile root;
SdFile file;

#define error(s) error_P(PSTR(s))
void error_P(const char* str) {
  PgmPrint("error: ");
  SerialPrintln_P(str);
  if (card.errorCode()) {
    PgmPrint("SD error: ");
    Serial.print(card.errorCode(), HEX);
    Serial.print(',');
    Serial.println(card.errorData(), HEX);
  }
  while(1);
}

void setup() {
  Serial.begin(9600);
  PgmPrint("Free RAM: ");
  Serial.println(FreeRam());
  pinMode(10, OUTPUT);
  digitalWrite(10, HIGH);
  if (!card.init(SPI_FULL_SPEED, 4)) error("card.init failed!");
  if (!volume.init(&card)) error("vol.init failed!");
  PgmPrint("Volume is FAT");
  Serial.println(volume.fatType(),DEC);
  Serial.println();
  if (!root.openRoot(&volume)) error("openRoot failed");
  PgmPrintln("Files found in root:");
  root.ls(LS_DATE | LS_SIZE);
  Serial.println();
  PgmPrintln("Files found in all dirs:");
  root.ls(LS_R);
  Serial.println();
  PgmPrintln("Done");
  Ethernet.begin(mac, ip);
  server.begin();
}
#define BUFSIZ 100

void loop()
{
  char clientline[BUFSIZ];
  char *filename;
  int index = 0;
  int image = 0;
EthernetClient client = server.available();
  if (client) {
    boolean current_line_is_blank = true;
    index = 0;
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();
        if (c != '\n' && c != '\r') {
          clientline[index] = c;
          index++;
          if (index >= BUFSIZ)
            index = BUFSIZ -1;
          continue;
        }
        clientline[index] = 0;
        filename = 0;
        Serial.println(clientline);
        if (strstr(clientline, "GET / ") != 0) {
          filename = rootFileName;
        }
        if (strstr(clientline, "GET /") != 0) {
          if (!filename) filename = clientline + 5;
          (strstr(clientline, " HTTP"))[0] = 0;
          Serial.println(filename);
          if (! file.open(&root, filename, O_READ)) {
            client.println("HTTP/1.1 404 Not Found");
            client.println("Content-Type: text/html");
            client.println();
            file.open(&root,"404.htm",O_READ);  //Opens the file 404.htm from the root directory.  This is if the file doesn't exist
            int16_t c;
            while((c=file.read())>=0){  //sends file (yes it is the slow way, but if you don't have a picture, thats ok
              client.write((char)c);
            }
            file.close();
            break;
          }
          Serial.println("Opened!");
          client.println("HTTP/1.1 200 OK");
          if (strstr(filename, ".htm") != 0)
            client.println("Content-Type: text/html");
          else if (strstr(filename, ".css") != 0)
            client.println("Content-Type: text/css");
          else if (strstr(filename, ".png") != 0)
            client.println("Content-Type: image/png");
          else if (strstr(filename, ".jpg") != 0)
            client.println("Content-Type: image/jpeg");
          else if (strstr(filename, ".gif") != 0)
            client.println("Content-Type: image/gif");
          else if (strstr(filename, ".3gp") != 0)
            client.println("Content-Type: video/mpeg");
          else if (strstr(filename, ".pdf") != 0)
            client.println("Content-Type: application/pdf");
          else if (strstr(filename, ".js") != 0)
            client.println("Content-Type: application/x-javascript");
          else if (strstr(filename, ".xml") != 0)
            client.println("Content-Type: application/xml");
          else
            client.println("Content-Type: text");
          client.println();
          int16_t c;
          while ((c = file.read()) >= 0) {
            client.write((char)c);
          }
          file.close();
        }
        else {
          client.println("HTTP/1.1 404 Not Found");
          client.println("Content-Type: text/html");
          client.println();
          file.open(&root,"404.htm",O_READ);  //this is if the "GET /" fails to retrieve data
          int16_t c;
          while((c=file.read())>=0){  //sends file.  still not fast.
            client.write((char)c);
          }
          file.close();
        }
        break;
      }
    }
    delay(1);
    client.stop();
  }
}

Hello,

Nice work, I a little green on programing HTML can you provide me with you html file so i can learn a lit bitte, I'm asking cause I would like to something like this.

Thanks,

André Domingues

SurferTim

This code is an inefficient way to transfer data over the ethernet connection.
Code: [Select]
          while ((c = file.read()) >= 0) {
            client.write((char)c);
          }
          file.close();


This way sends the data much faster. This is from zoomkat's code above.
Code: [Select]
              while (myFile.available())
              {
                clientBuf[clientCount] = myFile.read();
                clientCount++;

                if(clientCount > 63)
                {
                  client.write(clientBuf,64);
                  clientCount = 0;
                }               
              }
              if(clientCount > 0) client.write(clientBuf,clientCount);           
              myFile.close();


Go Up
 


Please enter a valid email to subscribe

Confirm your email address

We need to confirm your email address.
To complete the subscription, please click the link in the email we just sent you.

Thank you for subscribing!

Arduino
via Egeo 16
Torino, 10131
Italy