In the previous blog post, you learned how to send big files (html pages, images…) with your ENC28J60 shield. Today I’m going to show you a complete webserver!
Description
The user’s browser sends a request, through the network, to the ENC28J60 module. The request is analyzed by the sketch that is running on the Arduino, which also prepares the response. Both the ENC28J60 module and the SD card one are connected to the Arduino via SPI bus:
The webserver handles both static and dynamic resources:
- the static resources (html pages, images…) are fetched from the SD card
- the dynamic resources (AJAX requests…) are handled by the sketch itself
The sketch leverages the method described in my previous post to send static resources of any size.
Connections
Both the SD module and the ethernet one uses the SPI bus. That bus allows to connect more than one device at a time; thanks to a PIN (called chip-select) Arduino can decide which device will handle the command it is sending on the bus. You therefore need to connect the CS PINs of the different modules todifferent PINs of your Arduino and to configure the libraries accordingly.
Unfortunately I noticed that often the shields use the same PIN (for example PIN 10) as CS PIN or that – worse – they don’t allow to stack other SPI shields. I was forced to use two modules (instead of shields) and to connect them using wires:
The connections are:
- power supply (5V and ground);
- MOSI (Arduino->Device), PIN 11
- MISO (Device->Arduino), PIN 12
- CLK (clock), PIN 13
- CS (chip select) ->for the SD module PIN 4, for the ENC28J60 modyule PIN 10
The two PINs I chose to be chip select PINs are configured at the top of the sketch:
#define SD_CS_PIN 4 #define ETH_CS_PIN 10
Static resources from the SD card
To read the SD card, I chose the tinyFAT library instead of the built-in one because it needs less RAM memory.
In the setup(), I configure the Arduino PIN connected to the chip select one of the SD module and initialize the library:
file.setSSpin(SD_CS_PIN);
res = file.initFAT();
When a file is requested, at first the sketch verifies if the file exists on the SD card; if not a 404 error (= file not found) is sent back to the browser:
if(!file.exists(filename)) { [...] bfill.emit_p(PSTR("HTTP/1.0 404 Not Found\r\n\r\nNot Found"));
If the file exists, it is opened and read using blocks of 512 bytes. Each block is sent (one block => one packet) to the client:
res = file.openFile(filename, FILEMODE_BINARY); [...] bytesRead = file.readBinary(); uint8_t* payloadBuffer = ether.tcpOffset(); for(int i = 0; i < bytesRead; i++) payloadBuffer[i] = file.buffer[i];
Default webpage
A particular static resource is the default webpage: when you type an Internet address in the browser, the request it sends to the server is simply GET /. The server administrator can define which is the default page that is sent if the incoming request doesn’t include a specific one. In my sketch, the default webpage is defined as a constant:
static char* defaultPage = "index.htm"; [...] if(strncmp("GET / ", request, 6) == 0) { sendFile(defaultPage);
Dynamic resources
In the sketch you can find an example of a dynamic resource: the uptime.ino page.
That page is not retrieved from the SD card but it is created by the sketch itself and its content is the output of the millis() function, which counts the number of milliseconds since the Arduino was turned on (and therefore the uptime of your webserver):
bfill.emit_p(PSTR("HTTP/1.0 200 OK\r\nContent-Type: text/html\r\nPragma: no-cache\r\n\r\n" "$L"), millis()); ether.httpServerReply(bfill.position());
Example
I prepared a full example: a website that displays an homepage where, thanks to an AJAX call triggered every 30 seconds, the uptime of the webserver is displayed:
here are the AJAX calls performed by the browser:
The sketch and the resources for the example website are available on Github!
For more details,please refer to origianl post
http://www.lucadentella.it/en/2014/11/04/sdwebserver-enc28j60-e-arduino-20/
Leave a Reply
You must be logged in to post a comment.