The ESP8266 microcontroller chip is out there for almost a year now and it has already made a huge boom in the makers and IoT communities. It is cheap ($5), it has built in WiFi capabilities, and as of a few months ago, it is Arduino compatible.

Besides the unique built in WiFi capability, the ESP8266 has its own 32bit CPU running on 80MHz, up to 4MB flash, and can be extended with other devices via the GPIO pins which can act individually or as SPI, I2C or UART interfaces.

The early versions of the chip were used as add-on modules which provided WiFi access to an Arduino board. The communication was done via the exposed Rx and Tx pins and by using series of AT commands. However, after a while, the manufacturer released an SDK allowing code to be uploaded directly on the ESP chip and thus removing the need for a separate driver board. But still, the experience wasn’t nice, since the tools were buggy and the code was to be done in Lua. Then, after months of adaptations, an Arduino IDE port was release targeted for ESP8266, and it was a game changer.

What I did as a POC of the entire platform is a Colored WiFi light that I can control via my phone browser. My whole idea is to have this integrated in a home automation system, but let’s go step by step.

Hardware requirements:

NodeMCU devkit (preferrably for ease of usage and testing; or other ESP8266 board properly connected via FTDI)

A WS2812 / 2811 / NeoPixel LED strip. (any would do, just keep the number of LEDs low, so you won’t need external powering. You can even use PiMoroni’s Unicorn HAT)

Jumper wires

Micro USB cable (if NodeMCU) is to be used

To connect the WS2812 LED strip, use the jumper wires and connect the DataIn pin to GPIO4 which is actually D2 from the board, the input voltage to 5V on the board, and GND to any GND pin.

The NodeMCU devkit is a device board for prototyping with the ESP-12 chip. I’m using here the 0.9 version of the devkit, which is not the most recent. Bear in mind that the pin numbering on the board is NOT the same as the GPIO numbering in the SDK.

Next, download and configure the Arduino IDE:

Download and install the latest Arduino IDE with the Board Manager for ESP8266 as described here.

Get and install the device driver for the on-board USB to Serial from here. (needed for NodeMCU)

Get and install the NeoPixelBus library to your Arduino installation. Do that by placing everything in the folder arduino/libraries/NeoPixelBus.

Launch the Arduino IDE and choose the board to be NodeMCU (or generic ESP8266 if using the sole chip via FTDI) and select the COM port to which the device is connected.

Finally, the code to make it all work. You can see prior to this that there are already several examples which can get you started (look at the web server examples and the ones from the NeoPixelBus library). What is needed here is basically a mix between those two , some proper handlers and a simple web UI.

My try:

#include <ESP8266WiFi.h> #include <WiFiClient.h> #include <ESP8266WebServer.h> #include <ESP8266mDNS.h> #include <NeoPixelBus.h> #define pixelCount 8 #define colorSaturation 255 NeoPixelBus strip = NeoPixelBus(pixelCount, 4, NEO_GRB); RgbColor red = RgbColor(colorSaturation, 0, 0); RgbColor green = RgbColor(0, colorSaturation, 0); RgbColor blue = RgbColor(0, 0, colorSaturation); RgbColor white = RgbColor(colorSaturation); RgbColor black = RgbColor(0); const char *ssid = "CHANGE WITH YOUR NETWORK SSID"; const char *password = "CHANGE WITH YOUR NETWORK PASSWORD"; MDNSResponder mdns; ESP8266WebServer server ( 80 ); const int led = 13; void handleRoot() { digitalWrite ( led, 1 ); String out = "<html><head><title>Wifi light</title></head>"; out += "<body style='background-color:gray'>"; out += "<span style='display:block; width:100%; font-size:2em; font-family:Verdana; text-align:center'>Choose color</span><br/>"; out += "<a href='white'><span style='display:block; background-color:white; width:100%; height:6em;'></span></a><br/>"; out += "<a href='red'><span style='display:block; background-color:red; width:100%; height:6em;'></span></a><br/>"; out += "<a href='green'><span style='display:block; background-color:green; width:100%; height:6em;'></span></a><br/>"; out += "<a href='blue'><span style='display:block; background-color:blue; width:100%; height:6em;'></span></a><br/>"; out += "<a href='black'><span style='display:block; background-color:black; width:100%; height:6em;'></span></a>"; out += "</body>"; out += "</html>"; server.send ( 200, "text/html", out ); digitalWrite ( led, 0 ); } void handleNotFound() { digitalWrite ( led, 1 ); String message = "File Not Found



