From 71dd6e53cf2b7c43c6e58d7b27d173624df113ca Mon Sep 17 00:00:00 2001 From: Makuna Date: Mon, 15 Dec 2014 18:51:52 -0800 Subject: [PATCH] provide better samples and more two samples now are included improved the readme (changed from txt to md) NEO_RGB doesn;t require 400khz support, and 400khz support by default isn't compiled in --- NeoPixelBus.cpp | 32 ++-- NeoPixelBus.h | 18 +-- ReadMe.md | 95 ++++++++++++ ReadMe.txt | 66 --------- .../NeeoPixel16Ring/NeoPixel16RingFun.pde | 123 ---------------- examples/NeoPixelFun/NeoPixelFun.pde | 139 ++++++++++++++++++ examples/NeoPixelTest/NeoPixelTest.pde | 44 ++++++ 7 files changed, 297 insertions(+), 220 deletions(-) create mode 100644 ReadMe.md delete mode 100644 ReadMe.txt delete mode 100644 examples/NeeoPixel16Ring/NeoPixel16RingFun.pde create mode 100644 examples/NeoPixelFun/NeoPixelFun.pde create mode 100644 examples/NeoPixelTest/NeoPixelTest.pde diff --git a/NeoPixelBus.cpp b/NeoPixelBus.cpp index e4f098d..e4a66a4 100644 --- a/NeoPixelBus.cpp +++ b/NeoPixelBus.cpp @@ -37,9 +37,7 @@ NeoPixelBus::NeoPixelBus(uint16_t n, uint8_t p, uint8_t t) : _pin(p), _animationLastTick(0), _activeAnimations(0) -#if defined(NEO_RGB) || defined(NEO_KHZ400) ,_flagsPixels(t) -#endif { setPin(p); @@ -128,7 +126,7 @@ void NeoPixelBus::Show(void) // 8 MHz(ish) AVR --------------------------------------------------------- #if (F_CPU >= 7400000UL) && (F_CPU <= 9500000UL) -#ifdef NEO_KHZ400 +#ifdef INCLUDE_NEO_KHZ400_SUPPORT if ((_flagsPixels & NEO_SPDMASK) == NEO_KHZ800) { // 800 KHz bitstream @@ -335,7 +333,7 @@ void NeoPixelBus::Show(void) } // endif PORTB #endif -#ifdef NEO_KHZ400 +#ifdef INCLUDE_NEO_KHZ400_SUPPORT } else { @@ -394,7 +392,7 @@ void NeoPixelBus::Show(void) // 12 MHz(ish) AVR -------------------------------------------------------- #elif (F_CPU >= 11100000UL) && (F_CPU <= 14300000UL) -#ifdef NEO_KHZ400 +#ifdef INCLUDE_NEO_KHZ400_SUPPORT if ((_flagsPixels & NEO_SPDMASK) == NEO_KHZ800) { // 800 KHz bitstream @@ -526,7 +524,7 @@ void NeoPixelBus::Show(void) } #endif -#ifdef NEO_KHZ400 +#ifdef INCLUDE_NEO_KHZ400_SUPPORT } else { @@ -582,7 +580,7 @@ void NeoPixelBus::Show(void) // 16 MHz(ish) AVR -------------------------------------------------------- #elif (F_CPU >= 15400000UL) && (F_CPU <= 19000000L) -#ifdef NEO_KHZ400 +#ifdef INCLUDE_NEO_KHZ400_SUPPORT if ((_flagsPixels & NEO_SPDMASK) == NEO_KHZ800) { // 800 KHz bitstream @@ -633,7 +631,7 @@ void NeoPixelBus::Show(void) [hi] "r" (hi), [lo] "r" (lo)); -#ifdef NEO_KHZ400 +#ifdef INCLUDE_NEO_KHZ400_SUPPORT } else { @@ -719,7 +717,7 @@ void NeoPixelBus::Show(void) ARM_DEMCR |= ARM_DEMCR_TRCENA; ARM_DWT_CTRL |= ARM_DWT_CTRL_CYCCNTENA; -#ifdef NEO_KHZ400 +#ifdef INCLUDE_NEO_KHZ400_SUPPORT if ((_flagsPixels & NEO_SPDMASK) == NEO_KHZ800) { #endif @@ -745,7 +743,7 @@ void NeoPixelBus::Show(void) } } while (ARM_DWT_CYCCNT - cyc < CYCLES_800); -#ifdef NEO_KHZ400 +#ifdef INCLUDE_NEO_KHZ400_SUPPORT } else { @@ -807,7 +805,7 @@ void NeoPixelBus::Show(void) pix = *p++; mask = 0x80; -#ifdef NEO_KHZ400 +#ifdef INCLUDE_NEO_KHZ400_SUPPORT if ((_flagsPixels & NEO_SPDMASK) == NEO_KHZ800) { #endif @@ -815,7 +813,7 @@ void NeoPixelBus::Show(void) time0 = TIME_800_0; time1 = TIME_800_1; period = PERIOD_800; -#ifdef NEO_KHZ400 +#ifdef INCLUDE_NEO_KHZ400_SUPPORT } else { @@ -895,20 +893,17 @@ void NeoPixelBus::UpdatePixelColor( uint8_t b) { uint8_t *p = &_pixels[n * 3]; -#ifdef NEO_RGB if ((_flagsPixels & NEO_COLMASK) == NEO_GRB) { -#endif *p++ = g; *p++ = r; -#ifdef NEO_RGB } else { *p++ = r; *p++ = g; } -#endif + *p = b; } @@ -920,20 +915,17 @@ RgbColor NeoPixelBus::GetPixelColor(uint16_t n) const RgbColor c; uint8_t *p = &_pixels[n * 3]; -#ifdef NEO_RGB if ((_flagsPixels & NEO_COLMASK) == NEO_GRB) { -#endif c.G = *p++; c.R = *p++; -#ifdef NEO_RGB } else { c.R = *p++; c.G = *p++; } -#endif + c.B = *p; return c; } diff --git a/NeoPixelBus.h b/NeoPixelBus.h index 959e87a..00b024c 100644 --- a/NeoPixelBus.h +++ b/NeoPixelBus.h @@ -29,24 +29,22 @@ License along with NeoPixel. If not, see #include "RgbColor.h" // '_flagsPixels' flags for LED _pixels (third parameter to constructor): +#define NEO_RGB 0x00 // Wired for RGB data order #define NEO_GRB 0x01 // Wired for GRB data order #define NEO_COLMASK 0x01 +#define NEO_KHZ400 0x00 // 400 KHz datastream #define NEO_KHZ800 0x02 // 800 KHz datastream #define NEO_SPDMASK 0x02 -// Trinket flash space is tight, v1 NeoPixels aren't handled by default. -// Remove the ifndef/endif to add support -- but code will be bigger. -// Conversely, can comment out the #defines to save space on other MCUs. -#ifndef __AVR_ATtiny85__ -#define NEO_RGB 0x00 // Wired for RGB data order -#define NEO_KHZ400 0x00 // 400 KHz datastream -#endif +// v1 NeoPixels aren't handled by default, include the following define before the +// NeoPixelBus library include to support the slower bus speeds +// #define INCLUDE_NEO_KHZ400_SUPPORT class NeoPixelBus { public: // Constructor: number of LEDs, pin number, LED type - NeoPixelBus(uint16_t n, uint8_t p = 6, uint8_t t = NEO_GRB + NEO_KHZ800); + NeoPixelBus(uint16_t n, uint8_t p = 6, uint8_t t = NEO_GRB | NEO_KHZ800); ~NeoPixelBus(); void Begin(void); @@ -88,10 +86,8 @@ private: const uint16_t _countPixels; // Number of RGB LEDs in strip const uint16_t _sizePixels; // Size of '_pixels' buffer below - -#if defined(NEO_RGB) || defined(NEO_KHZ400) const uint8_t _flagsPixels; // Pixel flags (400 vs 800 KHz, RGB vs GRB color) -#endif + uint8_t _pin; // Output pin number uint8_t* _pixels; // Holds LED color values (3 bytes each) uint32_t _endTime; // Latch timing reference diff --git a/ReadMe.md b/ReadMe.md new file mode 100644 index 0000000..0e942a3 --- /dev/null +++ b/ReadMe.md @@ -0,0 +1,95 @@ +NeoPixelBus +==== +Arduino NeoPixel library + +Clone this into your Arduino\Library folder + +This library is a modification of the Adafruit NeoPixel library. +The Api is similiar, but it removes the overal brightness feature and adds animation support. + +Installing This Library +------------------------ +Create a directory in your Arduino\Library folder named "NeoPixelBus" +Clone (Git) this project into that folder. +It should now show up in the import list. + +Samples +------- +NeoPixelTest - this is simple example that sets four neopixels to red, green, blue, and then white in order; and then flashes them. If the first pixel is not green instead of read, you need to pass the NEO_RGB flag into the NeoPixelBus constructor. +NeoPixelFun - this is a more complex example, that includes code for three effects, and demonstrates animations. + +API Documentation +----------------- + +RgbColor object: +This represents a color and exposes useful methods to manipulate colors. +

