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/

Files at this revision

API Documentation at this revision

Comitter:
Bobty
Date:
Tue Sep 01 15:53:52 2015 +0000
Parent:
4:b521815f2657
Child:
6:8df79fe1afcd
Commit message:
Added an idle handler so there is something to show when nothing is being sent over HTTP

Changed in this revision

DrawingManager.cpp Show annotated file Show diff for this revision Revisions of this file
DrawingManager.h Show annotated file Show diff for this revision Revisions of this file
Idler.cpp Show annotated file Show diff for this revision Revisions of this file
Idler.h Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
--- a/DrawingManager.cpp	Mon Aug 31 15:21:47 2015 +0000
+++ b/DrawingManager.cpp	Tue Sep 01 15:53:52 2015 +0000
@@ -5,6 +5,7 @@
 
 #include "DrawingManager.h"
 #include "rtos.h"
+#include "colourconverters.h"
 
 DrawingManager::DrawingManager()
 {
@@ -68,6 +69,24 @@
         pLedStrip->ShowLeds();
 }
 
+void DrawingManager::DisplayIdle(unsigned int stepCount)
+{
+    // Display a step in an auto sequence
+    if (!pLedStrip)
+        return;
+    if (pLedStrip->IsBusy())
+        return;
+    pLedStrip->Clear();
+    int ledsPerGroup = pLedStrip->GetNumLeds() / 10;
+    for (int i = 0; i < pLedStrip->GetNumLeds(); i += ledsPerGroup)
+    {
+        RgbColor colrVal((stepCount * 7) + (i * 23) % 64, (stepCount * 17) + 77 + (i * 3) % 64, (stepCount * 37) + 117 + (i * 13) % 64);
+        RgbColor colrVal2((stepCount * 17) + (i * 33) % 64, (stepCount * 3) + 13 + (i * 13) % 64, (stepCount * 77) + 11 + (i * 23) % 64);
+        pLedStrip->Fill(i,ledsPerGroup,colrVal.r, colrVal.g, colrVal.b, colrVal2.r, colrVal2.g, colrVal2.b);
+    }
+    pLedStrip->ShowLeds();
+}
+
 int DrawingManager::GetIntFromNameValPair(char* buf, char* name, int invalidVal)
 {
     int val = invalidVal;
@@ -76,3 +95,4 @@
         val = atoi(pFnd + strlen(name));
     return val;
 }
+
--- a/DrawingManager.h	Mon Aug 31 15:21:47 2015 +0000
+++ b/DrawingManager.h	Tue Sep 01 15:53:52 2015 +0000
@@ -18,7 +18,7 @@
     void RawFill(char* args, unsigned char* payload, int payloadLen, int payloadOffset);
     void Fill(char* args);
     void ShowLeds();
-    
+    void DisplayIdle(unsigned int stepCount);
 
 private:
     ledstrip* pLedStrip;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Idler.cpp	Tue Sep 01 15:53:52 2015 +0000