"; message += "URI: "; message += server.uri(); message += "

Method: "; message += ( server.method() == HTTP_GET ) ? "GET" : "POST"; message += "

Arguments: "; message += server.args(); message += "

"; for ( uint8_t i = 0; i < server.args(); i++ ) { message += " " + server.argName ( i ) + ": " + server.arg ( i ) + "

"; } server.send ( 404, "text/plain", message ); digitalWrite ( led, 0 ); } void setup ( void ) { pinMode ( led, OUTPUT ); digitalWrite ( led, 0 ); strip.Begin(); strip.Show(); Serial.begin ( 115200 ); WiFi.begin ( ssid, password ); Serial.println ( "" ); // Wait for connection while ( WiFi.status() != WL_CONNECTED ) { delay ( 500 ); Serial.print ( "." ); } Serial.println ( "" ); Serial.print ( "Connected to " ); Serial.println ( ssid ); Serial.print ( "IP address: " ); Serial.println ( WiFi.localIP() ); if ( mdns.begin ( "esp8266", WiFi.localIP() ) ) { Serial.println ( "MDNS responder started" ); } server.on ( "/", []() {handleRoot();} ); server.on ( "/white", []() {setColor(white); handleRoot();} ); server.on ( "/red", []() {setColor(red); handleRoot();} ); server.on ( "/green", []() {setColor(green); handleRoot();} ); server.on ( "/blue", []() {setColor(blue); handleRoot();} ); server.on ( "/black", []() {setColor(black); handleRoot();} ); server.onNotFound ( handleNotFound ); server.begin(); Serial.println ( "HTTP server started" ); } void loop ( void ) { mdns.update(); server.handleClient(); } void setColor(RgbColor color) { int i; for (i=0; i<pixelCount; i++) { strip.SetPixelColor(i, color); } strip.Show(); } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 #include <ESP8266WiFi.h> #include <WiFiClient.h> #include <ESP8266WebServer.h> #include <ESP8266mDNS.h> #include <NeoPixelBus.h> #define pixelCount 8 #define colorSaturation 255 NeoPixelBus strip = NeoPixelBus ( pixelCount , 4 , NEO_GRB ) ; RgbColor red = RgbColor ( colorSaturation , 0 , 0 ) ; RgbColor green = RgbColor ( 0 , colorSaturation , 0 ) ; RgbColor blue = RgbColor ( 0 , 0 , colorSaturation ) ; RgbColor white = RgbColor ( colorSaturation ) ; RgbColor black = RgbColor ( 0 ) ; const char * ssid = "CHANGE WITH YOUR NETWORK SSID" ; const char * password = "CHANGE WITH YOUR NETWORK PASSWORD" ; MDNSResponder mdns ; ESP8266WebServer server ( 80 ) ; const int led = 13 ; void handleRoot ( ) { digitalWrite ( led , 1 ) ; String out = "<html><head><title>Wifi light</title></head>" ; out += "<body style='background-color:gray'>" ; out += "<span style='display:block; width:100%; font-size:2em; font-family:Verdana; text-align:center'>Choose color</span><br/>" ; out += "<a href='white'><span style='display:block; background-color:white; width:100%; height:6em;'></span></a><br/>" ; out += "<a href='red'><span style='display:block; background-color:red; width:100%; height:6em;'></span></a><br/>" ; out += "<a href='green'><span style='display:block; background-color:green; width:100%; height:6em;'></span></a><br/>" ; out += "<a href='blue'><span style='display:block; background-color:blue; width:100%; height:6em;'></span></a><br/>" ; out += "<a href='black'><span style='display:block; background-color:black; width:100%; height:6em;'></span></a>" ; out += "</body>" ; out += "</html>" ; server . send ( 200 , "text/html" , out ) ; digitalWrite ( led , 0 ) ; } void handleNotFound ( ) { digitalWrite ( led , 1 ) ; String message = "File Not Found



