Introduction: ESP8266 HTTP IO Server

This is a short article to introduce the ESP8266_http_io library. This is a simple http interface for getting to the ESP gpio with Python, Tcl, Javascript or any other language that can make http GET requests. This should work on any ESP module supported by the Arduino IDE.

With the module, you have several exposed basic wiring functions:

  • pinMode
  • digitalRead
  • digitalWrite
  • analogRead
  • analogWrite

As well as basic servo functions:

  • servoOpen
  • servoClose
  • servoRead
  • servoWrite

This is all available via a http server interface. The system is kind of REST like, but NOT fully RESTful. The returned data is in json format though for easy processing.

Step 1: Installing the Code

To use the library, you must first download it from the Github repo. After doing so, unzip the file and navigate to the directory that contains the file 'esp8266_http_io.ino'. Load this into the Arduino IDE and hook up your ESP board of choice up to the computer for programming. See ESP8266 Arduino IDE setup for info on getting the IDE. After you have the IDE ready and the board connected, select your board and com-port and load the code. You may see the pop up above, and if so just click 'OK'.

Step 2: Configuring the Server for Use

You will need to set your Wifi info in the code here:

// Define your Wifi info here</p>#define SSID "YOUR SSID"
#define PASSWD "YOUR PASSWORD"

Click the Upload button in the IDE and if all was well, you will have an ESP ready for http requests.

To test, open the serial monitor inside the IDE and get the url given:

Connecting to: .......

WiFi connected mDNS responder started
Use this URL to connect:  http://192.168.2.8/

Step 3: Running a Simple Test Demo

Now go to the examples/browser folder and open the file "esphttpio_test.html" in a web browser. If you have a NODEMCU board, you should be able to turn the led on and off by clicking the buttons in the browser. If nothing happens, you may need to edit the html file in your favorite text editor and set the "DEVICE_URL" variable to the IP given in the serial monitor and save the file.

<!--   ESP8266 http io server test.


   Gola in life:
     Tests exposed basic wiring functions: pinMode, digitalRead, digitalWrite,
     analogRead and analogWrite from the ESP8266 http server.


   Written By - Scott Beasley 2016.
   Public domain. Free to use or change. Enjoy :)
-->
<html>
  <script src="http://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"
          type="text/javascript" charset="utf-8">
  </script>
<head>
<title>ESP8266 HTTP IO TEST</title>
<script type="text/javascript">
var DEVICE_URL = 'http://espio_01.local' // Change to IP from serial monitor if needed.


pinMode ('16','OUTPUT'); // Set the pin as OUTPUT


function pinMode (pin, state) {
   var requestURL = DEVICE_URL + "/pinMode?" + pin + "," + state;
   $.get (requestURL);
}


function digitalWrite (pin, state) {
   var requestURL = DEVICE_URL + "/digitalWrite?" + pin + "," + state;
   $.get (requestURL);
}
</script>
</head>
<center>
  LED --> 
  <button onclick="digitalWrite ('16','LOW')">Led On</button>
  <button onclick="digitalWrite ('16','HIGH')">Led Off</button>
</center>
</html>

Step 4: Another Example From the Browser - Blink

There is also a browser Blink example as well. Go to the browser folder and find "esphttpio_blink.html"

If you need to edit the DEVICE_URL, do so before you run it. You can stop and and start the blink loop with the two provided buttons.

This is the blink code itself:

<!--   ESP8266 http io server test.
   Goal in life:
     Blink an LED every second.
   Written By - Scott Beasley 2016.
   Public domain. Free to use or change. Enjoy :)
-->
<html>
  <script src="http://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"
          type="text/javascript" charset="utf-8">
  </script>