+RgbColor(uint8_t r, uint8_t g, uint8_t b)
+
+ instantiates a RgbColor object with the given r, g, b values. +

+RgbColor(uint8_t brightness)
+
+ instantiates a RgbColor object with the given brightness. 0 is black, 128 is grey, 255 is white. +

+uint8_t CalculateBrightness()
+
+ returns the general brightness of the pixe, averaging color. +

+void Darken(uint8_t delta)
+
+ this will darken the color by the given amount +

+void Lighten(uint8_t delta)
+
+ this will lighten the color by the given amount +

+static RgbColor LinearBlend(RgbColor left, RgbColor right, uint8_t progress)
+
+ this will return a color that is a blend between the given colors. The amount to blend is given by the value of progress, 0 will return the left value, 255 will return the right value, 128 will return the value between them. + NOTE: This is not an accurate "visible light" color blend but is fast and in most cases good enough. + +NeoPixelBus object: +This represents a single NeoPixel Bus that is connected by a single pin. Please see Adafruit's documentation for details, but the differences are documented below. + +

+NeoPixelBus(uint16_t n, uint8_t p = 6, uint8_t t = NEO_GRB | NEO_KHZ800);
+

+instantiates a NewoPixelBus object, with n number of pixels on the bus, over the p pin, using the defined NeoPixel type.
+There are some NeoPixels that address the color values differently, so if you set the green color but it displays as red, use the NEO_RGB type flag.
+

