Give away medical masks when you place an order. learn more

Implementing an HTML Server on Open-source Embedded Platforms: Part 1

Equipping an embedded system with an HTML (Hypertext Markup Language) server enables it to communicate with users (or developers) via a standard web browser. Occupying a relatively small code footprint, the server can be implemented on nearly any modern MCU to present a GUI which can be used as a dashboard, control panel, or nearly any type of user interface. In this hands-on article, we will provide a practical example of a Wi-Fi™ wireless web server, implemented on a Microchip PIC32 MCU, which can serve as the basis for a similar design on your platform of choice.

Figure 1: Powered up on my lab bench, the Arduino-compatible Uno32 board flashes a greeting to my daughter as it awaits installation of its Wi-Fi networking shield.

In this first part of a two-part article, we will examine Hardware/Software selection, adding I/O shields, and getting familiar with networking software libraries.

The building blocks

This project was based on a 32-bit processor because of the memory and processing power requirements involved. A basic TCP/IP stack can be implemented on some modern 8-bit machines such as Microchip’s PIC18, STMicro’s ST8, and Atmel’s AVR family, but supporting a full-featured TCP/IP stack, along with the code for the http server and Wi-Fi driver, would probably be more than they could handle comfortably.

The server I built is based on the PIC32MX795F5 because I already had one kicking around in the lab (more about this shortly). The PIC32MX7xx series is based on the 32-bit MIPS M4K Core, which has a 5 Stage pipelined Harvard architecture that includes a single cycle multiply and hardware divide unit and 32 x 32-bit core registers. The ‘MX795 family used in this application runs at 80 MHz and is equipped with a compliment of 10/100 Ethernet, USB, and CAN interfaces that make it a good choice for a communication controller (Figure 2). The PIC32’s MIPS CPU, generous memory (512 K flash/128 K RAM), and wide assortment of networking interfaces, available in its more well-equipped variants, allows it to handle the TCP/IP stack and code for an HTTP server with room to spare for a non-trivial application.

Figure 2: Microchip Technology’s PIC32MX7xx MCU. (Courtesy of Microchip Technology.)

 Microchip makes several evaluation boards for the PIC32 that would work well for a web server, including their DM320004 Ethernet starter kit and MRF24WB0MA Wi-Fi demonstrator board. There are several low-cost, third-party development boards available for the PIC32, including the Olimex’s PIC32 Maxi-Web, and Digilent’s Cerebot Mx7ck, and PIC32-powered variants of the Arduino Uno board available from several manufacturers, including the Digilent Uno32 which uses Microchip Technologies’ PIC32MX795F512L.

Since I am already familiar with the Arduino IDE, and had a Uno32 board I obtained for another project, it became the basis for the server. The Uno board only has a USB interface, so I ordered up Digilent’s TDGL011 Wi-Fi Shield to serve as my network interface (Figure 3a). I also picked up Diligent’s TDG005 basic I/O shield to serve as a tool to help me learn a bit about performing I/O operations on shield cards before I tackled the Wi-Fi board (Figure 3b).

Figure 3: Digilent’s Wi-Fi Shield (a) and general-purpose I/O shield (b). (Courtesy of Digilent.)

The I/O shield is a ready-made collection of handy devices, many of which can be used to implement a temperature monitor or other real world interfaces for the server. The compact board includes digital I/O (button switches, and discrete LEDs), analog I/O (a potentiometer and an I²C temperature sensor) a serial EEPROM, and several high-current FET drivers. The shield also has a nifty little 128 x 32 pixel monochrome OLED display that talks to the MCU via an SPI interface and outputs alphanumeric text or simple graphics. Once the server is up and running solidly, I plan to use it to display the unit’s status or serve as a tiny remote messaging device.

Hardware and software integration

All of the sketches (programs) I had written up to this point were fairly simple and involved only the Arduino board itself, so I plugged in the I/O shield and mucked around with a few of the example sketches I found in a tutorial to get a feel for dealing with multiple-board systems. I studied some sample code that uses the “include” feature to call the various header files that provide the library inter-faces for protocol stacks and hardware drivers. I also experimented a bit with the String object class defined in the MPIDE core abstraction layer libraries I’d need to feed the OLED display’s driver or other I/O devices. The result was a highly-modified sample sketch which reads the voltage on the I/O shield’s potentiometer and uses it as a delay variable that determines how fast a message scrolls across the OLED.

Once I was comfortable with adding hardware and libraries to my sketches, I turned my attention to the Digilent chipKIT compatible Internet library1, a collection of reference designs, application notes and networking-oriented material that supports the Diligent board ecosystem. The DNETcK Internet Protocol Suite library provides a full set of Internet protocol capabilities for Digilent processor boards, which use the Microchip PIC32 MCU and its peripheral devices. It includes the necessary software classes to implement IP client and server functions for both UDP and TCP, and an HTTP server. Its companion library, DWIFIcK, adds support for Wi-Fi.

DNETck includes TcpServer.pde, a HTTP server sketch which is made up of several source files:

  1. HttpServer.pde — This file contains all of the network code and the basic server application.
  2. Parser.cpp — This file contains code used to parse the HTTP request messages.
  3. Render.cpp — This file contains code to generate the HTTP response messages and the HTML code that makes up the message bodies.
  4. BoardDefs.h — This file contains declarations for the I/O pins on the various board platforms supported by the sketch.
  5. Parser.h —This declares symbols shared by the parser and the rest of the sketch.
The network server operation is handled by the functions ServerTask() and Client-Task() in the module HttpServer.pde. The details of the HTTP protocol and the HTML responses are handled by AppTask() in HttpServer.pde and the code in Parser.cpp and Render.cpp.

All the libraries are designed for use in simple embedded systems like Arduino, which do not run an RTOS kernel and rely on a looping state-machine-type programming environment, with short and repetitive passes through the main loop. Although this arrangement works well, its reliance on software state machines does impose some restrictions on the applications that use it. The library’s application notes contain several dire warnings about making sure an application so that it does not block the periodic execution (at least every few milliseconds) of the network stack, and polls the network stack’s status to make sure it has returned before it begins to run.

After digesting these caveats, I used the IDE to configure the TCP stack and HTTP server for the hardware I was using before uploading and launching the software.

The second part of this article will begin with some of the juicy details of my struggles to get the DNETck library’s HTTP server to run on the Duo32 board and its Wi-Fi shield. We will also cover some simple modifications that can be made to the sketch’s HTML-based control panel GUI application. If it’s done in time, I’ll also include the details of a small application I’m working in that will use the I/O board as a remote sensor and display platform.

  1. Diligent’s support page offers a downloadable a zip file that contains libraries and documentation for using the Network Shield, Wi-Fi Shield, and PmodWiFi with the chipKIT MPIDE. The libraries provide Ethernet (TCP/IP and UDP), USB Host, USB Device, CAN, and Wi-Fi support.