@@ -0,0 +1,49 @@
+
+#include "Idler.h"
+
+DigitalOut* Idler::_pStatusLed = NULL;
+bool Idler::_isIdle = true;
+unsigned int Idler::_stepCount = 0;
+DrawingManager* Idler::_pDrawingManager = NULL;
+Ticker Idler::_idleTicker;
+Timer Idler::_idleTimer;
+
+const int IDLE_TIMEOUT = 10; // N seconds of no REST commands -> idle
+
+Idler::Idler(DigitalOut* pStatusLed, DrawingManager* pDrawingManager)
+{
+    _pStatusLed = pStatusLed;
+    _pDrawingManager = pDrawingManager;
+    _idleTicker.attach(&tick, 0.1);
+}
+
+void Idler::tick()
+{
+    // Check if idle
+    if (!_isIdle)
+    {
+        // Check time since last notIdle
+        if (_idleTimer.read() < IDLE_TIMEOUT)
+            return;
+        
+        // Now idle again
+        _idleTimer.stop();
+        _isIdle = true;
+    }
+
+    // Blink LED
+    *_pStatusLed = !(*_pStatusLed);
+    
+    // Step through display
+    _pDrawingManager->DisplayIdle(_stepCount);
+    _stepCount++;
+}
+
+void Idler::notIdle()
+{
+    _isIdle = false;
+    *_pStatusLed = false;
+    _idleTimer.reset();
+    _idleTimer.start();
+    _stepCount = 0;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Idler.h	Tue Sep 01 15:53:52 2015 +0000
@@ -0,0 +1,25 @@
+#ifndef IDLER__H
+#define IDLER__H
+
+#include "mbed.h"
+#include "DrawingManager.h"
+
+class Idler
+{
+    public:
+        Idler(DigitalOut* pStatusLed, DrawingManager* pDrawingManager);
+        static void tick();
+        static void notIdle();
+        static void displayStep();
+        
+    private:
+        static DigitalOut* _pStatusLed;
+        static bool _isIdle;
+        static unsigned int _stepCount;
+        static DrawingManager* _pDrawingManager;
+        static Ticker _idleTicker;
+        static Timer _idleTimer;
+
+};
+
+#endif
--- a/main.cpp	Mon Aug 31 15:21:47 2015 +0000
+++ b/main.cpp	Tue Sep 01 15:53:52 2015 +0000
@@ -10,6 +10,7 @@
 #include "EthernetInterface.h"
 #include "RdWebServer.h"
 #include "DrawingManager.h"
+#include "Idler.h"
 #include <string.h>
 
 // Web port
@@ -30,6 +31,9 @@
 // Drawing Manager
 DrawingManager drawingManager;
 
+// Idler - to display something when not being driven by the web interface
+Idler idler(&led2, &drawingManager);
+
 // General response string for REST requests
 char* generalRespStr = "HTTP/1.1 200 OK\r\nConnection: keep-alive\r\nAccess-Control-Allow-Origin: *\r\nAccess-Control-Allow-Methods: POST, GET, OPTIONS\r\nAccess-Control-Allow-Headers:accept, content-type\r\nContent-Length: 0\r\nContent-Type: application/octet-stream\r\n\r\n";
 
@@ -45,6 +49,7 @@
 char* lightwallClear(int method, char*cmdStr, char* argStr, char* msgBuffer, int msgLen, 
                 int contentLen, unsigned char* pPayload, int payloadLen, int splitPayloadPos)
 {
+    idler.notIdle();
     drawingManager.Clear();
     return generalRespStr;
 }
@@ -54,6 +59,7 @@
 char* lightwallRawFill(int method, char*cmdStr, char* argStr, char* msgBuffer, int msgLen, 
                 int contentLen, unsigned char* pPayload, int payloadLen, int splitPayloadPos)
 {
+    idler.notIdle();
     drawingManager.RawFill(argStr, pPayload, payloadLen, splitPayloadPos);
     return generalRespStr;
 }
@@ -64,6 +70,7 @@
 char* lightwallFill(int method, char*cmdStr, char* argStr, char* msgBuffer, int msgLen, 
                 int contentLen, unsigned char* pPayload, int payloadLen, int splitPayloadPos)
 {
+    idler.notIdle();
     drawingManager.Fill(argStr);
     return generalRespStr;
 }
@@ -75,6 +82,7 @@
     // Blink LED
     led1 = !led1;
     // Show LEDS
+    idler.notIdle();
     drawingManager.ShowLeds();
     return generalRespStr;
 }
@@ -131,7 +139,7 @@
     // Init
     pc.baud(115200);
     pc.printf("Light Wall - Rob Dobson 2015\r\n");
-    
+
     // Get the configuration of the system
     getSystemConfig();
 
@@ -143,14 +151,14 @@
     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");
-    
+
     // Init ethernet
     EthernetInterface::init();
 
     // Using code described here https://developer.mbed.org/questions/1602/How-to-set-the-TCPIP-stack-s-hostname-pr/
     // to setName on the ethernet interface
     EthernetInterface::setName(systemName);
-    
+
     // Connect ethernet
     EthernetInterface::connect();
     pc.printf("IP Address: %s HostName %s\r\n", EthernetInterface::getIPAddress(), EthernetInterface::getName());
@@ -161,7 +169,7 @@
     // This is the previous code...
     // Thread httpServer(&http_server, NULL, osPriorityNormal, (DEFAULT_STACK_SIZE * 3));
     http_server("");
-      
+
     // Forever - actually it won't even get here as the server has a forever loop in it too
     while(true)
     {