Introduction: ESP8266 HTTP IO Server
This is a short article to introduce the ESP8266_http_io library. It's 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
All of the above "functions" are available via an 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 #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: <a href="http://192.168.2.8/"> 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.