ESP8266: Handling analog signals without an analog input, just GPIO!

Experimenting with the ESP8266 at one point I came across the need of dealing with analog signals. There are a lot of versions of the module and most of them have GPIO accessibility but not ADC access. Some of the lates versions of the module have ADC though, but I have a few modules in stock that do not have it. And I need ADC handling.

Well, it is totally possible and here is how to do it.

There are 4 basic things that need to be done:

  • convert the analog signal into pulse width modulation (PWM)
  • read the PWM on any GPIO
  • read the PWM duty cycle on the ESP8266
  • calibrate the PWM to analog level response

I am using NodeMCU Lua API. Lets look in more detail:

Convert the analog signal into pulse width modulation (PWM)

This is quite simple. The popular LM555 will do the trick. Here is the circuit:

Screen Shot 2015-04-20 at 11.37.38 AM

A sawtooth signal ramping up from 0 to 5v simulates the analog signal, the 555 spits out a PWM, with duty cycle proportional to the analog level. The 555 output is then connected to a GPIO pin.

Read the PWM on any GPIO

This is even simpler. Just pipe the output of the 555 to any GPIO pin.

Read the PWM duty cycle on the ESP8266

To do this, watch for the GPIO pin ‘up’ and ‘down’ events:

file.writeline([[gpio.trig(pin, 'both', callback)]])

In the callback function, read the pin, track the time when the up and downs happen and calculate the ratio, that is the duty cycle:

file.writeline([[time_read= time_read-time_base]])
file.writeline([[if cnt == 0 and rp == 0 then low_start=time_read]])
file.writeline([[if cnt == 1 and rp == 1 then low_end=time_read]])
file.writeline([[if cnt == 2 and rp == 0 then high_end=time_read]])
file.writeline([[high_start = low_end]])
file.writeline([[if (high_end-low_start) > 0 and cnt == 3 then]])
file.writeline([[duty = (100*(high_end - high_start))/(high_end-low_start)]])
file.writeline([[print("Duty: " .. duty) ]])
file.writeline([[cnt = 0]])

Read the PWM duty cycle on the ESP8266

Finally, pick a few calibration points between the PWM duty cycle you are reading and the actual analog signal value and calibrate the reading.

My prototypes are available on Tindie.

Posted in Uncategorized | Leave a comment

WIFI vibration sensor using the ESP8266

A simple vibration sensor can be connected to the ESP8266 GPIO pin and an alarm can be triggered via TCP to report vibration. This could be useful for a number of things, including industrial monitoring, security, etc. The prototype uses a sensor originally designed for Arduino, but can easily be connected to one of the GPIOs in the ESP8266. The firmware checks whether the GPIO has triggered and if so it sends a TCP message to a server listening. SSID and password for the WIFI can be programmed remotely via web as with my other prototypes and the nice things is that the server address and the port number the server is listening at can also be programmed remotely via web, no serial connection required and it is persistent!!!



Vibration switch


Vibration switch connected to ESP8266 board

Screen Shot 2015-04-16 at 6.19.16 PM

TCP trigger received overtime there is a vibration

 Check my other and future boards on Tindie


Posted in Uncategorized | Leave a comment

Temperature and Humidity sensor and control using ESP8266-03

Temperature and humidity sensor and control

Temperature and humidity sensor and control

This module is available for preorder at Tindie click here

This project implements a temperature and humidity sensor using the ESP8266 WIFI module and a DHT11 temp/hum sensor.

The board can be configured via web in a similar way as previous projects. Connect to the  ESP8266 station (ESP8266-XXXXXXX) and on a web browser point to IP, then you are prompted to enter wifi network SSID and password. Within a few seconds, the IP address of the ESP8266 module will appear on the web page.

Any TCP message sent to the module IP address will return a JSON feed  with the current temperature and humidity:

{“dth11″: [{ “Temperature:”: “24”, “Humidity”: “39”,}]}

Now the interesting part. By sending a TCP special string, I can set a minimum and maximum temperature and humidity. When the minimum temperature is reached, then a relay is triggered; similarly, when the maximum temperature that has been set is reached, another relay is triggered and the other one is reset. The same can be done for humidity. Now we have a sensor that reacts.

The control string is of the form


and can be sent at any time to set the min/max limits, in return you always get the current temp and hum as

{“dth11″: [{ “Temperature:”: “24”, “Humidity”: “39”,}]}

A video of the project can be accessed here

Posted in Uncategorized | Leave a comment

General purpose WIFI control board x4 based on ESP8266-03

I’ve just finished getting the ESP8266 working. I can now configure it via a web browser and the LUA based firmware will also allow me to control 4 signal, on and off, that can feed relays or other low consumption devices.

ESP8266-03-x4ControlBoard-v01Pic2 ESP8266-03-x4ControlBoard-v01Pic1

