Displays text on a WS2812 (NeoPixel) matrix display
Dependencies: mbed miniFont wsDrive
Displays text on an array of WS2812 LEDs (NeoPixels)
Text is 5 rows tall so any grid larger than that can be used. The font supports A-Z (capitals only, any lowercase input will be capitalised) numbers and some basic punctuation. Letters are 5 LEDs wide, some numbers and punctuation are smaller but generally you need 6 pixels wide per character you wish to fit. If displaying a string a 1 row space is left between characters, for other spacings either edit the code or print one letter at a time and adjust the offset for the next letter.
LEDs must be connected in horizontal rows, top row first. Rows can be either direction or alternating directions.
NOTE: The testing on this has been fairly minimal. It works with my one physical configuration, I think the logic for other configurations is correct but haven't tested it. If you find a problem please let me know.
Diff: main.cpp
- Revision:
- 1:2014f027ed6f
- Parent:
- 0:bada179a0b70
--- a/main.cpp Thu Nov 06 13:55:51 2014 +0000 +++ b/main.cpp Thu Nov 06 17:32:12 2014 +0000 @@ -33,10 +33,12 @@ // LED config options: -//#define cascadeZigZag +// uncomment if the direction of connections reverse each row. +const bool cascadeZigZag = false; +const bool topRowL2R = true; -#define chainLen 35 -#define chainCount 5 +const uint16_t chainLen = 35; +const uint16_t chainCount = 5; // IO setup - currently set for mbuino. @@ -57,22 +59,41 @@ pixelInfo *livePixels; pixelInfo *nextPixels; - +// could be optimised more but most of this is constants so the compiler should +// do that for us. This is confusing enough as it is. +inline bool reverseRow(uint16_t row) +{ + if (cascadeZigZag) { + if (topRowL2R) { // left to right we reverse odd rows + if (row%2) // odd row + return true; + else + return false; + } else { // right to left reverse even rows. + if (row%2) // odd row + return false; + else + return true; + } + } else { + if (topRowL2R) // left to right reverse none + return false; + else // right to left reverse all. + return true; + } +} inline uint16_t xy2index(uint16_t x, uint16_t y) { if (x >= chainLen) x = 0; if (y >= chainCount) - y =0; -#ifdef cascadeZigZag - if (y%2) + y = 0; + + if (reverseRow(y)) return (y+1)*chainLen - x - 1; else return y*chainLen + x; -#else - return y*chainLen + x; -#endif } @@ -91,6 +112,24 @@ } } +void initGradient(pixelInfo *startColour, pixelInfo *endColour) +{ + uint16_t thisPixIndex; + float redDelta = ((float)(endColour->R) - (float)(startColour->R)) / chainLen; + float greenDelta = ((float)(endColour->G) - (float)(startColour->G)) / chainLen; + float blueDelta = ((float)(endColour->B) - (float)(startColour->B)) / chainLen; + + for (int i = 0; i<(chainLen); i++) { + for (uint8_t row = 0; row < chainCount; row++) { + + thisPixIndex = xy2index(i,row); + + nextPixels[thisPixIndex].R = redDelta*i + startColour->R; + nextPixels[thisPixIndex].G = greenDelta*i + startColour->G; + nextPixels[thisPixIndex].B = blueDelta*i + startColour->B; + } + } +} uint16_t initText(const char *text, pixelInfo colour, int16_t startPixel = 0, int16_t startRow = 0) { @@ -152,29 +191,45 @@ void initChain () { pixelInfo textColour; + pixelInfo bgColour1; + pixelInfo bgColour2; // optionally use initColour to set a background colour + bgColour1.R = 0x00; + bgColour1.G = 0x08; + bgColour1.B = 0x00; + + bgColour2.R = 0x08; + bgColour2.G = 0x00; + bgColour2.B = 0x00; + + initGradient(&bgColour1,&bgColour2); // set text colour - textColour.R = 0x30; - textColour.G = 0x30; + textColour.R = 0x40; + textColour.G = 0x00; textColour.B = 0x00; // add text keeping the index for the next character. uint16_t nextChar = initText("H", textColour); - // change the colour textColour.R = 0x10; textColour.G = 0x10; textColour.B = 0x30; // add more text. - nextChar = initText("ell", textColour, nextChar); + nextChar = initText("el", textColour, nextChar); + // change the colour + textColour.R = 0x30; + textColour.G = 0x30; + textColour.B = 0x00; + // add more text. + nextChar = initText("l", textColour, nextChar); // one more colour - textColour.R = 0x40; - textColour.G = 0x00; + textColour.R = 0x00; + textColour.G = 0x40; textColour.B = 0x00; // and a final letter. initText("0", textColour, nextChar); @@ -203,34 +258,40 @@ for (uint16_t col = 0; col<chainLen; col++) { for (uint8_t row = 0; row < chainCount; row++) { -#ifdef cascadeZigZag - if (row % 2) { - thisPixIndex = chainLen - col - 1 + row*chainLen; - redPixIndex = chainLen - redStep - 1 + row*chainLen; - greenPixIndex = chainLen - greenStep - 1 + row*chainLen; - bluePixIndex = chainLen - blueStep - 1 + row*chainLen; - } else -#endif - { - thisPixIndex = col + row*chainLen; - redPixIndex = redStep + row*chainLen; - greenPixIndex = greenStep + row*chainLen; - bluePixIndex = blueStep + row*chainLen; - } + thisPixIndex = xy2index(col,row); + + redPixIndex = xy2index((col+redStep)%chainLen, row); + bluePixIndex = xy2index((col+blueStep)%chainLen, row); + greenPixIndex = xy2index((col+greenStep)%chainLen,row); nextPixels[thisPixIndex].R = livePixels[redPixIndex].R; nextPixels[thisPixIndex].G = livePixels[greenPixIndex].G; nextPixels[thisPixIndex].B = livePixels[bluePixIndex].B; } - redStep = (redStep+1) % chainLen; - greenStep = (greenStep+1) % chainLen; - blueStep = (blueStep+1) % chainLen; } } + void rotateChain (int stepsLeft) { - rotateChain(stepsLeft,stepsLeft,stepsLeft); + while (stepsLeft < 0) + stepsLeft += chainLen; + + uint16_t thisPixIndex; + uint16_t sourcePixIndex; + + for (uint16_t col = 0; col<chainLen; col++) { + for (uint8_t row = 0; row < chainCount; row++) { + + thisPixIndex = xy2index(col,row); + + sourcePixIndex = xy2index((col+stepsLeft)%chainLen, row); + + nextPixels[thisPixIndex].R = livePixels[sourcePixIndex].R; + nextPixels[thisPixIndex].G = livePixels[sourcePixIndex].G; + nextPixels[thisPixIndex].B = livePixels[sourcePixIndex].B; + } + } }