Spidey Wall is the name for a physical wall lit up by multiple addressable LED strips. This program is an LPC1768 web server to control the wall from a browser.

Dependencies:   EthernetInterfacePlusHostname RdWebServer mbed-rtos mbed

This project is part of a Light-Wall using addressable LED strips (WS2801). I have published a few posts on my blog about the construction of the wall and building a game to play on it (PacMan). I have also had a guest post from a friend who has set his children the task of producing some interesting animations. The original post is http://robdobson.com/2015/07/spidey-wall/ /media/uploads/Bobty/20130722_112945_img_9674_62895-1184x1579.jpg

So far, however, I hadn't fully connected the physical (and electronic) wall with the web-browser creations to drive it. This project is hopefully the final link. A fast and reliable web server using REST commands to drive the 1686 LEDs in the Spidey Wall from code running in a browser (say on an iPad while you are playing a game).

The approach taken here results in the ability to control the RGB values of all 1686 LEDs at a rate of 20 frames per second.

A blog post describing the whole thing is here:

http://robdobson.com/2015/08/a-reliable-mbed-webserver/

Revision:
1:362331cec9b7
Parent:
0:887096209439
Child:
2:99eb4c6e9ea4
--- a/main.cpp	Tue Aug 18 16:03:29 2015 +0000
+++ b/main.cpp	Thu Aug 20 07:41:02 2015 +0000
@@ -1,170 +1,230 @@
-/* main.cpp
-   Rob Dobson 2013
-   More details at ???
-*/
+// 
+// Spidey Wall WebServer
+// 
+// Rob Dobson 2015
 
 #include "mbed.h"
 #include "EthernetInterface.h"
-#include <stdio.h>
+#include "RdWebServer.h"
+#include "DrawingManager.h"
 #include <string.h>
-#include "RdWebServer.h"
-#include "ledstrip.h"
-#include "LedCmdHandler.h"
+
+// Web port
+const int WEBPORT = 80; // Port for web server
 
-#define PORT   80
-
-Serial pc(USBTX, USBRX);
+// Debugging and status
+RawSerial pc(USBTX, USBRX);
+DigitalOut led1(LED1); // ticking (flashes)
+DigitalOut led2(LED2); //
+DigitalOut led3(LED3); //
+DigitalOut led4(LED4); // web server status
 
-RdWebServer webServer;
-
-EthernetInterface eth;
+// Drawing Manager
+DrawingManager drawingManager(1686, 780);
 
