Triple Server Update – Part 1: Serving Arduino


Happy New Year! I’m picking things up right where they ended last year…

There were some basic enhancements needed to my Triple Protocol Server. But in the process of implementing the updates, the limitations of the ESP8266 resources were reached. To make room for the new features, something had to go.

In this case, the CoAP server was eliminated. The choice was obvious. This protocol consumed a large chunk of the available heap, leaving little room for program execution. As result, the system became unstable. CoAP also does not lend itself easily to web browser based clients.

So with that gone, a valuable new feature was added. A light-weight modification that did not significantly burden the system. Something that Arduino users should find extremely useful.

What is it?

An Arduino Serial Port Web Server

What? We already have access from the Arduino using the AT command set. “So what’s so special about this?”, you say.

Well…this implementation removes most of the web server tasks from the Arduino and puts it in the ESP8266. The only thing the Arduino needs to do is read small strings (requests) from the ESP8266 and return a small string back. This frees the Arduino to concentrate on sensor readings and control functions.

This balances the load on the two micro-controllers, reducing the load on the Arduino while fully leveraging the available power of the ESP8266 as a web server.

So how does this work?

It’s really quite simple. The ESP8266 web server is already in place. All that is needed is a few new URL-based (or MQTT topic payload) commands to provide web-based access to the Arduino resources.

The New Arduino Commands

The commands are parsed and decoded by the ESP8266. The command is reduced to a small string that is passed to the Arduino for action with it’s hardware resources.

URL Suffix ESP8266 to Arduino Arduino Reply
Set Digital Channel 04 HI /?arduino=SetDigital&chan=04&state=1 Arduino_SD041 Digital Channel 04 is HI
Get Digital Channel 04 /?arduino=GetDigital&chan=04 Arduino_GD04 Digital Channel 04 is HI
Get Analog Channel 04 /?arduino=GetAnalog&chan=04 Arduino_GA04 Analog Channel 04 is 2.234

The Arduino returns a reply to the ESP8266, which, in turn, is returned to the http or mqtt client.

This structure is similar to the slash (/) delineated bridge interface used with the Arduino Yun to communicate between it’s Arduino and Linux processors. Instead of using a pricey Arduino Yun, you can use any model Arduino along with the very inexpensive ESP8266. In this test case, I used a $7 Arduino nano clone.

The example presented here only includes the basic digital and analog access to the Arduino. The digital interface is obvious, setting or reading the state of each pin. The analog channel reads returns a voltage between 0 and 5 volts, based on the 10-bit Arduino ADC channel reading.

From this command set, it should be obvious how to expand it to include bus oriented sensors such as 1-wire temperature and i2c connected devices.

ESP8266 Sketch

The ESP8266 Arduino IDE sketch is based upon my triple server sketch presented in a prior post. The default parameters are defined at the top of the sketch in the section titled “Initial EEPROM Values”. These can be revised to match your network setting as described in Part 2 of this post, and in the sketch’s github repository.

