Equipping Arduino with a powerful Web server thanks to the Wi-Fi Shield

By on November 11, 2014
Pin It


We’ll show you today how to use the WiFi shield and its libraries to turn Arduino into a Web Server; in addition, we are going to use the  I/O Expander shield to provide more input and outputs to the platform.

We will describe how to handle the specific library to use the WiFi shield as a WEB client for a public website that will collect data coming from sensors.

The Arduino-based WEB server can be accessed using a normal browser, displaying sensors values or activating outputs.

In the examples provided with the library, there is already a code sketch that shows how to create a WEB server. The shortcoming of this example, however, is that the functions used  only allow  you to build and load the entire web page, including the values to be shown. If you need to check the updated values, you are forced to refresh the page manually. Besides, the activation of a digital or PWM output is made by posting values through a “web form”, which returns the “Refreshed” page.



To overtake these limitations we have  implemented the WiFi library in a more efficient way, by using Javascript functions embedded in the HTML code, and controlling the browser – server communication through AJAX mechanisms (using Javascript XMLHttpRequest object).

This basically means that part of the graphic rendering is performed by the browser. The browser is normally running on a much more powerful hardware then Arduino and therefore it is requested to perform algorithms and animations unthinkable for the Arduino standard use. This shortcoming is balanced by an important advantage: with this solution, we help you also reduce the network traffic.

Having part of the code to be executed in the client browser, naturallyimplies a greater debugging difficulty. It is worth then building and testing scripts independently (stand-alone code) and then integrating them into the sketch. To draw HTML pages and test scripts you can use several commercial software like Adobe Dreamweaver or Microsoft FrontPage, or even free editors either visual such as Eclipse, PageBreeze, KompZer (portable), or textual like PSPad, Notepad ++.

For scripts debugging you can use the browser directly, because all browsers are equipped with the “development tools” that allow you to open a window to execute step-by-step the scripting code.

The new functions implemented in the HttpLib library (Version 2.4) are of two types: functions for HTML pages modular construction and functions for fast data exchange to be used with AJAX requests.

The first category was introduced because after the introduction of complicated HTML pages containing Javascript functions, it was very easy to saturate the 32K program memory because commonly those functions are shared among different pages. So it is much more comfortable to structure the HTML pages in blocks (for example header, JavaScript routines, body, footer) and compose them according to the target (scope) of each page.

The second category, called “response functions”, was introduced to send back data (often in JSON format) using a whole and not fragmented package (chunk) as it had been thought for the entire HTML pages in order to improve efficiency.


void sendResponse (int sk, prog _char *amodule[], uint8_t nm);void sendDynResponse (int sk, prog _char *amodule[], uint8_t nm, int npar, char *param[]);Respond to the “request” with a sequence of HTML code modules, stored in prog_char variables (Nm is the number of modules, i.e. the size of amodule[] array)
void sendShortResponse (int sk, char *data);Responds a “Request” with a buffer of data (in string format )


I/O Expander


To implement the example described on these pages, we will need one additional board necessary to read the state of a certain number of digital inputs and to set outputs: the I/O Expander Shield for Arduino.

WEB Server


Keeping in mind that A4 and A5 are used by I2C bus and that D2, D3 and D7 are used by WiFi shield, we can assign a function to the remaining Arduino pins to have a system capable of interacting with significant number of Input / Output.

4  Analog Input  A 0, A 1, A 2, A 3 on Arduino
8  Digital InputD 0, D 1, D 2, D 3, D 4, D 5, D 6, D 7 on IOExpander
8  Digital OutputD 0, D 1, D 2, D 3, D 4, D 5, D 6, D 7 on IOExpander
5  PWM OutputD 5, D 6, D 9, D 10, D 11 on Arduino



Of course, you can abstract this sketch to a software code template whenever you need to use Arduino with AJAX methods for the data exchange, even when using additional I/O shields. Both the menu and the activation pages have an automatic refresh rate (every minute), avoiding that the browser could terminate the communication after a long time of inactivity.

All other pages are static, only the values ​​(or their colors, representing on – off status) shall be automatically updated with a hidden refresh command based on AJAX functions.

The analog input value is updated every second while the digital input is checked and updated every 300ms. The digital output triggering is performed through a page, on which the relays are activated or deactivated by using a hidden function. their status is updated according to this response function.