" ; message += "URI: " ; message += server . uri ( ) ; message += "

Method: " ; message += ( server . method ( ) == HTTP _ GET ) ? "GET" : "POST" ; message += "

Arguments: " ; message += server . args ( ) ; message += "

" ; for ( uint8 _ t i = 0 ; i < server . args ( ) ; i ++ ) { message += " " + server . argName ( i ) + ": " + server . arg ( i ) + "

" ; } server . send ( 404 , "text/plain" , message ) ; digitalWrite ( led , 0 ) ; } void setup ( void ) { pinMode ( led , OUTPUT ) ; digitalWrite ( led , 0 ) ; strip . Begin ( ) ; strip . Show ( ) ; Serial . begin ( 115200 ) ; WiFi . begin ( ssid , password ) ; Serial . println ( "" ) ; // Wait for connection while ( WiFi . status ( ) != WL _ CONNECTED ) { delay ( 500 ) ; Serial . print ( "." ) ; } Serial . println ( "" ) ; Serial . print ( "Connected to " ) ; Serial . println ( ssid ) ; Serial . print ( "IP address: " ) ; Serial . println ( WiFi . localIP ( ) ) ; if ( mdns . begin ( "esp8266" , WiFi . localIP ( ) ) ) { Serial . println ( "MDNS responder started" ) ; } server . on ( "/" , [ ] ( ) { handleRoot ( ) ; } ) ; server . on ( "/white" , [ ] ( ) { setColor ( white ) ; handleRoot ( ) ; } ) ; server . on ( "/red" , [ ] ( ) { setColor ( red ) ; handleRoot ( ) ; } ) ; server . on ( "/green" , [ ] ( ) { setColor ( green ) ; handleRoot ( ) ; } ) ; server . on ( "/blue" , [ ] ( ) { setColor ( blue ) ; handleRoot ( ) ; } ) ; server . on ( "/black" , [ ] ( ) { setColor ( black ) ; handleRoot ( ) ; } ) ; server . onNotFound ( handleNotFound ) ; server . begin ( ) ; Serial . println ( "HTTP server started" ) ; } void loop ( void ) { mdns . update ( ) ; server . handleClient ( ) ; } void setColor ( RgbColor color ) { int i ; for ( i = 0 ; i < pixelCount ; i ++ ) { strip . SetPixelColor ( i , color ) ; } strip . Show ( ) ; }

In order to make the code work, you need to enter the SSID and the password of your network in the code. In my case, I set my phone to broadcast a personal hotspot, and I’m connecting directly to it. Also, set the pixelCount to the exact count of pixels you have in your WS2812 strip.

To upload the code to the device, you just click on upload in the IDE, and if everything is fine, the code will be compiled and flashed, and the ESP will be restarted immediately. To see the status, you can use the Serial Communication inspector in the IDE. It will also output the designated IP address from the DHCP server on the network.

At the end, open a browser in the same network and point to the device IP directly. Click on any color and see what happens. Here’s how it turned out on my side.

As a conclusion, I’m pretty satisfied with the outcome. The entire process was relatively short and straight-forward, and besides the device driver troubles I had, everything else went smoothly. I’m also pretty excited, cause more and more stuff is getting adapted for this platform (e.g. DHT sensor library) and inevitably will become the platform to code and make future IoT prototypes.

Useful links: