NeoPixelBrightnessBus (#143)

This commit is contained in:
Michael Miller
2016-12-11 14:51:35 -08:00
committed by GitHub
parent 487e0d2cd8
commit 89b3f85c18
6 changed files with 347 additions and 4 deletions

View File

@@ -0,0 +1,83 @@
// NeoPixelBrightness
// This example will cycle brightness from high to low of
// three pixels colored Red, Green, Blue.
// This demonstrates the use of the NeoPixelBrightnessBus
// with integrated brightness support
//
// There is serial output of the current state so you can
// confirm and follow along
//
#include <NeoPixelBrightnessBus.h> // instead of NeoPixelBus.h
const uint16_t PixelCount = 3; // this example assumes 3 pixels, making it smaller will cause a failure
const uint8_t PixelPin = 14; // make sure to set this to the correct pin, ignored for Esp8266
#define colorSaturation 255 // saturation of color constants
RgbColor red(colorSaturation, 0, 0);
RgbColor green(0, colorSaturation, 0);
RgbColor blue(0, 0, colorSaturation);
// Make sure to provide the correct color order feature
// for your NeoPixels
NeoPixelBrightnessBus<NeoRgbFeature, Neo800KbpsMethod> strip(PixelCount, PixelPin);
// you loose the original color the lower the dim value used
// here due to quantization
const uint8_t c_MinBrightness = 8;
const uint8_t c_MaxBrightness = 255;
int8_t direction; // current direction of dimming
void setup()
{
Serial.begin(115200);
while (!Serial); // wait for serial attach
Serial.println();
Serial.println("Initializing...");
Serial.flush();
// this resets all the neopixels to an off state
strip.Begin();
strip.Show();
direction = -1; // default to dim first
Serial.println();
Serial.println("Running...");
// set our three original colors
strip.SetPixelColor(0, red);
strip.SetPixelColor(1, green);
strip.SetPixelColor(2, blue);
strip.Show();
}
void loop()
{
uint8_t brightness = strip.GetBrightness();
Serial.println(brightness);
delay(100);
// swap diection of dim when limits are reached
//
if (direction < 0 && brightness <= c_MinBrightness)
{
direction = 1;
}
else if (direction > 0 && brightness >= c_MaxBrightness)
{
direction = -1;
}
// apply dimming
brightness += direction;
strip.SetBrightness(brightness);
// show the results
strip.Show();
}

View File

@@ -8,7 +8,7 @@
"type": "git",
"url": "https://github.com/Makuna/NeoPixelBus"
},
"version": "2.2.4",
"version": "2.2.5",
"frameworks": "arduino",
"platforms": "*"
}

View File

@@ -1,5 +1,5 @@
name=NeoPixelBus by Makuna
version=2.2.4
version=2.2.5
author=Michael C. Miller (makuna@live.com)
maintainer=Michael C. Miller (makuna@live.com)
sentence=A library that makes controlling NeoPixels (WS2811, WS2812 & SK6812) and DotStars (APA102) easy.

138
src/NeoPixelBrightnessBus.h Normal file
View File

