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:
Sun Nov 16 13:28:19 2014 +0000
Revision:
0:d21e3e1c0a4b
Child:
1:f07afcffeb5a
Initial Commit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
sschocke 0:d21e3e1c0a4b 1 #include "mbed.h"
sschocke 0:d21e3e1c0a4b 2 #include <string>
sschocke 0:d21e3e1c0a4b 3 #define DEBUG_WIFI
sschocke 0:d21e3e1c0a4b 4
sschocke 0:d21e3e1c0a4b 5 DigitalOut wifiCHPD(D4);
sschocke 0:d21e3e1c0a4b 6 DigitalOut wifiReset(D9);
sschocke 0:d21e3e1c0a4b 7
sschocke 0:d21e3e1c0a4b 8 int wifiOn = 0;
sschocke 0:d21e3e1c0a4b 9
sschocke 0:d21e3e1c0a4b 10 Serial wifiSerial(D8,D2);
sschocke 0:d21e3e1c0a4b 11 Serial pc(USBTX,USBRX);
sschocke 0:d21e3e1c0a4b 12
sschocke 0:d21e3e1c0a4b 13 char buffer[1024];
sschocke 0:d21e3e1c0a4b 14 char reply[1024];
sschocke 0:d21e3e1c0a4b 15 char response[2048];
sschocke 0:d21e3e1c0a4b 16 char* rxptr = buffer;
sschocke 0:d21e3e1c0a4b 17
sschocke 0:d21e3e1c0a4b 18 void rxint() {
sschocke 0:d21e3e1c0a4b 19 char c = wifiSerial.getc();
sschocke 0:d21e3e1c0a4b 20 if( wifiOn == 0 ) return;
sschocke 0:d21e3e1c0a4b 21 #ifdef DEBUG_WIFI
sschocke 0:d21e3e1c0a4b 22 pc.putc(c);
sschocke 0:d21e3e1c0a4b 23 #endif
sschocke 0:d21e3e1c0a4b 24 *rxptr = c;
sschocke 0:d21e3e1c0a4b 25 rxptr++;
sschocke 0:d21e3e1c0a4b 26 *rxptr = 0;
sschocke 0:d21e3e1c0a4b 27 }
sschocke 0:d21e3e1c0a4b 28
sschocke 0:d21e3e1c0a4b 29 void readBuffer() {
sschocke 0:d21e3e1c0a4b 30 strncpy(reply, buffer, 1024);
sschocke 0:d21e3e1c0a4b 31 rxptr = buffer;
sschocke 0:d21e3e1c0a4b 32 *rxptr = 0;
sschocke 0:d21e3e1c0a4b 33 }
sschocke 0:d21e3e1c0a4b 34
sschocke 0:d21e3e1c0a4b 35 short data_waiting(void)
sschocke 0:d21e3e1c0a4b 36 {
sschocke 0:d21e3e1c0a4b 37 char* ok = strstr(buffer, "OK\r\n");
sschocke 0:d21e3e1c0a4b 38 char* error = strstr(buffer, "ERROR\r\n");
sschocke 0:d21e3e1c0a4b 39 char* nochange = strstr(buffer, "no change\r\n");
sschocke 0:d21e3e1c0a4b 40
sschocke 0:d21e3e1c0a4b 41 if( (ok != NULL) || (error != NULL ) || (nochange != NULL ) )
sschocke 0:d21e3e1c0a4b 42 {
sschocke 0:d21e3e1c0a4b 43 return 1;
sschocke 0:d21e3e1c0a4b 44 }
sschocke 0:d21e3e1c0a4b 45
sschocke 0:d21e3e1c0a4b 46 return 0;
sschocke 0:d21e3e1c0a4b 47 }
sschocke 0:d21e3e1c0a4b 48
sschocke 0:d21e3e1c0a4b 49 short string_waiting(const char* str)
sschocke 0:d21e3e1c0a4b 50 {
sschocke 0:d21e3e1c0a4b 51 char* pr = strstr(buffer, str);
sschocke 0:d21e3e1c0a4b 52 char* error = strstr(buffer, "ERROR\r\n");
sschocke 0:d21e3e1c0a4b 53
sschocke 0:d21e3e1c0a4b 54 if( (pr != NULL) || (error != NULL ) )
sschocke 0:d21e3e1c0a4b 55 {
sschocke 0:d21e3e1c0a4b 56 return 1;
sschocke 0:d21e3e1c0a4b 57 }
sschocke 0:d21e3e1c0a4b 58
sschocke 0:d21e3e1c0a4b 59 return 0;
sschocke 0:d21e3e1c0a4b 60 }
sschocke 0:d21e3e1c0a4b 61
sschocke 0:d21e3e1c0a4b 62 int main() {
sschocke 0:d21e3e1c0a4b 63 pc.printf("WiFi Lamp Test...\r\n");
sschocke 0:d21e3e1c0a4b 64 wifiCHPD = 0;
sschocke 0:d21e3e1c0a4b 65 wifiReset = 0;
sschocke 0:d21e3e1c0a4b 66 wifiSerial.baud(9600);
sschocke 0:d21e3e1c0a4b 67 wifiSerial.attach(&rxint);
sschocke 0:d21e3e1c0a4b 68 wait_ms(1000);
sschocke 0:d21e3e1c0a4b 69
sschocke 0:d21e3e1c0a4b 70 pc.printf("Powering WiFi...\r\n");
sschocke 0:d21e3e1c0a4b 71 wifiCHPD = 1;
sschocke 0:d21e3e1c0a4b 72 wait_ms(250);
sschocke 0:d21e3e1c0a4b 73 pc.printf("Hardware Reset WiFi...\r\n");
sschocke 0:d21e3e1c0a4b 74 wifiReset = 1;
sschocke 0:d21e3e1c0a4b 75 wifiOn = 1;
sschocke 0:d21e3e1c0a4b 76 readBuffer();
sschocke 0:d21e3e1c0a4b 77 while( string_waiting("\r\nready\r\n") == 0 ) {
sschocke 0:d21e3e1c0a4b 78 wait_ms(10);
sschocke 0:d21e3e1c0a4b 79 }
sschocke 0:d21e3e1c0a4b 80 readBuffer();
sschocke 0:d21e3e1c0a4b 81
sschocke 0:d21e3e1c0a4b 82 pc.printf("Starting WiFi...\r\n");
sschocke 0:d21e3e1c0a4b 83 pc.printf("Setting Operating Mode...");
sschocke 0:d21e3e1c0a4b 84 wifiSerial.printf("AT+CWMODE=3\r\n");
sschocke 0:d21e3e1c0a4b 85 while( data_waiting() == 0 ) {
sschocke 0:d21e3e1c0a4b 86 wait_ms(10);
sschocke 0:d21e3e1c0a4b 87 }
sschocke 0:d21e3e1c0a4b 88 readBuffer();
sschocke 0:d21e3e1c0a4b 89
sschocke 0:d21e3e1c0a4b 90 pc.printf("Done\r\nAccept Multiple connections...");
sschocke 0:d21e3e1c0a4b 91 wifiSerial.printf("AT+CIPMUX=1\r\n");
sschocke 0:d21e3e1c0a4b 92 while( data_waiting() == 0 ) {
sschocke 0:d21e3e1c0a4b 93 wait_ms(10);
sschocke 0:d21e3e1c0a4b 94 }
sschocke 0:d21e3e1c0a4b 95 readBuffer();
sschocke 0:d21e3e1c0a4b 96
sschocke 0:d21e3e1c0a4b 97 pc.printf("Done\r\nStarting Web Server...");
sschocke 0:d21e3e1c0a4b 98 wifiSerial.printf("AT+CIPSERVER=1,80\r\n");
sschocke 0:d21e3e1c0a4b 99 while( data_waiting() == 0 ) {
sschocke 0:d21e3e1c0a4b 100 wait_ms(10);
sschocke 0:d21e3e1c0a4b 101 }
sschocke 0:d21e3e1c0a4b 102 readBuffer();
sschocke 0:d21e3e1c0a4b 103
sschocke 0:d21e3e1c0a4b 104 pc.printf("Done\r\n");
sschocke 0:d21e3e1c0a4b 105
sschocke 0:d21e3e1c0a4b 106 while(true) {
sschocke 0:d21e3e1c0a4b 107 if( (string_waiting("+IPD") == 1) && (string_waiting("\r\nOK\r\n") == 1) ) {
sschocke 0:d21e3e1c0a4b 108 pc.printf("\r\nGot Data\r\n");
sschocke 0:d21e3e1c0a4b 109 readBuffer();
sschocke 0:d21e3e1c0a4b 110
sschocke 0:d21e3e1c0a4b 111 char* ipdPacket = strstr(reply, "+IPD");
sschocke 0:d21e3e1c0a4b 112 int linkID, bytesRecv, ipdLen;
sschocke 0:d21e3e1c0a4b 113 int numMatched = sscanf(ipdPacket,"+IPD,%d,%d:%n", &linkID, &bytesRecv, &ipdLen);
sschocke 0:d21e3e1c0a4b 114 if( numMatched != 2 ) {
sschocke 0:d21e3e1c0a4b 115 pc.printf("IPD ERROR : Matched %d, LinkID=%d, BytesRecv=%d, IPD Header Len=%d\r\n", numMatched, linkID, bytesRecv, ipdLen);
sschocke 0:d21e3e1c0a4b 116 continue;
sschocke 0:d21e3e1c0a4b 117 }
sschocke 0:d21e3e1c0a4b 118
sschocke 0:d21e3e1c0a4b 119 pc.printf("IPD Data: LinkID=%d, BytesRecv=%d, IPD Header Len=%d\r\n", linkID, bytesRecv, ipdLen);
sschocke 0:d21e3e1c0a4b 120 if( strstr(ipdPacket, "HTTP") != NULL ) {
sschocke 0:d21e3e1c0a4b 121 pc.printf("Got HTTP Request\r\n");
sschocke 0:d21e3e1c0a4b 122 char* httpPacket = ipdPacket + ipdLen;
sschocke 0:d21e3e1c0a4b 123 pc.printf("HTTP Packet: %s\r\n", httpPacket);
sschocke 0:d21e3e1c0a4b 124
sschocke 0:d21e3e1c0a4b 125 std::string httpReply = "<html><head><title>WiFi Lamp</title></head><body><h1>The WiFi Lamp is alive</h1></body></html>";
sschocke 0:d21e3e1c0a4b 126 std::string httpReplyPacket = "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\nContent-Length: %d\r\n\r\n%s";
sschocke 0:d21e3e1c0a4b 127
sschocke 0:d21e3e1c0a4b 128 sprintf(response, httpReplyPacket.c_str(), httpReply.length(), httpReply.c_str());
sschocke 0:d21e3e1c0a4b 129 int bytes = strlen(response);
sschocke 0:d21e3e1c0a4b 130 pc.printf("HTTP Reply Packet(%d bytes): %s\r\n", bytes, response);
sschocke 0:d21e3e1c0a4b 131 wifiSerial.printf("AT+CIPSEND=%d,%d\r\n", linkID, bytes);
sschocke 0:d21e3e1c0a4b 132 wait_ms(500);
sschocke 0:d21e3e1c0a4b 133 if( (string_waiting("\r\n>") == 1) ) {
sschocke 0:d21e3e1c0a4b 134 wifiSerial.printf(response);
sschocke 0:d21e3e1c0a4b 135 }
sschocke 0:d21e3e1c0a4b 136 while( string_waiting("\r\nSEND OK\r\n") == 0 ) {
sschocke 0:d21e3e1c0a4b 137 wait_ms(10);
sschocke 0:d21e3e1c0a4b 138 }
sschocke 0:d21e3e1c0a4b 139 pc.printf("\r\nHTTP Reply Sent\r\n");
sschocke 0:d21e3e1c0a4b 140 }
sschocke 0:d21e3e1c0a4b 141 }
sschocke 0:d21e3e1c0a4b 142 wait_ms(10);
sschocke 0:d21e3e1c0a4b 143 }
sschocke 0:d21e3e1c0a4b 144 }