Additional code was needed to support the Arduino requests. The commands received are repacked into a small string to be sent to the Arduino via the ESP8266 serial port. The server code to process the three recognized requests (Set Digital, GetDigital and Get Analog) shown here can easily be expanded for addition requests:

  1. // -----------------------------------------------------------------------
  2. // Serving Arduino via serial port
  3. // -----------------------------------------------------------------------
  4. if(os_strcmp(pURL_Param->pParam[0], "arduino")==0) {
  5. //-------------- Request = SetDigital ---------------------
  6. if(os_strcmp(pURL_Param->pParVal[0], "SetDigital")==0){
  7. if(os_strcmp(pURL_Param->pParam[1], "chan")==0) {
  8.           ArduinoRequest = "Arduino_SD";
  9.            ArduinoRequest += pURL_Param->pParVal[1];
  10.         }
  11.        else {
  12.             ArduinoRequest = "Invalid Request";  
  13.         }
  14.         if((os_strcmp(pURL_Param->pParam[2], "state")==0)&&(os_strcmp(
  15. ArduinoRequest.c_str(), "Invalid Request")!=0)) {
  16.             ArduinoRequest += pURL_Param->pParVal[2];
  17.         }
  18.         else {
  19.             ArduinoRequest = "Invalid Request";  
  20.         }
  21. }
  22.     //-------------- Request = GetDigital ----------------------
  23.     else if(os_strcmp(pURL_Param->pParVal[0], "GetDigital")==0){
  24. if(os_strcmp(pURL_Param->pParam[1], "chan")==0) {
  25.          ArduinoRequest = "Arduino_GD";
  26.             ArduinoRequest += pURL_Param->pParVal[1];
  27.      }
  28.       else {
  29.             ArduinoRequest = "Invalid Request";  
  30.      }
  31.    }
  32.     //-------------- Request = GetAnalog ----------------------
  33.     else if(os_strcmp(pURL_Param->pParVal[0], "GetAnalog")==0){
  34.      if(os_strcmp(pURL_Param->pParam[1], "chan")==0) {
  35.          ArduinoRequest = "Arduino_GA";
  36.             ArduinoRequest += pURL_Param->pParVal[1];
  37.         }
  38.         else {
  39.             ArduinoRequest = "Invalid Request";  
  40.         }
  41.    }
  42.    //-------------- Request is not recognized -----------------
  43.    else {
  44.     ArduinoRequest = "Invalid Request";  
  45.    }
  46.    //-------- Execute valid request & get reply string --------
  47.    if(os_strcmp(ArduinoRequest.c_str(), "Invalid Request")==0) {
  48.      payld = ArduinoRequest;
  49.    }
  50.    else {
  51.     rparam.request = ARDUINO_REQUEST;
  52.        rparam.requestval = 0;
  53.        Server_ExecuteRequest(servertype, rparam, &payld, ArduinoRequest);
  54.   }
  55.   Server_SendReply(servertype, REPLY_TEXT, payld);
  56. }

Arduino Sketch

A simple Arduino sketch is provided here  as an example of how to receive and process requests from the ESP8266. Using the low-end Arduino nano, this example uses a software serial port (Arduino digital pins 10 and 11) to communicate with the ESP8266.

Due to the limited bandwidth for reliable operation with this software port, the baud was reduced to 1200 baud. If a dedicated hardware serial port is used, such as found with the Arduino mega, the baud can be increased considerably.

The example provided is fully functional, yet simple enough to understand and build upon with even modest programming skills.

Part 2: Web-based ESP8266 Configuration

So there you have it, an ESP8266 web server sketch that supports Arduino communication using either MQTT or url-based http protocols. But there is more to this update. I’ve also added web-browser configuration of the Network and MQTT settings.

Read on here for the details…

Share This:
Social tagging: >

2 Responses to Triple Server Update – Part 1: Serving Arduino

  1. I am curious about the next part :-). This (web-based Wifi configuration) is something that I had planned to do more or less as my next mini-project.

    What would also be great is somehow adding the WiFi stability thing (from this post into all further projects.

    Keep up the good work and thanks a lot!

    • facebook-profile-picture InternetOfHomeThings says:

      Thanks for your comment. In this project, the “WIFI stability thing” is implemented in the function util_startWIFI() which is executed at the start of every loop().

      While I have not finished the write-up (part 2), the Web-based Wifi configuration is included in the sketch referenced in this post. There is some instruction as to how to use it in the Github file, but how it works is yet to be described (post part 2). As noted above, the sketch and associated files are in the Github repository here:

      There were definitely some challenges storing and rendering a webpage within the constraints of the ESP8266 heap size and to carefully code without introducing memory leaks.

      Hope you find part 2 useful in your project. I should have the post ready in a couple of days…and there is more to the story beyond that. So much to do and so little time!

Leave a Reply

Press Ctrl+C to copy the following code.