LeeT WiFiLamp code and test

Dependencies:   ESP8266_WebServer mbed

Fork of WiFiLamp by Sebastian Schocke

main.cpp

Committer:
leet
Date:
2015-01-07
Revision:
26:ea5e0ff46492
Parent:
25:841fc9daffa5

File content as of revision 26:ea5e0ff46492:

#include "mbed.h"
#include "PololuLedStrip.h"
#include "ESP8266_WebServer.h"
#include "resource.h"
#include <string>
//#define DEBUG_WIFI

PololuLedStrip ledStrip(D11);

#define LED_COUNT 8
rgb_color colors[LED_COUNT];

DigitalOut wifiCHPD(D4);
DigitalOut wifiReset(D9);

int wifiOn = 0;
int opMode = 0;
std::string stationMAC;
std::string stationIP;
std::string ssid;
std::string apMAC;
std::string apIP;

Serial wifiSerial(D8,D2);
Serial pc(USBTX,USBRX);
ESP8266_WebServer server(&wifiSerial);

char temp[200];
const char* VERSION = "0.5-alpha";

#ifdef DEBUG_WIFI
void pcrxint(void) {
    //server.debugBuffers(&pc);
    pc.putc('@');
    server.echoMode = true;
}
#endif

void rxint(void) {
    server.rxint();
}

void setColor( uint8_t r, uint8_t g, uint8_t b )
{
    for ( int c = 0; c < LED_COUNT; c++ )
    {
        colors[c].red = r;
        colors[c].green = g;
        colors[c].blue = b;
    }
    
    ledStrip.write(colors, LED_COUNT);
}

void setDiscoColor( )
{
    for ( int c = 0; c < LED_COUNT; c++ )
    {
        colors[c].red = rand()%255;
        colors[c].green = rand()%255;
        colors[c].blue = rand()%255;
    }
    
    ledStrip.write(colors, LED_COUNT);
}

Timer DiscoTimer;
#define DiscoDelay 100

int lampMode = 0;

unsigned long heapSize()
{
    char   stackVariable;
    void   *heap;
    unsigned long result;
    heap  = malloc(4);
    result  = (uint8_t*)&stackVariable - (uint8_t*)heap;
    free(heap);
    return result;
}

void sendConfigJSONReply(int linkID, const char* result) {
    sprintf(temp, jsonConfigReply, opMode, stationIP.c_str(), ssid.c_str(), result);
    server.SendReply(linkID, temp, mimeJSON, 0);
}