+NeoPixelBus strip = NeoPixelBus(4, 8, NEO_GRB | NEO_KHZ800);
+
+It is rare, but some older NeoPixels require a slower communications speed, to include this support you must include the following define before the NeoPixelBus library include and then include the NEO_KHZ400 type flag to enable this slower speed. +

+#define INCLUDE_NEO_KHZ400_SUPPORT 
+#include <NeoPixelBus.h>
+
+NeoPixelBus strip = NeoPixelBus(4, 8, NEO_GRB | NEO_KHZ400);
+
+ +

+void SetPixelColor(uint16_t n, RgbColor c)
+
+ This allows setting a pixel on the bus to a color as defined by a color object. If an animation is actively running on a pixel, it will be stopped. +

+RgbColor GetPixelColor(uint16_t n) const
+
+ this allows retrieving the current pixel color +

+void LinearFadePixelColor(uint16_t time, uint16_t n, RgbColor color)
+
+ this will setup an animation for a pixel to linear fade between the current color and the given color over the time given. The time is in milliseconds. +

+void StartAnimating()
+
+ this method will initialize the animation state. This should be called only if there are no active animations and new animations are started. +

+void UpdateAnimations()
+
+ this method will allow the animations to processed and update the pixel color state. + NOTE: Show must still be called to push the color state to the physical NeoPixels. +