<head>
<title>ESP8266 Browser Blink</title>
<script type="text/javascript">
var DEVICE_URL = 'http://espio_01.local'
var LED_STATE = 'LOW'
var DO_BLINK = true
pinMode ('16','OUTPUT'); // Set the pin as OUTPUT
var tmr = setTimeout (blink, 1000);
function pinMode (pin, state) {
   var requestURL = DEVICE_URL + "/pinMode?" + pin + "," + state;
   $.get (requestURL);
}
function digitalWrite (pin, state) {
   var requestURL = DEVICE_URL + "/digitalWrite?" + pin + "," + state;
   $.get (requestURL);
}
function blink ( ) {
   LED_STATE = (LED_STATE == 'LOW' ? 'HIGH' : 'LOW');
   digitalWrite ('16', LED_STATE);
   if (DO_BLINK)
      tmr = setTimeout (blink, 1000);
}
function setBlink (state) {
   if (state == 'ON') {
      tmr = setTimeout (blink, 1000);
      DO_BLINK = true;
   }
   if (state == 'OFF') {
      clearTimeout (tmr);
      DO_BLINK = false;
   }
}
</script>
</head>
<center>
  LED -->
  <button onclick="setBlink ('ON')">Led Blink On</button>
  <button onclick="setBlink ('OFF')">Led Blink Off</button>
</center>
</html>

Step 5: Calling From Python

As stated in the intro, you can also call the server from Python and other languages.

To run the Python example, you will need to make the "DEVICE_URL" change before you run it. You will also need the requests package.

#   ESP8266 http io server test.
#
#   Goal in life:
#     Tests exposed basic wiring functions: pinMode, digitalRead, digitalWrite,
#     analogRead and analogWrite from the ESP8266 http server.
#
#   Written By - Scott Beasley 2016.
#   Public domain. Free to use or change. Enjoy :)
#

# requests info found here: <a href="http://docs.python-requests.org/en/latest/user/install/#install">  http://docs.python-requests.org/en/latest/user/in...>
import requests 
import time

DEVICE_URL = 'http://192.168.2.8' # IP of your ESP (Copied from the serial monitor) 

def digitalWrite (pin, state):
    r = requests.get (DEVICE_URL+'/digitalWrite', params=pin+','+state,
                      stream=False,
                      headers={'Connection':'close','keep_alive': 'False'})
    ret_json = r.json ( )
    r.connection.close()
    return_val = ret_json['return_code']
    return int(return_val)

def digitalRead (pin):
    r = requests.get (DEVICE_URL+'/digitalRead', params=pin, stream=False,
                      headers={'Connection':'close','keep_alive': 'False'})
    ret_json = r.json ( )
    return_val = ret_json['data_value']
    return return_val

def pinMode (pin, state):
    r = requests.get (DEVICE_URL+'/pinMode', params=pin+','+state,
                      stream=False,
                      headers={'Connection':'close','keep_alive': 'False'})
    ret_json = r.json ( )
    r.connection.close()
    return_val = ret_json['return_code']
    return int(return_val)

def analogWrite (pin, state):
    r = requests.get (DEVICE_URL+'/analogWrite', params=pin+','+state,
                      stream=False,
                      headers={'Connection':'close','keep_alive': 'False'})
    ret_json = r.json ( )
    r.connection.close()
    return_val = ret_json['return_code']
    return int(return_val)

def analogRead (pin):
    r = requests.get (DEVICE_URL+'/analogRead', params=pin, stream=False,
                      headers={'Connection':'close','keep_alive': 'False'})
    ret_json = r.json ( )
    return_val = ret_json['data_value']
    return int(return_val)

def main ( ):
    pinMode ("3", "INPUT_PULLUP")
    pinMode ("16", "OUTPUT") # on NODEMCU has an LED on it

    while 1:
        digitalWrite ("16", "LOW")
        time.sleep (1)
        digitalWrite ("16", "HIGH")
        print "A0 = " + str (analogRead ("0"))
        print "D3 = " + digitalRead ("3")
    end

if __name__ == "__main__":
    main ( )

Step 6: Conclusion

The API's that are exposed by the server again are:

  • /pinMode
  • /digitalWrite
  • /digitalRead
  • /analogRead - (Note: Just A0)
  • /analogWrite
  • /servoOpen
  • /servoClose
  • /servoWrite
  • /servoRead

The current examples are in Python, browser based JavaScript and Tcl, but you could easily call the it with nodejs, curl or any language or utility that allows for http gets and json data strings. Thats basicly most of them! I am adding more examples as time permits. Have a look at the server code and other examples for more information.

This code should be valuable to anyone wanting to easily access GPIO of an ESP module from a an easy to use HTTP interface familiar by many in today's IoT world.

Comments