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/
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 0:887096209439, committed 2015-08-18
- Comitter:
- Bobty
- Date:
- Tue Aug 18 16:03:29 2015 +0000
- Child:
- 1:362331cec9b7
- Commit message:
- Initial - unchanged since 2013
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Effect.h Tue Aug 18 16:03:29 2015 +0000
@@ -0,0 +1,16 @@
+// Base class for led effects
+
+#ifndef EFFECT__H
+#define EFFECT__H
+
+class Effect
+{
+ public:
+ Effect() {}
+ virtual char* GetName() = 0;
+ virtual void Init(char* argStr) = 0;
+ virtual void NextGen() = 0;
+ virtual void Stop() = 0;
+};
+
+#endif
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/EffectSmooth.h Tue Aug 18 16:03:29 2015 +0000
@@ -0,0 +1,52 @@
+// Smooth transition effect
+#include "Effect.h"
+#include "colourconverters.h"
+
+class EffectSmooth : public virtual Effect
+{
+ private:
+ int genCount;
+ ledstrip* pLedStrip;
+ HsvColor curHsv;
+
+ public:
+ EffectSmooth(ledstrip* pleds) : Effect(), curHsv(0,0,0)
+ {
+ genCount = 0;
+ pLedStrip = pleds;
+ }
+
+ virtual char* GetName()
+ {
+ return "smooth";
+ }
+
+ virtual void Init(char* argStr)
+ {
+ return;
+ genCount = 0;
+ pLedStrip->Clear();
+ pLedStrip->ShowLeds();
+ RgbColor startRGB(60,0,0);
+ curHsv = RgbToHsv(startRGB);
+ }
+
+ virtual void NextGen()
+ {
+ return;
+ pLedStrip->Clear();
+ RgbColor colrVal = HsvToRgb(curHsv);
+ pLedStrip->Fill(0,pLedStrip->GetNumLeds(),colrVal.r, colrVal.g, colrVal.b);
+ pLedStrip->ShowLeds();
+ curHsv.h++;
+ }
+
+ virtual void Stop()
+ {
+ return;
+
+ pLedStrip->Clear();
+ pLedStrip->ShowLeds();
+ }
+};
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/EffectSnake.h Tue Aug 18 16:03:29 2015 +0000
@@ -0,0 +1,68 @@
+// Snake transition effect
+#include "Effect.h"
+#include "colourconverters.h"
+
+class EffectSnake : public virtual Effect
+{
+ private:
+ int snakeLen;
+ int snakeHead;
+ int snakeDir;
+ ledstrip* pLedStrip;
+ RgbColor curColour;
+
+ public:
+ EffectSnake(ledstrip* pleds) : Effect(), curColour(0,0,0)
+ {
+ snakeLen = 10;
+ snakeHead = 0;
+ snakeDir = 0;
+ pLedStrip = pleds;
+ }
+
+ virtual char* GetName()
+ {
+ return "snake";
+ }
+
+ virtual void Init(char* argStr)
+ {
+ return;
+ snakeLen = 0;
+ snakeHead = 0;
+ snakeDir = 0;
+ pLedStrip->Clear();
+ pLedStrip->ShowLeds();
+ curColour = RgbColor(60,60,0);
+ }
+
+ virtual void NextGen()
+ {
+ return;
+ pLedStrip->Clear();
+ pLedStrip->Fill(snakeHead,snakeLen,curColour.r, curColour.g, curColour.b);
+ pLedStrip->ShowLeds();
+ if (snakeDir == 0)
+ {
+ snakeHead++;
+ if (snakeHead > pLedStrip->GetNumLeds() - snakeLen)
+ snakeDir = 1;
+ }
+ else
+ {
+ snakeHead--;
+ if (snakeHead <= 0)
+ {
+ snakeHead = 0;
+ snakeDir = 0;
+ }
+ }
+ }
+
+ virtual void Stop()
+ {
+ return;
+ pLedStrip->Clear();
+ pLedStrip->ShowLeds();
+ }
+};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/EthernetInterface.lib Tue Aug 18 16:03:29 2015 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/mbed_official/code/EthernetInterface/#cba86db5ab96
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/LedCmdHandler.cpp Tue Aug 18 16:03:29 2015 +0000
@@ -0,0 +1,55 @@
+// Handle Led Commands
+
+#include "mbed.h"
+#include <stdio.h>
+#include <string.h>
+#include "ledstrip.h"
+#include "LedCmdHandler.h"
+#include "EffectSmooth.h"
+#include "EffectSnake.h"
+
+void LedCmdHandler::AddEffects()
+{
+ effects.push_back(new EffectSmooth(pLedStrip));
+ effects.push_back(new EffectSnake(pLedStrip));
+}
+
+void LedCmdHandler::DoCommand(char* cmdStr)
+{
+ // Stop any existing command
+ Stop();
+
+ printf("Cmd %s\n\r", cmdStr);
+ // Extract command
+ char* pch = strtok (cmdStr,"/");
+ if (pch == NULL)
+ return;
+
+ // Find a matching command
+ list<Effect*>::iterator iter;
+ for(iter = effects.begin(); iter != effects.end(); ++iter)
+ {
+ printf("Trying %s vs %s\n\r", (*iter)->GetName(), pch);
+ wait_ms(1000);
+ if (strcmp((*iter)->GetName(), pch) == 0)
+ {
+ pCurEffect = *iter;
+ printf("Command = %s", pCurEffect->GetName());
+ pCurEffect->Init(cmdStr);
+ break;
+ }
+ }
+}
+
+void LedCmdHandler::NextGen()
+{
+ if (pCurEffect != NULL)
+ pCurEffect->NextGen();
+}
+
+void LedCmdHandler::Stop()
+{
+ if (pCurEffect != NULL)
+ pCurEffect->Stop();
+ pCurEffect = NULL;
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/LedCmdHandler.h Tue Aug 18 16:03:29 2015 +0000
@@ -0,0 +1,24 @@
+// Led Command Handler
+#include <list>
+#include "ledstrip.h"
+#include "Effect.h"
+
+class LedCmdHandler
+{
+ private:
+ std::list<Effect*> effects;
+ ledstrip* pLedStrip;
+ Effect* pCurEffect;
+
+ public:
+ LedCmdHandler(ledstrip* pleds)
+ {
+ pLedStrip = pleds;
+ AddEffects();
+ pCurEffect = NULL;
+ }
+ void AddEffects();
+ void DoCommand(char* cmdStr);
+ void NextGen();
+ void Stop();
+};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/RdWebServer.lib Tue Aug 18 16:03:29 2015 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/Bobty/code/RdWebServer/#594136d34a32
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/colourconverters.cpp Tue Aug 18 16:03:29 2015 +0000
@@ -0,0 +1,79 @@
+#include "colourconverters.h"
+
+RgbColor HsvToRgb(HsvColor hsv)
+{
+ RgbColor rgb(0,0,0);
+ unsigned char region, remainder, p, q, t;
+
+ if (hsv.s == 0)
+ {
+ rgb.r = hsv.v;
+ rgb.g = hsv.v;
+ rgb.b = hsv.v;
+ return rgb;
+ }
+
+ region = hsv.h / 43;
+ remainder = (hsv.h - (region * 43)) * 6;
+
+ p = (hsv.v * (255 - hsv.s)) >> 8;
+ q = (hsv.v * (255 - ((hsv.s * remainder) >> 8))) >> 8;
+ t = (hsv.v * (255 - ((hsv.s * (255 - remainder)) >> 8))) >> 8;
+
+ switch (region)
+ {
+ case 0:
+ rgb.r = hsv.v; rgb.g = t; rgb.b = p;
+ break;
+ case 1:
+ rgb.r = q; rgb.g = hsv.v; rgb.b = p;
+ break;
+ case 2:
+ rgb.r = p; rgb.g = hsv.v; rgb.b = t;
+ break;
+ case 3:
+ rgb.r = p; rgb.g = q; rgb.b = hsv.v;
+ break;
+ case 4:
+ rgb.r = t; rgb.g = p; rgb.b = hsv.v;
+ break;
+ default:
+ rgb.r = hsv.v; rgb.g = p; rgb.b = q;
+ break;
+ }
+
+ return rgb;
+}
+
+HsvColor RgbToHsv(RgbColor rgb)
+{
+ HsvColor hsv(0,0,0);
+ unsigned char rgbMin, rgbMax;
+
+ rgbMin = rgb.r < rgb.g ? (rgb.r < rgb.b ? rgb.r : rgb.b) : (rgb.g < rgb.b ? rgb.g : rgb.b);
+ rgbMax = rgb.r > rgb.g ? (rgb.r > rgb.b ? rgb.r : rgb.b) : (rgb.g > rgb.b ? rgb.g : rgb.b);
+
+ hsv.v = rgbMax;
+ if (hsv.v == 0)
+ {
+ hsv.h = 0;
+ hsv.s = 0;
+ return hsv;
+ }
+
+ hsv.s = 255 * long(rgbMax - rgbMin) / hsv.v;
+ if (hsv.s == 0)
+ {
+ hsv.h = 0;
+ return hsv;
+ }
+
+ if (rgbMax == rgb.r)
+ hsv.h = 0 + 43 * (rgb.g - rgb.b) / (rgbMax - rgbMin);
+ else if (rgbMax == rgb.g)
+ hsv.h = 85 + 43 * (rgb.b - rgb.r) / (rgbMax - rgbMin);
+ else
+ hsv.h = 171 + 43 * (rgb.r - rgb.g) / (rgbMax - rgbMin);
+
+ return hsv;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/colourconverters.h Tue Aug 18 16:03:29 2015 +0000
@@ -0,0 +1,37 @@
+#ifndef COLOURCONVERTERS__H
+#define COLOURCONVERTERS__H
+
+typedef struct RgbColor
+{
+ unsigned char r;
+ unsigned char g;
+ unsigned char b;
+
+ RgbColor(int inr, int ing, int inb)
+ {
+ r = (unsigned char) inr;
+ g = (unsigned char) ing;
+ b = (unsigned char) inb;
+ }
+} RgbColor;
+
+typedef struct HsvColor
+{
+ unsigned char h;
+ unsigned char s;
+ unsigned char v;
+
+ HsvColor(int inh, int ins, int inv)
+ {
+ h = (unsigned char) inh;
+ s = (unsigned char) ins;
+ v = (unsigned char) inv;
+ }
+
+} HsvColor;
+
+RgbColor HsvToRgb(HsvColor hsv);
+
+HsvColor RgbToHsv(RgbColor rgb);
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/ledstrip.cpp Tue Aug 18 16:03:29 2015 +0000
@@ -0,0 +1,285 @@
+#include "ledstrip.h"
+#include "colourconverters.h"
+#include "stddef.h"
+
+#define SPIF 0 // SPI interrupt flag bit
+#define SSP_IMSC_TX_RDY 3
+#define SSP_IMSC_BITMASK 0x0f
+
+volatile int mCurPos0;
+int mEndPos0;
+volatile int mCurPos1;
+int mEndPos1;
+volatile bool mShowingLeds0;
+volatile bool mShowingLeds1;
+unsigned char* pLedValues;
+bool inISR;
+
+extern "C" void spi0_isr()
+{
+ if (mCurPos0 < mEndPos0)
+ {
+ LPC_SSP0->DR = pLedValues[mCurPos0]; // write to FIFO data register
+ mCurPos0++;
+ }
+ else
+ {
+ // Turn off interrupts
+ LPC_SSP0->IMSC = 0;
+ mShowingLeds0 = false;
+ }
+}
+
+extern "C" void spi1_isr()
+{
+ if (mCurPos1 < mEndPos1)
+ {
+ LPC_SSP1->DR = pLedValues[mCurPos1]; // write to FIFO data register
+ mCurPos1++;
+ }
+ else
+ {
+ // Turn off interrupts
+ LPC_SSP1->IMSC = 0;
+ mShowingLeds1 = false;
+ }
+}
+
+ledstrip::ledstrip(int length, int splitPoint)
+{
+ mpLedValuesA = 0;
+ mpLedValuesB = 0;
+ mpCurLedValues = 0;
+
+ // SPI0 (using SSP 0 in 1768 chip)
+ mpSPI0 = new SPI(p11, NC, p13);
+ mpSPI0->format(8,0);
+ mpSPI0->frequency(500000);
+ LPC_SSP0->IMSC = 0; // initially no interrupts requested
+ NVIC_SetVector(SSP0_IRQn,( uint32_t ) spi0_isr);
+ NVIC_ClearPendingIRQ(SSP0_IRQn);
+ NVIC_SetPriority(SSP0_IRQn, 2);
+ NVIC_EnableIRQ(SSP0_IRQn);
+
+ // SPI1 (using SSP 1 in 1768 chip)
+ mpSPI1 = new SPI(p5, NC, p7);
+ mpSPI1->format(8,0);
+ mpSPI1->frequency(500000);
+ LPC_SSP1->IMSC = 0; // initially no interrupts requested
+ NVIC_SetVector(SSP1_IRQn,( uint32_t ) spi1_isr);
+ NVIC_ClearPendingIRQ(SSP1_IRQn);
+ NVIC_SetPriority(SSP1_IRQn, 2);
+ NVIC_EnableIRQ(SSP1_IRQn);
+
+ // Enable interrupts
+ __enable_irq();
+
+ // Resize the string length
+ Resize(length, splitPoint);
+}
+
+ledstrip::~ledstrip()
+{
+ delete mpLedValuesA;
+ delete mpLedValuesB;
+}
+
+bool ledstrip::Resize(int length, int splitPoint)
+{
+ if (mShowingLeds0 || mShowingLeds1)
+ return false;
+ if (mpLedValuesA != 0)
+ delete mpLedValuesA;
+ if (mpLedValuesB != 0)
+ delete mpLedValuesB;
+ mLedsBufSize = length*mColoursPerLed;
+ mpLedValuesA = new unsigned char[mLedsBufSize];
+ mpLedValuesB = new unsigned char[mLedsBufSize];
+ mpCurLedValues = mpLedValuesA;
+ mLedsInStrip = length;
+ mSplitPoint = splitPoint;
+ Clear();
+ return true;
+}
+
+void ledstrip::Clear()
+{
+/* Timer timr;
+ timr.start();
+ for (int i = 0; i < mLedsInStrip*mColoursPerLed; i++)
+ mpCurLedValues[i] = 0;
+ timr.stop();
+ printf("ClearTime loop %d\n", timr.read_us()); // Result is 863uS for 2500 x 3colour LEDS
+ timr.reset();
+ timr.start();
+ */
+ memset(mpCurLedValues, 0, mLedsBufSize);
+ /* timr.stop();
+ printf("ClearTime memset %d\n", timr.read_us()); // Result is 35uS for 2500 x 3 colour LEDS
+*/
+}
+
+unsigned char* ledstrip::GetBuffer()
+{
+ return mpCurLedValues;
+}
+
+int ledstrip::GetBufferSizeinBytes()
+{
+ return mLedsBufSize;
+}
+
+bool ledstrip::IsBusy()
+{
+ return mShowingLeds0 || mShowingLeds1;
+}
+
+// Fill - solid colour
+void ledstrip::Fill(int startLed, int numLeds,
+ int r1, int g1, int b1)
+{
+/* Timer timr;
+ timr.start();
+*/
+ if ((startLed < 0) || (startLed >= mLedsInStrip))
+ return;
+ if (numLeds >= mLedsInStrip - startLed)
+ numLeds = mLedsInStrip - startLed;
+ int pos = startLed * mColoursPerLed;
+ unsigned char* pBuf = GetBuffer();
+ for (int i = 0; i < numLeds; i++)
+ {
+ pBuf[pos] = (unsigned char) r1;
+ pBuf[pos+1] = (unsigned char) g1;
+ pBuf[pos+2] = (unsigned char) b1;
+ pos += mColoursPerLed;
+ }
+/* timr.stop();
+ printf("Fill solid %d\n", timr.read_us()); // Fill 50 LEDS solid colour = 11uS
+ */
+}
+
+// Fill - with interpolation of colours using HSV colour space
+void ledstrip::Fill(int startLed, int numLeds,
+ int r1, int g1, int b1,
+ int r2, int g2, int b2)
+{
+/* Timer timr;
+ timr.start();
+ */
+ if ((startLed < 0) || (startLed >= mLedsInStrip))
+ return;
+ if (numLeds >= mLedsInStrip - startLed)
+ numLeds = mLedsInStrip - startLed;
+ int pos = startLed * mColoursPerLed;
+ RgbColor startRGB(r1,g1,b1);
+ HsvColor startHsv = RgbToHsv(startRGB);
+ RgbColor endRGB(r2,g2,b2);
+ HsvColor endHsv = RgbToHsv(endRGB);
+ int curH = startHsv.h << 16;
+ int curS = startHsv.s << 16;
+ int curV = startHsv.v << 16;
+ int interpSteps = numLeds - 1;
+ if (interpSteps < 1)
+ interpSteps = 1;
+ int incH = ((endHsv.h - startHsv.h) << 16) / interpSteps;
+ int incS = ((endHsv.s - startHsv.s) << 16) / interpSteps;
+ int incV = ((endHsv.v - startHsv.v) << 16) / interpSteps;
+ // Since H is a polar value we need to find out if it is best to go clockwise or anti-clockwise
+ if (endHsv.h > startHsv.h)
+ {
+ if (endHsv.h-startHsv.h > 128)
+ incH = ((startHsv.h-endHsv.h) << 16) / interpSteps;
+ }
+ else
+ {
+ // Go "round the top" using modulo result
+ if (startHsv.h-endHsv.h > 128)
+ incH = ((endHsv.h + 255 - startHsv.h) << 16) / interpSteps;
+ }
+
+// printf("StartHSV %d %d %d EndHSV %d %d %d IncHSV %d %d %d\n", startHsv.h, startHsv.s, startHsv.v, endHsv.h, endHsv.s, endHsv.v, incH, incS, incV);
+ unsigned char* pBuf = GetBuffer();
+ for (int i = 0; i < numLeds; i++)
+ {
+ RgbColor colrVal = HsvToRgb(HsvColor((curH>>16)&0xff,curS>>16,curV>>16));
+ pBuf[pos] = colrVal.r;
+ pBuf[pos+1] = colrVal.g;
+ pBuf[pos+2] = colrVal.b;
+// printf("HSV %d %d %d RGB %d %d %d\n", curH>>16, curS>>16, curV>>16, colrVal.r, colrVal.g, colrVal.b);
+ pos += mColoursPerLed;
+ curH = curH + incH;
+ curS = curS + incS;
+ curV = curV + incV;
+ }
+ /*
+ timr.stop();
+ printf("Fill gradient %d\n", timr.read_us()); // Fill gradient 50 LEDS = 64uS
+ */
+}
+
+
+void ledstrip::ShowLeds()
+{
+ // Check if busy
+ while (mShowingLeds0 || mShowingLeds1)
+ ;
+ wait_us(750);
+
+ // Set up start points
+ mCurPos0 = 0;
+ mEndPos0 = mSplitPoint*mColoursPerLed;
+ mCurPos1 = mSplitPoint*mColoursPerLed;
+ mEndPos1 = mLedsInStrip*mColoursPerLed;
+
+ // Set the buffer for the ISRs
+ pLedValues = mpCurLedValues;
+
+ // Flip the current buffer to the alternate one for interleaved writing
+ if (mpCurLedValues == mpLedValuesA)
+ mpCurLedValues = mpLedValuesB;
+ else
+ mpCurLedValues = mpLedValuesA;
+
+ // Enable interrupts
+ mShowingLeds0 = true;
+ LPC_SSP0->IMSC = (1 << SSP_IMSC_TX_RDY) & SSP_IMSC_BITMASK;
+
+ // Check if second strip is used
+ if (mSplitPoint < mLedsInStrip)
+ {
+ LPC_SSP1->IMSC = (1 << SSP_IMSC_TX_RDY) & SSP_IMSC_BITMASK;
+ mShowingLeds1 = true;
+ }
+ // for (int q = 0; q < mLedsInStrip*3; q+=3)
+ // printf("%d %02x%02x%02x\n", q/3, mpLedValues[q], mpLedValues[q+1], mpLedValues[q+2]);
+/*
+ int pos1 = 0;
+ int pos2 = mSplitPoint * mColoursPerLed;
+ for (int j = 0; j < mMaxChainLength; j++)
+ {
+ for (int k = 0; k < mColoursPerLed; k++)
+ {
+ unsigned char tval1 = 0;
+ if (pos1 + k < mLedsBufSize)
+ tval1 = mpLedValues[pos1 + k];
+ unsigned char tval2 = 0;
+ if (pos2 + k < mLedsBufSize)
+ tval2 = mpLedValues[pos2 + k];
+ for (int i = 0; i < 8; i++)
+ {
+ dat1 = (tval1 & 0x80) != 0;
+ tval1 = tval1 << 1;
+ dat2 = (tval2 & 0x80) != 0;
+ tval2 = tval2 << 1;
+ clk = 1;
+ clk = 0;
+ wait_us(1);
+ }
+ }
+ pos1 += mColoursPerLed;
+ pos2 += mColoursPerLed;
+ }
+ wait_us(750);
+*/
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/ledstrip.h Tue Aug 18 16:03:29 2015 +0000
@@ -0,0 +1,42 @@
+#ifndef LEDSTRIP__H
+#define LEDSTRIP__H
+
+#include "mbed.h"
+
+class ledstrip
+{
+ private:
+ unsigned char* mpLedValuesA;
+ unsigned char* mpLedValuesB;
+ unsigned char* mpCurLedValues;
+ int mLedsInStrip;
+ int mSplitPoint;
+ int mLedsBufSize;
+ SPI* mpSPI0;
+ SPI* mpSPI1;
+
+ public:
+ static const int mColoursPerLed = 3;
+
+ public:
+ ledstrip(int length, int splitPoint);
+ ~ledstrip();
+ unsigned char* GetBuffer();
+ int GetBufferSizeinBytes();
+ bool Resize(int length, int splitPoint);
+ bool IsBusy();
+ int GetNumLeds()
+ {
+ return mLedsInStrip;
+ }
+ void Clear();
+ void Fill(int startLed, int numLeds,
+ int r1, int g1, int b1,
+ int r2, int g2, int b2);
+ void Fill(int startLed, int numLeds,
+ int r1, int g1, int b1);
+ void ShowLeds();
+
+};
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp Tue Aug 18 16:03:29 2015 +0000
@@ -0,0 +1,170 @@
+/* main.cpp
+ Rob Dobson 2013
+ More details at ???
+*/
+
+#include "mbed.h"
+#include "EthernetInterface.h"
+#include <stdio.h>
+#include <string.h>
+#include "RdWebServer.h"
+#include "ledstrip.h"
+#include "LedCmdHandler.h"
+
+#define PORT 80
+
+Serial pc(USBTX, USBRX);
+
+RdWebServer webServer;
+
+EthernetInterface eth;
+
+DigitalOut led1(LED1); //server listning status
+DigitalOut led2(LED2); //socket connecting status
+
+Ticker ledTick;
+
+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()
+{
+ 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();
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-rtos.lib Tue Aug 18 16:03:29 2015 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/mbed_official/code/mbed-rtos/#29007aef10a4
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed.bld Tue Aug 18 16:03:29 2015 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/mbed_official/code/mbed/builds/a9913a65894f \ No newline at end of file