-DigitalOut led1(LED1); //server listning status
-DigitalOut led2(LED2); //socket connecting status
-
-Ticker ledTick;
+//int ledsCount = 904;
+//int ledSplitPoint = 448;
+//ledstrip* pLedStrip = NULL;
+//
+//char* indexHtmName = "index.htm";
+//
+//const int TICK_MS = 100;
+//LedCmdHandler* pLedCmdHandler = NULL;
+//int blinkCtr = 0;
+//
+//void ledTickfunc()
+//{
+//    if(webServer.isListening())
+//    {
+//        blinkCtr++;
+//        if (blinkCtr > 1)
+//        {
+//            led1 = !led1;
+//            blinkCtr = 0;
+//        }
+//    }
+//    else
+//    {
+//        led1 = false;
+//    }
+//    
+//    if (pLedCmdHandler != NULL)
+//        pLedCmdHandler->NextGen();
+//}
+//
+//void handleCmd_ledControl(char* cmdStr, char* argStr)
+//{
+//    printf("LEDS COMMAND %s %s\r\n", cmdStr, argStr);
+//    if (argStr == NULL)
+//        return;
+//    pLedCmdHandler->DoCommand(argStr);
+//    
+//    // Store last command
+//    LocalFileSystem local("local");
+//    FILE* fp = fopen("/local/lastcmd.inf", "w");
+//    if (fp != NULL)
+//    {
+//        fwrite(argStr, 1, strlen(argStr)+1, fp);
+//        fclose(fp);
+//    }    
+//}
+//
+//void reRunLastCommand()
+//{
+//    // Store last command
+//    LocalFileSystem local("local");
+//    FILE* fp = fopen("/local/lastcmd.inf", "r");
+//    if (fp != NULL)
+//    {
+//        char buf[501];
+//        buf[sizeof(buf)-1] = 0;
+//        int nread = fread(buf, 1, sizeof(buf), fp);
+//        fclose(fp);
+//        if (nread > 0 && nread <= sizeof(buf))
+//        {
+//            buf[nread] = 0;
+//            pLedCmdHandler->DoCommand(buf);
+//        }
+//    }    
+//}
+//
+//#include "colourconverters.h"
+//
+//void BodgeSmooth(ledstrip* pLedStrip)
+//{
+//    pLedStrip->Clear();
+//    pLedStrip->ShowLeds();
+//
+//
+//    RgbColor startRGB(50,0,0);
+//    HsvColor curHsv = RgbToHsv(startRGB);
+//    while(1)
+//    for (int k = 0; k < 1000; k++)
+//    for (int j = 0; j < 255; j++)
+//    {
+//        pLedStrip->Clear();
+//        RgbColor colrVal = HsvToRgb(curHsv);        
+//        pLedStrip->Fill(0,pLedStrip->GetNumLeds(),colrVal.r, colrVal.g, colrVal.b);
+//        pLedStrip->ShowLeds();
+//        wait_ms(250);
+//        curHsv.h++;
+//    }
+//}
+//
+//void setLightsConfig()
+//{
+//    printf("Rob LightWall - Configured for ");
+//    // Check for a config file on the local file system
+//    strcpy(nameOfLights, "Spidey");
+//    LocalFileSystem local("local");
+//    FILE* fp = fopen("/local/spidey.cnf", "r");
+//    if (fp != NULL)
+//    {
+//        char buf[201];
+//        buf[sizeof(buf)-1] = 0;
+//        int nread = fread(buf, 1, sizeof(buf), fp);
+//        if (nread > 0 && nread <= sizeof(buf))
+//        {
+//            buf[nread] = 0;
+//            sscanf(buf, "%s %d %d", nameOfLights, &ledsCount, &ledSplitPoint);
+//        }
+//        fclose(fp);
+//        printf("%s (%d LEDs, Split at %d)", nameOfLights, ledsCount, ledSplitPoint);
+//        printf("\n\r");
+//    }
+//    
+//    // Leds setup
+//    pLedStrip = new ledstrip(ledsCount, ledSplitPoint);
+//    wait_ms(100);
+//    pLedStrip->Clear();
+//    pLedStrip->ShowLeds();
+//
+//    // Cmd handler
+//    pLedCmdHandler = new LedCmdHandler(pLedStrip);
+//}
+//
+//int main (void)
+//{
+//    pc.baud(115200);
+//    
+//    setLightsConfig();
+//    
+//    BodgeSmooth(pLedStrip);
+//    
+//    ledTick.attach(&ledTickfunc,TICK_MS / 1000.0);
+//
+////    reRunLastCommand();
+//    
+//    // setup ethernet interface
+//    eth.init(); //Use DHCP
+//    eth.connect();
+//    printf("IP Address is %s\n\r", eth.getIPAddress());
+//
+//    webServer.addCommand("", RdWebServerCmdDef::CMD_LOCALFILE, NULL, indexHtmName, true);
+//    webServer.addCommand("cmd", RdWebServerCmdDef::CMD_CALLBACK, &handleCmd_ledControl);
+//    webServer.init(PORT, &led2);
+//    webServer.run();
+//}
 
-char nameOfLights[50];
-int ledsCount = 904;
-int ledSplitPoint = 448;
-ledstrip* pLedStrip = NULL;
-
-char* indexHtmName = "index.htm";
-
-const int TICK_MS = 100;
-LedCmdHandler* pLedCmdHandler = NULL;
-int blinkCtr = 0;
-
-void ledTickfunc()
+// Handle a command
+char* lightwallCmd(int method, char* cmdStr, char* argStr, char* msgBuf)
 {
-    if(webServer.isListening())
+    int cmdLen = RdWebServer::getPayloadLengthFromMsg(msgBuf);
+    unsigned char* cmdBuf = RdWebServer::getPayloadDataFromMsg(msgBuf);
+    pc.printf("Command Payload Len %d\r\n", cmdLen);
+    if (cmdLen == 256)
     {
-        blinkCtr++;
-        if (blinkCtr > 1)
-        {
-            led1 = !led1;
-            blinkCtr = 0;
-        }
-    }
-    else
-    {
-        led1 = false;
+        for (int i = 0; i < cmdLen; i++)
+            if (cmdBuf[i] != i)
+            {
+                printf("Binary content err at %d\r\n", i);
+                break;
+            }
     }
-    
-    if (pLedCmdHandler != NULL)
-        pLedCmdHandler->NextGen();
-}
-
-void handleCmd_ledControl(char* cmdStr, char* argStr)
-{
-    printf("LEDS COMMAND %s %s\r\n", cmdStr, argStr);
-    if (argStr == NULL)
-        return;
-    pLedCmdHandler->DoCommand(argStr);
-    
-    // Store last command
-    LocalFileSystem local("local");
-    FILE* fp = fopen("/local/lastcmd.inf", "w");
-    if (fp != NULL)
-    {
-        fwrite(argStr, 1, strlen(argStr)+1, fp);
-        fclose(fp);
-    }    
+    char* respStr = "";
+    respStr = drawingManager.start(cmdBuf, cmdLen);
+    return respStr;
 }
 
