Add Concentric Ring Topology (#154)

This commit is contained in:
Michael Miller
2017-01-14 12:50:35 -08:00
committed by GitHub
parent 033fbe68c0
commit f182797159
4 changed files with 195 additions and 0 deletions

View File

@@ -0,0 +1,100 @@
//----------------------------------------------------------------------
// NeoPixelRingTopologyTest
// This will display specific colors in specific locations on the led rings
//
// This is useful in confirming the layout of your rings
//
// It does require that you have the actual series of rings connected
//----------------------------------------------------------------------
#include <NeoPixelBus.h>
const uint8_t PixelCount = 119;
const uint8_t PixelPin = 2; // make sure to set this to the correct pin, ignored for Esp8266
// define the layout of your series of rings
//
// This example is using all of Adafruits rings and a Jewel in the center.
// The center is the input and all the rings are connected in series going outward
//
// Rings:
// 0 - 1 (virtual ring, the center of the jewel)
// 1 - 6 (virtual ring, the outer ring of the jewel)
// 2 - 12 count ring
// 3 - 16 count ring
// 4 - 24 count ring
// 5 - 60 count ring comprised of four arc segments
//
// The values below in Rings[] are the index of the first pixel in each ring.
// An extra value is appended for a virtual ring start that also
// represents the total count of pixels in the complete series and this extra
// value is required.
//
class MyRingsLayout
{
protected:
const uint16_t Rings[7] = {0, 1, 7, 19, 35, 59, PixelCount};
};
// use the MyRingsLayout to declare the topo object
//
NeoRingTopology<MyRingsLayout> topo;
// declare our strip
//
NeoPixelBus<NeoGrbFeature, Neo800KbpsMethod> strip(PixelCount, PixelPin);
// define some handy colors
//
RgbColor red(128, 0, 0);
RgbColor green(0, 128, 0);
RgbColor blue(0, 0, 128);
RgbColor black(0);
void setup()
{
Serial.begin(115200);
while (!Serial); // wait for serial attach
Serial.println();
Serial.println("Initializing...");
strip.Begin();
strip.Show();
Serial.println();
Serial.println("Running...");
}
void loop()
{
delay(2500);
Serial.println();
Serial.println("If your panel is correctly defined, you should see ...");
Serial.println("First pixel in each ring is Red.");
Serial.println("Middle pixel in each ring is Green.");
Serial.println("Last Pixel in each ring is Blue.");
// use the topo to map the 2d polar cordinate to the pixel
// and use that to SetPixelColor
for (uint16_t ring = 0; ring < topo.getCountOfRings(); ring++)
{
// first pixel in each ring is red
strip.SetPixelColor(topo.Map(ring, 0), red);
// last pixel in each ring is blue
strip.SetPixelColor(topo.Map(ring, topo.getPixelCountAtRing(ring) - 1), blue);
// middle pixel in each ring is green
strip.SetPixelColor(topo.Map(ring, topo.getPixelCountAtRing(ring) / 2), green);
}
strip.Show();
delay(5000);
Serial.println();
Serial.println("Cleared to black ...");
strip.ClearTo(black);
strip.Show();
}

View File

@@ -56,6 +56,7 @@ ColumnMajorAlternating90Layout KEYWORD1
ColumnMajorAlternating180Layout KEYWORD1 ColumnMajorAlternating180Layout KEYWORD1
ColumnMajorAlternating270Layout KEYWORD1 ColumnMajorAlternating270Layout KEYWORD1
NeoTopology KEYWORD1 NeoTopology KEYWORD1
NeoRingTopology KEYWORD1
NeoTiles KEYWORD1 NeoTiles KEYWORD1
NeoMosaic KEYWORD1 NeoMosaic KEYWORD1
NeoGammaEquationMethod KEYWORD1 NeoGammaEquationMethod KEYWORD1
@@ -139,6 +140,9 @@ Map KEYWORD2
MapProbe KEYWORD2 MapProbe KEYWORD2
getWidth KEYWORD2 getWidth KEYWORD2
getHeight KEYWORD2 getHeight KEYWORD2
getCountOfRings KEYWORD2
getPixelCountAtRing KEYWORD2
getPixelCount KEYWORD2
TopologyHint KEYWORD2 TopologyHint KEYWORD2
Correct KEYWORD2 Correct KEYWORD2
SpriteWidth KEYWORD2 SpriteWidth KEYWORD2
@@ -151,6 +155,7 @@ Parse KEYWORD2
ToString KEYWORD2 ToString KEYWORD2
ToNumericalString KEYWORD2 ToNumericalString KEYWORD2
####################################### #######################################
# Constants (LITERAL1) # Constants (LITERAL1)
####################################### #######################################

View File

@@ -40,6 +40,7 @@ License along with NeoPixel. If not, see
#include "internal/Layouts.h" #include "internal/Layouts.h"
#include "internal/NeoTopology.h" #include "internal/NeoTopology.h"
#include "internal/NeoRingTopology.h"
#include "internal/NeoTiles.h" #include "internal/NeoTiles.h"
#include "internal/NeoMosaic.h" #include "internal/NeoMosaic.h"

View File

@@ -0,0 +1,89 @@
#pragma once
/*-------------------------------------------------------------------------
NeoRingTopology provides a mapping feature of a 2d polar cordinate to a
linear 1d cordinate.
It is used to map a series of concentric rings of NeoPixels to a index on
the NeoPixelBus.
Written by Michael C. Miller.
I invest time and resources providing this open source code,
please support me by dontating (see https://github.com/Makuna/NeoPixelBus)
-------------------------------------------------------------------------
This file is part of the Makuna/NeoPixelBus library.
NeoPixelBus is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as
published by the Free Software Foundation, either version 3 of
the License, or (at your option) any later version.
NeoPixelBus is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with NeoPixel. If not, see
<http://www.gnu.org/licenses/>.
-------------------------------------------------------------------------*/
template <typename T_LAYOUT> class NeoRingTopology : protected T_LAYOUT
{
public:
NeoRingTopology()
{
}
uint16_t Map(uint8_t ring, uint16_t pixel) const
{
if (pixel >= getPixelCountAtRing(ring))
{
return 0; // invalid ring and/or pixel argument, always return a valid value, the first one
}
return _map(ring, pixel);
}
uint16_t MapProbe(uint8_t ring, uint16_t pixel) const
{
if (pixel >= getPixelCountAtRing(ring))
{
return getPixelCount(); // total count, out of bounds
}
return _map(ring, pixel);
}
uint16_t getCountOfRings() const
{
return _ringCount() - 1; // minus one as the Rings includes the extra value
}
uint16_t getPixelCountAtRing(uint16_t ring) const
{
if (ring >= getCountOfRings())
{
return 0; // invalid, no pixels
}
return T_LAYOUT::Rings[ring + 1] - T_LAYOUT::Rings[ring]; // using the extra value for count calc
}
uint16_t getPixelCount() const
{
T_LAYOUT::Rings[_ringCount() - 1]; // the last entry is the total count
}
private:
uint16_t _map(uint16_t ring, uint16_t pixel) const
{
return T_LAYOUT::Rings[ring] + pixel;
}
uint16_t _ringCount() const
{
return sizeof(T_LAYOUT::Rings) / sizeof(T_LAYOUT::Rings[0]);
}
};