On the PWM management page, we have implemented a JavaScript animation, as follows:

  • By pressing on button “>” or “<” the value and the related graphical bar are modified only locally
  • When the button is released, the current value is sent to Arduino (that will acknowledge the message with a response).

In this way, with light network traffic load, we have realized a real time I/O remote monitoring window on Arduino, without using proprietary protocols based on sockets.


You can imagine many of these Arduino – Webserver connected on a local network though an access point and managed by a single desktop pc. Implementation based on WAN (geographic distribution) is too complex and not suggested. In fact, Arduino cannot support HTTPS security (strongly recommended on Internet connections) while on a local network WAP protection and WEB authentication represent a reasonable security level to manage sensors and actuators. If you need a WAN implementation, we suggest the use of Raspberry as interface.

Let’s look at the example now, analyzing the general structure first and few significant points too.

The program size is really consistent (31KB, very close to the limit of 32K) because of the many libraries included and the HTML pages stored on program memory. The code itself is compact indeed.

The sketch allows the connection to both unprotected and password-protected waypoints (WPA). In the latter case, if a keyword is already stored on the EEPROM then it is  directly used, otherwise it connects using the password and the keyword calculated is stored on the EEPROM. This concept is important since a keyword connection is really fast while the calculation task is time consuming (even up to 1 minute). The EEPROM keyword management and the WEB authentication based on username/password have been implemented from library version 2.2.

Define and Global variablesAccess point, wifi password, WEB username and password, etc.
HTML blocksStyle header and definition block; block to create and launch XMLHttpRequest object (AJAX); Javascript blocks for the page request; blocks with the body of pages; final block .
SetupWifi and IOExpander initialize, encoding the username – password (if any) for authenticated access), connects to the accesspoint and activates the server on port 80.
LoopRe-connect if not connected, handles the requests; if the request is a page GET or an AJAX POST it will call the right function that will send back a page or interact with I/O and reply with a shortResponse
Connection functionsConnects to access point and listens on port 80
Response/Resource functionsStack the page blocks and send them
AJAX functionsIf the command is a value refresh, check the values, format to JSON string and send as shortResponse; if the command is a trigger, activate the corresponding pin and send back a refresh of all values


In the code listing, you can see the HTML block and the AJAX functions, that is common to every page.

In any case, we do note that using an asynchronous management for XMLHttpRequest we are forced to implement a semaphore since Arduino is single task and can manage only one task every cycle.

The Javascript function ajax() has four parameters: the requested resource plus three additional parameters corresponding respectively to a command code, a pin number and a value.

Those three parameters will be handled by Arduino resource function to execute the request.

The callback function is activated after the response is received. It has always the same name but different implementations according to the web page that embeds it. Besides, it also resets the semaphore to step over the next request.

On the listing, you can look at one of the javascript functions block needed to build and manage a page (specifically, the “analog values read” page). You can note the implementation of “setData” (callback function for XMLHttpRequest) and “make”, common to any page to build up the page when requested. In fact, taking into account the table format of each page and the Arduino limited memory resources, we preferred to implement the page construction by using a “for” cycle.


Let’s analyze now the Arduino functions. In “listing” you can look at the setup() function and the loop() function.

The main function called in loop() is “getRequest”. As already seen on WiFi library post, this function is responsible of receiving the message, decoding the request and finally activating the target resource. To bind the resource name to the corresponding Arduino function, it uses a matching array. A part of these resources reply with entire pages, the other are managed by AJAX background activity.


Eventually you can look at a “page request” reply and at a “data refresh request” example code.


From the store

WiFi shield for Arduino

I/O expander shield


About Boris Landoni

Boris Landoni is the technical manager of Open-Electronics.org. Skilled in the GSM field, embraces the Open Source philosophy and its projects are available to the community.


  1. Pingback: Web server | Pearltrees

  2. Pingback: Web server | Pearltrees

  3. Pingback: Even more | Pearltrees

  4. ed

    November 22, 2014 at 11:09 AM

    great article. a pity that the webserver in the examples of the MWIFI library doesnt compile: “No matching function for call to HTTP::getParameter….”

    • BorisLandoni

      December 1, 2014 at 6:43 PM

      Have you import the library?

  5. Pingback: Web-server | Pearltrees

Leave a Reply