WiFi RGB Lamp Web Server

Dependencies:   mbed ESP8266_WebServer

RGB WiFi Lamp

Firmware

This is the official firmware repository for the BinarySpace RGB WiFi Lamp project. This firmware is still in alpha stage, and subject to change.

Planned changes include:

  • Configure the WiFi Lamp to connect onto your SSID
  • Variety of operating modes like
    • Fixed colour operation
    • Rainbow gradient
    • Time-based colour changing
    • API-based colour changing

Connecting to the WiFi lamp

To connect to the WiFi lamp web server, scan for an open WiFi network using your cellphone, tablet or laptop that begins with the letters ESP_xxxxxx. This is the automatically created SSID of the ESP8266 WiFi module used in the lamp. Your WiFi client needs to be configured to use DHCP.

Once connected, simply point your browser at http://192.168.4.1 and you should see the rudementary web interface allowing you to switch the WiFi lamp on in the red colour or off.

A second option is to enter the following URL
http://192.168.4.1/setcolor?r=x&g=x&b=x
where x is a number between 0 and 255 for the intensity of (r)ed, (g)reen and (b)lue respectively. Any of the r,g,b parts not specified will automatically default to 0

Supported Platforms

  • ST Nucleo F103RB
  • ST Nucleo F302R8
  • ST Nucleo L152RE
  • ST Nucleo F401RE

Unsupported Platforms

  • ST Nucleo F030R8 (unsupported due to insufficient registers for PololuLed library)

How to update your firmware

One of the best things about the ST Nucleo series is that they enumerate as a USB Mass Storage device when plugged in. Updating the firmware is as simple as compiling it using mbed compiler(free registration required to use) for your selected platform, plugging in your Nucleo and copying the .bin file created by the compiler to the USB drive enumerated by the Nucleo. That's it!

Code is fully Open Source

Please feel free to fork this repository and to submit pull requests if you make any cool additions/changes.

If you are developing changes to the firmware and monitoring via serial console for debugging purposes, note than you can simply comment out the #define DEBUG_WIFI line at the top of the main.cpp file to make the output much less verbose. This effectively disables debugging of the WebServer library code and echoing of communications between the Nucleo and the ESP. It also makes the web server noticeably faster, as it doesn't have to output a lot of serial data before handling requests.

LED Strip colour inconsistency

If you are experiencing problems with the LED's not all changing colour, or perhaps flickering or incorrect colour, there could be 2 potential problems we have identified.

  • Power Supply problems - If the power supply is not providing enough power, or not clean enough power, you may experience flickering or random colour changes. Ensure that your power supply can provide enough power (1A @ 5V recommended). If this does not solve your problem, soldering a capacitor over the power supply lines(5V, GND) may help to clean out any noise from the power supply. (100uF minimum)
  • Depending on cable lengths and connectors, noise on the data line may also be a problem. Try soldering a 100Ω - 500Ω resistor in line on the Din pin of the LED strip

Firmware update for the ESP8266 Module

We suggest you upgrade the firmware on the ESP8266 module to the latest official AT firmware from Espressif. Click Here for a detailed upgrade quide.

Committer:
sschocke
Date:
Tue Jan 06 18:44:43 2015 +0000
Revision:
25:841fc9daffa5
Parent:
24:849265425708
Child:
26:ea5e0ff46492
Removed unnecessary code that was commented out

Who changed what in which revision?

