Monday, April 2, 2018

An ESP8266 Web Server

A web based micro SBC has always been on my wishlist. It wasn’t the internet connectivity that was the attraction – it was the support for a browser based UI. A hardware based user interface is so limited and clunky. Having a software based GUI is always great. In the old days, it would have been a serial port and a windows program front-end talking to it. With a web based micro, I can have a rich, browser based UI. Then it was Ethernet based PIC solutions like the 18F67J60. Enter the ESP8266.

The ESP8266 is a micro with wifi support in a small package. Thrown together with a flash chip and a few other components, it is a fully functional module. The game changer is the low cost – the module I use goes for under AU$5. Just what I was looking for. ESP indeed!

The NodeMcu DevKit

The NodeMcu DevKit has the ESP8266 module, 4MB of flash and an FTDI chip to allow connection directly to USB, pushbuttons for reset and flash and an LED. It is a full-fledged development board in a 25x50mm footprint. Connect it to a laptop USB port and you have an easy way to download code and get debug messages from the running code. It has a few GPIOs and other pins brought out to 2 x 15 pin headers. This allows it to be plugged into a larger board, or as I prefer, a PCB of roughly the same size.

Another option is a similar module based on the newer chip ESP32. It is a little bigger, a little more expensive but a lot faster and has more I/O. In particular, the ESP8266 has 1.5 UARTs (one of them is output only) while the ESP32 has 2 UARTs. There are some applications I have in mind that need a UART. As one UART is taken up for code download and debug, another port is needed. This pretty much eliminates the ESP8266.

Here is a very superficial comparison of the two. The NodeMcu ESP32 module has a pin row pitch of 25.4mm (1.0") and is not easily breadboardable - a common hack is to use two breadboards next to each other. The pinouts, besides being physically incompatible, don't have much in common.

Function NodeMcu
ESP8266
NodeMcu
ESP32
Cost AU$5 AU$8
Size 25x48mm 29x51mm
Pins 2 x 15 pins 2 x 15 pins
Pin row pitch 0.9" 1.0"
UARTs 1.5 2
Bluetooth N Y

The project I had in mind did not need the extra features of the ESP32 so I stuck to an ESP8266.

My software platform of choice is Mongoose OS and C. Mongoose OS provides a web server out of the box, including a file system for serving static files. There are a lot of web resources out there on various topics.

There are two parts to implementing a web server – serving up static files and executing code on the system in response to certain URLs and possibly sending a response. Static files are easy – just put them in the fs sub-directory of the project and they will end up on flash and are served up on request. I am also using the zepto.js library. This is a lightweight version of the jquery javascript library and is only 26K in size.

The second part is to invoke code based on a URl – like some kind of a cgi handler. Register the handler in the app init routine.

enum mgos_app_init_result mgos_app_init(void) {
 ...
 mgos_register_http_endpoint("/cgi/", cgi_handler, NULL);
 ...
 return MGOS_APP_INIT_SUCCESS;
}

All URLs starting with /cgi/ will be redirected to the routine cgi_handler().

static void cgi_handler(struct mg_connection *c, int ev, void *p,
  void *user_data) {
 struct http_message *hm = (struct http_message *)p;
 LOG(LL_INFO, ("URI=%.*s", hm->uri.len, hm->uri.p));
 LOG(LL_INFO, ("QS=%.*s", hm->query_string.len, hm->query_string.p));
 if (ev != MG_EV_HTTP_REQUEST) {
  return;
 }
 if (strncmp("/cgi/Send", hm->uri.p, hm->uri.len) == 0) {
  ...
  mg_send_response_line(c, 200,
    "Content-Type: text/plain\r\n");
  mg_printf(c, "OK\r\n");
 }
 else {
  ...
 }
 c->flags |= MG_F_SEND_AND_CLOSE;
 (void) user_data;
}

That takes care of the backend. All cgi calls will have a very short response. The cgi calls are made from within javascript and use ajax calls to get the data. The data is them incorporated into the web page. This is typical of SPA (Single Page Application) web pages.

In the next few posts I will be looking at implementing an IR remote control with a web based UI.

No comments:

Post a Comment