forked from Makuna/NeoPixelBus
Topology, Curves, Gamma, and Samples
Topology, Tiles, and Mosaic layout Animation Curves Color Gamma correct change timescale dynamically on NeoPixelAnimator bilinear color blend methods new samples to support new features
This commit is contained in:
14
ReadMe.md
14
ReadMe.md
@@ -8,6 +8,7 @@ A library to control one wire protocol RGB and RGBW leds like SK6812, WS2811, an
|
|||||||
Supports most Arduino platforms.
|
Supports most Arduino platforms.
|
||||||
This is the most funtional library for the Esp8266 as it provides solutions for all Esp8266 module types even when WiFi is used.
|
This is the most funtional library for the Esp8266 as it provides solutions for all Esp8266 module types even when WiFi is used.
|
||||||
|
|
||||||
|
|
||||||
Please read this best practices link before connecting your NeoPixels, it will save you alot of time and effort.
|
Please read this best practices link before connecting your NeoPixels, it will save you alot of time and effort.
|
||||||
[Adafruit NeoPixel Best Practices](https://learn.adafruit.com/adafruit-neopixel-uberguide/best-practices)
|
[Adafruit NeoPixel Best Practices](https://learn.adafruit.com/adafruit-neopixel-uberguide/best-practices)
|
||||||
|
|
||||||
@@ -16,21 +17,18 @@ For quick questions jump on Gitter and ask away.
|
|||||||
|
|
||||||
For bugs, make sure there isn't an active issue and then create one.
|
For bugs, make sure there isn't an active issue and then create one.
|
||||||
|
|
||||||
This new library supports a templatized model of defining which method gets used to send data and what order and size the pixel data is sent in. This new design creates the smallest code for each definition of features used. Further it allows for picking which method to send the data on the Esp8266 in an easy to change way.
|
## Documentation
|
||||||
Please see examples to become familiar with the new design.
|
[See Wiki](https://github.com/Makuna/NeoPixelBus/wiki)
|
||||||
Due to this design you will often realize over 500 bytes of more program storage for your sketch. Important for the smallest Arduinos project.
|
|
||||||
|
|
||||||
|
## Installing This Library (prefered, you just want to use it)
|
||||||
## Installing This Library (prefered)
|
|
||||||
Open the Library Manager and search for "NeoPixelBus by Makuna" and install
|
Open the Library Manager and search for "NeoPixelBus by Makuna" and install
|
||||||
|
|
||||||
## Installing This Library From GitHub
|
## Installing This Library From GitHub (advanced, you want to contribute)
|
||||||
Create a directory in your Arduino\Library folder named "NeoPixelBus"
|
Create a directory in your Arduino\Library folder named "NeoPixelBus"
|
||||||
Clone (Git) this project into that folder.
|
Clone (Git) this project into that folder.
|
||||||
It should now show up in the import list when you restart Arduino IDE.
|
It should now show up in the import list when you restart Arduino IDE.
|
||||||
|
|
||||||
## Documentation
|
|
||||||
[See Wiki](https://github.com/Makuna/NeoPixelBus/wiki)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
121
examples/NeoPixelCylon/NeoPixelCylon.ino
Normal file
121
examples/NeoPixelCylon/NeoPixelCylon.ino
Normal file
@@ -0,0 +1,121 @@
|
|||||||
|
// NeoPixelCylon
|
||||||
|
// This example will move a Cylong Red Eye back and forth across the
|
||||||
|
// the full collection of pixels on the strip.
|
||||||
|
//
|
||||||
|
// This will demonstrate the use of the NeoEase animation ease methods; that provide
|
||||||
|
// simulated acceleration to the animations.
|
||||||
|
//
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <NeoPixelBus.h>
|
||||||
|
#include <NeoPixelAnimator.h>
|
||||||
|
|
||||||
|
const uint16_t PixelCount = 16; // make sure to set this to the number of pixels in your strip
|
||||||
|
const uint8_t PixelPin = 2; // make sure to set this to the correct pin, ignored for Esp8266
|
||||||
|
const RgbColor CylonEyeColor(HtmlColor(0x7f0000));
|
||||||
|
|
||||||
|
NeoPixelBus<NeoGrbFeature, Neo800KbpsMethod> strip(PixelCount, PixelPin);
|
||||||
|
|
||||||
|
NeoPixelAnimator animations(2); // only ever need 2 animations
|
||||||
|
|
||||||
|
uint16_t lastPixel = 0; // track the eye position
|
||||||
|
int8_t moveDir = 1; // track the direction of movement
|
||||||
|
|
||||||
|
// uncomment one of the lines below to see the effects of
|
||||||
|
// changing the ease function on the movement animation
|
||||||
|
AnimEaseFunction moveEase =
|
||||||
|
// NeoEase::Linear;
|
||||||
|
// NeoEase::QuadraticInOut;
|
||||||
|
// NeoEase::CubicInOut;
|
||||||
|
NeoEase::QuarticInOut;
|
||||||
|
// NeoEase::QuinticInOut;
|
||||||
|
// NeoEase::SinusoidalInOut;
|
||||||
|
// NeoEase::ExponentialInOut;
|
||||||
|
// NeoEase::CircularInOut;
|
||||||
|
|
||||||
|
void FadeAll(uint8_t darkenBy)
|
||||||
|
{
|
||||||
|
RgbColor color;
|
||||||
|
for (uint16_t indexPixel = 0; indexPixel < strip.PixelCount(); indexPixel++)
|
||||||
|
{
|
||||||
|
color = strip.GetPixelColor(indexPixel);
|
||||||
|
color.Darken(darkenBy);
|
||||||
|
strip.SetPixelColor(indexPixel, color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void FadeAnimUpdate(const AnimationParam& param)
|
||||||
|
{
|
||||||
|
if (param.state == AnimationState_Completed)
|
||||||
|
{
|
||||||
|
FadeAll(10);
|
||||||
|
animations.RestartAnimation(param.index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MoveAnimUpdate(const AnimationParam& param)
|
||||||
|
{
|
||||||
|
// apply the movement animation curve
|
||||||
|
float progress = moveEase(param.progress);
|
||||||
|
|
||||||
|
// use the curved progress to calculate the pixel to effect
|
||||||
|
uint16_t nextPixel;
|
||||||
|
if (moveDir > 0)
|
||||||
|
{
|
||||||
|
nextPixel = progress * PixelCount;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
nextPixel = (1.0f - progress) * PixelCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
// if progress moves fast enough, we may move more than
|
||||||
|
// one pixel, so we update all between the calculated and
|
||||||
|
// the last
|
||||||
|
if (lastPixel != nextPixel)
|
||||||
|
{
|
||||||
|
for (uint16_t i = lastPixel + moveDir; i != nextPixel; i += moveDir)
|
||||||
|
{
|
||||||
|
strip.SetPixelColor(i, CylonEyeColor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
strip.SetPixelColor(nextPixel, CylonEyeColor);
|
||||||
|
|
||||||
|
lastPixel = nextPixel;
|
||||||
|
|
||||||
|
if (param.state == AnimationState_Completed)
|
||||||
|
{
|
||||||
|
// reverse direction of movement
|
||||||
|
moveDir *= -1;
|
||||||
|
|
||||||
|
// done, time to restart this position tracking animation/timer
|
||||||
|
animations.RestartAnimation(param.index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetupAnimations()
|
||||||
|
{
|
||||||
|
// fade all pixels providing a tail that is longer the faster
|
||||||
|
// the pixel moves.
|
||||||
|
animations.StartAnimation(0, 5, FadeAnimUpdate);
|
||||||
|
|
||||||
|
// take several seconds to move eye fron one side to the other
|
||||||
|
animations.StartAnimation(1, 2000, MoveAnimUpdate);
|
||||||
|
}
|
||||||
|
|
||||||
|
void setup()
|
||||||
|
{
|
||||||
|
strip.Begin();
|
||||||
|
strip.Show();
|
||||||
|
|
||||||
|
SetupAnimations();
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop()
|
||||||
|
{
|
||||||
|
// this is all that is needed to keep it running
|
||||||
|
// and avoiding using delay() is always a good thing for
|
||||||
|
// any timing related routines
|
||||||
|
animations.UpdateAnimations();
|
||||||
|
strip.Show();
|
||||||
|
}
|
93
examples/NeoPixelGamma/NeoPixelGamma.ino
Normal file
93
examples/NeoPixelGamma/NeoPixelGamma.ino
Normal file
@@ -0,0 +1,93 @@
|
|||||||
|
// NeoPixelGamma
|
||||||
|
// This example will display a timed series of color gradiants with gamma correction
|
||||||
|
// and then without.
|
||||||
|
// If the last pixel is on, then the colors being shown are color corrected.
|
||||||
|
// It will show Red grandiant, Green grandiant, Blue grandiant, a White grandiant, and
|
||||||
|
// then repeat.
|
||||||
|
//
|
||||||
|
// This will demonstrate the use of the NeoGamma class
|
||||||
|
//
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <NeoPixelBus.h>
|
||||||
|
#include <NeoPixelAnimator.h>
|
||||||
|
|
||||||
|
const uint16_t PixelCount = 16; // make sure to set this to the number of pixels in your strip
|
||||||
|
const uint8_t PixelPin = 2; // make sure to set this to the correct pin, ignored for Esp8266
|
||||||
|
|
||||||
|
NeoPixelBus<NeoGrbFeature, Neo800KbpsMethod> strip(PixelCount, PixelPin);
|
||||||
|
|
||||||
|
// uncomment only one of these to compare memory use or speed
|
||||||
|
//
|
||||||
|
// NeoGamma<NeoGammaEquationMethod> gamma;
|
||||||
|
NeoGamma<NeoGammaTableMethod> gamma;
|
||||||
|
|
||||||
|
void DrawPixels(bool corrected, HslColor startColor, HslColor stopColor)
|
||||||
|
{
|
||||||
|
for (uint16_t index = 0; index < strip.PixelCount() - 1; index++)
|
||||||
|
{
|
||||||
|
float progress = index / static_cast<float>(strip.PixelCount() - 2);
|
||||||
|
RgbColor color = HslColor::LinearBlend(startColor, stopColor, progress);
|
||||||
|
if (corrected)
|
||||||
|
{
|
||||||
|
color = gamma.Correct(color);
|
||||||
|
}
|
||||||
|
strip.SetPixelColor(index, color);
|
||||||
|
}
|
||||||
|
|
||||||
|
// use the last pixel to indicate if we are showing corrected colors or not
|
||||||
|
if (corrected)
|
||||||
|
{
|
||||||
|
strip.SetPixelColor(strip.PixelCount() - 1, RgbColor(64));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
strip.SetPixelColor(strip.PixelCount() - 1, RgbColor(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
strip.Show();
|
||||||
|
}
|
||||||
|
|
||||||
|
void setup()
|
||||||
|
{
|
||||||
|
strip.Begin();
|
||||||
|
strip.Show();
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop()
|
||||||
|
{
|
||||||
|
HslColor startColor;
|
||||||
|
HslColor stopColor;
|
||||||
|
|
||||||
|
// red color
|
||||||
|
startColor = HslColor(0.0f, 1.0f, 0.0f);
|
||||||
|
stopColor = HslColor(0.0f, 1.0f, 0.5f);
|
||||||
|
DrawPixels(true, startColor, stopColor);
|
||||||
|
delay(5000);
|
||||||
|
DrawPixels(false, startColor, stopColor);
|
||||||
|
delay(5000);
|
||||||
|
|
||||||
|
// green color
|
||||||
|
startColor = HslColor(0.33f, 1.0f, 0.0f);
|
||||||
|
stopColor = HslColor(0.33f, 1.0f, 0.5f);
|
||||||
|
DrawPixels(true, startColor, stopColor);
|
||||||
|
delay(5000);
|
||||||
|
DrawPixels(false, startColor, stopColor);
|
||||||
|
delay(5000);
|
||||||
|
|
||||||
|
// blue color
|
||||||
|
startColor = HslColor(0.66f, 1.0f, 0.0f);
|
||||||
|
stopColor = HslColor(0.66f, 1.0f, 0.5f);
|
||||||
|
DrawPixels(true, startColor, stopColor);
|
||||||
|
delay(5000);
|
||||||
|
DrawPixels(false, startColor, stopColor);
|
||||||
|
delay(5000);
|
||||||
|
|
||||||
|
// white color
|
||||||
|
startColor = HslColor(0.0f, 0.0f, 0.0f);
|
||||||
|
stopColor = HslColor(0.0f, 0.0f, 0.5f);
|
||||||
|
DrawPixels(true, startColor, stopColor);
|
||||||
|
delay(5000);
|
||||||
|
DrawPixels(false, startColor, stopColor);
|
||||||
|
delay(5000);
|
||||||
|
}
|
98
examples/NeoPixelMosaicDump/NeoPixelMosaicDump.ino
Normal file
98
examples/NeoPixelMosaicDump/NeoPixelMosaicDump.ino
Normal file
@@ -0,0 +1,98 @@
|
|||||||
|
//----------------------------------------------------------------------
|
||||||
|
// NeoPixelMosaicDump
|
||||||
|
// This will dump to the serial output a grid map of the defined mosaic
|
||||||
|
// The output is displayed as row column labeled grid with the NeoPixelBus
|
||||||
|
// index of the pixel at the intersection of the row and column.
|
||||||
|
//
|
||||||
|
// To help with physical layout, there maybe included a symbol following the index
|
||||||
|
// < means the index is the input index for the panel, the first on the panel
|
||||||
|
// > means the index is the output index for the panel, the last on the panel
|
||||||
|
//
|
||||||
|
// This is useful in visualising the mosaic layout of your panels to
|
||||||
|
// confirm you have them correctly wired together for this mosaic pattern
|
||||||
|
//
|
||||||
|
// It does not require that you have the actual panel connected
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
|
||||||
|
#include <NeoPixelAnimator.h>
|
||||||
|
#include <NeoPixelBus.h>
|
||||||
|
|
||||||
|
// uncomment one of these that matches your panel pixel layouts
|
||||||
|
// rotation is ignored for mosaic as it applies a rotation for you
|
||||||
|
// that is specific to the location of the panel within the mosaic
|
||||||
|
// to reduce connection lengths
|
||||||
|
|
||||||
|
typedef ColumnMajorAlternatingLayout MyPanelLayout;
|
||||||
|
// typedef ColumnMajorLayout MyPanelLayout;
|
||||||
|
// typedef RowMajorAlternatingLayout MyPanelLayout;
|
||||||
|
// typedef RowMajorLayout MyPanelLayout;
|
||||||
|
|
||||||
|
// make sure to set these panel and tile layout to match your sizes
|
||||||
|
const uint8_t PanelWidth = 8; // a 8 pixel x 8 pixel matrix of leds on the panel
|
||||||
|
const uint8_t PanelHeight = 8;
|
||||||
|
const uint8_t TileWidth = 4; // laid out in 4 panels x 2 panels mosaic
|
||||||
|
const uint8_t TileHeight = 2;
|
||||||
|
|
||||||
|
NeoMosaic <MyPanelLayout> mosaic(
|
||||||
|
PanelWidth,
|
||||||
|
PanelHeight,
|
||||||
|
TileWidth,
|
||||||
|
TileHeight);
|
||||||
|
|
||||||
|
void DumpMosaic()
|
||||||
|
{
|
||||||
|
Serial.println();
|
||||||
|
|
||||||
|
Serial.print("\t\t");
|
||||||
|
for (int x = 0; x < mosaic.getWidth(); x++)
|
||||||
|
{
|
||||||
|
Serial.print(x);
|
||||||
|
Serial.print("\t");
|
||||||
|
}
|
||||||
|
Serial.println();
|
||||||
|
|
||||||
|
Serial.print("\t---");
|
||||||
|
for (int x = 0; x < mosaic.getWidth(); x++)
|
||||||
|
{
|
||||||
|
Serial.print("--------");
|
||||||
|
}
|
||||||
|
Serial.println();
|
||||||
|
|
||||||
|
for (int y = 0; y < mosaic.getHeight(); y++)
|
||||||
|
{
|
||||||
|
Serial.print(" ");
|
||||||
|
Serial.print(y);
|
||||||
|
Serial.print("\t|\t");
|
||||||
|
|
||||||
|
for (int x = 0; x < mosaic.getWidth(); x++)
|
||||||
|
{
|
||||||
|
NeoTopologyHint hint = mosaic.TopologyHint(x, y);
|
||||||
|
|
||||||
|
Serial.print(mosaic.Map(x, y));
|
||||||
|
if (hint == NeoTopologyHint_FirstOnPanel)
|
||||||
|
{
|
||||||
|
Serial.print("<");
|
||||||
|
}
|
||||||
|
else if (hint == NeoTopologyHint_LastOnPanel)
|
||||||
|
{
|
||||||
|
Serial.print(">");
|
||||||
|
}
|
||||||
|
Serial.print("\t");
|
||||||
|
}
|
||||||
|
Serial.println();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void setup()
|
||||||
|
{
|
||||||
|
Serial.begin(115200);
|
||||||
|
while (!Serial); // wait for serial attach
|
||||||
|
|
||||||
|
DumpMosaic();
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
97
examples/NeoPixelMosaicTest/NeoPixelMosaicTest.ino
Normal file
97
examples/NeoPixelMosaicTest/NeoPixelMosaicTest.ino
Normal file
@@ -0,0 +1,97 @@
|
|||||||
|
//----------------------------------------------------------------------
|
||||||
|
// NeoPixelTopologyTest
|
||||||
|
// This will display specific colors in specific locations on the led panels
|
||||||
|
//
|
||||||
|
// This is useful in confirming the layout of your panels
|
||||||
|
//
|
||||||
|
// It does require that you have the actual panels connected
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
|
||||||
|
#include <NeoPixelAnimator.h>
|
||||||
|
#include <NeoPixelBus.h>
|
||||||
|
|
||||||
|
// uncomment one of these that matches your panel pixel layouts
|
||||||
|
// rotation is ignored for mosaic as it applies a rotation for you
|
||||||
|
// that is specific to the location of the panel within the mosaic
|
||||||
|
// to reduce connection lengths
|
||||||
|
|
||||||
|
typedef ColumnMajorAlternatingLayout MyPanelLayout;
|
||||||
|
// typedef ColumnMajorLayout MyPanelLayout;
|
||||||
|
// typedef RowMajorAlternatingLayout MyPanelLayout;
|
||||||
|
// typedef RowMajorLayout MyPanelLayout;
|
||||||
|
|
||||||
|
// make sure to set these panel values to the sizes of yours
|
||||||
|
const uint8_t PanelWidth = 8; // 8 pixel x 8 pixel matrix of leds
|
||||||
|
const uint8_t PanelHeight = 8;
|
||||||
|
const uint8_t TileWidth = 4; // laid out in 4 panels x 2 panels mosaic
|
||||||
|
const uint8_t TileHeight = 2;
|
||||||
|
|
||||||
|
const uint16_t PixelCount = PanelWidth * PanelHeight * TileWidth * TileHeight;
|
||||||
|
const uint8_t PixelPin = 2;
|
||||||
|
|
||||||
|
NeoMosaic <MyPanelLayout> mosaic(
|
||||||
|
PanelWidth,
|
||||||
|
PanelHeight,
|
||||||
|
TileWidth,
|
||||||
|
TileHeight);
|
||||||
|
|
||||||
|
NeoPixelBus<NeoGrbFeature, Neo800KbpsMethod> strip(PixelCount, PixelPin);
|
||||||
|
//NeoPixelBus<NeoRgbFeature, Neo800KbpsMethod> strip(PixelCount, PixelPin);
|
||||||
|
//NeoPixelBus<NeoRgbwFeature, Neo800KbpsMethod> strip(PixelCount, PixelPin);
|
||||||
|
|
||||||
|
RgbColor red(128, 0, 0);
|
||||||
|
RgbColor green(0, 128, 0);
|
||||||
|
RgbColor blue(0, 0, 128);
|
||||||
|
RgbColor white(128);
|
||||||
|
// if using NeoRgbwFeature above, use this white instead to use
|
||||||
|
// the correct white element of the LED
|
||||||
|
//RgbwColor white(128);
|
||||||
|
RgbColor black(0);
|
||||||
|
|
||||||
|
const uint16_t left = 0;
|
||||||
|
const uint16_t right = PanelWidth - 1;
|
||||||
|
const uint16_t top = 0;
|
||||||
|
const uint16_t bottom = PanelHeight - 1;
|
||||||
|
|
||||||
|
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("Upper left is white.");
|
||||||
|
Serial.println("Upper right is Red.");
|
||||||
|
Serial.println("Lower right is Green");
|
||||||
|
Serial.println("Lower Left is Blue");
|
||||||
|
|
||||||
|
// use the topo to map the 2d cordinate to the pixel
|
||||||
|
// and use that to SetPixelColor
|
||||||
|
strip.SetPixelColor(mosaic.Map(left, top), white);
|
||||||
|
strip.SetPixelColor(mosaic.Map(right, top), red);
|
||||||
|
strip.SetPixelColor(mosaic.Map(right, bottom), green);
|
||||||
|
strip.SetPixelColor(mosaic.Map(left, bottom), blue);
|
||||||
|
strip.Show();
|
||||||
|
|
||||||
|
delay(5000);
|
||||||
|
|
||||||
|
Serial.println();
|
||||||
|
Serial.println("Cleared to black ...");
|
||||||
|
strip.ClearTo(black);
|
||||||
|
strip.Show();
|
||||||
|
}
|
||||||
|
|
102
examples/NeoPixelTilesDump/NeoPixelTilesDump.ino
Normal file
102
examples/NeoPixelTilesDump/NeoPixelTilesDump.ino
Normal file
@@ -0,0 +1,102 @@
|
|||||||
|
//----------------------------------------------------------------------
|
||||||
|
// NeoPixelTileDump
|
||||||
|
// This will dump to the serial output a grid map of the defined tiles
|
||||||
|
// The output is displayed as row column labeled grid with the NeoPixelBus
|
||||||
|
// index of the pixel at the intersection of the row and column
|
||||||
|
//
|
||||||
|
// To help with physical layout, there maybe included a symbol following the index
|
||||||
|
// < means the index is the input index for the panel, the first on the panel
|
||||||
|
// > means the index is the output index for the panel, the last on the panel
|
||||||
|
//
|
||||||
|
// This is useful in visualising the tile layout of your panels to
|
||||||
|
// confirm you have them correctly wired together for the defined pattern
|
||||||
|
//
|
||||||
|
// It does not require that you have the actual panel connected
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
|
||||||
|
#include <NeoPixelAnimator.h>
|
||||||
|
#include <NeoPixelBus.h>
|
||||||
|
|
||||||
|
// uncomment one of these that matches your panel pixel layouts and
|
||||||
|
// how you want them rotated. Not all the rotations are listed here
|
||||||
|
// but you can modifiy the name to include the rotation of 90,180, or 270.
|
||||||
|
|
||||||
|
typedef ColumnMajorAlternatingLayout MyPanelLayout;
|
||||||
|
// typedef ColumnMajorLayout MyPanelLayout;
|
||||||
|
// typedef RowMajorAlternatingLayout MyPanelLayout;
|
||||||
|
// typedef RowMajorLayout MyPanelLayout;
|
||||||
|
// typedef RowMajor90Layout MyPanelLayout; // note rotation 90 was used
|
||||||
|
|
||||||
|
// change this to be one of the layouts which will define the layout
|
||||||
|
// of the panels themselves
|
||||||
|
typedef ColumnMajorLayout MyTilesLayout;
|
||||||
|
|
||||||
|
// make sure to set these panel and tile layout to match your sizes
|
||||||
|
const uint8_t PanelWidth = 8; // 8 pixel x 8 pixel matrix of leds
|
||||||
|
const uint8_t PanelHeight = 8;
|
||||||
|
const uint8_t TileWidth = 4; // laid out in 4 panels x 2 panels mosaic
|
||||||
|
const uint8_t TileHeight = 2;
|
||||||
|
|
||||||
|
NeoTiles <MyPanelLayout, MyTilesLayout> tiles(
|
||||||
|
PanelWidth,
|
||||||
|
PanelHeight,
|
||||||
|
TileWidth,
|
||||||
|
TileHeight);
|
||||||
|
|
||||||
|
void DumpTopo()
|
||||||
|
{
|
||||||
|
Serial.println();
|
||||||
|
|
||||||
|
Serial.print("\t\t");
|
||||||
|
for (int x = 0; x < tiles.getWidth(); x++)
|
||||||
|
{
|
||||||
|
Serial.print(x);
|
||||||
|
Serial.print("\t");
|
||||||
|
}
|
||||||
|
Serial.println();
|
||||||
|
|
||||||
|
Serial.print("\t---");
|
||||||
|
for (int x = 0; x < tiles.getWidth(); x++)
|
||||||
|
{
|
||||||
|
Serial.print("--------");
|
||||||
|
}
|
||||||
|
Serial.println();
|
||||||
|
|
||||||
|
for (int y = 0; y < tiles.getHeight(); y++)
|
||||||
|
{
|
||||||
|
Serial.print(" ");
|
||||||
|
Serial.print(y);
|
||||||
|
Serial.print("\t|\t");
|
||||||
|
|
||||||
|
for (int x = 0; x < tiles.getWidth(); x++)
|
||||||
|
{
|
||||||
|
NeoTopologyHint hint = tiles.TopologyHint(x, y);
|
||||||
|
|
||||||
|
Serial.print(tiles.Map(x, y));
|
||||||
|
if (hint == NeoTopologyHint_FirstOnPanel)
|
||||||
|
{
|
||||||
|
Serial.print("<");
|
||||||
|
}
|
||||||
|
else if (hint == NeoTopologyHint_LastOnPanel)
|
||||||
|
{
|
||||||
|
Serial.print(">");
|
||||||
|
}
|
||||||
|
Serial.print("\t");
|
||||||
|
}
|
||||||
|
Serial.println();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void setup()
|
||||||
|
{
|
||||||
|
Serial.begin(115200);
|
||||||
|
while (!Serial); // wait for serial attach
|
||||||
|
|
||||||
|
DumpTopo();
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
101
examples/NeoPixelTilesTest/NeoPixelTilesTest.ino
Normal file
101
examples/NeoPixelTilesTest/NeoPixelTilesTest.ino
Normal file
@@ -0,0 +1,101 @@
|
|||||||
|
//----------------------------------------------------------------------
|
||||||
|
// NeoPixelTilesTest
|
||||||
|
// This will display specific colors in specific locations on the led panels
|
||||||
|
//
|
||||||
|
// This is useful in confirming the layout of your panels
|
||||||
|
//
|
||||||
|
// It does require that you have the actual panels connected
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
|
||||||
|
#include <NeoPixelAnimator.h>
|
||||||
|
#include <NeoPixelBus.h>
|
||||||
|
|
||||||
|
// uncomment one of these that matches your panel pixel layouts and
|
||||||
|
// how you want them rotated. Not all the rotations are listed here
|
||||||
|
// but you can modifiy the name to include the rotation of 90,180, or 270.
|
||||||
|
|
||||||
|
typedef ColumnMajorAlternatingLayout MyPanelLayout;
|
||||||
|
// typedef ColumnMajorLayout MyPanelLayout;
|
||||||
|
// typedef RowMajorAlternatingLayout MyPanelLayout;
|
||||||
|
// typedef RowMajorLayout MyPanelLayout;
|
||||||
|
// typedef RowMajor90Layout MyPanelLayout; // note rotation 90 was used
|
||||||
|
|
||||||
|
// change this to be one of the layouts which will define the layout
|
||||||
|
// of the panels themselves
|
||||||
|
typedef ColumnMajorLayout MyTilesLayout;
|
||||||
|
|
||||||
|
// make sure to set these panel values to the sizes of yours
|
||||||
|
const uint8_t PanelWidth = 8; // 8 pixel x 8 pixel matrix of leds
|
||||||
|
const uint8_t PanelHeight = 8;
|
||||||
|
const uint8_t TileWidth = 4; // laid out in 4 panels x 2 panels mosaic
|
||||||
|
const uint8_t TileHeight = 2;
|
||||||
|
|
||||||
|
const uint16_t PixelCount = PanelWidth * PanelHeight * TileWidth * TileHeight;
|
||||||
|
const uint8_t PixelPin = 2;
|
||||||
|
|
||||||
|
NeoTiles <MyPanelLayout, MyTilesLayout> tiles(
|
||||||
|
PanelWidth,
|
||||||
|
PanelHeight,
|
||||||
|
TileWidth,
|
||||||
|
TileHeight);
|
||||||
|
|
||||||
|
NeoPixelBus<NeoGrbFeature, Neo800KbpsMethod> strip(PixelCount, PixelPin);
|
||||||
|
//NeoPixelBus<NeoRgbFeature, Neo800KbpsMethod> strip(PixelCount, PixelPin);
|
||||||
|
//NeoPixelBus<NeoRgbwFeature, Neo800KbpsMethod> strip(PixelCount, PixelPin);
|
||||||
|
|
||||||
|
RgbColor red(128, 0, 0);
|
||||||
|
RgbColor green(0, 128, 0);
|
||||||
|
RgbColor blue(0, 0, 128);
|
||||||
|
RgbColor white(128);
|
||||||
|
// if using NeoRgbwFeature above, use this white instead to use
|
||||||
|
// the correct white element of the LED
|
||||||
|
//RgbwColor white(128);
|
||||||
|
RgbColor black(0);
|
||||||
|
|
||||||
|
const uint16_t left = 0;
|
||||||
|
const uint16_t right = PanelWidth - 1;
|
||||||
|
const uint16_t top = 0;
|
||||||
|
const uint16_t bottom = PanelHeight - 1;
|
||||||
|
|
||||||
|
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("Upper left is white.");
|
||||||
|
Serial.println("Upper right is Red.");
|
||||||
|
Serial.println("Lower right is Green");
|
||||||
|
Serial.println("Lower Left is Blue");
|
||||||
|
|
||||||
|
// use the topo to map the 2d cordinate to the pixel
|
||||||
|
// and use that to SetPixelColor
|
||||||
|
strip.SetPixelColor(tiles.Map(left, top), white);
|
||||||
|
strip.SetPixelColor(tiles.Map(right, top), red);
|
||||||
|
strip.SetPixelColor(tiles.Map(right, bottom), green);
|
||||||
|
strip.SetPixelColor(tiles.Map(left, bottom), blue);
|
||||||
|
strip.Show();
|
||||||
|
|
||||||
|
delay(5000);
|
||||||
|
|
||||||
|
Serial.println();
|
||||||
|
Serial.println("Cleared to black ...");
|
||||||
|
strip.ClearTo(black);
|
||||||
|
strip.Show();
|
||||||
|
}
|
||||||
|
|
78
examples/NeoPixelTopologyDump/NeoPixelTopologyDump.ino
Normal file
78
examples/NeoPixelTopologyDump/NeoPixelTopologyDump.ino
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
//----------------------------------------------------------------------
|
||||||
|
// NeoPixelTopologyDump
|
||||||
|
// This will dump to the serial output a grid map of the defined topology
|
||||||
|
// The output is displayed as row column labeled grid with the NeoPixelBus
|
||||||
|
// index of the pixel at the intersection of the row and column
|
||||||
|
//
|
||||||
|
// This is useful in visualising the layout of your panel so you can
|
||||||
|
// confirm you have the correct pattern
|
||||||
|
//
|
||||||
|
// It does not require that you have the actual panel connected
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
|
||||||
|
#include <NeoPixelAnimator.h>
|
||||||
|
#include <NeoPixelBus.h>
|
||||||
|
|
||||||
|
// uncomment one of these that matches your panel pixel layouts and
|
||||||
|
// how you want them rotated. Not all the rotations are listed here
|
||||||
|
// but you can modifiy the name to include the rotation of 90,180, or 270.
|
||||||
|
|
||||||
|
typedef ColumnMajorAlternatingLayout MyPanelLayout;
|
||||||
|
// typedef ColumnMajorLayout MyPanelLayout;
|
||||||
|
// typedef RowMajorAlternatingLayout MyPanelLayout;
|
||||||
|
// typedef RowMajorLayout MyPanelLayout;
|
||||||
|
// typedef RowMajor90Layout MyPanelLayout; // note rotation 90 was used
|
||||||
|
|
||||||
|
// make sure to set these panel values to the sizes of yours
|
||||||
|
const uint8_t PanelWidth = 8; // 8 pixel x 8 pixel matrix of leds
|
||||||
|
const uint8_t PanelHeight = 8;
|
||||||
|
|
||||||
|
NeoTopology<MyPanelLayout> topo(PanelWidth, PanelHeight);
|
||||||
|
|
||||||
|
void DumpTopo()
|
||||||
|
{
|
||||||
|
Serial.println();
|
||||||
|
|
||||||
|
Serial.print("\t\t");
|
||||||
|
for (int x = 0; x < topo.getWidth(); x++)
|
||||||
|
{
|
||||||
|
Serial.print(x);
|
||||||
|
Serial.print("\t");
|
||||||
|
}
|
||||||
|
Serial.println();
|
||||||
|
|
||||||
|
Serial.print("\t--");
|
||||||
|
for (int x = 0; x < topo.getWidth(); x++)
|
||||||
|
{
|
||||||
|
Serial.print("--------");
|
||||||
|
}
|
||||||
|
Serial.println();
|
||||||
|
|
||||||
|
for (int y = 0; y < topo.getHeight(); y++)
|
||||||
|
{
|
||||||
|
Serial.print(" ");
|
||||||
|
Serial.print(y);
|
||||||
|
Serial.print("\t|\t");
|
||||||
|
|
||||||
|
for (int x = 0; x < topo.getWidth(); x++)
|
||||||
|
{
|
||||||
|
Serial.print(topo.Map(x, y));
|
||||||
|
Serial.print("\t");
|
||||||
|
}
|
||||||
|
Serial.println();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void setup()
|
||||||
|
{
|
||||||
|
Serial.begin(115200);
|
||||||
|
while (!Serial); // wait for serial attach
|
||||||
|
|
||||||
|
DumpTopo();
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
90
examples/NeoPixelTopologyTest/NeoPixelTopologyTest.ino
Normal file
90
examples/NeoPixelTopologyTest/NeoPixelTopologyTest.ino
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
//----------------------------------------------------------------------
|
||||||
|
// NeoPixelTopologyTest
|
||||||
|
// This will display specific colors in specific locations on the led panel
|
||||||
|
//
|
||||||
|
// This is useful in confirming the layout of your panel
|
||||||
|
//
|
||||||
|
// It does require that you have the actual panel connected
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
|
||||||
|
#include <NeoPixelAnimator.h>
|
||||||
|
#include <NeoPixelBus.h>
|
||||||
|
|
||||||
|
// uncomment one of these that matches your panel pixel layouts and
|
||||||
|
// how you want them rotated. Not all the rotations are listed here
|
||||||
|
// but you can modifiy the name to include the rotation of 90,180, or 270.
|
||||||
|
|
||||||
|
typedef ColumnMajorAlternatingLayout MyPanelLayout;
|
||||||
|
// typedef ColumnMajorLayout MyPanelLayout;
|
||||||
|
// typedef RowMajorAlternatingLayout MyPanelLayout;
|
||||||
|
// typedef RowMajorLayout MyPanelLayout;
|
||||||
|
// typedef RowMajor90Layout MyPanelLayout; // note rotation 90 was used
|
||||||
|
|
||||||
|
// make sure to set these panel values to the sizes of yours
|
||||||
|
const uint8_t PanelWidth = 8; // 8 pixel x 8 pixel matrix of leds
|
||||||
|
const uint8_t PanelHeight = 8;
|
||||||
|
const uint16_t PixelCount = PanelWidth * PanelHeight;
|
||||||
|
const uint8_t PixelPin = 2; // make sure to set this to the correct pin, ignored for Esp8266
|
||||||
|
|
||||||
|
NeoTopology<MyPanelLayout> topo(PanelWidth, PanelHeight);
|
||||||
|
|
||||||
|
NeoPixelBus<NeoGrbFeature, Neo800KbpsMethod> strip(PixelCount, PixelPin);
|
||||||
|
//NeoPixelBus<NeoRgbFeature, Neo800KbpsMethod> strip(PixelCount, PixelPin);
|
||||||
|
//NeoPixelBus<NeoRgbwFeature, Neo800KbpsMethod> strip(PixelCount, PixelPin);
|
||||||
|
|
||||||
|
RgbColor red(128, 0, 0);
|
||||||
|
RgbColor green(0, 128, 0);
|
||||||
|
RgbColor blue(0, 0, 128);
|
||||||
|
RgbColor white(128);
|
||||||
|
// if using NeoRgbwFeature above, use this white instead to use
|
||||||
|
// the correct white element of the LED
|
||||||
|
//RgbwColor white(128);
|
||||||
|
RgbColor black(0);
|
||||||
|
|
||||||
|
const uint16_t left = 0;
|
||||||
|
const uint16_t right = PanelWidth - 1;
|
||||||
|
const uint16_t top = 0;
|
||||||
|
const uint16_t bottom = PanelHeight - 1;
|
||||||
|
|
||||||
|
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("Upper left is white.");
|
||||||
|
Serial.println("Upper right is Red.");
|
||||||
|
Serial.println("Lower right is Green");
|
||||||
|
Serial.println("Lower Left is Blue");
|
||||||
|
|
||||||
|
// use the topo to map the 2d cordinate to the pixel
|
||||||
|
// and use that to SetPixelColor
|
||||||
|
strip.SetPixelColor(topo.Map(left, top), white);
|
||||||
|
strip.SetPixelColor(topo.Map(right, top), red);
|
||||||
|
strip.SetPixelColor(topo.Map(right, bottom), green);
|
||||||
|
strip.SetPixelColor(topo.Map(left, bottom), blue);
|
||||||
|
strip.Show();
|
||||||
|
|
||||||
|
delay(5000);
|
||||||
|
|
||||||
|
Serial.println();
|
||||||
|
Serial.println("Cleared to black ...");
|
||||||
|
strip.ClearTo(black);
|
||||||
|
strip.Show();
|
||||||
|
}
|
||||||
|
|
35
keywords.txt
35
keywords.txt
@@ -31,6 +31,28 @@ AnimUpdateCallback KEYWORD1
|
|||||||
AnimationParam KEYWORD1
|
AnimationParam KEYWORD1
|
||||||
NeoEase KEYWORD1
|
NeoEase KEYWORD1
|
||||||
AnimEaseFunction KEYWORD1
|
AnimEaseFunction KEYWORD1
|
||||||
|
RowMajorLayout KEYWORD1
|
||||||
|
RowMajor90Layout KEYWORD1
|
||||||
|
RowMajor180Layout KEYWORD1
|
||||||
|
RowMajor270Layout KEYWORD1
|
||||||
|
RowMajorAlternatingLayout KEYWORD1
|
||||||
|
RowMajorAlternating90Layout KEYWORD1
|
||||||
|
RowMajorAlternating180Layout KEYWORD1
|
||||||
|
RowMajorAlternating270Layout KEYWORD1
|
||||||
|
ColumnMajorLayout KEYWORD1
|
||||||
|
ColumnMajor90Layout KEYWORD1
|
||||||
|
ColumnMajor180Layout KEYWORD1
|
||||||
|
ColumnMajor270Layout KEYWORD1
|
||||||
|
ColumnMajorAlternatingLayout KEYWORD1
|
||||||
|
ColumnMajorAlternating90Layout KEYWORD1
|
||||||
|
ColumnMajorAlternating180Layout KEYWORD1
|
||||||
|
ColumnMajorAlternating270Layout KEYWORD1
|
||||||
|
NeoTopology KEYWORD1
|
||||||
|
NeoTiles KEYWORD1
|
||||||
|
NeoMosaic KEYWORD1
|
||||||
|
NeoGammaEquationMethod KEYWORD1
|
||||||
|
NeoGammaTableMethod KEYWORD1
|
||||||
|
NeoGamma KEYWORD1
|
||||||
|
|
||||||
#######################################
|
#######################################
|
||||||
# Methods and Functions (KEYWORD2)
|
# Methods and Functions (KEYWORD2)
|
||||||
@@ -52,6 +74,7 @@ CalculateBrightness KEYWORD2
|
|||||||
Darken KEYWORD2
|
Darken KEYWORD2
|
||||||
Lighten KEYWORD2
|
Lighten KEYWORD2
|
||||||
LinearBlend KEYWORD2
|
LinearBlend KEYWORD2
|
||||||
|
BilinearBlend KEYWORD2
|
||||||
IsAnimating KEYWORD2
|
IsAnimating KEYWORD2
|
||||||
NextAvailableAnimation KEYWORD2
|
NextAvailableAnimation KEYWORD2
|
||||||
StartAnimation KEYWORD2
|
StartAnimation KEYWORD2
|
||||||
@@ -63,7 +86,8 @@ UpdateAnimations KEYWORD2
|
|||||||
IsPaused KEYWORD2
|
IsPaused KEYWORD2
|
||||||
Pause KEYWORD2
|
Pause KEYWORD2
|
||||||
Resume KEYWORD2
|
Resume KEYWORD2
|
||||||
TimeScale KEYWORD2
|
getTimeScale KEYWORD2
|
||||||
|
setTimeScale KEYWORD2
|
||||||
QuadraticIn KEYWORD2
|
QuadraticIn KEYWORD2
|
||||||
QuadraticOut KEYWORD2
|
QuadraticOut KEYWORD2
|
||||||
QuadraticInOut KEYWORD2
|
QuadraticInOut KEYWORD2
|
||||||
@@ -85,6 +109,12 @@ ExponentialInOut KEYWORD2
|
|||||||
CircularIn KEYWORD2
|
CircularIn KEYWORD2
|
||||||
CircularOut KEYWORD2
|
CircularOut KEYWORD2
|
||||||
CircularInOut KEYWORD2
|
CircularInOut KEYWORD2
|
||||||
|
Gamma KEYWORD2
|
||||||
|
Map KEYWORD2
|
||||||
|
getWidth KEYWORD2
|
||||||
|
getHeight KEYWORD2
|
||||||
|
TopologyHint KEYWORD2
|
||||||
|
Correct KEYWORD2
|
||||||
|
|
||||||
#######################################
|
#######################################
|
||||||
# Constants (LITERAL1)
|
# Constants (LITERAL1)
|
||||||
@@ -98,3 +128,6 @@ NEO_DECASECONDS LITERAL1
|
|||||||
AnimationState_Started LITERAL1
|
AnimationState_Started LITERAL1
|
||||||
AnimationState_Progress LITERAL1
|
AnimationState_Progress LITERAL1
|
||||||
AnimationState_Completed LITERAL1
|
AnimationState_Completed LITERAL1
|
||||||
|
NeoTopologyHint_FirstOnPanel LITERAL1
|
||||||
|
NeoTopologyHint_InPanel LITERAL1
|
||||||
|
NeoTopologyHint_LastOnPanel LITERAL1
|
||||||
|
@@ -1,9 +1,9 @@
|
|||||||
name=NeoPixelBus by Makuna
|
name=NeoPixelBus by Makuna
|
||||||
version=2.0.3
|
version=2.0.4
|
||||||
author=Michael C. Miller (makuna@live.com)
|
author=Michael C. Miller (makuna@live.com)
|
||||||
maintainer=Michael C. Miller (makuna@live.com)
|
maintainer=Michael C. Miller (makuna@live.com)
|
||||||
sentence=A library that makes controlling NeoPixels (WS2811, WS2812 & SK6812) easy.
|
sentence=A library that makes controlling NeoPixels (WS2811, WS2812 & SK6812) easy.
|
||||||
paragraph=Supports most Arduino platforms, and especially Esp8266. Support for RGBW pixels. Includes seperate RgbColor, RgbwColor, HslColor, and HsbColor objects. Includes an animator class that helps create asyncronous animations. For Esp8266 it has three methods of sending data, DMA, UART, and Bit Bang.
|
paragraph=Supports most Arduino platforms, and especially Esp8266. Support for RGBW pixels. Includes seperate RgbColor, RgbwColor, HslColor, and HsbColor objects. Includes an animator class that helps create asyncronous animations. For Esp8266 it has three methods of sending data, DMA, UART, and Bit Bang.
|
||||||
category=Display
|
category=Display
|
||||||
url=https://github.com/Makuna/NeoPixelBus
|
url=https://github.com/Makuna/NeoPixelBus/wiki
|
||||||
architectures=*
|
architectures=*
|
@@ -125,11 +125,16 @@ public:
|
|||||||
_animationLastTick = millis();
|
_animationLastTick = millis();
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t TimeScale()
|
uint16_t getTimeScale()
|
||||||
{
|
{
|
||||||
return _timeScale;
|
return _timeScale;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void setTimeScale(uint16_t timeScale)
|
||||||
|
{
|
||||||
|
_timeScale = (timeScale < 1) ? (1) : (timeScale > 32768) ? 32768 : timeScale;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct AnimationContext
|
struct AnimationContext
|
||||||
{
|
{
|
||||||
|
@@ -32,6 +32,15 @@ License along with NeoPixel. If not, see
|
|||||||
#include "internal/HsbColor.h"
|
#include "internal/HsbColor.h"
|
||||||
#include "internal/HtmlColor.h"
|
#include "internal/HtmlColor.h"
|
||||||
#include "internal/RgbwColor.h"
|
#include "internal/RgbwColor.h"
|
||||||
|
|
||||||
|
#include "internal/Layouts.h"
|
||||||
|
#include "internal/NeoTopology.h"
|
||||||
|
#include "internal/NeoTiles.h"
|
||||||
|
#include "internal/NeoMosaic.h"
|
||||||
|
|
||||||
|
#include "internal/NeoEase.h"
|
||||||
|
#include "internal/NeoGamma.h"
|
||||||
|
|
||||||
#include "internal/NeoColorFeatures.h"
|
#include "internal/NeoColorFeatures.h"
|
||||||
|
|
||||||
#if defined(ARDUINO_ARCH_ESP8266)
|
#if defined(ARDUINO_ARCH_ESP8266)
|
||||||
@@ -124,7 +133,7 @@ public:
|
|||||||
return _countPixels;
|
return _countPixels;
|
||||||
};
|
};
|
||||||
|
|
||||||
void SetPixelColor(uint16_t indexPixel, typename T_COLOR_FEATURE::ColorObject color)
|
void SetPixelColor(uint16_t indexPixel, const typename T_COLOR_FEATURE::ColorObject& color)
|
||||||
{
|
{
|
||||||
if (indexPixel < _countPixels)
|
if (indexPixel < _countPixels)
|
||||||
{
|
{
|
||||||
|
@@ -67,7 +67,7 @@ HsbColor::HsbColor(const RgbColor& color)
|
|||||||
B = v;
|
B = v;
|
||||||
}
|
}
|
||||||
|
|
||||||
HsbColor HsbColor::LinearBlend(HsbColor left, HsbColor right, float progress)
|
HsbColor HsbColor::LinearBlend(const HsbColor& left, const HsbColor& right, float progress)
|
||||||
{
|
{
|
||||||
return HsbColor(left.H + ((right.H - left.H) * progress),
|
return HsbColor(left.H + ((right.H - left.H) * progress),
|
||||||
left.S + ((right.S - left.S) * progress),
|
left.S + ((right.S - left.S) * progress),
|
||||||
|
@@ -1,3 +1,4 @@
|
|||||||
|
|
||||||
/*-------------------------------------------------------------------------
|
/*-------------------------------------------------------------------------
|
||||||
HsbColor provides a color object that can be directly consumed by NeoPixelBus
|
HsbColor provides a color object that can be directly consumed by NeoPixelBus
|
||||||
|
|
||||||
@@ -62,7 +63,7 @@ struct HsbColor
|
|||||||
// progress - (0.0 - 1.0) value where 0.0 will return left and 1.0 will return right
|
// progress - (0.0 - 1.0) value where 0.0 will return left and 1.0 will return right
|
||||||
// and a value between will blend the color weighted linearly between them
|
// and a value between will blend the color weighted linearly between them
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
static HsbColor LinearBlend(HsbColor left, HsbColor right, float progress);
|
static HsbColor LinearBlend(const HsbColor& left, const HsbColor& right, float progress);
|
||||||
|
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
// Hue, Saturation, Brightness color members
|
// Hue, Saturation, Brightness color members
|
||||||
|
@@ -1,6 +1,7 @@
|
|||||||
/*-------------------------------------------------------------------------
|
/*-------------------------------------------------------------------------
|
||||||
HslColor provides a color object that can be directly consumed by NeoPixelBus
|
HslColor provides a color object that can be directly consumed by NeoPixelBus
|
||||||
|
|
||||||
|
|
||||||
Written by Michael C. Miller.
|
Written by Michael C. Miller.
|
||||||
|
|
||||||
I invest time and resources providing this open source code,
|
I invest time and resources providing this open source code,
|
||||||
@@ -70,7 +71,7 @@ HslColor::HslColor(const RgbColor& color)
|
|||||||
L = l;
|
L = l;
|
||||||
}
|
}
|
||||||
|
|
||||||
HslColor HslColor::LinearBlend(HslColor left, HslColor right, float progress)
|
HslColor HslColor::LinearBlend(const HslColor& left, const HslColor& right, float progress)
|
||||||
{
|
{
|
||||||
return HslColor(left.H + ((right.H - left.H) * progress),
|
return HslColor(left.H + ((right.H - left.H) * progress),
|
||||||
left.S + ((right.S - left.S) * progress),
|
left.S + ((right.S - left.S) * progress),
|
||||||
|
@@ -64,7 +64,7 @@ struct HslColor
|
|||||||
// progress - (0.0 - 1.0) value where 0.0 will return left and 1.0 will return right
|
// progress - (0.0 - 1.0) value where 0.0 will return left and 1.0 will return right
|
||||||
// and a value between will blend the color weighted linearly between them
|
// and a value between will blend the color weighted linearly between them
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
static HslColor LinearBlend(HslColor left, HslColor right, float progress);
|
static HslColor LinearBlend(const HslColor& left, const HslColor& right, float progress);
|
||||||
|
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
// Hue, Saturation, Lightness color members
|
// Hue, Saturation, Lightness color members
|
||||||
|
@@ -62,6 +62,24 @@ struct HtmlColor
|
|||||||
{
|
{
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
// BilinearBlend between four colors by the amount defined by 2d variable
|
||||||
|
// c00 - upper left quadrant color
|
||||||
|
// c01 - upper right quadrant color
|
||||||
|
// c10 - lower left quadrant color
|
||||||
|
// c11 - lower right quadrant color
|
||||||
|
// x - unit value (0.0 - 1.0) that defines the blend progress in horizontal space
|
||||||
|
// y - unit value (0.0 - 1.0) that defines the blend progress in vertical space
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
static HtmlColor BilinearBlend(const HtmlColor& c00,
|
||||||
|
const HtmlColor& c01,
|
||||||
|
const HtmlColor& c10,
|
||||||
|
const HtmlColor& c11,
|
||||||
|
float x,
|
||||||
|
float y)
|
||||||
|
{
|
||||||
|
return RgbColor::BilinearBlend(c00, c01, c10, c11, x, y);
|
||||||
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
// Color member (0-0xffffff) where
|
// Color member (0-0xffffff) where
|
||||||
|
425
src/internal/Layouts.h
Normal file
425
src/internal/Layouts.h
Normal file
@@ -0,0 +1,425 @@
|
|||||||
|
#pragma once
|
||||||
|
/*-------------------------------------------------------------------------
|
||||||
|
Layout provides a collection of class objects that are used with NeoTopology
|
||||||
|
object.
|
||||||
|
They define the specific layout of pixels and do the math to change the 2d
|
||||||
|
cordinate space to 1d cordinate space
|
||||||
|
|
||||||
|
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/>.
|
||||||
|
-------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// RowMajor
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
class RowMajorLayout;
|
||||||
|
class RowMajor90Layout;
|
||||||
|
class RowMajor180Layout;
|
||||||
|
class RowMajor270Layout;
|
||||||
|
|
||||||
|
class RowMajorTilePreference
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef RowMajorLayout EvenRowEvenColumnLayout;
|
||||||
|
typedef RowMajor270Layout EvenRowOddColumnLayout;
|
||||||
|
typedef RowMajor90Layout OddRowEvenColumnLayout;
|
||||||
|
typedef RowMajor180Layout OddRowOddColumnLayout;
|
||||||
|
};
|
||||||
|
|
||||||
|
// layout example of 4x4
|
||||||
|
// 00 01 02 03
|
||||||
|
// 04 05 06 07
|
||||||
|
// 08 09 10 11
|
||||||
|
// 12 13 14 15
|
||||||
|
//
|
||||||
|
class RowMajorLayout : public RowMajorTilePreference
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static uint16_t Map(uint16_t width, uint16_t height, uint16_t x, uint16_t y)
|
||||||
|
{
|
||||||
|
return x + y * width;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// layout example of 4x4
|
||||||
|
// 12 08 04 00
|
||||||
|
// 13 09 05 01
|
||||||
|
// 14 10 06 02
|
||||||
|
// 15 11 07 03
|
||||||
|
//
|
||||||
|
class RowMajor90Layout : public RowMajorTilePreference
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static uint16_t Map(uint16_t width, uint16_t height, uint16_t x, uint16_t y)
|
||||||
|
{
|
||||||
|
return (width - 1 - x) * height + y;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// layout example of 4x4
|
||||||
|
// 15 14 13 12
|
||||||
|
// 11 10 09 08
|
||||||
|
// 07 06 05 04
|
||||||
|
// 03 02 01 00
|
||||||
|
//
|
||||||
|
class RowMajor180Layout : public RowMajorTilePreference
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static uint16_t Map(uint16_t width, uint16_t height, uint16_t x, uint16_t y)
|
||||||
|
{
|
||||||
|
return (width - 1 - x) + (height - 1 - y) * width;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// layout example of 4x4
|
||||||
|
// 03 07 11 15
|
||||||
|
// 02 06 10 14
|
||||||
|
// 01 05 09 13
|
||||||
|
// 00 04 08 12
|
||||||
|
//
|
||||||
|
class RowMajor270Layout : public RowMajorTilePreference
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static uint16_t Map(uint16_t width, uint16_t height, uint16_t x, uint16_t y)
|
||||||
|
{
|
||||||
|
return x * height + (height - 1 - y);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// ColumnMajor
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
class ColumnMajorLayout;
|
||||||
|
class ColumnMajor90Layout;
|
||||||
|
class ColumnMajor180Layout;
|
||||||
|
class ColumnMajor270Layout;
|
||||||
|
|
||||||
|
class ColumnMajorTilePreference
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef ColumnMajorLayout EvenRowEvenColumnLayout;
|
||||||
|
typedef ColumnMajor270Layout EvenRowOddColumnLayout;
|
||||||
|
typedef ColumnMajor90Layout OddRowEvenColumnLayout;
|
||||||
|
typedef ColumnMajor180Layout OddRowOddColumnLayout;
|
||||||
|
};
|
||||||
|
|
||||||
|
// layout example of 4x4
|
||||||
|
// 00 04 08 12
|
||||||
|
// 01 05 09 13
|
||||||
|
// 02 06 10 14
|
||||||
|
// 03 07 11 15
|
||||||
|
//
|
||||||
|
class ColumnMajorLayout : public ColumnMajorTilePreference
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static uint16_t Map(uint16_t width, uint16_t height, uint16_t x, uint16_t y)
|
||||||
|
{
|
||||||
|
return x * height + y;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// layout example of 4x4
|
||||||
|
// 03 02 01 00
|
||||||
|
// 07 06 05 04
|
||||||
|
// 11 10 09 08
|
||||||
|
// 15 14 13 12
|
||||||
|
//
|
||||||
|
class ColumnMajor90Layout : public ColumnMajorTilePreference
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static uint16_t Map(uint16_t width, uint16_t height, uint16_t x, uint16_t y)
|
||||||
|
{
|
||||||
|
return (width - 1 - x) + y * width;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// layout example of 4x4
|
||||||
|
// 15 11 07 03
|
||||||
|
// 14 10 06 02
|
||||||
|
// 13 09 05 01
|
||||||
|
// 12 08 04 00
|
||||||
|
//
|
||||||
|
class ColumnMajor180Layout : public ColumnMajorTilePreference
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static uint16_t Map(uint16_t width, uint16_t height, uint16_t x, uint16_t y)
|
||||||
|
{
|
||||||
|
return (width - 1 - x) * height + (height - 1 - y);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// layout example of 4x4
|
||||||
|
// 12 13 14 15
|
||||||
|
// 08 09 10 11
|
||||||
|
// 04 05 06 07
|
||||||
|
// 00 01 02 03
|
||||||
|
//
|
||||||
|
class ColumnMajor270Layout : public ColumnMajorTilePreference
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static uint16_t Map(uint16_t width, uint16_t height, uint16_t x, uint16_t y)
|
||||||
|
{
|
||||||
|
return x + (height - 1 - y) * width;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// RowMajorAlternating
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
class RowMajorAlternating270Layout;
|
||||||
|
class RowMajorAlternating90Layout;
|
||||||
|
|
||||||
|
class RowMajorAlternatingTilePreference
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef RowMajorAlternating270Layout EvenRowEvenColumnLayout;
|
||||||
|
typedef RowMajorAlternating270Layout EvenRowOddColumnLayout;
|
||||||
|
typedef RowMajorAlternating90Layout OddRowEvenColumnLayout;
|
||||||
|
typedef RowMajorAlternating90Layout OddRowOddColumnLayout;
|
||||||
|
};
|
||||||
|
|
||||||
|
// layout example of 4x4
|
||||||
|
// 00 01 02 03
|
||||||
|
// 07 06 05 04
|
||||||
|
// 08 09 10 11
|
||||||
|
// 15 14 13 12
|
||||||
|
//
|
||||||
|
class RowMajorAlternatingLayout : public RowMajorAlternatingTilePreference
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static uint16_t Map(uint16_t width, uint16_t height, uint16_t x, uint16_t y)
|
||||||
|
{
|
||||||
|
uint16_t index = y * width;
|
||||||
|
|
||||||
|
if (y & 0x0001)
|
||||||
|
{
|
||||||
|
index += ((width - 1) - x);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
index += x;
|
||||||
|
}
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// layout example of 4x4
|
||||||
|
// 15 08 07 00
|
||||||
|
// 14 09 06 01
|
||||||
|
// 13 10 05 02
|
||||||
|
// 12 11 04 03
|
||||||
|
//
|
||||||
|
class RowMajorAlternating90Layout : public RowMajorAlternatingTilePreference
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static uint16_t Map(uint16_t width, uint16_t height, uint16_t x, uint16_t y)
|
||||||
|
{
|
||||||
|
uint16_t mx = ((width - 1) - x);
|
||||||
|
uint16_t index = mx * height;
|
||||||
|
|
||||||
|
if (mx & 0x0001)
|
||||||
|
{
|
||||||
|
index += ((height - 1) - y);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
index += y;
|
||||||
|
}
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// layout example of 4x4
|
||||||
|
// 12 13 14 15
|
||||||
|
// 11 10 09 08
|
||||||
|
// 04 05 06 07
|
||||||
|
// 03 02 01 00
|
||||||
|
//
|
||||||
|
class RowMajorAlternating180Layout : public RowMajorAlternatingTilePreference
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static uint16_t Map(uint16_t width, uint16_t height, uint16_t x, uint16_t y)
|
||||||
|
{
|
||||||
|
uint16_t my = ((height - 1) - y);
|
||||||
|
uint16_t index = my * width;
|
||||||
|
|
||||||
|
if (my & 0x0001)
|
||||||
|
{
|
||||||
|
index += x;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
index += ((width - 1) - x);
|
||||||
|
}
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// layout example of 4x4
|
||||||
|
// 03 04 11 12
|
||||||
|
// 02 05 10 13
|
||||||
|
// 01 06 09 14
|
||||||
|
// 00 07 08 15
|
||||||
|
//
|
||||||
|
class RowMajorAlternating270Layout : public RowMajorAlternatingTilePreference
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static uint16_t Map(uint16_t width, uint16_t height, uint16_t x, uint16_t y)
|
||||||
|
{
|
||||||
|
uint16_t index = x * height;
|
||||||
|
|
||||||
|
if (x & 0x0001)
|
||||||
|
{
|
||||||
|
index += y;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
index += ((height - 1) - y);
|
||||||
|
}
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// ColumnMajorAlternating
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
class ColumnMajorAlternatingLayout;
|
||||||
|
class ColumnMajorAlternating180Layout;
|
||||||
|
|
||||||
|
class ColumnMajorAlternatingTilePreference
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef ColumnMajorAlternatingLayout EvenRowEvenColumnLayout;
|
||||||
|
typedef ColumnMajorAlternatingLayout EvenRowOddColumnLayout;
|
||||||
|
typedef ColumnMajorAlternating180Layout OddRowEvenColumnLayout;
|
||||||
|
typedef ColumnMajorAlternating180Layout OddRowOddColumnLayout;
|
||||||
|
};
|
||||||
|
|
||||||
|
// layout example of 4x4
|
||||||
|
// 00 07 08 15
|
||||||
|
// 01 06 09 14
|
||||||
|
// 02 05 10 13
|
||||||
|
// 03 04 11 12
|
||||||
|
//
|
||||||
|
class ColumnMajorAlternatingLayout : public ColumnMajorAlternatingTilePreference
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static uint16_t Map(uint16_t width, uint16_t height, uint16_t x, uint16_t y)
|
||||||
|
{
|
||||||
|
uint16_t index = x * height;
|
||||||
|
|
||||||
|
if (x & 0x0001)
|
||||||
|
{
|
||||||
|
index += ((height - 1) - y);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
index += y;
|
||||||
|
}
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// layout example of 4x4
|
||||||
|
// 03 02 01 00
|
||||||
|
// 04 05 06 07
|
||||||
|
// 11 10 09 08
|
||||||
|
// 12 13 14 15
|
||||||
|
//
|
||||||
|
class ColumnMajorAlternating90Layout : public ColumnMajorAlternatingTilePreference
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static uint16_t Map(uint16_t width, uint16_t height, uint16_t x, uint16_t y)
|
||||||
|
{
|
||||||
|
uint16_t index = y * width;
|
||||||
|
|
||||||
|
if (y & 0x0001)
|
||||||
|
{
|
||||||
|
index += x;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
index += ((width - 1) - x);
|
||||||
|
}
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// layout example of 4x4
|
||||||
|
// 12 11 04 03
|
||||||
|
// 13 10 05 02
|
||||||
|
// 14 09 06 01
|
||||||
|
// 15 08 07 00
|
||||||
|
//
|
||||||
|
class ColumnMajorAlternating180Layout : public ColumnMajorAlternatingTilePreference
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static uint16_t Map(uint16_t width, uint16_t height, uint16_t x, uint16_t y)
|
||||||
|
{
|
||||||
|
uint16_t mx = ((width - 1) - x);
|
||||||
|
uint16_t index = mx * height;
|
||||||
|
|
||||||
|
if (mx & 0x0001)
|
||||||
|
{
|
||||||
|
index += y;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
index += ((height - 1) - y);
|
||||||
|
}
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// layout example of 4x4
|
||||||
|
// 15 14 13 12
|
||||||
|
// 08 09 10 11
|
||||||
|
// 07 06 05 04
|
||||||
|
// 00 01 02 03
|
||||||
|
//
|
||||||
|
class ColumnMajorAlternating270Layout : public ColumnMajorAlternatingTilePreference
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static uint16_t Map(uint16_t width, uint16_t height, uint16_t x, uint16_t y)
|
||||||
|
{
|
||||||
|
uint16_t my = ((height - 1) - y);
|
||||||
|
uint16_t index = my * width;
|
||||||
|
|
||||||
|
if (my & 0x0001)
|
||||||
|
{
|
||||||
|
index += ((width - 1) - x);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
index += x;
|
||||||
|
}
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
};
|
@@ -30,26 +30,23 @@ class Neo3Elements
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static const size_t PixelSize = 3;
|
static const size_t PixelSize = 3;
|
||||||
static const RgbColor Empty();
|
|
||||||
|
|
||||||
static uint8_t* getPixelAddress(uint8_t* pPixels, uint16_t indexPixel)
|
static uint8_t* getPixelAddress(uint8_t* pPixels, uint16_t indexPixel)
|
||||||
{
|
{
|
||||||
return &pPixels[indexPixel * PixelSize];
|
return pPixels + indexPixel * PixelSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef RgbColor ColorObject;
|
typedef RgbColor ColorObject;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class Neo4Elements
|
class Neo4Elements
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static const size_t PixelSize = 4;
|
static const size_t PixelSize = 4;
|
||||||
static const RgbColor Empty();
|
|
||||||
|
|
||||||
static uint8_t* getPixelAddress(uint8_t* pPixels, uint16_t indexPixel)
|
static uint8_t* getPixelAddress(uint8_t* pPixels, uint16_t indexPixel)
|
||||||
{
|
{
|
||||||
return &pPixels[indexPixel * PixelSize];
|
return pPixels + indexPixel * PixelSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef RgbwColor ColorObject;
|
typedef RgbwColor ColorObject;
|
||||||
|
@@ -28,187 +28,197 @@ License along with NeoPixel. If not, see
|
|||||||
|
|
||||||
#ifdef ARDUINO_ARCH_AVR
|
#ifdef ARDUINO_ARCH_AVR
|
||||||
|
|
||||||
typedef float(*AnimEaseFunction)(float linear);
|
typedef float(*AnimEaseFunction)(float unitValue);
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
#undef max
|
#undef max
|
||||||
#undef min
|
#undef min
|
||||||
#include <functional>
|
#include <functional>
|
||||||
typedef std::function<float(float linear)> AnimEaseFunction;
|
typedef std::function<float(float unitValue)> AnimEaseFunction;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
class NeoEase
|
class NeoEase
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static float QuadraticIn(float linear)
|
static float Linear(float unitValue)
|
||||||
{
|
{
|
||||||
return linear * linear;
|
return unitValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
static float QuadraticOut(float linear)
|
static float QuadraticIn(float unitValue)
|
||||||
{
|
{
|
||||||
return (-linear * (linear - 2.0f));
|
return unitValue * unitValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
static float QuadraticInOut(float linear)
|
static float QuadraticOut(float unitValue)
|
||||||
{
|
{
|
||||||
linear *= 2.0f;
|
return (-unitValue * (unitValue - 2.0f));
|
||||||
if (linear < 1.0f)
|
}
|
||||||
|
|
||||||
|
static float QuadraticInOut(float unitValue)
|
||||||
|
{
|
||||||
|
unitValue *= 2.0f;
|
||||||
|
if (unitValue < 1.0f)
|
||||||
{
|
{
|
||||||
return (0.5f * linear * linear);
|
return (0.5f * unitValue * unitValue);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
linear -= 1.0f;
|
unitValue -= 1.0f;
|
||||||
return (-0.5f * (linear * (linear - 2.0f) - 1.0f));
|
return (-0.5f * (unitValue * (unitValue - 2.0f) - 1.0f));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static float CubicIn(float linear)
|
static float CubicIn(float unitValue)
|
||||||
{
|
{
|
||||||
return (linear * linear * linear);
|
return (unitValue * unitValue * unitValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
static float CubicOut(float linear)
|
static float CubicOut(float unitValue)
|
||||||
{
|
{
|
||||||
linear -= 1.0f;
|
unitValue -= 1.0f;
|
||||||
return (linear * linear * linear + 1);
|
return (unitValue * unitValue * unitValue + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static float CubicInOut(float linear)
|
static float CubicInOut(float unitValue)
|
||||||
{
|
{
|
||||||
linear *= 2.0f;
|
unitValue *= 2.0f;
|
||||||
if (linear < 1.0f)
|
if (unitValue < 1.0f)
|
||||||
{
|
{
|
||||||
return (0.5f * linear * linear * linear);
|
return (0.5f * unitValue * unitValue * unitValue);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
linear -= 2.0f;
|
unitValue -= 2.0f;
|
||||||
return (0.5f * (linear * linear * linear + 2.0f));
|
return (0.5f * (unitValue * unitValue * unitValue + 2.0f));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static float QuarticIn(float linear)
|
static float QuarticIn(float unitValue)
|
||||||
{
|
{
|
||||||
return (linear * linear * linear * linear);
|
return (unitValue * unitValue * unitValue * unitValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
static float QuarticOut(float linear)
|
static float QuarticOut(float unitValue)
|
||||||
{
|
{
|
||||||
linear -= 1.0f;
|
unitValue -= 1.0f;
|
||||||
return -(linear * linear * linear * linear - 1);
|
return -(unitValue * unitValue * unitValue * unitValue - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static float QuarticInOut(float linear)
|
static float QuarticInOut(float unitValue)
|
||||||
{
|
{
|
||||||
linear *= 2.0f;
|
unitValue *= 2.0f;
|
||||||
if (linear < 1.0f)
|
if (unitValue < 1.0f)
|
||||||
{
|
{
|
||||||
return (0.5f * linear * linear * linear * linear);
|
return (0.5f * unitValue * unitValue * unitValue * unitValue);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
linear -= 2.0f;
|
unitValue -= 2.0f;
|
||||||
return (-0.5f * (linear * linear * linear * linear - 2.0f));
|
return (-0.5f * (unitValue * unitValue * unitValue * unitValue - 2.0f));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static float QuinticIn(float linear)
|
static float QuinticIn(float unitValue)
|
||||||
{
|
{
|
||||||
return (linear * linear * linear * linear * linear);
|
return (unitValue * unitValue * unitValue * unitValue * unitValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
static float QuinticOut(float linear)
|
static float QuinticOut(float unitValue)
|
||||||
{
|
{
|
||||||
linear -= 1.0f;
|
unitValue -= 1.0f;
|
||||||
return (linear * linear * linear * linear * linear + 1.0f);
|
return (unitValue * unitValue * unitValue * unitValue * unitValue + 1.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
static float QuinticInOut(float linear)
|
static float QuinticInOut(float unitValue)
|
||||||
{
|
{
|
||||||
linear *= 2.0f;
|
unitValue *= 2.0f;
|
||||||
if (linear < 1.0f)
|
if (unitValue < 1.0f)
|
||||||
{
|
{
|
||||||
return (0.5f * linear * linear * linear * linear * linear);
|
return (0.5f * unitValue * unitValue * unitValue * unitValue * unitValue);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
linear -= 2.0f;
|
unitValue -= 2.0f;
|
||||||
return (0.5f * (linear * linear * linear * linear * linear + 2.0f));
|
return (0.5f * (unitValue * unitValue * unitValue * unitValue * unitValue + 2.0f));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static float SinusoidalIn(float linear)
|
static float SinusoidalIn(float unitValue)
|
||||||
{
|
{
|
||||||
return (-cos(linear * HALF_PI) + 1.0f);
|
return (-cos(unitValue * HALF_PI) + 1.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
static float SinusoidalOut(float linear)
|
static float SinusoidalOut(float unitValue)
|
||||||
{
|
{
|
||||||
return (sin(linear * HALF_PI));
|
return (sin(unitValue * HALF_PI));
|
||||||
}
|
}
|
||||||
|
|
||||||
static float SinusoidalInOut(float linear)
|
static float SinusoidalInOut(float unitValue)
|
||||||
{
|
{
|
||||||
return -0.5 * (cos(PI * linear) - 1.0f);
|
return -0.5 * (cos(PI * unitValue) - 1.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
static float ExponentialIn(float linear)
|
static float ExponentialIn(float unitValue)
|
||||||
{
|
{
|
||||||
return (pow(2, 10.0f * (linear - 1.0f)));
|
return (pow(2, 10.0f * (unitValue - 1.0f)));
|
||||||
}
|
}
|
||||||
|
|
||||||
static float ExponentialOut(float linear)
|
static float ExponentialOut(float unitValue)
|
||||||
{
|
{
|
||||||
return (-pow(2, -10.0f * linear) + 1.0f);
|
return (-pow(2, -10.0f * unitValue) + 1.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
static float ExponentialInOut(float linear)
|
static float ExponentialInOut(float unitValue)
|
||||||
{
|
{
|
||||||
linear *= 2.0f;
|
unitValue *= 2.0f;
|
||||||
if (linear < 1.0f)
|
if (unitValue < 1.0f)
|
||||||
{
|
{
|
||||||
return (0.5f * pow(2, 10.0f * (linear - 1.0f)));
|
return (0.5f * pow(2, 10.0f * (unitValue - 1.0f)));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
linear -= 1.0f;
|
unitValue -= 1.0f;
|
||||||
return (0.5f * (-pow(2, -10.0f * linear) + 2.0f));
|
return (0.5f * (-pow(2, -10.0f * unitValue) + 2.0f));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static float CircularIn(float linear)
|
static float CircularIn(float unitValue)
|
||||||
{
|
{
|
||||||
if (linear == 1.0f)
|
if (unitValue == 1.0f)
|
||||||
{
|
{
|
||||||
return 1.0f;
|
return 1.0f;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return (-(sqrt(1.0f - linear * linear) - 1.0f));
|
return (-(sqrt(1.0f - unitValue * unitValue) - 1.0f));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static float CircularOut(float linear)
|
static float CircularOut(float unitValue)
|
||||||
{
|
{
|
||||||
linear -= 1.0f;
|
unitValue -= 1.0f;
|
||||||
return (sqrt(1.0f - linear * linear));
|
return (sqrt(1.0f - unitValue * unitValue));
|
||||||
}
|
}
|
||||||
|
|
||||||
static float CircularInOut(float linear)
|
static float CircularInOut(float unitValue)
|
||||||
{
|
{
|
||||||
linear *= 2.0f;
|
unitValue *= 2.0f;
|
||||||
if (linear < 1.0f)
|
if (unitValue < 1.0f)
|
||||||
{
|
{
|
||||||
return (-0.5f * (sqrt(1.0f - linear * linear) - 1));
|
return (-0.5f * (sqrt(1.0f - unitValue * unitValue) - 1));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
linear -= 2.0f;
|
unitValue -= 2.0f;
|
||||||
return (0.5f * (sqrt(1.0f - linear * linear) + 1.0f));
|
return (0.5f * (sqrt(1.0f - unitValue * unitValue) + 1.0f));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static float Gamma(float unitValue)
|
||||||
|
{
|
||||||
|
return pow(unitValue, 1.0f / 0.45f);
|
||||||
|
}
|
||||||
};
|
};
|
90
src/internal/NeoGamma.h
Normal file
90
src/internal/NeoGamma.h
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
/*-------------------------------------------------------------------------
|
||||||
|
NeoPixelGamma class is used to correct RGB colors for human eye gamma levels
|
||||||
|
|
||||||
|
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/>.
|
||||||
|
-------------------------------------------------------------------------*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
// NeoGammaEquationMethod uses no memory but is slower than NeoGammaTableMethod
|
||||||
|
class NeoGammaEquationMethod
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static uint8_t Correct(uint8_t value)
|
||||||
|
{
|
||||||
|
return static_cast<uint8_t>(255.0f * NeoEase::Gamma(value / 255.0f) + 0.5f);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// NeoGammaTableMethod uses 256 bytes of memory, but is significantly faster
|
||||||
|
class NeoGammaTableMethod
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static uint8_t Correct(uint8_t value)
|
||||||
|
{
|
||||||
|
return _table[value];
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
static const uint8_t _table[256];
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// use one of the method classes above as a converter for this template class
|
||||||
|
template<typename T_METHOD> class NeoGamma
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
RgbColor Correct(const RgbColor& original)
|
||||||
|
{
|
||||||
|
return RgbColor(T_METHOD::Correct(original.R),
|
||||||
|
T_METHOD::Correct(original.G),
|
||||||
|
T_METHOD::Correct(original.B));
|
||||||
|
}
|
||||||
|
|
||||||
|
RgbwColor Correct(const RgbwColor& original)
|
||||||
|
{
|
||||||
|
return RgbwColor(T_METHOD::Correct(original.R),
|
||||||
|
T_METHOD::Correct(original.G),
|
||||||
|
T_METHOD::Correct(original.B),
|
||||||
|
T_METHOD::Correct(original.W) );
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
const uint8_t NeoGammaTableMethod::_table[] = {
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2,
|
||||||
|
3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6,
|
||||||
|
6, 7, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10, 11, 11, 11,
|
||||||
|
12, 12, 13, 13, 14, 14, 14, 15, 15, 16, 16, 17, 17, 18, 18, 19,
|
||||||
|
19, 20, 20, 21, 22, 22, 23, 23, 24, 25, 25, 26, 26, 27, 28, 28,
|
||||||
|
29, 30, 30, 31, 32, 33, 33, 34, 35, 35, 36, 37, 38, 39, 39, 40,
|
||||||
|
41, 42, 43, 43, 44, 45, 46, 47, 48, 49, 50, 50, 51, 52, 53, 54,
|
||||||
|
55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 71,
|
||||||
|
72, 73, 74, 75, 76, 77, 78, 80, 81, 82, 83, 84, 86, 87, 88, 89,
|
||||||
|
91, 92, 93, 94, 96, 97, 98, 100, 101, 102, 104, 105, 106, 108, 109, 110,
|
||||||
|
112, 113, 115, 116, 118, 119, 121, 122, 123, 125, 126, 128, 130, 131, 133, 134,
|
||||||
|
136, 137, 139, 140, 142, 144, 145, 147, 149, 150, 152, 154, 155, 157, 159, 160,
|
||||||
|
162, 164, 166, 167, 169, 171, 173, 175, 176, 178, 180, 182, 184, 186, 187, 189,
|
||||||
|
191, 193, 195, 197, 199, 201, 203, 205, 207, 209, 211, 213, 215, 217, 219, 221,
|
||||||
|
223, 225, 227, 229, 231, 233, 235, 238, 240, 242, 244, 246, 248, 251, 253, 255
|
||||||
|
};
|
157
src/internal/NeoMosaic.h
Normal file
157
src/internal/NeoMosaic.h
Normal file
@@ -0,0 +1,157 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
/*-------------------------------------------------------------------------
|
||||||
|
Mosiac provides a mapping feature of a 2d cordinate to linear 1d cordinate
|
||||||
|
It is used to map tiles of matricies of NeoPixels to a index on the NeoPixelBus
|
||||||
|
where the the matricies use a set of prefered topology and the tiles of
|
||||||
|
those matricies use the RowMajorAlternating layout
|
||||||
|
|
||||||
|
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/>.
|
||||||
|
-------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// class NeoMosaic
|
||||||
|
// Complex Tile layout class that reduces distance of the interconnects between
|
||||||
|
// the tiles by using different rotations of the layout at specific locations
|
||||||
|
//
|
||||||
|
// T_LAYOUT = the layout used for matrix panel (rotation is ignored)
|
||||||
|
//
|
||||||
|
// NOTE: The tiles in the mosaic are always laid out using RowMajorAlternating
|
||||||
|
//
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
template <typename T_LAYOUT> class NeoMosaic
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
NeoMosaic(uint16_t topoWidth, uint16_t topoHeight,
|
||||||
|
uint16_t mosaicWidth, uint16_t mosaicHeight) :
|
||||||
|
_topoWidth(topoWidth),
|
||||||
|
_topoHeight(topoHeight),
|
||||||
|
_mosaicWidth(mosaicWidth),
|
||||||
|
_mosaicHeight(mosaicHeight)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t Map(uint16_t x, uint16_t y) const
|
||||||
|
{
|
||||||
|
uint16_t localIndex;
|
||||||
|
uint16_t tileOffset;
|
||||||
|
|
||||||
|
calculate(x, y, &localIndex, &tileOffset);
|
||||||
|
|
||||||
|
return localIndex + tileOffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
NeoTopologyHint TopologyHint(uint16_t x, uint16_t y) const
|
||||||
|
{
|
||||||
|
uint16_t localIndex;
|
||||||
|
uint16_t tileOffset;
|
||||||
|
NeoTopologyHint result;
|
||||||
|
|
||||||
|
calculate(x, y, &localIndex, &tileOffset);
|
||||||
|
|
||||||
|
if (localIndex == 0)
|
||||||
|
{
|
||||||
|
result = NeoTopologyHint_FirstOnPanel;
|
||||||
|
}
|
||||||
|
else if (localIndex == (_topoWidth * _topoHeight - 1))
|
||||||
|
{
|
||||||
|
result = NeoTopologyHint_LastOnPanel;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
result = NeoTopologyHint_InPanel;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t getWidth() const
|
||||||
|
{
|
||||||
|
return _topoWidth * _mosaicWidth;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t getHeight() const
|
||||||
|
{
|
||||||
|
return _topoHeight * _mosaicHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
const uint16_t _topoWidth;
|
||||||
|
const uint16_t _topoHeight;
|
||||||
|
const uint16_t _mosaicWidth;
|
||||||
|
const uint16_t _mosaicHeight;
|
||||||
|
|
||||||
|
void calculate(uint16_t x, uint16_t y, uint16_t* pLocalIndex, uint16_t* pTileOffset) const
|
||||||
|
{
|
||||||
|
uint16_t totalWidth = getWidth();
|
||||||
|
uint16_t totalHeight = getHeight();
|
||||||
|
|
||||||
|
if (x >= totalWidth)
|
||||||
|
{
|
||||||
|
x = totalWidth - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (y >= totalHeight)
|
||||||
|
{
|
||||||
|
y = totalHeight - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t tileX = x / _topoWidth;
|
||||||
|
uint16_t topoX = x % _topoWidth;
|
||||||
|
|
||||||
|
uint16_t tileY = y / _topoHeight;
|
||||||
|
uint16_t topoY = y % _topoHeight;
|
||||||
|
|
||||||
|
*pTileOffset = RowMajorAlternatingLayout::Map(_mosaicWidth,
|
||||||
|
_mosaicHeight,
|
||||||
|
tileX,
|
||||||
|
tileY) * _topoWidth * _topoHeight;
|
||||||
|
|
||||||
|
if (tileX & 0x0001)
|
||||||
|
{
|
||||||
|
// odd columns
|
||||||
|
if (tileY & 0x0001)
|
||||||
|
{
|
||||||
|
*pLocalIndex = T_LAYOUT::OddRowOddColumnLayout::Map(_topoWidth, _topoHeight, topoX, topoY);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*pLocalIndex = T_LAYOUT::EvenRowOddColumnLayout::Map(_topoWidth, _topoHeight, topoX, topoY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// even columns
|
||||||
|
if (tileY & 0x0001)
|
||||||
|
{
|
||||||
|
*pLocalIndex = T_LAYOUT::OddRowEvenColumnLayout::Map(_topoWidth, _topoHeight, topoX, topoY);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*pLocalIndex = T_LAYOUT::EvenRowEvenColumnLayout::Map(_topoWidth, _topoHeight, topoX, topoY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
@@ -32,10 +32,7 @@ NeoPixelAnimator::NeoPixelAnimator(uint16_t countAnimations, uint16_t timeScale)
|
|||||||
_activeAnimations(0),
|
_activeAnimations(0),
|
||||||
_isRunning(true)
|
_isRunning(true)
|
||||||
{
|
{
|
||||||
// due to strange esp include header issues, min and max aren't usable
|
setTimeScale(timeScale);
|
||||||
_timeScale = (timeScale < 1) ? (1) : (timeScale > 32768) ? 32768 : timeScale;
|
|
||||||
//_timeScale = max(1, min(32768, timeScale));
|
|
||||||
|
|
||||||
_animations = new AnimationContext[_countAnimations];
|
_animations = new AnimationContext[_countAnimations];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
124
src/internal/NeoTiles.h
Normal file
124
src/internal/NeoTiles.h
Normal file
@@ -0,0 +1,124 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
/*-------------------------------------------------------------------------
|
||||||
|
NeoTiles provides a mapping feature of a 2d cordinate to linear 1d cordinate
|
||||||
|
It is used to map tiles of matricies of NeoPixels to a index on the NeoPixelBus
|
||||||
|
where the the matricies use one topology and the tiles of those matricies can
|
||||||
|
use another
|
||||||
|
|
||||||
|
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/>.
|
||||||
|
-------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// class NeoTiles
|
||||||
|
// Simple template Tile layout class
|
||||||
|
// T_MATRIX_LAYOUT = the layout used on the pixel matrix panel (a tile)
|
||||||
|
// T_TILE_LAYOUT = the layout used for the tiles.
|
||||||
|
//
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
template <typename T_MATRIX_LAYOUT, typename T_TILE_LAYOUT> class NeoTiles
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
NeoTiles(uint16_t topoWidth, uint16_t topoHeight,
|
||||||
|
uint16_t tilesWidth, uint16_t tilesHeight) :
|
||||||
|
_topo(topoWidth, topoHeight),
|
||||||
|
_width(tilesWidth),
|
||||||
|
_height(tilesHeight)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t Map(uint16_t x, uint16_t y) const
|
||||||
|
{
|
||||||
|
uint16_t localIndex;
|
||||||
|
uint16_t tileOffset;
|
||||||
|
|
||||||
|
calculate(x, y, &localIndex, &tileOffset);
|
||||||
|
|
||||||
|
return localIndex + tileOffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
NeoTopologyHint TopologyHint(uint16_t x, uint16_t y) const
|
||||||
|
{
|
||||||
|
uint16_t localIndex;
|
||||||
|
uint16_t tileOffset;
|
||||||
|
NeoTopologyHint result;
|
||||||
|
|
||||||
|
calculate(x, y, &localIndex, &tileOffset);
|
||||||
|
|
||||||
|
if (localIndex == 0)
|
||||||
|
{
|
||||||
|
result = NeoTopologyHint_FirstOnPanel;
|
||||||
|
}
|
||||||
|
else if (localIndex == (_topo.getWidth() * _topo.getHeight() - 1))
|
||||||
|
{
|
||||||
|
result = NeoTopologyHint_LastOnPanel;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
result = NeoTopologyHint_InPanel;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t getWidth() const
|
||||||
|
{
|
||||||
|
return _width * _topo.getWidth();
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t getHeight() const
|
||||||
|
{
|
||||||
|
return _height * _topo.getHeight();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
const NeoTopology<T_MATRIX_LAYOUT> _topo;
|
||||||
|
const uint16_t _width;
|
||||||
|
const uint16_t _height;
|
||||||
|
|
||||||
|
void calculate(uint16_t x, uint16_t y, uint16_t* pLocalIndex, uint16_t* pTileOffset) const
|
||||||
|
{
|
||||||
|
uint16_t totalWidth = getWidth();
|
||||||
|
uint16_t totalHeight = getHeight();
|
||||||
|
|
||||||
|
if (x >= totalWidth)
|
||||||
|
{
|
||||||
|
x = totalWidth - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (y >= totalHeight)
|
||||||
|
{
|
||||||
|
y = totalHeight - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t tileX = x / _topo.getWidth();
|
||||||
|
uint16_t topoX = x % _topo.getWidth();
|
||||||
|
|
||||||
|
uint16_t tileY = y / _topo.getHeight();
|
||||||
|
uint16_t topoY = y % _topo.getHeight();
|
||||||
|
|
||||||
|
*pTileOffset = T_TILE_LAYOUT::Map(_width, _height, tileX, tileY) * _topo.getWidth() * _topo.getHeight();
|
||||||
|
*pLocalIndex = _topo.Map(topoX, topoY);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
73
src/internal/NeoTopology.h
Normal file
73
src/internal/NeoTopology.h
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
/*-------------------------------------------------------------------------
|
||||||
|
NeoTopology provides a mapping feature of a 2d cordinate to linear 1d cordinate
|
||||||
|
It is used to map a matrix 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/>.
|
||||||
|
-------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
enum NeoTopologyHint
|
||||||
|
{
|
||||||
|
NeoTopologyHint_FirstOnPanel,
|
||||||
|
NeoTopologyHint_InPanel,
|
||||||
|
NeoTopologyHint_LastOnPanel,
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T_LAYOUT> class NeoTopology
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
NeoTopology(uint16_t width, uint16_t height) :
|
||||||
|
_width(width),
|
||||||
|
_height(height)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t Map(uint16_t x, uint16_t y) const
|
||||||
|
{
|
||||||
|
if (x >= _width)
|
||||||
|
{
|
||||||
|
x = _width - 1;
|
||||||
|
}
|
||||||
|
if (y >= _height)
|
||||||
|
{
|
||||||
|
y = _height - 1;
|
||||||
|
}
|
||||||
|
return T_LAYOUT::Map(_width, _height, x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t getWidth() const
|
||||||
|
{
|
||||||
|
return _width;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t getHeight() const
|
||||||
|
{
|
||||||
|
return _height;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
const uint16_t _width;
|
||||||
|
const uint16_t _height;
|
||||||
|
};
|
@@ -217,9 +217,27 @@ void RgbColor::Lighten(uint8_t delta)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
RgbColor RgbColor::LinearBlend(RgbColor left, RgbColor right, float progress)
|
RgbColor RgbColor::LinearBlend(const RgbColor& left, const RgbColor& right, float progress)
|
||||||
{
|
{
|
||||||
return RgbColor( left.R + ((right.R - left.R) * progress),
|
return RgbColor( left.R + ((right.R - left.R) * progress),
|
||||||
left.G + ((right.G - left.G) * progress),
|
left.G + ((right.G - left.G) * progress),
|
||||||
left.B + ((right.B - left.B) * progress));
|
left.B + ((right.B - left.B) * progress));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RgbColor RgbColor::BilinearBlend(const RgbColor& c00,
|
||||||
|
const RgbColor& c01,
|
||||||
|
const RgbColor& c10,
|
||||||
|
const RgbColor& c11,
|
||||||
|
float x,
|
||||||
|
float y)
|
||||||
|
{
|
||||||
|
float v00 = (1.0f - x) * (1.0f - y);
|
||||||
|
float v10 = x * (1.0f - y);
|
||||||
|
float v01 = (1.0f - x) * y;
|
||||||
|
float v11 = x * y;
|
||||||
|
|
||||||
|
return RgbColor(
|
||||||
|
c00.R * v00 + c10.R * v10 + c01.R * v01 + c11.R * v11,
|
||||||
|
c00.G * v00 + c10.G * v10 + c01.G * v01 + c11.G * v11,
|
||||||
|
c00.B * v00 + c10.B * v10 + c01.B * v01 + c11.B * v11);
|
||||||
|
}
|
@@ -79,6 +79,16 @@ struct RgbColor
|
|||||||
{
|
{
|
||||||
};
|
};
|
||||||
|
|
||||||
|
bool operator==(const RgbColor& other) const
|
||||||
|
{
|
||||||
|
return (R == other.R && G == other.G && B == other.B);
|
||||||
|
};
|
||||||
|
|
||||||
|
bool operator!=(const RgbColor& other) const
|
||||||
|
{
|
||||||
|
return !(*this == other);
|
||||||
|
};
|
||||||
|
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
// CalculateBrightness will calculate the overall brightness
|
// CalculateBrightness will calculate the overall brightness
|
||||||
// NOTE: This is a simple linear brightness
|
// NOTE: This is a simple linear brightness
|
||||||
@@ -93,7 +103,7 @@ struct RgbColor
|
|||||||
void Darken(uint8_t delta);
|
void Darken(uint8_t delta);
|
||||||
|
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
// Lighten will adjust the color by the given delta toward white
|
// Lighten will adjust the color by the given delta toward ite
|
||||||
// NOTE: This is a simple linear change
|
// NOTE: This is a simple linear change
|
||||||
// delta - (0-255) the amount to lighten the color
|
// delta - (0-255) the amount to lighten the color
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
@@ -106,7 +116,23 @@ struct RgbColor
|
|||||||
// progress - (0.0 - 1.0) value where 0 will return left and 1.0 will return right
|
// progress - (0.0 - 1.0) value where 0 will return left and 1.0 will return right
|
||||||
// and a value between will blend the color weighted linearly between them
|
// and a value between will blend the color weighted linearly between them
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
static RgbColor LinearBlend(RgbColor left, RgbColor right, float progress);
|
static RgbColor LinearBlend(const RgbColor& left, const RgbColor& right, float progress);
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
// BilinearBlend between four colors by the amount defined by 2d variable
|
||||||
|
// c00 - upper left quadrant color
|
||||||
|
// c01 - upper right quadrant color
|
||||||
|
// c10 - lower left quadrant color
|
||||||
|
// c11 - lower right quadrant color
|
||||||
|
// x - unit value (0.0 - 1.0) that defines the blend progress in horizontal space
|
||||||
|
// y - unit value (0.0 - 1.0) that defines the blend progress in vertical space
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
static RgbColor BilinearBlend(const RgbColor& c00,
|
||||||
|
const RgbColor& c01,
|
||||||
|
const RgbColor& c10,
|
||||||
|
const RgbColor& c11,
|
||||||
|
float x,
|
||||||
|
float y);
|
||||||
|
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
// Red, Green, Blue color members (0-255) where
|
// Red, Green, Blue color members (0-255) where
|
||||||
|
@@ -29,13 +29,13 @@ License along with NeoPixel. If not, see
|
|||||||
#include "HsbColor.h"
|
#include "HsbColor.h"
|
||||||
#include "RgbwColor.h"
|
#include "RgbwColor.h"
|
||||||
|
|
||||||
RgbwColor::RgbwColor(HslColor color)
|
RgbwColor::RgbwColor(const HslColor& color)
|
||||||
{
|
{
|
||||||
RgbColor rgbColor(color);
|
RgbColor rgbColor(color);
|
||||||
*this = rgbColor;
|
*this = rgbColor;
|
||||||
}
|
}
|
||||||
|
|
||||||
RgbwColor::RgbwColor(HsbColor color)
|
RgbwColor::RgbwColor(const HsbColor& color)
|
||||||
{
|
{
|
||||||
RgbColor rgbColor(color);
|
RgbColor rgbColor(color);
|
||||||
*this = rgbColor;
|
*this = rgbColor;
|
||||||
@@ -137,10 +137,29 @@ void RgbwColor::Lighten(uint8_t delta)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
RgbwColor RgbwColor::LinearBlend(RgbwColor left, RgbwColor right, float progress)
|
RgbwColor RgbwColor::LinearBlend(const RgbwColor& left, const RgbwColor& right, float progress)
|
||||||
{
|
{
|
||||||
return RgbwColor( left.R + ((right.R - left.R) * progress),
|
return RgbwColor( left.R + ((right.R - left.R) * progress),
|
||||||
left.G + ((right.G - left.G) * progress),
|
left.G + ((right.G - left.G) * progress),
|
||||||
left.B + ((right.B - left.B) * progress),
|
left.B + ((right.B - left.B) * progress),
|
||||||
left.W + ((right.W - left.W) * progress) );
|
left.W + ((right.W - left.W) * progress) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RgbwColor RgbwColor::BilinearBlend(const RgbwColor& c00,
|
||||||
|
const RgbwColor& c01,
|
||||||
|
const RgbwColor& c10,
|
||||||
|
const RgbwColor& c11,
|
||||||
|
float x,
|
||||||
|
float y)
|
||||||
|
{
|
||||||
|
float v00 = (1.0f - x) * (1.0f - y);
|
||||||
|
float v10 = x * (1.0f - y);
|
||||||
|
float v01 = (1.0f - x) * y;
|
||||||
|
float v11 = x * y;
|
||||||
|
|
||||||
|
return RgbwColor(
|
||||||
|
c00.R * v00 + c10.R * v10 + c01.R * v01 + c11.R * v11,
|
||||||
|
c00.G * v00 + c10.G * v10 + c01.G * v01 + c11.G * v11,
|
||||||
|
c00.B * v00 + c10.B * v10 + c01.B * v01 + c11.B * v11,
|
||||||
|
c00.W * v00 + c10.W * v10 + c01.W * v01 + c11.W * v11 );
|
||||||
|
}
|
@@ -59,7 +59,7 @@ struct RgbwColor
|
|||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
// Construct a RgbwColor using RgbColor
|
// Construct a RgbwColor using RgbColor
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
RgbwColor(RgbColor color) :
|
RgbwColor(const RgbColor& color) :
|
||||||
R(color.R),
|
R(color.R),
|
||||||
G(color.G),
|
G(color.G),
|
||||||
B(color.B),
|
B(color.B),
|
||||||
@@ -71,12 +71,12 @@ struct RgbwColor
|
|||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
// Construct a RgbwColor using HslColor
|
// Construct a RgbwColor using HslColor
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
RgbwColor(HslColor color);
|
RgbwColor(const HslColor& color);
|
||||||
|
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
// Construct a RgbwColor using HsbColor
|
// Construct a RgbwColor using HsbColor
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
RgbwColor(HsbColor color);
|
RgbwColor(const HsbColor& color);
|
||||||
|
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
// Construct a RgbwColor that will have its values set in latter operations
|
// Construct a RgbwColor that will have its values set in latter operations
|
||||||
@@ -86,6 +86,16 @@ struct RgbwColor
|
|||||||
{
|
{
|
||||||
};
|
};
|
||||||
|
|
||||||
|
bool operator==(const RgbwColor& other) const
|
||||||
|
{
|
||||||
|
return (R == other.R && G == other.G && B == other.B && W == other.W);
|
||||||
|
};
|
||||||
|
|
||||||
|
bool operator!=(const RgbwColor& other) const
|
||||||
|
{
|
||||||
|
return !(*this == other);
|
||||||
|
};
|
||||||
|
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
// Returns if the color is grey, all values are equal other than white
|
// Returns if the color is grey, all values are equal other than white
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
@@ -130,7 +140,23 @@ struct RgbwColor
|
|||||||
// progress - (0.0 - 1.0) value where 0 will return left and 1.0 will return right
|
// progress - (0.0 - 1.0) value where 0 will return left and 1.0 will return right
|
||||||
// and a value between will blend the color weighted linearly between them
|
// and a value between will blend the color weighted linearly between them
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
static RgbwColor LinearBlend(RgbwColor left, RgbwColor right, float progress);
|
static RgbwColor LinearBlend(const RgbwColor& left, const RgbwColor& right, float progress);
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
// BilinearBlend between four colors by the amount defined by 2d variable
|
||||||
|
// c00 - upper left quadrant color
|
||||||
|
// c01 - upper right quadrant color
|
||||||
|
// c10 - lower left quadrant color
|
||||||
|
// c11 - lower right quadrant color
|
||||||
|
// x - unit value (0.0 - 1.0) that defines the blend progress in horizontal space
|
||||||
|
// y - unit value (0.0 - 1.0) that defines the blend progress in vertical space
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
static RgbwColor BilinearBlend(const RgbwColor& c00,
|
||||||
|
const RgbwColor& c01,
|
||||||
|
const RgbwColor& c10,
|
||||||
|
const RgbwColor& c11,
|
||||||
|
float x,
|
||||||
|
float y);
|
||||||
|
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
// Red, Green, Blue, White color members (0-255) where
|
// Red, Green, Blue, White color members (0-255) where
|
||||||
|
Reference in New Issue
Block a user