-void reRunLastCommand()
+// Create, configure and run the web server
+void http_thread(void const* arg)
 {
-    // Store last command
-    LocalFileSystem local("local");
-    FILE* fp = fopen("/local/lastcmd.inf", "r");
-    if (fp != NULL)
-    {
-        char buf[501];
-        buf[sizeof(buf)-1] = 0;
-        int nread = fread(buf, 1, sizeof(buf), fp);
-        fclose(fp);
-        if (nread > 0 && nread <= sizeof(buf))
-        {
-            buf[nread] = 0;
-            pLedCmdHandler->DoCommand(buf);
-        }
-    }    
-}
-
-#include "colourconverters.h"
-
-void BodgeSmooth(ledstrip* pLedStrip)
-{
-    pLedStrip->Clear();
-    pLedStrip->ShowLeds();
-
-
-    RgbColor startRGB(50,0,0);
-    HsvColor curHsv = RgbToHsv(startRGB);
-    while(1)
-    for (int k = 0; k < 1000; k++)
-    for (int j = 0; j < 255; j++)
-    {
-        pLedStrip->Clear();
-        RgbColor colrVal = HsvToRgb(curHsv);        
-        pLedStrip->Fill(0,pLedStrip->GetNumLeds(),colrVal.r, colrVal.g, colrVal.b);
-        pLedStrip->ShowLeds();
-        wait_ms(250);
-        curHsv.h++;
-    }
+    pc.printf("Starting web server\r\n");
+    char* baseWebFolder = "/sd/";  // should be /sd/ for SDcard files - not used for local file system
+    RdWebServer webServer;
+    webServer.addCommand("", RdWebServerCmdDef::CMD_LOCALFILE, NULL, "index.htm", true);
+    webServer.addCommand("favicon.ico", RdWebServerCmdDef::CMD_LOCALFILE, NULL, NULL, true);
+    webServer.addCommand("cmd", RdWebServerCmdDef::CMD_CALLBACK, &lightwallCmd);
+    webServer.init(WEBPORT, &led4, baseWebFolder);
+    webServer.run();
 }
 
-void setLightsConfig()
+int main() 
 {
-    printf("Rob LightWall - Configured for ");
-    // Check for a config file on the local file system
-    strcpy(nameOfLights, "Spidey");
-    LocalFileSystem local("local");
-    FILE* fp = fopen("/local/spidey.cnf", "r");
-    if (fp != NULL)
-    {
-        char buf[201];
-        buf[sizeof(buf)-1] = 0;
-        int nread = fread(buf, 1, sizeof(buf), fp);
-        if (nread > 0 && nread <= sizeof(buf))
-        {
-            buf[nread] = 0;
-            sscanf(buf, "%s %d %d", nameOfLights, &ledsCount, &ledSplitPoint);
-        }
-        fclose(fp);
-        printf("%s (%d LEDs, Split at %d)", nameOfLights, ledsCount, ledSplitPoint);
-        printf("\n\r");
-    }
+    // Init
+    pc.baud(115200);
+    pc.printf("Light Wall - Rob Dobson 2015\r\n");
+
+    // Setup ethernet interface
+    char macAddr[6];
+    mbed_mac_address(macAddr);
+    pc.printf("Ethernet MAC address: %02x:%02x:%02x:%02x:%02x:%02x\r\n", macAddr[0], macAddr[1], macAddr[2], macAddr[3], macAddr[4], macAddr[5]); 
+    pc.printf("Connecting to ethernet ...\r\n");
+    EthernetInterface::init();
+    EthernetInterface::connect();
+    pc.printf("IP Address: %s\r\n", EthernetInterface::getIPAddress());
+
+    // Web Server
+    Thread httpServer(&http_thread, NULL, osPriorityNormal, (DEFAULT_STACK_SIZE * 4));
     
-    // Leds setup
-    pLedStrip = new ledstrip(ledsCount, ledSplitPoint);
-    wait_ms(100);
-    pLedStrip->Clear();
-    pLedStrip->ShowLeds();
-
-    // Cmd handler
-    pLedCmdHandler = new LedCmdHandler(pLedStrip);
-}
+    // Home
+    drawingManager.init();
 
-int main (void)
-{
-    pc.baud(115200);
-    
-    setLightsConfig();
-    
-    BodgeSmooth(pLedStrip);
-    
-    ledTick.attach(&ledTickfunc,TICK_MS / 1000.0);
-
-//    reRunLastCommand();
-    
-    // setup ethernet interface
-    eth.init(); //Use DHCP
-    eth.connect();
-    printf("IP Address is %s\n\r", eth.getIPAddress());
-
-    webServer.addCommand("", RdWebServerCmdDef::CMD_LOCALFILE, NULL, indexHtmName, true);
-    webServer.addCommand("cmd", RdWebServerCmdDef::CMD_CALLBACK, &handleCmd_ledControl);
-    webServer.init(PORT, &led2);
-    webServer.run();
+    while(true)
+    {
+//        led1=!led1;
+        // Service drawing manager
+        drawingManager.service();
+//        Thread::wait(500);
+    }
 }