UserRevisionLine numberNew contents of line
sschocke 0:d21e3e1c0a4b 1 #include "mbed.h"
sschocke 1:f07afcffeb5a 2 #include "PololuLedStrip.h"
sschocke 7:f15c81074400 3 #include "ESP8266_WebServer.h"
sschocke 22:6d7a72fab8ff 4 #include "resource.h"
sschocke 0:d21e3e1c0a4b 5 #include <string>
sschocke 13:1e8f27da036a 6 //#define DEBUG_WIFI
sschocke 0:d21e3e1c0a4b 7
sschocke 8:f819de1946a7 8 PololuLedStrip ledStrip(D11);
sschocke 1:f07afcffeb5a 9
sschocke 8:f819de1946a7 10 #define LED_COUNT 8
sschocke 1:f07afcffeb5a 11 rgb_color colors[LED_COUNT];
sschocke 1:f07afcffeb5a 12
sschocke 0:d21e3e1c0a4b 13 DigitalOut wifiCHPD(D4);
sschocke 0:d21e3e1c0a4b 14 DigitalOut wifiReset(D9);
sschocke 0:d21e3e1c0a4b 15
sschocke 0:d21e3e1c0a4b 16 int wifiOn = 0;
sschocke 23:3563e1699fb9 17 int opMode = 0;
sschocke 23:3563e1699fb9 18 std::string stationMAC;
sschocke 23:3563e1699fb9 19 std::string stationIP;
sschocke 23:3563e1699fb9 20 std::string ssid;
sschocke 23:3563e1699fb9 21 std::string apMAC;
sschocke 23:3563e1699fb9 22 std::string apIP;
sschocke 0:d21e3e1c0a4b 23
sschocke 0:d21e3e1c0a4b 24 Serial wifiSerial(D8,D2);
sschocke 0:d21e3e1c0a4b 25 Serial pc(USBTX,USBRX);
sschocke 7:f15c81074400 26 ESP8266_WebServer server(&wifiSerial);
sschocke 0:d21e3e1c0a4b 27
sschocke 22:6d7a72fab8ff 28 char temp[200];
sschocke 23:3563e1699fb9 29 const char* VERSION = "0.5-alpha";
sschocke 20:f5a6527bfda6 30
sschocke 20:f5a6527bfda6 31 #ifdef DEBUG_WIFI
sschocke 20:f5a6527bfda6 32 void pcrxint(void) {
sschocke 23:3563e1699fb9 33 //server.debugBuffers(&pc);
sschocke 23:3563e1699fb9 34 pc.putc('@');
sschocke 20:f5a6527bfda6 35 server.echoMode = true;
sschocke 20:f5a6527bfda6 36 }
sschocke 20:f5a6527bfda6 37 #endif
sschocke 20:f5a6527bfda6 38
sschocke 7:f15c81074400 39 void rxint(void) {
sschocke 7:f15c81074400 40 server.rxint();
sschocke 0:d21e3e1c0a4b 41 }
sschocke 0:d21e3e1c0a4b 42
tomvdb 4:4a502f72cbe3 43 void setColor( uint8_t r, uint8_t g, uint8_t b )
tomvdb 4:4a502f72cbe3 44 {
tomvdb 4:4a502f72cbe3 45 for ( int c = 0; c < LED_COUNT; c++ )
tomvdb 4:4a502f72cbe3 46 {
tomvdb 4:4a502f72cbe3 47 colors[c].red = r;
tomvdb 4:4a502f72cbe3 48 colors[c].green = g;
tomvdb 4:4a502f72cbe3 49 colors[c].blue = b;
tomvdb 4:4a502f72cbe3 50 }
tomvdb 4:4a502f72cbe3 51
tomvdb 4:4a502f72cbe3 52 ledStrip.write(colors, LED_COUNT);
tomvdb 4:4a502f72cbe3 53 }
tomvdb 4:4a502f72cbe3 54
sschocke 23:3563e1699fb9 55 void sendConfigJSONReply(int linkID, const char* result) {
sschocke 23:3563e1699fb9 56 sprintf(temp, jsonConfigReply, opMode, stationIP.c_str(), ssid.c_str(), result);
sschocke 23:3563e1699fb9 57 server.SendReply(linkID, temp, mimeJSON, 0);
sschocke 23:3563e1699fb9 58 }
sschocke 23:3563e1699fb9 59
sschocke 0:d21e3e1c0a4b 60 int main() {
sschocke 13:1e8f27da036a 61 pc.baud(115200);
sschocke 20:f5a6527bfda6 62 #ifdef DEBUG_WIFI
sschocke 20:f5a6527bfda6 63 pc.attach(&pcrxint);
sschocke 20:f5a6527bfda6 64 #endif
leet 10:f48a9f923271 65
sschocke 23:3563e1699fb9 66 pc.printf("WiFi Lamp - %s...\r\n", VERSION);
leet 10:f48a9f923271 67
sschocke 13:1e8f27da036a 68 setColor( 25, 0, 0);
tomvdb 4:4a502f72cbe3 69
sschocke 0:d21e3e1c0a4b 70 wifiCHPD = 0;
sschocke 0:d21e3e1c0a4b 71 wifiReset = 0;
sschocke 13:1e8f27da036a 72 wifiSerial.baud(115200);
sschocke 0:d21e3e1c0a4b 73 wifiSerial.attach(&rxint);
sschocke 7:f15c81074400 74 #ifdef DEBUG_WIFI
sschocke 7:f15c81074400 75 server.debugSerial = &pc;
sschocke 7:f15c81074400 76 #endif
sschocke 0:d21e3e1c0a4b 77 wait_ms(1000);
sschocke 0:d21e3e1c0a4b 78
sschocke 0:d21e3e1c0a4b 79 pc.printf("Powering WiFi...\r\n");
sschocke 0:d21e3e1c0a4b 80 wifiCHPD = 1;
sschocke 13:1e8f27da036a 81 wifiReset = 1;
sschocke 0:d21e3e1c0a4b 82 wait_ms(250);
sschocke 0:d21e3e1c0a4b 83 pc.printf("Hardware Reset WiFi...\r\n");
sschocke 24:849265425708 84 server.ResetModule();
sschocke 0:d21e3e1c0a4b 85 wifiOn = 1;
sschocke 0:d21e3e1c0a4b 86
sschocke 24:849265425708 87
sschocke 23:3563e1699fb9 88 std::string fwVer = server.GetFirmwareVersion();
sschocke 23:3563e1699fb9 89 pc.printf("ESP Firmware Version: %s\r\n", fwVer.c_str());
sschocke 23:3563e1699fb9 90
sschocke 7:f15c81074400 91 pc.printf("Starting Web Server...\r\n");
sschocke 7:f15c81074400 92 server.Initialize();
sschocke 23:3563e1699fb9 93 pc.printf("Done\r\n");
sschocke 23:3563e1699fb9 94
sschocke 23:3563e1699fb9 95 opMode = server.GetOperatingMode();
sschocke 23:3563e1699fb9 96 pc.printf("Operating Mode: %s(%d)\r\n", opModes[opMode], opMode);
sschocke 23:3563e1699fb9 97 if( (opMode & OPMODE_STATION) ) {
sschocke 23:3563e1699fb9 98 pc.printf("Waiting 5 secs for join to WiFi Network...\r\n");
sschocke 23:3563e1699fb9 99 wait_ms(5000);
sschocke 23:3563e1699fb9 100 stationMAC = server.GetStationMAC();
sschocke 23:3563e1699fb9 101 stationIP = server.GetStationIP();
sschocke 23:3563e1699fb9 102 ssid = server.GetStationSSID();
sschocke 23:3563e1699fb9 103 pc.printf("Station MAC: %s, Station SSID: %s, Station IP: %s\r\n", stationMAC.c_str(), ssid.c_str(), stationIP.c_str());
sschocke 23:3563e1699fb9 104 }
sschocke 23:3563e1699fb9 105 if( (opMode & OPMODE_SOFTAP) ) {
sschocke 23:3563e1699fb9 106 apMAC = server.GetAPMAC();
sschocke 23:3563e1699fb9 107 apIP = server.GetAPIP();
sschocke 23:3563e1699fb9 108 pc.printf("SoftAP MAC: %s, SoftAP IP: %s\r\n", apMAC.c_str(), apIP.c_str());
sschocke 23:3563e1699fb9 109 }
sschocke 23:3563e1699fb9 110
sschocke 13:1e8f27da036a 111 setColor( 0, 25, 0);
tomvdb 4:4a502f72cbe3 112 wait_ms(500);
tomvdb 4:4a502f72cbe3 113 setColor( 0, 0, 0);
tomvdb 4:4a502f72cbe3 114
sschocke 23:3563e1699fb9 115 std::string httpReply;
sschocke 0:d21e3e1c0a4b 116 while(true) {
sschocke 9:319aeb6e0123 117 ESP8266_WebRequest* request = server.GetRequest();
sschocke 9:319aeb6e0123 118 if( request != NULL ) {
sschocke 9:319aeb6e0123 119 pc.printf("HTTP %s %s\r\n", request->Method.c_str(), request->URI.c_str());
sschocke 9:319aeb6e0123 120 for( std::map<std::string,std::string>::iterator it = request->Parameters.begin(); it!=request->Parameters.end(); ++it ) {
sschocke 9:319aeb6e0123 121 pc.printf("HTTP Parameter %s = %s\r\n", it->first.c_str(), it->second.c_str());
sschocke 9:319aeb6e0123 122 }
sschocke 9:319aeb6e0123 123 if( request->URI == "/" ) {
sschocke 23:3563e1699fb9 124 httpReply = htmlHead;
sschocke 23:3563e1699fb9 125 httpReply += "<table><tr><td align='right'><a href='config'><img src='config.gif' /></a></td></tr>";
sschocke 23:3563e1699fb9 126 httpReply += "<tr><td align='center'>";
sschocke 23:3563e1699fb9 127 httpReply += "<img style='margin-right:2px' src='colormap.gif' usemap='#colormap' />";
sschocke 23:3563e1699fb9 128 httpReply += "<map id='colormap' name='colormap'>";
sschocke 23:3563e1699fb9 129 httpReply += "</map></td></tr><tr><td><span onClick=\"changeColor('#000000')\">Turn Off</span></td></tr></table>";
sschocke 23:3563e1699fb9 130 httpReply += htmlTail;
sschocke 23:3563e1699fb9 131 server.SendReply(request->LinkID, httpReply, mimeHTML);
sschocke 23:3563e1699fb9 132 } else if( request->URI == "/config" ) {
sschocke 23:3563e1699fb9 133 if( (opMode & OPMODE_STATION) ) {
sschocke 23:3563e1699fb9 134 stationIP = server.GetStationIP();
sschocke 23:3563e1699fb9 135 ssid = server.GetStationSSID();
sschocke 23:3563e1699fb9 136 }
sschocke 23:3563e1699fb9 137 httpReply = htmlHead;
sschocke 23:3563e1699fb9 138 httpReply += htmlConfigHTML;
sschocke 23:3563e1699fb9 139 httpReply += htmlTail;
sschocke 23:3563e1699fb9 140 httpReply = httpReply.replace(httpReply.find("%opmode1%"), 9, (opMode==1? " selected" : ""));
sschocke 23:3563e1699fb9 141 httpReply = httpReply.replace(httpReply.find("%opmode2%"), 9, (opMode==2? " selected" : ""));
sschocke 23:3563e1699fb9 142 httpReply = httpReply.replace(httpReply.find("%opmode3%"), 9, (opMode==3? " selected" : ""));
sschocke 23:3563e1699fb9 143 httpReply = httpReply.replace(httpReply.find("%stamac%"), 8, stationMAC);
sschocke 23:3563e1699fb9 144 httpReply = httpReply.replace(httpReply.find("%staip%"), 7, stationIP);
sschocke 23:3563e1699fb9 145 httpReply = httpReply.replace(httpReply.find("%apmac%"), 7, apMAC);
sschocke 23:3563e1699fb9 146 httpReply = httpReply.replace(httpReply.find("%apip%"), 6, apIP);
sschocke 23:3563e1699fb9 147 httpReply = httpReply.replace(httpReply.find("%ssid%"), 6, ssid);
sschocke 23:3563e1699fb9 148 server.SendReply(request->LinkID, httpReply, mimeHTML, 0);
sschocke 23:3563e1699fb9 149 } else if( request->URI == "/updateconfig" ) {
sschocke 23:3563e1699fb9 150 bool result = true;
sschocke 23:3563e1699fb9 151 int newOpMode = atoi(request->Parameters["opmode"].c_str());
sschocke 23:3563e1699fb9 152 std::string newSSID = request->Parameters["ssid"];
sschocke 23:3563e1699fb9 153 std::string newPassword = request->Parameters["pwd"];
sschocke 23:3563e1699fb9 154 if( newOpMode != opMode ) {
sschocke 23:3563e1699fb9 155 result = server.SetOperatingMode(newOpMode);
sschocke 23:3563e1699fb9 156 if( result == false ) {
sschocke 23:3563e1699fb9 157 sendConfigJSONReply(request->LinkID, "Error setting Operating Mode");
sschocke 23:3563e1699fb9 158 delete request;
sschocke 23:3563e1699fb9 159 continue;
sschocke 22:6d7a72fab8ff 160 }
sschocke 23:3563e1699fb9 161 opMode = newOpMode;
sschocke 23:3563e1699fb9 162 }
sschocke 23:3563e1699fb9 163 if( (opMode & OPMODE_STATION) ) {
sschocke 23:3563e1699fb9 164 if( (ssid.compare(newSSID) != 0) || (newPassword.empty() == false) ) {
sschocke 23:3563e1699fb9 165 result = server.SetStationSSID(newSSID, newPassword);
sschocke 23:3563e1699fb9 166 if( result == false ) {
sschocke 23:3563e1699fb9 167 sendConfigJSONReply(request->LinkID, "Error connecting to SSID");
sschocke 23:3563e1699fb9 168 delete request;
sschocke 23:3563e1699fb9 169 continue;
sschocke 23:3563e1699fb9 170 }
sschocke 23:3563e1699fb9 171 // Wait for SSID to connect
sschocke 23:3563e1699fb9 172 for( int retries=0; retries < 6; retries++) {
sschocke 23:3563e1699fb9 173 wait_ms(5000);
sschocke 23:3563e1699fb9 174 ssid = server.GetStationSSID();
sschocke 23:3563e1699fb9 175 if( ssid.compare(newSSID) == 0 ) {
sschocke 23:3563e1699fb9 176 break;
sschocke 23:3563e1699fb9 177 }
sschocke 23:3563e1699fb9 178 }
sschocke 23:3563e1699fb9 179 stationIP = server.GetStationIP();
sschocke 22:6d7a72fab8ff 180 }
sschocke 22:6d7a72fab8ff 181 }
sschocke 23:3563e1699fb9 182 sendConfigJSONReply(request->LinkID, "Success");
sschocke 20:f5a6527bfda6 183 } else if( request->URI == "/wifilamp.js" ) {
sschocke 20:f5a6527bfda6 184 server.SendReply(request->LinkID, javascript, strlen(javascript), mimeJavaScript);
sschocke 20:f5a6527bfda6 185 } else if( request->URI == "/wifilamp.css" ) {
sschocke 20:f5a6527bfda6 186 server.SendReply(request->LinkID, css, strlen(css), mimeCSS);
sschocke 22:6d7a72fab8ff 187 } else if( request->URI == "/colormap.gif" ) {
sschocke 23:3563e1699fb9 188 server.SendReply(request->LinkID, (char*)colormap, sizeof(colormap), mimeGIF);
sschocke 23:3563e1699fb9 189 } else if( request->URI == "/config.gif" ) {
sschocke 23:3563e1699fb9 190 server.SendReply(request->LinkID, (char*)configIcon, sizeof(configIcon), mimeGIF);
leet 16:f2f2da9ef9ab 191 } else if( request->URI == "/setcolour" || request->URI == "/setcolor" ) {
sschocke 7:f15c81074400 192 int r=0, g=0, b=0;
sschocke 9:319aeb6e0123 193
sschocke 9:319aeb6e0123 194 if(request->Parameters.count("r") > 0) r=atoi(request->Parameters["r"].c_str());
sschocke 9:319aeb6e0123 195 if(request->Parameters.count("g") > 0) g=atoi(request->Parameters["g"].c_str());
sschocke 9:319aeb6e0123 196 if(request->Parameters.count("b") > 0) b=atoi(request->Parameters["b"].c_str());
sschocke 7:f15c81074400 197
leet 16:f2f2da9ef9ab 198 pc.printf( "Set colour to (%i, %i, %i)\r\n", r,g,b);
sschocke 0:d21e3e1c0a4b 199
sschocke 7:f15c81074400 200 setColor( r,g,b );
sschocke 7:f15c81074400 201
sschocke 23:3563e1699fb9 202 server.SendReply(request->LinkID, "OK", mimeText, 0);
sschocke 7:f15c81074400 203 } else {
sschocke 11:3ab606a42227 204 server.Send404Error(request->LinkID);
sschocke 0:d21e3e1c0a4b 205 }
sschocke 7:f15c81074400 206 pc.printf("\r\nHTTP Reply Sent\r\n");
sschocke 9:319aeb6e0123 207 delete request;
sschocke 0:d21e3e1c0a4b 208 }
sschocke 0:d21e3e1c0a4b 209 }
sschocke 0:d21e3e1c0a4b 210 }