int main() {
    pc.baud(115200);
#ifdef DEBUG_WIFI
    pc.attach(&pcrxint);
#endif
    
    pc.printf("\r\nWiFi Lamp - %s...\r\n", VERSION);    
    
    setColor( 25, 0, 0);
    
    wifiCHPD = 0;
    wifiReset = 0;
    wifiSerial.baud(115200);
    wifiSerial.attach(&rxint);
#ifdef DEBUG_WIFI
    server.debugSerial = &pc;
    pc.printf("Debug WiFi Enabled!\r\n");
#endif
    wait_ms(1000);
    
    pc.printf("Powering WiFi...\r\n");    
    wifiCHPD = 1;
    wifiReset = 1;
    wait_ms(250);
    pc.printf("Hardware Reset WiFi...\r\n");    
    server.ResetModule();
    wifiOn = 1;
    
    std::string fwVer = server.GetFirmwareVersion();
    pc.printf("ESP Firmware Version: %s\r\n", fwVer.c_str());
    
    pc.printf("Starting Web Server...\r\n");
    server.Initialize();
    pc.printf("Done\r\n");
    
    opMode = server.GetOperatingMode();
    pc.printf("Operating Mode: %s(%d)\r\n", opModes[opMode], opMode);
    if( (opMode & OPMODE_STATION) ) {
        pc.printf("Waiting 5 secs for join to WiFi Network...\r\n");
        wait_ms(5000);
        stationMAC = server.GetStationMAC();
        stationIP = server.GetStationIP();
        ssid = server.GetStationSSID();
        pc.printf("Station MAC: %s, Station SSID: %s, Station IP: %s\r\n", stationMAC.c_str(), ssid.c_str(), stationIP.c_str());
    }
    if( (opMode & OPMODE_SOFTAP) ) {
        apMAC = server.GetAPMAC();
        apIP = server.GetAPIP();
        pc.printf("SoftAP MAC: %s, SoftAP IP: %s\r\n", apMAC.c_str(), apIP.c_str());
    }
    
    setColor( 0, 25, 0);
    wait_ms(500);
    setColor( 0, 0, 0);
    
    pc.printf("Heap Memory %d", heapSize());
    DiscoTimer.start();
                    
    std::string httpReply;
    while(true) {
        ESP8266_WebRequest* request = server.GetRequest();
        if( request != NULL ) {
            pc.printf("HTTP %s %s\r\n", request->Method.c_str(), request->URI.c_str());
            for( std::map<std::string,std::string>::iterator it = request->Parameters.begin(); it!=request->Parameters.end(); ++it ) {
                pc.printf("HTTP Parameter %s = %s\r\n", it->first.c_str(), it->second.c_str());
            }
            if( request->URI == "/" || request->URI == "/index.html" ) {
                httpReply = htmlHead;
                httpReply += "<table><tr><td align='right'><a href='config'><img src='config.gif' /></a></td></tr>";
                httpReply += "<tr><td align='center'>";
                httpReply += "<img style='margin-right:2px' src='colormap.gif' usemap='#colormap' />";
                httpReply += "<map id='colormap' name='colormap'>";
                httpReply += "</map></td></tr><tr><td><span onClick=\"changeColor('#000000')\">Turn Off</span></td></tr></table>";
                httpReply += htmlTail;
                server.SendReply(request->LinkID, httpReply, mimeHTML);
            } else if( request->URI == "/config" ) {
                if( (opMode & OPMODE_STATION) ) {
                    stationIP = server.GetStationIP();
                    ssid = server.GetStationSSID();
                }
                httpReply = htmlHead;
                httpReply += htmlConfigHTML;
                httpReply += htmlTail;
                httpReply = httpReply.replace(httpReply.find("%opmode1%"), 9, (opMode==1? " selected" : ""));
                httpReply = httpReply.replace(httpReply.find("%opmode2%"), 9, (opMode==2? " selected" : ""));
                httpReply = httpReply.replace(httpReply.find("%opmode3%"), 9, (opMode==3? " selected" : ""));
                httpReply = httpReply.replace(httpReply.find("%stamac%"), 8, stationMAC);
                httpReply = httpReply.replace(httpReply.find("%staip%"), 7, stationIP);
                httpReply = httpReply.replace(httpReply.find("%apmac%"), 7, apMAC);
                httpReply = httpReply.replace(httpReply.find("%apip%"), 6, apIP);
                httpReply = httpReply.replace(httpReply.find("%ssid%"), 6, ssid);
                server.SendReply(request->LinkID, httpReply, mimeHTML, 0);
            } else if( request->URI == "/updateconfig" ) {
                bool result = true;
                int newOpMode = atoi(request->Parameters["opmode"].c_str());
                std::string newSSID = request->Parameters["ssid"];
                std::string newPassword = request->Parameters["pwd"];
                if( newOpMode != opMode ) {
                    result = server.SetOperatingMode(newOpMode);
                    if( result == false ) {
                        sendConfigJSONReply(request->LinkID, "Error setting Operating Mode");
                        delete request;
                        continue;
                    }
                    opMode = newOpMode;
                }
                if( (opMode & OPMODE_STATION) ) {
                    if( (ssid.compare(newSSID) != 0) || (newPassword.empty() == false) ) {
                        result = server.SetStationSSID(newSSID, newPassword);
                        if( result == false ) {
                            sendConfigJSONReply(request->LinkID, "Error connecting to SSID");
                            delete request;
                            continue;
                        }
                        // Wait for SSID to connect
                        for( int retries=0; retries < 6; retries++) {
                            wait_ms(5000);
                            ssid = server.GetStationSSID();
                            if( ssid.compare(newSSID) == 0 ) {
                                break;
                            }
                        }
                        stationIP = server.GetStationIP();
                    }
                }
                sendConfigJSONReply(request->LinkID, "Success");
            } else if( request->URI == "/wifilamp.js" ) {
                server.SendReply(request->LinkID, javascript, strlen(javascript), mimeJavaScript);
            } else if( request->URI == "/wifilamp.css" ) {
                server.SendReply(request->LinkID, css, strlen(css), mimeCSS);
            } else if( request->URI == "/colormap.gif" ) {
                server.SendReply(request->LinkID, (char*)colorMap, sizeof(colorMap), mimeGIF);
            } else if( request->URI == "/config.gif" ) {
                server.SendReply(request->LinkID, (char*)configIcon, sizeof(configIcon), mimeGIF);
           } else if( request->URI == "/robtos.txt" ) {
                server.SendReply(request->LinkID, robotsTxt, strlen(robotsTxt), mimeText);
            } else if( request->URI == "/favicon.ico" ) {
                server.SendReply(request->LinkID, (char*)favIcon, sizeof(favIcon), "image/x-icon");
            } else if( request->URI == "/disco" ) {
                lampMode = 2; // All colours
                DiscoTimer.reset();
                server.SendReply(request->LinkID, "OK", mimeText, 0);
            } else if( request->URI == "/setcolour" || request->URI == "/setcolor" ) {
                int r=0, g=0, b=0;

                lampMode = 1; // All LED 1 colour                
                
                if(request->Parameters.count("r") > 0) r=atoi(request->Parameters["r"].c_str());
                if(request->Parameters.count("g") > 0) g=atoi(request->Parameters["g"].c_str());
                if(request->Parameters.count("b") > 0) b=atoi(request->Parameters["b"].c_str());
                
                pc.printf( "Set colour to (%i, %i, %i)\r\n", r,g,b);
                
                setColor( r,g,b );
                
                server.SendReply(request->LinkID, "OK", mimeText, 0);
            } else {
                server.Send404Error(request->LinkID);
            }
            pc.printf("\r\nHTTP Reply Sent\r\n");
            delete request;
        }
        if( lampMode == 2 && DiscoTimer.read_ms() > DiscoDelay ) {
            setDiscoColor();
            // Delay random colour change, else it just looks white
            DiscoTimer.reset();
        }
/*
        if( lampMode == 3 ) {
            // strobe
        }

        if( lampMode == 4 ) {
            // fade
        }

*/
    }
}