@@ -0,0 +1,138 @@
/*-------------------------------------------------------------------------
NeoPixelBus library wrapper template class that provides overall brightness control
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
#include "NeoPixelBus.h"
template<typename T_COLOR_FEATURE, typename T_METHOD> class NeoPixelBrightnessBus :
public NeoPixelBus<T_COLOR_FEATURE, T_METHOD>
{
public:
NeoPixelBrightnessBus(uint16_t countPixels, uint8_t pin) :
NeoPixelBus<T_COLOR_FEATURE, T_METHOD>(countPixels, pin),
_brightness(0)
{
}
NeoPixelBrightnessBus(uint16_t countPixels, uint8_t pinClock, uint8_t pinData) :
NeoPixelBus<T_COLOR_FEATURE, T_METHOD>(countPixels, pinClock, pinData),
_brightness(0)
{
}
NeoPixelBrightnessBus(uint16_t countPixels) :
NeoPixelBus<T_COLOR_FEATURE, T_METHOD>(countPixels),
_brightness(0)
{
}
void SetBrightness(uint8_t brightness)
{
// Due to using fixed point math, we modifiy the brightness
// before storing making the math faster
uint8_t newBrightness = brightness + 1;
// Only update if there is a change
if (newBrightness != _brightness)
{
// calculate a scale to modify from old brightness to new brightness
//
uint8_t oldBrightness = _brightness - 1; // unmodify brightness value
uint16_t scale;
if (oldBrightness == 0)
{
scale = 0; // Avoid divide by 0
}
else if (brightness == 255)
{
scale = 65535 / oldBrightness;
}
else
{
scale = (((uint16_t)newBrightness << 8) - 1) / oldBrightness;
}
// re-scale existing pixels
//
uint8_t* ptr = this->Pixels();
uint8_t* ptrEnd = ptr + this->PixelsSize();
while (ptr != ptrEnd)
{
uint16_t value = *ptr;
*ptr++ = (value * scale) >> 8;
}
_brightness = newBrightness;
this->Dirty();
}
}
uint8_t GetBrightness() const
{
return _brightness - 1;
}
void SetPixelColor(uint16_t indexPixel, typename T_COLOR_FEATURE::ColorObject color)
{
if (_brightness)
{
uint8_t* ptr = (uint8_t*)&color;
uint8_t* ptrEnd = ptr + T_COLOR_FEATURE::PixelSize;
while (ptr != ptrEnd)
{
uint16_t value = *ptr;
*ptr++ = (value * _brightness) >> 8;
}
}
NeoPixelBus<T_COLOR_FEATURE, T_METHOD>::SetPixelColor(indexPixel, color);
}
typename T_COLOR_FEATURE::ColorObject GetPixelColor(uint16_t indexPixel) const
{
typename T_COLOR_FEATURE::ColorObject color = NeoPixelBus<T_COLOR_FEATURE, T_METHOD>::GetPixelColor(indexPixel);
if (_brightness)
{
uint8_t* ptr = (uint8_t*)&color;
uint8_t* ptrEnd = ptr + T_COLOR_FEATURE::PixelSize;
while (ptr != ptrEnd)
{
uint16_t value = *ptr;
*ptr++ = (value << 8) / _brightness;
}
}
return color;
}
protected:
uint8_t _brightness;
};

View File

@@ -152,7 +152,7 @@ public:
_state &= ~NEO_DIRTY;
};
uint8_t* Pixels() const
uint8_t* Pixels()
{
return _method.getPixels();
};
@@ -307,7 +307,7 @@ public:
private:
protected:
const uint16_t _countPixels; // Number of RGB LEDs in strip
uint8_t _state; // internal state
@@ -381,3 +381,4 @@ private:
}
};

View File

@@ -0,0 +1,121 @@
/*-------------------------------------------------------------------------
NeoPixel library helper template class that provides overall brightness control
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
template<typename T_COLOR_FEATURE, typename T_METHOD> class NeoBrightnessBus :
public NeoPixelBus<T_COLOR_FEATURE, T_METHOD>
{
public:
void SetBrightness(uint8_t brightness)
{
// Stored brightness value is different than what's passed.
// This simplifies the actual scaling math later, allowing a fast
// 8x8-bit multiply and taking the MSB. 'brightness' is a uint8_t,
// adding 1 here may (intentionally) roll over...so 0 = max brightness
// (color values are interpreted literally; no scaling), 1 = min
// brightness (off), 255 = just below max brightness.
uint8_t newBrightness = brightness + 1;
// Only update if there is a change
if (newBrightness != _brightness)
{
// calculate a scale to modify from old brightness to new brightness
//
uint8_t oldBrightness = _brightness - 1; // De-wrap old brightness value
uint16_t scale;
if (oldBrightness == 0)
{
scale = 0; // Avoid divide by 0
}
else if (brightness == 255)
{
scale = 65535 / oldBrightness;
}
else
{
scale = (((uint16_t)newBrightness << 8) - 1) / oldBrightness;
}
// re-scale existing data in RAM
//
uint8_t* ptr = pixels;
uint8_t* ptrEnd = pixels + PixelsSize();
while (ptr != ptrEnd)
{
uint16_t value = *ptr;
*ptr++ = (value * scale) >> 8;
}
_brightness = newBrightness;
Dirty();
}
}
uint8_t GetBrightness() const
{
return _brightness;
}
void SetPixelColor(uint16_t indexPixel, typename T_COLOR_FEATURE::ColorObject color)
{
if (_brightness)
{
uint8_t* ptr = (uint8_t*)&color;
uint8_t* ptrEnd = ptr + T_COLOR_FEATURE::PixelSize;
while (ptr != ptrEnd)
{
uint16_t value = *ptr;
*ptr++ = (value * _brightness) >> 8;
}
}
NeoPixelBus<T_COLOR_FEATURE, T_METHOD>::SetPixelColor(indexPixel, color);
}
typename T_COLOR_FEATURE::ColorObject GetPixelColor(uint16_t indexPixel) const
{
T_COLOR_FEATURE::ColorObject color = NeoPixelBus<T_COLOR_FEATURE, T_METHOD>::GetPixelColor(indexPixel);
if (_brightness)
{
uint8_t* ptr = (uint8_t*)&color;
uint8_t* ptrEnd = ptr + T_COLOR_FEATURE::PixelSize;
while (ptr != ptrEnd)
{
uint16_t value = *ptr;
*ptr++ = (value << 8) / _brightness);
}
}
return color;
}
protected:
uint8_t _brightness;
};