Rob Dobson / Mbed 2 deprecated SpideyWallWeb

Dependencies:   EthernetInterfacePlusHostname RdWebServer mbed-rtos mbed

Committer:
Bobty
Date:
Thu Aug 20 07:41:02 2015 +0000
Revision:
1:362331cec9b7
Child:
3:e5ea80fae61d
Implemented a command protocol using HTTP POST

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Bobty 1:362331cec9b7 1 #include "mbed.h"
Bobty 1:362331cec9b7 2 #include "cmdmsg.h"
Bobty 1:362331cec9b7 3 #include "ledstrip.h"
Bobty 1:362331cec9b7 4 //#define DETECT_LEDS
Bobty 1:362331cec9b7 5 #ifdef DETECT_LEDS
Bobty 1:362331cec9b7 6 #include "detectled.h"
Bobty 1:362331cec9b7 7 #endif
Bobty 1:362331cec9b7 8 //#define USE_SPIDEY_GEOM
Bobty 1:362331cec9b7 9 #ifdef USE_SPIDEY_GEOM
Bobty 1:362331cec9b7 10 #include "spideyGeometry.h"
Bobty 1:362331cec9b7 11 #endif
Bobty 1:362331cec9b7 12 /*
Bobty 1:362331cec9b7 13
Bobty 1:362331cec9b7 14 Message format is:
Bobty 1:362331cec9b7 15 <SEQ><CMD><CMD><CMD> ... <ZERO>
Bobty 1:362331cec9b7 16
Bobty 1:362331cec9b7 17 Where:
Bobty 1:362331cec9b7 18 <SEQ> is a two byte sequence count
Bobty 1:362331cec9b7 19 <CMD> is a series of bytes as follows:
Bobty 1:362331cec9b7 20 <LEN><COD><PARAMS>
Bobty 1:362331cec9b7 21
Bobty 1:362331cec9b7 22 Where:
Bobty 1:362331cec9b7 23 <LEN> is a two byte with value 1..65535 depicting msg len
Bobty 1:362331cec9b7 24 <COD> is a one byte command code - see below
Bobty 1:362331cec9b7 25 <PARAMS> are a series of bytes containing the parameters for the command
Bobty 1:362331cec9b7 26
Bobty 1:362331cec9b7 27 <COD> values:
Bobty 1:362331cec9b7 28
Bobty 1:362331cec9b7 29 NOTE MSB of COD is used to indicate that no response is required on success
Bobty 1:362331cec9b7 30 i.e. if MSB of COD is 1 then no response is required on success
Bobty 1:362331cec9b7 31
Bobty 1:362331cec9b7 32 (COD & 0x7f) ....
Bobty 1:362331cec9b7 33 0x01:
Bobty 1:362331cec9b7 34 Clear the entire strip
Bobty 1:362331cec9b7 35 0x02:
Bobty 1:362331cec9b7 36 Fill a series of leds with RGB values
Bobty 1:362331cec9b7 37 <PARAMS> := <START><NUM><RGB1><RGB2>
Bobty 1:362331cec9b7 38 Where:
Bobty 1:362331cec9b7 39 <START> is a two byte value (bigendian) for led to start series
Bobty 1:362331cec9b7 40 <NUM> is a two byte (bigendian) number of leds to set
Bobty 1:362331cec9b7 41 <RGB1> is the starting RGB value (24bits)
Bobty 1:362331cec9b7 42 <RGB2> is the ending RGB value (24bits) - OPTIONAL
Bobty 1:362331cec9b7 43 The RGB2 value is optional - the LEN value determines whether it is present or not
Bobty 1:362331cec9b7 44 - if present the colour values are interpolated (HSV) between RGB1 and RGB2
Bobty 1:362331cec9b7 45 - if not present all leds are set to colour RGB1
Bobty 1:362331cec9b7 46 0x03:
Bobty 1:362331cec9b7 47 Detect LED with opto-sensor (put opto-sensor on LED and run command)
Bobty 1:362331cec9b7 48 Sensor must be attached to p20 - currently using BPX65 with 470K pullup
Bobty 1:362331cec9b7 49 Returns string with LED number
Bobty 1:362331cec9b7 50 0x04:
Bobty 1:362331cec9b7 51 Set number of leds and split point
Bobty 1:362331cec9b7 52 <PARAMS> := <NUMLEDS><SPLITPOINT>
Bobty 1:362331cec9b7 53 Where:
Bobty 1:362331cec9b7 54 <NUMLEDS> is a two byte (bigendian) value for number of leds in strip
Bobty 1:362331cec9b7 55 <SPLITPOINT> is a two byte (bigendian) value for point at which DigitalOut(p10) is used instead of p12 for data
Bobty 1:362331cec9b7 56 (this is because the spidey wall is two parallel chains of LEDS)
Bobty 1:362331cec9b7 57 0x05:
Bobty 1:362331cec9b7 58 Raw RGB values for a series of leds
Bobty 1:362331cec9b7 59 <PARAMS> := <START><NUM><RGB1><RGB2><RGB2>....<RGBn>
Bobty 1:362331cec9b7 60 Where:
Bobty 1:362331cec9b7 61 <START> is a two byte value (bigendian) for led to start series
Bobty 1:362331cec9b7 62 <NUM> is a two byte (bigendian) number of leds to set
Bobty 1:362331cec9b7 63 <RGB1> is the RGB value for 1st LED (24bits)
Bobty 1:362331cec9b7 64 <RGB2> is the RGB value for 2nd LED (24bits)
Bobty 1:362331cec9b7 65 <RGBn> is the RGB value for nth LED (24bits)
Bobty 1:362331cec9b7 66 0x06:
Bobty 1:362331cec9b7 67 Set colour for leds on a pad
Bobty 1:362331cec9b7 68 <PARAMS> := <PAD><RGB1><RGB2>
Bobty 1:362331cec9b7 69 Where:
Bobty 1:362331cec9b7 70 <PAD> is the pad number (1 byte)
Bobty 1:362331cec9b7 71 <RGB1> is the starting RGB value (24bits)
Bobty 1:362331cec9b7 72 <RGB2> is the ending RGB value (24bits) - OPTIONAL
Bobty 1:362331cec9b7 73 The RGB2 value is optional - the LEN value determines whether it is present or not
Bobty 1:362331cec9b7 74 - if present the colour values are interpolated (HSV) between RGB1 and RGB2
Bobty 1:362331cec9b7 75 - if not present all leds are set to colour RGB1
Bobty 1:362331cec9b7 76 0x07:
Bobty 1:362331cec9b7 77 Set node and link info
Bobty 1:362331cec9b7 78 <PARAMS> := <NODE><NODEFLAGS><NODERGB><LINKIDX><LINKLEDSTART><LINKNUMLEDS><LINKRGB>
Bobty 1:362331cec9b7 79 Where:
Bobty 1:362331cec9b7 80 <NODE> is the node number (1 byte)
Bobty 1:362331cec9b7 81 <NODEFLAGS> LSB is 0 if the RGB value for the node is not to be changed, or 1 otherwise (1 byte)
Bobty 1:362331cec9b7 82 <NODERGB> is the RBG value for the leds in the node itself (3 bytes)
Bobty 1:362331cec9b7 83 <LINKIDX> is the index of the link (edge) from this node to control (1 byte)
Bobty 1:362331cec9b7 84 <LINKLEDSTART> is the LED along the link to start controlling (1 byte)
Bobty 1:362331cec9b7 85 <LINKNUMLEDS> is the number of LEDs to control (1 byte)
Bobty 1:362331cec9b7 86 <LINKRGB> is the colour to make the link LEDs (3 bytes)
Bobty 1:362331cec9b7 87
Bobty 1:362331cec9b7 88 */
Bobty 1:362331cec9b7 89
Bobty 1:362331cec9b7 90 #ifdef USE_SPIDEY_GEOM
Bobty 1:362331cec9b7 91 int cmdmsg::getLedNumFromSeq(const int* edgeLeds, int numLedsInSeq, int seqIdx)
Bobty 1:362331cec9b7 92 {
Bobty 1:362331cec9b7 93 if (seqIdx >= numLedsInSeq)
Bobty 1:362331cec9b7 94 return -1;
Bobty 1:362331cec9b7 95 int curSeqPos = 0;
Bobty 1:362331cec9b7 96 bool reverseSeq = false;
Bobty 1:362331cec9b7 97 for (int i = 0; i < MAX_SPIDEY_LINK_ELS/2; i++)
Bobty 1:362331cec9b7 98 {
Bobty 1:362331cec9b7 99 int startLedIdx = edgeLeds[i * 2];
Bobty 1:362331cec9b7 100 int endLedIdx = edgeLeds[i * 2 + 1];
Bobty 1:362331cec9b7 101 int nLeds = endLedIdx - startLedIdx + 1;
Bobty 1:362331cec9b7 102 if (startLedIdx > endLedIdx)
Bobty 1:362331cec9b7 103 {
Bobty 1:362331cec9b7 104 reverseSeq = true;
Bobty 1:362331cec9b7 105 nLeds = startLedIdx - endLedIdx + 1;
Bobty 1:362331cec9b7 106 }
Bobty 1:362331cec9b7 107 if (seqIdx - curSeqPos < nLeds)
Bobty 1:362331cec9b7 108 {
Bobty 1:362331cec9b7 109 if (reverseSeq)
Bobty 1:362331cec9b7 110 return startLedIdx - seqIdx;
Bobty 1:362331cec9b7 111 return startLedIdx + seqIdx;
Bobty 1:362331cec9b7 112 }
Bobty 1:362331cec9b7 113 curSeqPos = nLeds;
Bobty 1:362331cec9b7 114 }
Bobty 1:362331cec9b7 115 return -1;
Bobty 1:362331cec9b7 116 }
Bobty 1:362331cec9b7 117 #endif
Bobty 1:362331cec9b7 118
Bobty 1:362331cec9b7 119 char* cmdmsg::Interpret(const unsigned char* msg, int msgLen, ledstrip* pLedStrip)
Bobty 1:362331cec9b7 120 {
Bobty 1:362331cec9b7 121 // Get message details
Bobty 1:362331cec9b7 122 static char responseStr[50];
Bobty 1:362331cec9b7 123 unsigned char* ledStrip = pLedStrip->GetBuffer();
Bobty 1:362331cec9b7 124 int nBytesLeft = msgLen - 2;
Bobty 1:362331cec9b7 125 int seqCount = (msg[0] * 256) + msg[1];
Bobty 1:362331cec9b7 126 msg += 2;
Bobty 1:362331cec9b7 127 while (nBytesLeft > 0)
Bobty 1:362331cec9b7 128 {
Bobty 1:362331cec9b7 129 // Length of chunk
Bobty 1:362331cec9b7 130 int chunkLen = (msg[0] * 256) + msg[1];
Bobty 1:362331cec9b7 131 if (chunkLen == 0)
Bobty 1:362331cec9b7 132 break;
Bobty 1:362331cec9b7 133
Bobty 1:362331cec9b7 134 // Params length
Bobty 1:362331cec9b7 135 int paramsLen = chunkLen - 1;
Bobty 1:362331cec9b7 136 // printf("Chunklen = %d, Paramslen = %d\r\n", chunkLen, paramsLen);
Bobty 1:362331cec9b7 137
Bobty 1:362331cec9b7 138 // Command and whether response required on success
Bobty 1:362331cec9b7 139 int cmdCode = msg[2];
Bobty 1:362331cec9b7 140 if ((cmdCode & 0x80) == 0)
Bobty 1:362331cec9b7 141 sprintf(responseStr, "%04x OK", seqCount);
Bobty 1:362331cec9b7 142 else
Bobty 1:362331cec9b7 143 strcpy(responseStr, "");
Bobty 1:362331cec9b7 144
Bobty 1:362331cec9b7 145 // Move message pointer to assist in decoding the payload
Bobty 1:362331cec9b7 146 msg += 3;
Bobty 1:362331cec9b7 147 switch(cmdCode & 0x7f)
Bobty 1:362331cec9b7 148 {
Bobty 1:362331cec9b7 149 case 0x01: // Clear
Bobty 1:362331cec9b7 150 {
Bobty 1:362331cec9b7 151 // printf("Clear - nextbyte %d\r\n", msg[0]);
Bobty 1:362331cec9b7 152 pLedStrip->Clear();
Bobty 1:362331cec9b7 153 break;
Bobty 1:362331cec9b7 154 }
Bobty 1:362331cec9b7 155 case 0x02: // Fill
Bobty 1:362331cec9b7 156 {
Bobty 1:362331cec9b7 157 // printf("Fill\r\n");
Bobty 1:362331cec9b7 158
Bobty 1:362331cec9b7 159 int startLed = (msg[0] * 256) + msg[1];
Bobty 1:362331cec9b7 160 int numLeds = (msg[2] * 256) + msg[3];
Bobty 1:362331cec9b7 161 // printf("F Q%04x S%d N%d Pa%d Ln%d\r\n", seqCount, startLed, numLeds, paramsLen, msgLen);
Bobty 1:362331cec9b7 162 if (paramsLen == 10) // RGB2 is provided
Bobty 1:362331cec9b7 163 {
Bobty 1:362331cec9b7 164 pLedStrip->Fill(startLed, numLeds, msg[4], msg[5], msg[6], msg[7], msg[8], msg[9]);
Bobty 1:362331cec9b7 165 } else if (paramsLen == 7) // only RGB1 - so solid colour fill
Bobty 1:362331cec9b7 166 {
Bobty 1:362331cec9b7 167 pLedStrip->Fill(startLed, numLeds, msg[4], msg[5], msg[6]);
Bobty 1:362331cec9b7 168 }
Bobty 1:362331cec9b7 169 break;
Bobty 1:362331cec9b7 170 }
Bobty 1:362331cec9b7 171 case 0x03: // Detect LED
Bobty 1:362331cec9b7 172 {
Bobty 1:362331cec9b7 173 #ifdef DETECT_LEDS
Bobty 1:362331cec9b7 174 detectled ledDetector(p20);
Bobty 1:362331cec9b7 175 int selectedLed = ledDetector.DetectSelectedLed(pLedStrip);
Bobty 1:362331cec9b7 176 sprintf(responseStr, "%02x OK LED %d", seqCount, selectedLed);
Bobty 1:362331cec9b7 177 #endif
Bobty 1:362331cec9b7 178 break;
Bobty 1:362331cec9b7 179 }
Bobty 1:362331cec9b7 180 case 0x04: // Set numleds and splitpoint
Bobty 1:362331cec9b7 181 {
Bobty 1:362331cec9b7 182 // printf("Set numleds and splitpoint\r\n");
Bobty 1:362331cec9b7 183
Bobty 1:362331cec9b7 184 if (paramsLen == 4)
Bobty 1:362331cec9b7 185 {
Bobty 1:362331cec9b7 186 int numLeds = (msg[0] * 256) + msg[1];
Bobty 1:362331cec9b7 187 int splitPoint = (msg[2] * 256) + msg[3];
Bobty 1:362331cec9b7 188 pLedStrip->Resize(numLeds, splitPoint);
Bobty 1:362331cec9b7 189 }
Bobty 1:362331cec9b7 190 sprintf(responseStr, "%04x OK Resized", seqCount);
Bobty 1:362331cec9b7 191 break;
Bobty 1:362331cec9b7 192 }
Bobty 1:362331cec9b7 193 case 0x05: // Raw - set LEDs to RGB values from buffer
Bobty 1:362331cec9b7 194 {
Bobty 1:362331cec9b7 195 if (paramsLen > 4)
Bobty 1:362331cec9b7 196 {
Bobty 1:362331cec9b7 197 int startLed = (msg[0] * 256) + msg[1];
Bobty 1:362331cec9b7 198 int numLeds = (msg[2] * 256) + msg[3];
Bobty 1:362331cec9b7 199 if (paramsLen >= numLeds * 3 + 4)
Bobty 1:362331cec9b7 200 {
Bobty 1:362331cec9b7 201 pLedStrip->RawFill(startLed, numLeds, msg+4);
Bobty 1:362331cec9b7 202 // printf("R Q%04x S%d N%d Pa%d Ln%d\r\n", seqCount, startLed, numLeds, paramsLen, mMsgLen);
Bobty 1:362331cec9b7 203 }
Bobty 1:362331cec9b7 204 else
Bobty 1:362331cec9b7 205 {
Bobty 1:362331cec9b7 206 sprintf(responseStr, "%04x RAW FILL - BufLengthMismatch %d", seqCount, paramsLen);
Bobty 1:362331cec9b7 207 }
Bobty 1:362331cec9b7 208 }
Bobty 1:362331cec9b7 209 else
Bobty 1:362331cec9b7 210 {
Bobty 1:362331cec9b7 211 sprintf(responseStr, "%04x RAW FILL - ParamsLen Error %d", seqCount, paramsLen);
Bobty 1:362331cec9b7 212 }
Bobty 1:362331cec9b7 213 break;
Bobty 1:362331cec9b7 214 }
Bobty 1:362331cec9b7 215 case 0x06: // Set pad leds to a colour
Bobty 1:362331cec9b7 216 {
Bobty 1:362331cec9b7 217 #ifdef USE_SPIDEY_GEOM
Bobty 1:362331cec9b7 218 printf("Pad\r\n");
Bobty 1:362331cec9b7 219
Bobty 1:362331cec9b7 220 if (paramsLen > 2)
Bobty 1:362331cec9b7 221 {
Bobty 1:362331cec9b7 222 int padIdx = msg[0];
Bobty 1:362331cec9b7 223 if (padIdx < sizeof(_spideyPads)/sizeof(SpideyPadInfo))
Bobty 1:362331cec9b7 224 {
Bobty 1:362331cec9b7 225 int firstLed = _spideyPads[padIdx].padLeds[0];
Bobty 1:362331cec9b7 226 int numLeds = _spideyPads[padIdx].padLeds[1] - _spideyPads[padIdx].padLeds[0] + 1;
Bobty 1:362331cec9b7 227 if (paramsLen == 4) // Only 1 RGB value
Bobty 1:362331cec9b7 228 pLedStrip->Fill(firstLed, numLeds, msg[1], msg[2], msg[3]);
Bobty 1:362331cec9b7 229 else if (paramsLen == 7) // Two RGB values
Bobty 1:362331cec9b7 230 pLedStrip->Fill(firstLed, numLeds, msg[1], msg[2], msg[3], msg[4], msg[5], msg[6]);
Bobty 1:362331cec9b7 231 }
Bobty 1:362331cec9b7 232 }
Bobty 1:362331cec9b7 233 #endif
Bobty 1:362331cec9b7 234 break;
Bobty 1:362331cec9b7 235 }
Bobty 1:362331cec9b7 236 case 0x07: // Control node
Bobty 1:362331cec9b7 237 {
Bobty 1:362331cec9b7 238 #ifdef USE_SPIDEY_GEOM
Bobty 1:362331cec9b7 239 printf("Node\r\n");
Bobty 1:362331cec9b7 240
Bobty 1:362331cec9b7 241 if (paramsLen == 11)
Bobty 1:362331cec9b7 242 {
Bobty 1:362331cec9b7 243 int nodeIdx = msg[0];
Bobty 1:362331cec9b7 244 if (nodeIdx < sizeof(_spideyNodes)/sizeof(SpideyNodeInfo))
Bobty 1:362331cec9b7 245 {
Bobty 1:362331cec9b7 246 const SpideyNodeInfo& sni = _spideyNodes[nodeIdx];
Bobty 1:362331cec9b7 247
Bobty 1:362331cec9b7 248 // Handle the node leds
Bobty 1:362331cec9b7 249 printf("Node %d leds %d colour %d,%d,%d ... ", nodeIdx, sni.numNodeLeds, msg[2], msg[3], msg[4]);
Bobty 1:362331cec9b7 250 bool setNodeRGB = ((msg[1] & 0x01) != 0);
Bobty 1:362331cec9b7 251 if (setNodeRGB)
Bobty 1:362331cec9b7 252 {
Bobty 1:362331cec9b7 253 for (int i = 0; (i < sni.numNodeLeds) && (i < MAX_SPIDEY_NODE_LEDS); i++)
Bobty 1:362331cec9b7 254 {
Bobty 1:362331cec9b7 255 pLedStrip->Fill(sni.nodeLeds[i], 1, msg[2], msg[3], msg[4]);
Bobty 1:362331cec9b7 256 printf("Led %d", sni.nodeLeds[i]);
Bobty 1:362331cec9b7 257 }
Bobty 1:362331cec9b7 258 }
Bobty 1:362331cec9b7 259 printf("\r\n");
Bobty 1:362331cec9b7 260
Bobty 1:362331cec9b7 261 // Handle the link leds
Bobty 1:362331cec9b7 262 int linkIdx = msg[5];
Bobty 1:362331cec9b7 263 int linkLedStart = msg[6];
Bobty 1:362331cec9b7 264 int linkNumLeds = msg[7];
Bobty 1:362331cec9b7 265 printf("Link %d st %d num %d colour %d,%d,%d ... ", linkIdx, linkLedStart, linkNumLeds, msg[8], msg[9], msg[10]);
Bobty 1:362331cec9b7 266 if ((linkIdx < sni.numLinks) && (linkIdx < MAX_SPIDEY_NODE_LINKS))
Bobty 1:362331cec9b7 267 {
Bobty 1:362331cec9b7 268 const SpideyLinkInfo* pSli = sni.nodeLinks[linkIdx];
Bobty 1:362331cec9b7 269 for (int i = 0; i < linkNumLeds; i++)
Bobty 1:362331cec9b7 270 {
Bobty 1:362331cec9b7 271 int ledIdx = linkLedStart + i;
Bobty 1:362331cec9b7 272 int ledNumA = getLedNumFromSeq(pSli->edgeLedsA, pSli->edgeLengthA, ledIdx);
Bobty 1:362331cec9b7 273 if (ledNumA >= 0)
Bobty 1:362331cec9b7 274 {
Bobty 1:362331cec9b7 275 pLedStrip->Fill(ledNumA, 1, msg[8], msg[9], msg[10]);
Bobty 1:362331cec9b7 276 printf("A=%d/", ledNumA);
Bobty 1:362331cec9b7 277 }
Bobty 1:362331cec9b7 278 int ledNumB = getLedNumFromSeq(pSli->edgeLedsB, pSli->edgeLengthB, ledIdx);
Bobty 1:362331cec9b7 279 if (ledNumB >= 0)
Bobty 1:362331cec9b7 280 {
Bobty 1:362331cec9b7 281 pLedStrip->Fill(ledNumB, 1, msg[8], msg[9], msg[10]);
Bobty 1:362331cec9b7 282 printf("B=%d, ", ledNumB);
Bobty 1:362331cec9b7 283 }
Bobty 1:362331cec9b7 284 }
Bobty 1:362331cec9b7 285 }
Bobty 1:362331cec9b7 286 else
Bobty 1:362331cec9b7 287 {
Bobty 1:362331cec9b7 288 sprintf(responseStr, "%04x NODE - linkInvalid %d", seqCount, linkIdx);
Bobty 1:362331cec9b7 289 }
Bobty 1:362331cec9b7 290 printf("\r\n");
Bobty 1:362331cec9b7 291 }
Bobty 1:362331cec9b7 292 else
Bobty 1:362331cec9b7 293 {
Bobty 1:362331cec9b7 294 sprintf(responseStr, "%04x NODE - nodeInvalid %d", seqCount, nodeIdx);
Bobty 1:362331cec9b7 295 }
Bobty 1:362331cec9b7 296 }
Bobty 1:362331cec9b7 297 else
Bobty 1:362331cec9b7 298 {
Bobty 1:362331cec9b7 299 sprintf(responseStr, "%04x NODE - BufLengthMismatch %d", seqCount, paramsLen);
Bobty 1:362331cec9b7 300 }
Bobty 1:362331cec9b7 301 #endif
Bobty 1:362331cec9b7 302 break;
Bobty 1:362331cec9b7 303 }
Bobty 1:362331cec9b7 304 default:
Bobty 1:362331cec9b7 305 {
Bobty 1:362331cec9b7 306 sprintf(responseStr, "%04x CMD %02x UNKNOWN", seqCount, cmdCode);
Bobty 1:362331cec9b7 307 break;
Bobty 1:362331cec9b7 308 }
Bobty 1:362331cec9b7 309 }
Bobty 1:362331cec9b7 310
Bobty 1:362331cec9b7 311 // Move to next chunk
Bobty 1:362331cec9b7 312 nBytesLeft = nBytesLeft - chunkLen - 2;
Bobty 1:362331cec9b7 313 msg += paramsLen;
Bobty 1:362331cec9b7 314 // printf("Bytesleft = %d, msg[0] = %d\r\n", nBytesLeft, msg[0]);
Bobty 1:362331cec9b7 315 }
Bobty 1:362331cec9b7 316 return responseStr;
Bobty 1:362331cec9b7 317 }