+bool IsAnimating() const
+
+ this method will return the current animation state. It will return false if there are no active animations. \ No newline at end of file diff --git a/ReadMe.txt b/ReadMe.txt deleted file mode 100644 index 0c851b1..0000000 --- a/ReadMe.txt +++ /dev/null @@ -1,66 +0,0 @@ -NeoPixelBus: - -This library is a modification of the Adafruit NeoPixel library. -The Api is similiar, but it removes the overal brightness feature and adds animation support. - -Installing This Library: -Create a directory in your Library folder named "NeoPixelBus" -Clone (Git) this project into that folder. -It should now show up in the import list. - -Sample: - There is a sample project under the Sample sub-directory. Just copy and change the extention to ino. - -Documentation: - -RgbColor object: -This represents a color and exposes useful methods to manipulate colors. - -RgbColor(uint8_t r, uint8_t g, uint8_t b) - instantiates a RgbColor object with the given r, g, b values. - -RgbColor(uint8_t brightness) - instantiates a RgbColor object with the given brightness. 0 is black, 128 is grey, 255 is white. - -uint8_t CalculateBrightness() - returns the general brightness of the pixe, averaging color. - -void Darken(uint8_t delta) - this will darken the color by the given amount - -void Lighten(uint8_t delta) - this will lighten the color by the given amount - -static RgbColor LinearBlend(RgbColor left, RgbColor right, uint8_t progress) - this will return a color that is a blend between the given colors. The amount to blend is given - by the value of progress, 0 will return the left value, 255 will return the right value, - 128 will return the value between them. - NOTE: This is note an accurate "light" color blend but is fast and in most cases good enough. - - -NeoPixelBus object: -This represents a single NeoPixel Bus that is connected by a single pin. Please see Adafruit's -documentation for details, but the differences are documented below. - -void SetPixelColor(uint16_t n, RgbColor c) - This allows setting a pixel on the bus to a color as defined by a color object. - If an animation is actively running on a pixel, it will be stopped. - -RgbColor GetPixelColor(uint16_t n) const - this allows retrieving the current pixel color - -void LinearFadePixelColor(uint16_t time, uint16_t n, RgbColor color) - this will setup an animation for a pixel to linear fade between the current color and the - given color over the time given. The time is in milliseconds. - -void StartAnimating() - this method will initialize the animation state. This should be called only if there - are no active animations and new animations are started. - -void UpdateAnimations() - this method will allow the animations to processed and update the pixel color state. - NOTE: Show must still be called to push the color state to the physical NeoPixels. - -bool IsAnimating() const - this method will return the current animation state. It will return false if there are - no active animations. \ No newline at end of file diff --git a/examples/NeeoPixel16Ring/NeoPixel16RingFun.pde b/examples/NeeoPixel16Ring/NeoPixel16RingFun.pde deleted file mode 100644 index 8990529..0000000 --- a/examples/NeeoPixel16Ring/NeoPixel16RingFun.pde +++ /dev/null @@ -1,123 +0,0 @@ -#include - -NeoPixelBus strip = NeoPixelBus(16, 8); -uint16_t p = 0; - - - -void setup() -{ - strip.Begin(); - strip.Show(); - randomSeed(analogRead(0)); - Serial.begin(9600); - -} - - -void loop() -{ - Serial.println("next"); - - - - // LoopAround(192, 200); - PickRandom(128); - // FadeInFadeOutRinseRepeat(192); - - // start animating - strip.StartAnimating(); - - // wait until no more animations are running - while (strip.IsAnimating()) - { - strip.UpdateAnimations(); - strip.Show(); - delay(31); // ~30hz change cycle - } - -} - -void FadeInFadeOutRinseRepeat(uint8_t peak) -{ - if (p == 0) - { - for (uint8_t pixel = 0; pixel < 16; pixel++) - { - uint16_t time = random(800,1000); - strip.LinearFadePixelColor(time, pixel, RgbColor(random(peak), random(peak), random(peak))); - } - } - else if (p == 1) - { - for (uint8_t pixel = 0; pixel < 16; pixel++) - { - uint16_t time = random(600,700); - strip.LinearFadePixelColor(time, pixel, RgbColor(0, 0, 0)); - } - } - p = (p + 1) % 2; // next procedure and keep within the number of procedures - -} - -void PickRandom(uint8_t peak) -{ - - // pick random set of pixels to animate - uint8_t count = random(16); - while (count > 0) - { - uint8_t pixel = random(16); - - // configure the animations - RgbColor color; // = strip.getPixelColor(pixel); - - color = RgbColor(random(peak), random(peak), random(peak)); - - - uint16_t time = random(100,400); - strip.LinearFadePixelColor( time, pixel, color); - - count--; - } -} - -void LoopAround(uint8_t peak, uint16_t speed) -{ - // Looping around the ring sample - uint16_t prev; - RgbColor prevColor; - - // fade previous one dark - prev = (p + 11) % 16; - strip.LinearFadePixelColor(speed, prev, RgbColor(0, 0, 0)); - - // fade previous one dark - prev = (p + 12) % 16; - prevColor = strip.GetPixelColor( prev ); - prevColor.Darken(prevColor.CalculateBrightness() / 2); - strip.LinearFadePixelColor(speed, prev, prevColor); - - // fade previous one dark - prev = (p + 13) % 16; - prevColor = strip.GetPixelColor( prev ); - prevColor.Darken(prevColor.CalculateBrightness() / 2); - strip.LinearFadePixelColor(speed, prev, prevColor); - - // fade previous one dark - prev = (p + 14) % 16; - prevColor = strip.GetPixelColor( prev ); - prevColor.Darken(prevColor.CalculateBrightness() / 2); - strip.LinearFadePixelColor(speed, prev, prevColor); - - // fade previous one dark - prev = (p + 15) % 16; - prevColor = strip.GetPixelColor( prev ); - prevColor.Darken(prevColor.CalculateBrightness() / 2); - strip.LinearFadePixelColor(speed, prev, prevColor); - - // fade current one light - strip.LinearFadePixelColor(speed, p, RgbColor(random(peak), random(peak), random(peak))); - p = (p+1) % 16; -} - diff --git a/examples/NeoPixelFun/NeoPixelFun.pde b/examples/NeoPixelFun/NeoPixelFun.pde new file mode 100644 index 0000000..b97ec40 --- /dev/null +++ b/examples/NeoPixelFun/NeoPixelFun.pde @@ -0,0 +1,139 @@ +#include + +#define pixelCount 4 + +NeoPixelBus strip = NeoPixelBus(pixelCount, 8); +uint16_t effectState = 0; + + +void setup() +{ + strip.Begin(); + strip.Show(); + SetRandomSeed(); +} + + +void loop() +{ + // There are three fun functions that implement different effects + // uncomment one at a time and upload to see the effect + + // LoopAround(192, 200); // very interesting on rings of NeoPixels + PickRandom(128); + // FadeInFadeOutRinseRepeat(192); + + // start animating + strip.StartAnimating(); + + // wait until no more animations are running + while (strip.IsAnimating()) + { + strip.UpdateAnimations(); + strip.Show(); + delay(31); // ~30hz change cycle + } + +} + +void FadeInFadeOutRinseRepeat(uint8_t peak) +{ + if (effectState == 0) + { + for (uint8_t pixel = 0; pixel < pixelCount; pixel++) + { + uint16_t time = random(800,1000); + strip.LinearFadePixelColor(time, pixel, RgbColor(random(peak), random(peak), random(peak))); + } + } + else if (effectState == 1) + { + for (uint8_t pixel = 0; pixel < pixelCount; pixel++) + { + uint16_t time = random(600,700); + strip.LinearFadePixelColor(time, pixel, RgbColor(0, 0, 0)); + } + } + effectState = (effectState + 1) % 2; // next effectState and keep within the number of effectStates + +} + +void PickRandom(uint8_t peak) +{ + + // pick random set of pixels to animate + uint8_t count = random(pixelCount); + while (count > 0) + { + uint8_t pixel = random(pixelCount); + + // configure the animations + RgbColor color; // = strip.getPixelColor(pixel); + + color = RgbColor(random(peak), random(peak), random(peak)); + + + uint16_t time = random(100,400); + strip.LinearFadePixelColor( time, pixel, color); + + count--; + } +} + +void LoopAround(uint8_t peak, uint16_t speed) +{ + // Looping around the ring sample + uint16_t prevPixel; + RgbColor prevColor; + + // fade previous one dark + prevPixel = (effectState + (pixelCount - 5)) % pixelCount; + strip.LinearFadePixelColor(speed, prevPixel, RgbColor(0, 0, 0)); + + // fade previous one dark + prevPixel = (effectState + (pixelCount - 4)) % pixelCount; + prevColor = strip.GetPixelColor( prevPixel ); + prevColor.Darken(prevColor.CalculateBrightness() / 2); + strip.LinearFadePixelColor(speed, prevPixel, prevColor); + + // fade previous one dark + prevPixel = (effectState + (pixelCount - 3)) % pixelCount; + prevColor = strip.GetPixelColor( prevPixel ); + prevColor.Darken(prevColor.CalculateBrightness() / 2); + strip.LinearFadePixelColor(speed, prevPixel, prevColor); + + // fade previous one dark + prevPixel = (effectState + (pixelCount - 2)) % pixelCount; + prevColor = strip.GetPixelColor( prevPixel ); + prevColor.Darken(prevColor.CalculateBrightness() / 2); + strip.LinearFadePixelColor(speed, prevPixel, prevColor); + + // fade previous one dark + prevPixel = (effectState + (pixelCount - 1)) % pixelCount; + prevColor = strip.GetPixelColor( prevPixel ); + prevColor.Darken(prevColor.CalculateBrightness() / 2); + strip.LinearFadePixelColor(speed, prevPixel, prevColor); + + // fade current one light + strip.LinearFadePixelColor(speed, effectState, RgbColor(random(peak), random(peak), random(peak))); + effectState = (effectState + 1) % pixelCount; +} + +void SetRandomSeed() +{ + uint32_t seed; + + // random works best with a seed that can use 31 bits + // analogRead on a unconnected pin tends toward less than four bits + seed = analogRead(0); + delay(1); + + for (int shifts = 3; shifts < 31; shifts += 3) + { + seed ^= analogRead(0) << shifts; + delay(1); + } + + // Serial.println(seed); + randomSeed(seed); +} diff --git a/examples/NeoPixelTest/NeoPixelTest.pde b/examples/NeoPixelTest/NeoPixelTest.pde new file mode 100644 index 0000000..8ef226d --- /dev/null +++ b/examples/NeoPixelTest/NeoPixelTest.pde @@ -0,0 +1,44 @@ +#include + +#define pixelCount 4 +#define colorSaturation 128 + +NeoPixelBus strip = NeoPixelBus(pixelCount, 8); + +RgbColor red = RgbColor(colorSaturation, 0, 0); +RgbColor green = RgbColor(0, colorSaturation, 0); +RgbColor blue = RgbColor(0, 0, colorSaturation); +RgbColor white = RgbColor(colorSaturation); +RgbColor black = RgbColor(0); + +void setup() +{ + // this resets all the neopixels to an off state + strip.Begin(); + strip.Show(); +} + + +void loop() +{ + delay(1000); + + // set the colors, + // if they don't match in order, you may need to use NEO_GRB flag + strip.SetPixelColor(0, red); + strip.SetPixelColor(1, green); + strip.SetPixelColor(2, blue); + strip.SetPixelColor(3, white); + strip.Show(); + + delay(3000); + + // turn off the pixels + strip.SetPixelColor(0, black); + strip.SetPixelColor(1, black); + strip.SetPixelColor(2, black); + strip.SetPixelColor(3, black); + strip.Show(); +} + +