Check the video on Youtube


Next is the temperature logger…

Image | Posted on by | Leave a comment

ESP8266 Breadboard Adapter with Reset and Flash jumper (8266BBA01) available on Tindie and eBay

The 8266BBA01 ESP8266 Breadboard Adaptor makes it easy to connect the ESP8266 to a breadboard or standalone for programming and testing. An 8 pin 0.1 inch pitch terminal is available in the bottom to directly connect to a breadboard.

An 8 pos screw terminal is available to get access to all the ESP8266 pins without soldering. A 2×4 socket makes it really easy to switch ESP8266 modules for quick testing and programming. (ESP8266 not included)

Order it on Tindie or eBay

Esp8266_Breadboard_v01_01 Esp8266_Breadboard_v01_02 Esp8266_Breadboard_v01_03 Esp8266_Breadboard_v01_04 Esp8266_Breadboard_v01_05 Esp8266_Breadboard_v07_01 Esp8266_Breadboard_v01_06 copy

Posted in Uncategorized | Leave a comment

ESP8266 based web configurable wifi general purpose control (Part III)

NOTE: Ready to go boards can be purchased here

The electronics part

InPart I and II we saw how to program and remotely configure the ESP8266 to turn it into a processor of TCP events. Now we will take those events and turn them into something useful by controlling a set of switches.

We start with a dual 4 bit binary counter, 74LS393N. This chip has 2 full 4 bit binary counters. We will connect the inputs together and the resets together. GPIO0 from the ESP8266 will be connected to the inputs and GPIO2 to the reset.  The output of the 393 will go into ULN2803 which is a 8xdarlington driver. The 2803 will drive relays or any other low power stuff. A set of leds will indicate which output is on.

Now when a TCP GPIO High/Low event is sent to the module IP address port 9999, this event will be redirected to the binary counter. The process is as follows:

  • a low/high event on GPIO2 sent to the port will reset the binary counter
  • a low/high event on GPIO0 sent to the port will count once
  • an ‘n’ low/high events on GPIO0 sent to the port will count ‘n’ times
  • with this arrangement we can count to 16 on each 1.2 of the binary counter.
  • we will use each of the 4 bits outputs to drive a signal (led, relay, etc)
  • one low/high events on GPIO0 will turn on output 1A and 1B
  • 2 low/high events on GPIO0 will turn on output 2A and 2B
  • 3 low/high events on GPIO0 will turn on output 1A, 2A, 1B and 2B
  • 16 low/high events on GPIO0 will turn on all outputs
  • a low/high event on GPIO2 will reset the binary counter and turn off all outputs.

Quite simple. Here is the circuit.


and the breadboard


Watch the prototype


Video | Posted on by | 9 Comments

ESP8266 based web configurable wifi general purpose control (Part II)

NOTE: Ready to go boards can be purchased here

On Part II I will go over how to program the ESP8266 so a USB to serial module and a terminal is not necessary: it will all be done via web. Also, I will explain how to drive a binary counter and control 4 relays (multi on/multi off) using GPIO0 as control and GPIO2 as reset. This way the ESP8266 really turns into a powerful device that can be added to any automation project and its easy to program on site.

The control firmware

The firmware needs to be able to allow the user to connect to the module and set the SSID and password of the network the module will be connected to. The steps to design the firmware are as follows:

  1. set the module to server (AP) mode
  2. set a name and password
  3. create a server
  4. listen on port 80
  5. module address is
  6. present a web page asking for SSID and password
  7. switch to Station mode and set SSID and password
  8. connect to network
  9. start listening for events coming on the ip address assigned by the network and port 9999

