From 99f8bcf6f76c536a2e6a874b11f0382b2f314e01 Mon Sep 17 00:00:00 2001 From: nick-diel <35879080+nick-diel@users.noreply.github.com> Date: Wed, 13 Dec 2023 17:33:42 -0700 Subject: [PATCH] Support for Adafruit Pixie (#749) * Support for Adafruit Pixie * Updated based on PR review to align with library style and added Pixie constructor to NeoPixelBugLg --- examples/PixieSerial/PixieSerial.ino | 78 +++++++++++++++++ src/NeoPixelBus.h | 7 ++ src/NeoPixelBusLg.h | 6 ++ src/internal/NeoMethods.h | 4 + src/internal/methods/PixieStreamMethod.h | 105 +++++++++++++++++++++++ 5 files changed, 200 insertions(+) create mode 100644 examples/PixieSerial/PixieSerial.ino create mode 100644 src/internal/methods/PixieStreamMethod.h diff --git a/examples/PixieSerial/PixieSerial.ino b/examples/PixieSerial/PixieSerial.ino new file mode 100644 index 0000000..280b315 --- /dev/null +++ b/examples/PixieSerial/PixieSerial.ino @@ -0,0 +1,78 @@ +// PixieTest +// This example will cycle between showing Pixies as Red, Green, Blue, White +// and then showing those Pixies as Black. +// +// There is serial output of the current state so you can confirm and follow along +// + +#include + +const uint16_t PixelCount = 1; // Number of Pixies daisycahined + +#define colorSaturation 128 + +// Pixie reads data in at 115.2k serial, 8N1. +// Byte order is R1, G1, B1, R2, G2, B2, ... where the first triplet is the +// color of the LED that's closest to the controller. 1ms of silence triggers +// latch. 2 seconds silence (or overheating) triggers LED off (for safety). + +// Use either Software Serial or hardware serial depending on the board + +// #include "SoftwareSerial.h" +// #define PIXIEPIN 6 // Pin number for SoftwareSerial output +// SoftwareSerial pixieSerial(-1, PIXIEPIN); + +//hardware Serial +#define pixieSerial Serial2 + +NeoPixelBus strip(PixelCount, &pixieSerial); + +RgbColor colors[5]; + +void setup() +{ + Serial.begin(115200); + while (!Serial); // wait for serial attach + + Serial.println(); + Serial.println("Initializing..."); + Serial.flush(); + + // Pixie requires 115200 buard rate and 8N1 (eight bits, no parity, 1 stop bit). + pixieSerial.begin(115200, SERIAL_8N1); + + //setup array of colors (R,G,B,W,Black) + colors[0] = RgbColor(colorSaturation, 0, 0); + colors[1] = RgbColor(0, colorSaturation, 0); + colors[2] = RgbColor(0, 0, colorSaturation); + colors[3] = RgbColor(colorSaturation); + colors[4] = RgbColor(0); + + // this resets all the Pixies to an off state + strip.Begin(); + strip.Show(); + + Serial.println(); + Serial.println("Running..."); +} + + +void loop() +{ + Serial.println("RGB Colors R, G, B, W, Off"); + // Cycle all the Pixies through Red->Green->Blue->White->Black/Off from the colors array + for(int colorIndex=0; colorIndex<5; colorIndex++) + { + for(int pixelIndex=0; pixelIndex2 seconds + // Adafruit recomends sending data <1 second. If needed, .Show() can be called + // again to resend the existing color value to reset this timer. + + } + +} \ No newline at end of file diff --git a/src/NeoPixelBus.h b/src/NeoPixelBus.h index bf6344f..e7e92af 100644 --- a/src/NeoPixelBus.h +++ b/src/NeoPixelBus.h @@ -84,6 +84,13 @@ public: { } + NeoPixelBus(uint16_t countPixels, Stream* pixieStream) : + _countPixels(countPixels), + _state(0), + _method(countPixels, T_COLOR_FEATURE::PixelSize, T_COLOR_FEATURE::SettingsSize, pixieStream) + { + } + ~NeoPixelBus() { } diff --git a/src/NeoPixelBusLg.h b/src/NeoPixelBusLg.h index 9afaeee..7544bef 100644 --- a/src/NeoPixelBusLg.h +++ b/src/NeoPixelBusLg.h @@ -131,6 +131,12 @@ public: NeoPixelBus(countPixels), Shader() { + } + + NeoPixelBusLg(uint16_t countPixels, Stream* pixieStream) : + NeoPixelBus(countPixels, pixieStream), + Shader() + { } ~NeoPixelBusLg() diff --git a/src/internal/NeoMethods.h b/src/internal/NeoMethods.h index 27ac2bc..876b9fe 100644 --- a/src/internal/NeoMethods.h +++ b/src/internal/NeoMethods.h @@ -37,6 +37,10 @@ License along with NeoPixel. If not, see #include "methods/Sm16716GenericMethod.h" #include "methods/Mbi6033GenericMethod.h" +//Adafruit Pixie via UART, not platform specific +// +#include "methods/PixieStreamMethod.h" + // Platform specific and One Wire (data) methods // #if defined(ARDUINO_ARCH_ESP8266) diff --git a/src/internal/methods/PixieStreamMethod.h b/src/internal/methods/PixieStreamMethod.h new file mode 100644 index 0000000..b290d28 --- /dev/null +++ b/src/internal/methods/PixieStreamMethod.h @@ -0,0 +1,105 @@ +/*------------------------------------------------------------------------- +NeoPixel library helper functions for DotStars using general Pins (APA102). + +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 +. +-------------------------------------------------------------------------*/ + +/* + Pixie reads data in at 115.2k serial, 8N1. + Byte order is R1, G1, B1, R2, G2, B2, ... where the first triplet is the + color of the LED that's closest to the controller. 1ms of silence triggers + latch. 2 seconds silence (or overheating) triggers LED off (for safety). +*/ + + +#pragma once + + +class PixieStreamMethod +{ +public: + typedef NeoNoSettings SettingsObject; + + PixieStreamMethod(uint16_t pixelCount, size_t elementSize, size_t settingsSize, Stream* pixieStream) : + _sizeData(pixelCount * elementSize + settingsSize), + _usEndTime(0), + _stream(pixieStream) + { + _data = static_cast(malloc(_sizeData)); + // data cleared later in Begin() + } + + ~PixieStreamMethod() + { + free(_data); + } + + bool IsReadyToUpdate() const + { + return (micros() - _usEndTime) > 1000L; // ensure 1ms delay between calls + } + + void Initialize() + { + // nothing to initialize, UART is managed outside this library + } + + void Update(bool) + { + while (!IsReadyToUpdate()) + { + } + _stream->write(_data, _sizeData); + _usEndTime = micros(); // Save time to ensure 1ms delay + } + + bool AlwaysUpdate() + { + // Pixie expects to receive data every <2 seconds, Adafruit recommends <1. + // Ensuring data is sent every <2 seconds needs to happen outside of the library + // Returning true will allow data to be re-sent even if no changes to buffer. + + return true; + } + + uint8_t* getData() const + { + return _data; + }; + + size_t getDataSize() const + { + return _sizeData; + }; + + void applySettings([[maybe_unused]] const SettingsObject& settings) + { + } + +private: + const size_t _sizeData; // Size of '_data' buffer below + + uint8_t* _data; // Holds LED color values + Stream* _stream; + uint32_t _usEndTime; // microseconds EndTime +};