Let’s build a functional Arduino webserver with the Ethernet/SD Card shield

ardethernetIt’s that time of the week! We’ve been playing around with the Ethernet shield again and this time we’ve come up with an article about creating a webserver from scratch; using the Arduino SD/Ethernet Shield.

This article will show you how to serve files from the SD Card file system and use Javascript to get sensor/variable values via AJAX.

This would be ideal for people looking to add a basic web system to their projects.

 

So, what do we need?

  • 1x Arduino
  • 1x SD/Ethernet Shield (eBay, Sparkfun, Adafruit etc.)
  • 1x Micro-SD Card (or Micro SDHC, same as above, anywhere online)
  • Our code!

We’ll be using an Arduino Uno R3 for this and we have an Ethernet Shield with SD Card capability, this shield is based on the Wiznet W5100 chip. Sparkfun are hosting the Datasheet which can be found here.

Before running any code below; run one of the SD Card examples such as CardInfo so that you can verify that the SD Card is fully working. If you are using the Ethernet Shield version you MUST set pin 10 to HIGH (using digitalWrite(10, HIGH);¬†) in the setup function; if you don’t then the SD will not initialise properly.

What will this project do?

  1. Serve files from the SD Card via a Web Browser
  2. Provide Javascript code to get any sort of values from the Arduino anywhere on the page.
  3. Give you a base to easily add web functionality to your projects.

First things first, insert the SD Card into a Card Reader and the card should be formatted to a FAT file system – You can do this easily on any Windows based PC by right clicking the drive in Computer and selecting Format. We have tested this on a Sandisk 2GB SDHC Micro Card – These are extremely cheap from any online retailer.

The next thing we’ll need to do is actually create the file that we’ll be serving. Save the following file below as index.htm

This is a basic HTML page with a little bit of styling. The styling part actually doesn’t matter; it’s just for easier reading. The important part is the actual content of the page (between the <body></body> tags) and the Javascript that is doing the work.

Once the page is actually loaded; it’ll fire off an XMLHttpRequest to the IP Address of the Arduino Webserver – which then gets the content of this and places it inside of the <span id=”val1″></span> tags. If you have used Ajax before then this will be pretty straightforward.

Let’s get started with the actual webserver!

The following sketch is the complete web server code; you can copy this into a new sketch and upload it to the Arduino. I have removed most debugging statements to save memory. This sketch uses 25,728 bytes of 28,672 available; although most of this is just the Ethernet library.

Let me start by saying that this was based on the example code from Adafruit and modified to add features/functionality.

The first thing you’ll need to do is make sure that the network settings match your network. The following code should be altered to suit your setup:

 Note: If you are changing the IP Address also make sure to change the URL in the Javascript Ajax request in index.htm.

That’s about it for displaying a page. You’ll see that if you add html pages to the SD Card you can browse to them. Any missing files will be displayed with an HTTP 404 error code “File not Found” message.

You should see on the page (also shown below) that the value is entered at the end of the sentence “1337″ this is configurable in the sketch and can easily be sensor data or anything else. This is just added to prove that the code actually requests data from the Arduino and feeds it back into the web page.

webpage

 

An example of adding more Ajax requests to the project (you can have an unlimited amount of variables, your only limitation is the memory):

Just modify the YOURSTRING and you will be able to browse to it and have it show the variable value. You will also need to copy the Javascript code in the index.htm page to suit the new variable; but this request can be copied over and over again and should work fine.

Also note that the speed of the web server will also depend of the speed and type of the SD Card. The faster the card the faster you can serve files. This is because the code is looking to see if a file exists before serving it to the client. If you are using this in a project where you know the files always exist; you could remove this check to make it faster.

If you are wanting to serve images from the SD Card; you’ll need to output the correct content types or it will just display as raw data. We have left it out of this example to try and get the code as small as possible.

Ideally this code would be suited to run on the MEGA and not the Uno/Leonardo as there isn’t much free space to work with; but it’s certainly doable and seems to work really well.

This should pretty much be it. There isn’t too much for you to modify in the code to get it working, if you have any questions or need any help please feel free to leave a comment or send us a message using our contact page.

Enjoy!

Email this to someoneShare on Google+Pin on PinterestTweet about this on TwitterShare on RedditShare on Facebook

5 thoughts on “Let’s build a functional Arduino webserver with the Ethernet/SD Card shield

  1. I’m struggling slightly with this one, all I’m getting is ‘no data received’ when I try to log in! Any ideas? I’ve altered the IP addresses to suit my network, 192.168.0.13 in the intex.htm and the sketch. The basic webserver example seems to work, so I don’t think it’s a hardware problem…

  2. When the web page is refreshed it does print ‘Requested:’ to the serial monitor though, but nothing more.

  3. I’m an idiot, I’d saved the file as .html instead of .htm

    Superb, thankyou! works well!! (when it isn’t used by a complete clown)

  4. Firstly I’d like to say what a good intro to HTTP this is.
    A couple of things that might be useful:

    1. I found that whilst this ran in Internet Explorer it didn’t show the value in any of the other browsers I tried.
    After a bit of research I added the following line to the code200() method.
    client.println(“Access-Control-Allow-Origin: *”);
    I don’t think it matters where this goes (but after the HTTP line and before the close line).
    All the browsers I tried now work (IE, Firefox, Chrome & Maxthon).

    2. I then tried incrementing the value each time a request was received.
    This time all the browsers displayed the new value except Internet Explorer.
    After clearing the IE cache it did on the next refresh but not on subsequent ones.
    The following line prevents IE using the cache and so allows the new value on each request.
    client.println(“Cache-control: max-age = 0″);
    Once again position in the method isn’t important but note that you will need to clear the cache before it will work. (Do this on Win8 by selecting ‘Tools’, ‘Internet Options’, ‘General’, Browsing History ‘Delete…’. Then make sure ‘Temporary Internet files and website files’ is ticked and remove ticks from other selections you don’t want deleted.)
    Press ‘Delete’ then ‘OK’ to finish.

    3. The incrementing value I achieved using the following lines:
    Put this line in anywhere before setup():
    int val = 1337; // or any other value you like.
    in loop(), swap
    client.println(1337);
    for
    client.println(val++);
    That’s it.
    Happy programming.

  5. One thing ought to be noticed is that normally it takes quite a while to do the file movements if you have a mostly full 32
    GB card and moving to a more substantial 64 GB card or larger because you copy and paste
    three times, Once from old card to computer, 2nd
    from computer to brand-new card, third from outdated folder
    inside cards to new folder inside card.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">