Skip to content

Commit

Permalink
NeoPixelBrightnessBus (#143)
Browse files Browse the repository at this point in the history
  • Loading branch information
Makuna authored Dec 11, 2016
1 parent 487e0d2 commit 89b3f85
Show file tree
Hide file tree
Showing 6 changed files with 347 additions and 4 deletions.
83 changes: 83 additions & 0 deletions examples/NeoPixelBrightness/NeoPixelBrightness.ino
Original file line number Diff line number Diff line change
@@ -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();
}

2 changes: 1 addition & 1 deletion library.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
"type": "git",
"url": "https://github.com/Makuna/NeoPixelBus"
},
"version": "2.2.4",
"version": "2.2.5",
"frameworks": "arduino",
"platforms": "*"
}
Expand Down
2 changes: 1 addition & 1 deletion library.properties
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name=NeoPixelBus by Makuna
version=2.2.4
version=2.2.5
author=Michael C. Miller ([email protected])
maintainer=Michael C. Miller ([email protected])
sentence=A library that makes controlling NeoPixels (WS2811, WS2812 & SK6812) and DotStars (APA102) easy.
Expand Down
138 changes: 138 additions & 0 deletions src/NeoPixelBrightnessBus.h
Original file line number Diff line number Diff line change
@@ -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;
};


5 changes: 3 additions & 2 deletions src/NeoPixelBus.h
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ template<typename T_COLOR_FEATURE, typename T_METHOD> class NeoPixelBus
_state &= ~NEO_DIRTY;
};

uint8_t* Pixels() const
uint8_t* Pixels()
{
return _method.getPixels();
};
Expand Down Expand Up @@ -307,7 +307,7 @@ template<typename T_COLOR_FEATURE, typename T_METHOD> class NeoPixelBus



private:
protected:
const uint16_t _countPixels; // Number of RGB LEDs in strip

uint8_t _state; // internal state
Expand Down Expand Up @@ -381,3 +381,4 @@ template<typename T_COLOR_FEATURE, typename T_METHOD> class NeoPixelBus
}
};


121 changes: 121 additions & 0 deletions src/internal/NeoBrightnessBus.h
Original file line number Diff line number Diff line change
@@ -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;
};


0 comments on commit 89b3f85

Please sign in to comment.