Here is the code to do it:“init.lua”,”w”)
file.writeline([[print(“WIFI control”)]])
— put module in AP mode
file.writeline([[print(“ESP8266 mode is: ” .. wifi.getmode())]])
— Set the SSID of the module in AP mode and access password
file.writeline([[if ssid and password then]])
file.writeline([[print(“ESP8266 SSID is: ” .. cfg.ssid .. ” and PASSWORD is: ” .. cfg.password)]])
— Now you should see an SSID wireless router named ESP_STATION when you scan for available WIFI networks
— Lets connect to the module from a computer of mobile device. So, find the SSID and connect using the password selected
file.writeline([[ap_mac = wifi.ap.getmac()]])
— create a server on port 80 and wait for a connection, when a connection is coming in function c will be executed
file.writeline([[c:on(“receive”, function(c, pl)]])

— print the payload pl received from the connection

— wait until SSID comes back and parse the SSID and the password
file.writeline([[if ssid_start and ssid_end then]])
file.writeline([[amper1_start, amper1_end =string.find(pl,”&”, ssid_end+1)]])
file.writeline([[if amper1_start and amper1_end then]])
file.writeline([[http_start, http_end =string.find(pl,”HTTP/1.1″, ssid_end+1)]])
file.writeline([[if http_start and http_end then]])
file.writeline([[ssid=string.sub(pl,ssid_end+1, amper1_start-1)]])
file.writeline([[password=string.sub(pl,amper1_end+10, http_start-2)]])
file.writeline([[print(“ESP8266 connecting to SSID: ” .. ssid .. ” with PASSWORD: ” .. password)]])
file.writeline([[if ssid and password then]])
— close the server and set the module to STATION mode
file.writeline([[print(“ESP8266 mode now is: ” .. wifi.getmode())]])
— configure the module wso it can connect to the network using the received SSID and password
file.writeline([[print(“Setting up ESP8266 for station mode…Please wait.”)]])
file.writeline([[print(“ESP8266 STATION IP now is: ” .. wifi.sta.getip())]])
file.writeline([[print(“ESP8266 AP IP now is: ” .. wifi.ap.getip())]])
— now the module is configured and connected to the network so lets start setting things up for the control logic

file.writeline([[tmr.delay(10) ]])
file.writeline([[sv=net.createServer(net.TCP, 30) ]])
file.writeline([[c:on(“receive”, function(c, pl)]])
file.writeline([[if tonumber(pl) ~= nil then]])
file.writeline([[if tonumber(pl) >= 1 and tonumber(pl) <= 16 then]])
file.writeline([[for count =1,tonumber(pl) do]])
file.writeline([[ print(count)]])
file.writeline([[tmr.delay(10) ]])
file.writeline([[ gpio.write(9,gpio.LOW)]])
file.writeline([[c:send(“Sequence finished”) ]])

file.writeline([[print(“ESP8266 STATION IP now is: ” .. new_ip)]])

file.writeline([[c:send(“ESP8266 STATION IP now is: ” .. new_ip) ]])

file.writeline([[c:send(“Action completed”) ]])

— this is the web page that requests the SSID and password from the user
file.writeline([[c:send(“<!DOCTYPE html> “)]])
file.writeline([[c:send(“<html lang=’en’> “)]])
file.writeline([[c:send(“<body> “)]])
file.writeline([[c:send(“<h1>ESP8266 Wireless control setup</h1> “)]])
file.writeline([[mac_mess1 = “The module MAC address is: ” .. ap_mac]])
file.writeline([[mac_mess2 = “You will need this MAC address to find the IP address of the module, please take note of it.”]])

file.writeline([[c:send(“<h2>” .. mac_mess1 .. “</h2> “)]])
file.writeline([[c:send(“<h2>” .. mac_mess2 .. “</h2> “)]])
file.writeline([[c:send(“<h2>Enter SSID and Password for your WIFI router</h2> “)]])
file.writeline([[c:send(“</form> </body> </html>”)]])
file.writeline([[c:send(“<form action=” method=’get’>”)]])
file.writeline([[c:send(“<input type=’text’ name=’SSID’ value=” maxlength=’100′ />”)]])
file.writeline([[c:send(“<br />”)]])
file.writeline([[c:send(“<input type=’text’ name=‘Password’ value=” maxlength=’100′ />”)]])
file.writeline([[c:send(“<input type=’submit’ value=’Submit’ />”)]])

Loading the firmware and testing

Load the file with the code written above as explained in Part I. Once the file is sent to the module you should do a node.restart() and will see the following:

OK. The module is now in AP mode so it is like a WIFI router and you should see ESP_STATION on your list of WIFI networks.


Now connect to ESP_STATION using the password that you have programmed into the firmware, “the_ESP8266_WIFI_password” above. Now connect to from a browser. You should see the webpage below. Enter SSID and password of your WIFI network so the ESP8266 can connect to it.



After a few seconds of waiting you should receive a message on the web browser with the IP address assigned to the module by your router; if you get a, just refresh the browser pointing to and you should get the new IP address. Since for this test we are monitoring the ESP8266 through a serial terminal, lets check what the output was:



On your browser you should see:


Now the ESP8266 is connected to our WIFI network and has IP address However, if you don;t get the browser to show the IP address, you can always refer to the MAC address of the ESP8266 shown on the SSID/Password entry page and the user will have to find the IP address by going into the router setup, depending on what kind of router that is. I will in the future figure out how to ensure that IP address is always posted back to the browser.


On Part II we saw how to configure the ESP8266 directly from a web browser and bypassing the USB to serial. Now we are getting closer to something that can be commercialized.

On Part III (yes, sorry, I chopped it into 3 parts) I will show how to connect the GPIO0 and GPIO2 signals to some binary counters and driver to drive relays or any other device.

Posted in Uncategorized | 20 Comments