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:
Thu Nov 20 17:44:22 2014 +0000
Revision:
1:f07afcffeb5a
Parent:
0:d21e3e1c0a4b
Child:
4:4a502f72cbe3
Extracting URI and Pololu LED Intergation

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 0:d21e3e1c0a4b 3 #include <string>
sschocke 0:d21e3e1c0a4b 4 #define DEBUG_WIFI
sschocke 0:d21e3e1c0a4b 5
sschocke 1:f07afcffeb5a 6 PololuLedStrip ledStrip(PA_7);
sschocke 1:f07afcffeb5a 7
sschocke 1:f07afcffeb5a 8 #define LED_COUNT 4
sschocke 1:f07afcffeb5a 9 rgb_color colors[LED_COUNT];
sschocke 1:f07afcffeb5a 10
sschocke 0:d21e3e1c0a4b 11 DigitalOut wifiCHPD(D4);
sschocke 0:d21e3e1c0a4b 12 DigitalOut wifiReset(D9);
sschocke 0:d21e3e1c0a4b 13
sschocke 0:d21e3e1c0a4b 14 int wifiOn = 0;
sschocke 0:d21e3e1c0a4b 15
sschocke 0:d21e3e1c0a4b 16 Serial wifiSerial(D8,D2);
sschocke 0:d21e3e1c0a4b 17 Serial pc(USBTX,USBRX);
sschocke 0:d21e3e1c0a4b 18
sschocke 0:d21e3e1c0a4b 19 char buffer[1024];
sschocke 0:d21e3e1c0a4b 20 char reply[1024];
sschocke 0:d21e3e1c0a4b 21 char response[2048];
sschocke 1:f07afcffeb5a 22 char httpMethod[64];
sschocke 1:f07afcffeb5a 23 char httpURI[512];
sschocke 0:d21e3e1c0a4b 24 char* rxptr = buffer;
sschocke 0:d21e3e1c0a4b 25
sschocke 0:d21e3e1c0a4b 26 void rxint() {
sschocke 0:d21e3e1c0a4b 27 char c = wifiSerial.getc();
sschocke 0:d21e3e1c0a4b 28 if( wifiOn == 0 ) return;
sschocke 0:d21e3e1c0a4b 29 #ifdef DEBUG_WIFI
sschocke 0:d21e3e1c0a4b 30 pc.putc(c);
sschocke 0:d21e3e1c0a4b 31 #endif
sschocke 0:d21e3e1c0a4b 32 *rxptr = c;
sschocke 0:d21e3e1c0a4b 33 rxptr++;
sschocke 0:d21e3e1c0a4b 34 *rxptr = 0;
sschocke 0:d21e3e1c0a4b 35 }
sschocke 0:d21e3e1c0a4b 36
sschocke 0:d21e3e1c0a4b 37 void readBuffer() {
sschocke 0:d21e3e1c0a4b 38 strncpy(reply, buffer, 1024);
sschocke 0:d21e3e1c0a4b 39 rxptr = buffer;
sschocke 0:d21e3e1c0a4b 40 *rxptr = 0;
sschocke 0:d21e3e1c0a4b 41 }
sschocke 0:d21e3e1c0a4b 42
sschocke 0:d21e3e1c0a4b 43 short data_waiting(void)
sschocke 0:d21e3e1c0a4b 44 {
sschocke 0:d21e3e1c0a4b 45 char* ok = strstr(buffer, "OK\r\n");
sschocke 0:d21e3e1c0a4b 46 char* error = strstr(buffer, "ERROR\r\n");
sschocke 0:d21e3e1c0a4b 47 char* nochange = strstr(buffer, "no change\r\n");
sschocke 0:d21e3e1c0a4b 48
sschocke 0:d21e3e1c0a4b 49 if( (ok != NULL) || (error != NULL ) || (nochange != NULL ) )
sschocke 0:d21e3e1c0a4b 50 {
sschocke 0:d21e3e1c0a4b 51 return 1;
sschocke 0:d21e3e1c0a4b 52 }
sschocke 0:d21e3e1c0a4b 53
sschocke 0:d21e3e1c0a4b 54 return 0;
sschocke 0:d21e3e1c0a4b 55 }
sschocke 0:d21e3e1c0a4b 56
sschocke 0:d21e3e1c0a4b 57 short string_waiting(const char* str)
sschocke 0:d21e3e1c0a4b 58 {
sschocke 0:d21e3e1c0a4b 59 char* pr = strstr(buffer, str);
sschocke 0:d21e3e1c0a4b 60 char* error = strstr(buffer, "ERROR\r\n");
sschocke 0:d21e3e1c0a4b 61
sschocke 0:d21e3e1c0a4b 62 if( (pr != NULL) || (error != NULL ) )
sschocke 0:d21e3e1c0a4b 63 {
sschocke 0:d21e3e1c0a4b 64 return 1;
sschocke 0:d21e3e1c0a4b 65 }
sschocke 0:d21e3e1c0a4b 66
sschocke 0:d21e3e1c0a4b 67 return 0;
sschocke 0:d21e3e1c0a4b 68 }
sschocke 0:d21e3e1c0a4b 69
sschocke 0:d21e3e1c0a4b 70 int main() {
sschocke 0:d21e3e1c0a4b 71 pc.printf("WiFi Lamp Test...\r\n");
sschocke 1:f07afcffeb5a 72 colors[0].red = 0;
sschocke 1:f07afcffeb5a 73 colors[0].green = 0;
sschocke 1:f07afcffeb5a 74 colors[0].blue = 0;
sschocke 1:f07afcffeb5a 75 colors[1].red = 0;
sschocke 1:f07afcffeb5a 76 colors[1].green = 0;
sschocke 1:f07afcffeb5a 77 colors[1].blue = 0;
sschocke 1:f07afcffeb5a 78 colors[2].red = 0;
sschocke 1:f07afcffeb5a 79 colors[2].green = 0;
sschocke 1:f07afcffeb5a 80 colors[2].blue = 0;
sschocke 1:f07afcffeb5a 81 colors[3].red = 0;
sschocke 1:f07afcffeb5a 82 colors[3].green = 0;
sschocke 1:f07afcffeb5a 83 colors[3].blue = 0;
sschocke 0:d21e3e1c0a4b 84 wifiCHPD = 0;
sschocke 0:d21e3e1c0a4b 85 wifiReset = 0;
sschocke 0:d21e3e1c0a4b 86 wifiSerial.baud(9600);
sschocke 0:d21e3e1c0a4b 87 wifiSerial.attach(&rxint);
sschocke 1:f07afcffeb5a 88 ledStrip.write(colors, LED_COUNT);
sschocke 0:d21e3e1c0a4b 89 wait_ms(1000);
sschocke 0:d21e3e1c0a4b 90
sschocke 0:d21e3e1c0a4b 91 pc.printf("Powering WiFi...\r\n");
sschocke 0:d21e3e1c0a4b 92 wifiCHPD = 1;
sschocke 0:d21e3e1c0a4b 93 wait_ms(250);
sschocke 0:d21e3e1c0a4b 94 pc.printf("Hardware Reset WiFi...\r\n");
sschocke 0:d21e3e1c0a4b 95 wifiReset = 1;
sschocke 0:d21e3e1c0a4b 96 wifiOn = 1;
sschocke 0:d21e3e1c0a4b 97 readBuffer();
sschocke 0:d21e3e1c0a4b 98 while( string_waiting("\r\nready\r\n") == 0 ) {
sschocke 0:d21e3e1c0a4b 99 wait_ms(10);
sschocke 0:d21e3e1c0a4b 100 }
sschocke 0:d21e3e1c0a4b 101 readBuffer();
sschocke 0:d21e3e1c0a4b 102
sschocke 0:d21e3e1c0a4b 103 pc.printf("Starting WiFi...\r\n");
sschocke 0:d21e3e1c0a4b 104 pc.printf("Setting Operating Mode...");
sschocke 0:d21e3e1c0a4b 105 wifiSerial.printf("AT+CWMODE=3\r\n");
sschocke 0:d21e3e1c0a4b 106 while( data_waiting() == 0 ) {
sschocke 0:d21e3e1c0a4b 107 wait_ms(10);
sschocke 0:d21e3e1c0a4b 108 }
sschocke 0:d21e3e1c0a4b 109 readBuffer();
sschocke 0:d21e3e1c0a4b 110
sschocke 0:d21e3e1c0a4b 111 pc.printf("Done\r\nAccept Multiple connections...");
sschocke 0:d21e3e1c0a4b 112 wifiSerial.printf("AT+CIPMUX=1\r\n");
sschocke 0:d21e3e1c0a4b 113 while( data_waiting() == 0 ) {
sschocke 0:d21e3e1c0a4b 114 wait_ms(10);
sschocke 0:d21e3e1c0a4b 115 }
sschocke 0:d21e3e1c0a4b 116 readBuffer();
sschocke 0:d21e3e1c0a4b 117
sschocke 0:d21e3e1c0a4b 118 pc.printf("Done\r\nStarting Web Server...");
sschocke 0:d21e3e1c0a4b 119 wifiSerial.printf("AT+CIPSERVER=1,80\r\n");
sschocke 0:d21e3e1c0a4b 120 while( data_waiting() == 0 ) {
sschocke 0:d21e3e1c0a4b 121 wait_ms(10);
sschocke 0:d21e3e1c0a4b 122 }
sschocke 0:d21e3e1c0a4b 123 readBuffer();
sschocke 0:d21e3e1c0a4b 124
sschocke 0:d21e3e1c0a4b 125 pc.printf("Done\r\n");
sschocke 0:d21e3e1c0a4b 126
sschocke 0:d21e3e1c0a4b 127 while(true) {
sschocke 0:d21e3e1c0a4b 128 if( (string_waiting("+IPD") == 1) && (string_waiting("\r\nOK\r\n") == 1) ) {
sschocke 0:d21e3e1c0a4b 129 pc.printf("\r\nGot Data\r\n");
sschocke 0:d21e3e1c0a4b 130 readBuffer();
sschocke 0:d21e3e1c0a4b 131
sschocke 0:d21e3e1c0a4b 132 char* ipdPacket = strstr(reply, "+IPD");
sschocke 0:d21e3e1c0a4b 133 int linkID, bytesRecv, ipdLen;
sschocke 0:d21e3e1c0a4b 134 int numMatched = sscanf(ipdPacket,"+IPD,%d,%d:%n", &linkID, &bytesRecv, &ipdLen);
sschocke 0:d21e3e1c0a4b 135 if( numMatched != 2 ) {
sschocke 0:d21e3e1c0a4b 136 pc.printf("IPD ERROR : Matched %d, LinkID=%d, BytesRecv=%d, IPD Header Len=%d\r\n", numMatched, linkID, bytesRecv, ipdLen);
sschocke 0:d21e3e1c0a4b 137 continue;
sschocke 0:d21e3e1c0a4b 138 }
sschocke 0:d21e3e1c0a4b 139
sschocke 0:d21e3e1c0a4b 140 pc.printf("IPD Data: LinkID=%d, BytesRecv=%d, IPD Header Len=%d\r\n", linkID, bytesRecv, ipdLen);
sschocke 0:d21e3e1c0a4b 141 if( strstr(ipdPacket, "HTTP") != NULL ) {
sschocke 0:d21e3e1c0a4b 142 pc.printf("Got HTTP Request\r\n");
sschocke 0:d21e3e1c0a4b 143 char* httpPacket = ipdPacket + ipdLen;
sschocke 1:f07afcffeb5a 144 //pc.printf("HTTP Packet: %s\r\n", httpPacket);
sschocke 1:f07afcffeb5a 145
sschocke 1:f07afcffeb5a 146 numMatched = sscanf(httpPacket, "%s %s HTTP/%*c.%*c", httpMethod, httpURI);
sschocke 1:f07afcffeb5a 147 if( numMatched != 2 ) {
sschocke 1:f07afcffeb5a 148 pc.printf("HTTP ERROR : Matched %d, Method=%s, URI=%s\r\n", numMatched, httpMethod, httpURI);
sschocke 1:f07afcffeb5a 149 continue;
sschocke 1:f07afcffeb5a 150 }
sschocke 1:f07afcffeb5a 151 pc.printf("HTTP %s %s\r\n", httpMethod, httpURI);
sschocke 1:f07afcffeb5a 152
sschocke 1:f07afcffeb5a 153 std::string method = httpMethod;
sschocke 1:f07afcffeb5a 154 std::string uri = httpURI;
sschocke 0:d21e3e1c0a4b 155
sschocke 1:f07afcffeb5a 156 std::string httpReply;
sschocke 1:f07afcffeb5a 157 std::string httpReplyPacket;
sschocke 1:f07afcffeb5a 158 if( uri == "/" ) {
sschocke 1:f07afcffeb5a 159 httpReply = "<html><head><title>WiFi Lamp</title></head><body><h1>The WiFi Lamp is alive(<a href='/red'>Red</a>)</h1></body></html>";
sschocke 1:f07afcffeb5a 160 httpReplyPacket = "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\nContent-Length: %d\r\n\r\n%s";
sschocke 1:f07afcffeb5a 161 colors[0].red = 0;
sschocke 1:f07afcffeb5a 162 colors[0].green = 0;
sschocke 1:f07afcffeb5a 163 colors[0].blue = 0;
sschocke 1:f07afcffeb5a 164 ledStrip.write(colors, LED_COUNT);
sschocke 1:f07afcffeb5a 165 } else if( uri == "/red" ) {
sschocke 1:f07afcffeb5a 166 httpReply = "<html><head><title>WiFi Lamp</title></head><body><h1>The WiFi Lamp(Red) is alive(<a href='/'>Off</a>)</h1></body></html>";
sschocke 1:f07afcffeb5a 167 httpReplyPacket = "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\nContent-Length: %d\r\n\r\n%s";
sschocke 1:f07afcffeb5a 168 colors[0].red = 64;
sschocke 1:f07afcffeb5a 169 colors[0].green = 0;
sschocke 1:f07afcffeb5a 170 colors[0].blue = 0;
sschocke 1:f07afcffeb5a 171 ledStrip.write(colors, LED_COUNT);
sschocke 1:f07afcffeb5a 172 } else {
sschocke 1:f07afcffeb5a 173 httpReply = "404 Not Found";
sschocke 1:f07afcffeb5a 174 httpReplyPacket = "HTTP/1.1 404 Not Found\r\nContent-Type: text/html\r\nContent-Length: %d\r\n\r\n%s";
sschocke 1:f07afcffeb5a 175 }
sschocke 0:d21e3e1c0a4b 176
sschocke 0:d21e3e1c0a4b 177 sprintf(response, httpReplyPacket.c_str(), httpReply.length(), httpReply.c_str());
sschocke 0:d21e3e1c0a4b 178 int bytes = strlen(response);
sschocke 0:d21e3e1c0a4b 179 pc.printf("HTTP Reply Packet(%d bytes): %s\r\n", bytes, response);
sschocke 0:d21e3e1c0a4b 180 wifiSerial.printf("AT+CIPSEND=%d,%d\r\n", linkID, bytes);
sschocke 0:d21e3e1c0a4b 181 wait_ms(500);
sschocke 0:d21e3e1c0a4b 182 if( (string_waiting("\r\n>") == 1) ) {
sschocke 0:d21e3e1c0a4b 183 wifiSerial.printf(response);
sschocke 0:d21e3e1c0a4b 184 }
sschocke 0:d21e3e1c0a4b 185 while( string_waiting("\r\nSEND OK\r\n") == 0 ) {
sschocke 0:d21e3e1c0a4b 186 wait_ms(10);
sschocke 0:d21e3e1c0a4b 187 }
sschocke 0:d21e3e1c0a4b 188 pc.printf("\r\nHTTP Reply Sent\r\n");
sschocke 0:d21e3e1c0a4b 189 }
sschocke 0:d21e3e1c0a4b 190 }
sschocke 1:f07afcffeb5a 191
sschocke 0:d21e3e1c0a4b 192 wait_ms(10);
sschocke 0:d21e3e1c0a4b 193 }
sschocke 0:d21e3e1c0a4b 194 }