Skip to content

Instantly share code, notes, and snippets.

@Aircoookie
Created April 14, 2020 22:57
Show Gist options
  • Save Aircoookie/974ef271fa9b73db45aebc5199302ee5 to your computer and use it in GitHub Desktop.
Save Aircoookie/974ef271fa9b73db45aebc5199302ee5 to your computer and use it in GitHub Desktop.
New WLED multi-pin pixel driver (untested, alpha)
//this code is a modified version of https://github.com/Makuna/NeoPixelBus/issues/103
#ifndef PixelDrv_h
#define PixelDrv_h
#ifndef LEDPIN
#define LEDPIN 2
#endif
#ifndef BTNPIN
#define BTNPIN 0 //button pin. Needs to have pullup (gpio0 recommended)
#endif
#ifndef IR_PIN
#define IR_PIN 4 //infrared pin (-1 to disable) MagicHome: 4, H801 Wifi: 0
#endif
#ifndef RLYPIN
#define RLYPIN 12 //pin for relay, will be set HIGH if LEDs are on (-1 to disable). Also usable for standby leds, triggers,...
#endif
#ifndef AUXPIN
#define AUXPIN -1 //debug auxiliary output pin (-1 to disable)
#endif
#ifndef RLYMDE
#define RLYMDE 1 //mode for relay, 0: LOW if LEDs are on 1: HIGH if LEDs are on
#endif
#include <NeoPixelBrightnessBus.h>
class PixelDriver
{
public:
PixelDriver() :
// initialize bus pointer to null
_pGrb(NULL),
lightType(TYPE_NONE)
{
}
~PixelDriver()
{
cleanup();
}
bool begin(byte type, uint16_t countPixels, byte* pins, byte rmt_id)
{
cleanup();
lightType = type;
byte* _pins = {2, 0, 0, 0, 0}; //temp
switch (lightType)
{
case TYPE_NONE:
return false;
case TYPE_RESERVERD:
return false;
case TYPE_WS2812_RGB: //those two are identical driver-wise
case TYPE_WS2812_WWA:
#ifdef ESP8266
switch(pins[0])
{
case 1: psr0_rgb0 = new NeoPixelBrightnessBus<NeoGrbFeature , NeoEsp8266Uart0Ws2813Method >(countPixels); break;
case 2: psr1_rgb0 = new NeoPixelBrightnessBus<NeoGrbFeature , NeoEsp8266Uart1Ws2813Method >(countPixels); break;
case 3: pdma_rgb0 = new NeoPixelBrightnessBus<NeoGrbFeature , NeoEsp8266Dma800KbpsMethod >(countPixels); break;
default: pbbg_rgb0 = new NeoPixelBrightnessBus<NeoGrbFeature , NeoEsp8266BitBang800KbpsMethod>(countPixels, pins[0]);
}
#else //ESP32 RMT
switch(rmt_id)
{
case 0: prm0_rgb0 = new NeoPixelBrightnessBus<NeoGrbFeature , NeoEsp32Rmt0Ws2812xMethod>(countPixels, pins[0]); break;
case 1: prm1_rgb0 = new NeoPixelBrightnessBus<NeoGrbFeature , NeoEsp32Rmt1Ws2812xMethod>(countPixels, pins[0]); break;
case 2: prm2_rgb0 = new NeoPixelBrightnessBus<NeoGrbFeature , NeoEsp32Rmt2Ws2812xMethod>(countPixels, pins[0]); break;
case 3: prm3_rgb0 = new NeoPixelBrightnessBus<NeoGrbFeature , NeoEsp32Rmt3Ws2812xMethod>(countPixels, pins[0]); break;
case 4: prm4_rgb0 = new NeoPixelBrightnessBus<NeoGrbFeature , NeoEsp32Rmt4Ws2812xMethod>(countPixels, pins[0]); break;
case 5: prm5_rgb0 = new NeoPixelBrightnessBus<NeoGrbFeature , NeoEsp32Rmt5Ws2812xMethod>(countPixels, pins[0]); break;
case 6: prm6_rgb0 = new NeoPixelBrightnessBus<NeoGrbFeature , NeoEsp32Rmt6Ws2812xMethod>(countPixels, pins[0]); break;
case 7: prm7_rgb0 = new NeoPixelBrightnessBus<NeoGrbFeature , NeoEsp32Rmt7Ws2812xMethod>(countPixels, pins[0]); break;
default: return false;
}
#endif
break;
case TYPE_SK6812_RGBW:
#ifdef ESP8266
switch(pins[0])
{
case 1: psr0_rgbw = new NeoPixelBrightnessBus<NeoGrbwFeature, NeoEsp8266Uart0Ws2813Method >(countPixels); break;
case 2: psr1_rgbw = new NeoPixelBrightnessBus<NeoGrbwFeature, NeoEsp8266Uart1Ws2813Method >(countPixels); break;
case 3: pdma_rgbw = new NeoPixelBrightnessBus<NeoGrbwFeature, NeoEsp8266Dma800KbpsMethod >(countPixels); break;
default: pbbg_rgbw = new NeoPixelBrightnessBus<NeoGrbwFeature, NeoEsp8266BitBang800KbpsMethod>(countPixels, pins[0]);
}
#else //ESP32 RMT
switch(rmt_id)
{
case 0: prm0_rgb0 = new NeoPixelBrightnessBus<NeoGrbwFeature, NeoEsp32Rmt0Ws2812xMethod>(countPixels, pins[0]); break;
case 1: prm1_rgb0 = new NeoPixelBrightnessBus<NeoGrbwFeature, NeoEsp32Rmt1Ws2812xMethod>(countPixels, pins[0]); break;
case 2: prm2_rgb0 = new NeoPixelBrightnessBus<NeoGrbwFeature, NeoEsp32Rmt2Ws2812xMethod>(countPixels, pins[0]); break;
case 3: prm3_rgb0 = new NeoPixelBrightnessBus<NeoGrbwFeature, NeoEsp32Rmt3Ws2812xMethod>(countPixels, pins[0]); break;
case 4: prm4_rgb0 = new NeoPixelBrightnessBus<NeoGrbwFeature, NeoEsp32Rmt4Ws2812xMethod>(countPixels, pins[0]); break;
case 5: prm5_rgb0 = new NeoPixelBrightnessBus<NeoGrbwFeature, NeoEsp32Rmt5Ws2812xMethod>(countPixels, pins[0]); break;
case 6: prm6_rgb0 = new NeoPixelBrightnessBus<NeoGrbwFeature, NeoEsp32Rmt6Ws2812xMethod>(countPixels, pins[0]); break;
case 7: prm7_rgb0 = new NeoPixelBrightnessBus<NeoGrbwFeature, NeoEsp32Rmt7Ws2812xMethod>(countPixels, pins[0]); break;
default: return false;
}
#endif
break;
case TYPE_APA102:
if (isSPI) {
pdhd_rgb0 = new NeoPixelBrightnessBus<DotStarBgrFeature, DotStarSpiMethod>(countPixels);
} else {
pdts_rgb0 = new NeoPixelBrightnessBus<DotStarBgrFeature, DotStarMethod >(countPixels, pins[1], pins[0]);
}
break;
case TYPE_WS2801:
if (isSPI) {
pwhd_rgb0 = new NeoPixelBrightnessBus<NeoGrbFeature, NeoWs2801SpiMethod>(countPixels);
} else {
pws1_rgb0 = new NeoPixelBrightnessBus<NeoGrbFeature, NeoWs2801Method >(countPixels, pins[1], pins[0]);
}
break;
case TYPE_LPD8806:
if (isSPI) {
plhd_rgb0 = new NeoPixelBrightnessBus<Lpd8806GrbFeature, Lpd8806SpiMethod>(countPixels);
} else {
plpd_rgb0 = new NeoPixelBrightnessBus<Lpd8806GrbFeature, Lpd8806Method >(countPixels, pins[1], pins[0]);
}
break;
default: //analog
#ifdef ARDUINO_ARCH_ESP32
ledcSetup(0, 5000, 8);
ledcAttachPin(RPIN, 0);
ledcSetup(1, 5000, 8);
ledcAttachPin(GPIN, 1);
ledcSetup(2, 5000, 8);
ledcAttachPin(BPIN, 2);
if(_type == NeoPixelType_Grbw)
{
ledcSetup(3, 5000, 8);
ledcAttachPin(WPIN, 3);
#ifdef WLED_USE_5CH_LEDS
ledcSetup(4, 5000, 8);
ledcAttachPin(W2PIN, 4);
#endif
}
#else // ESP8266
//init PWM pins
pinMode(RPIN, OUTPUT);
pinMode(GPIN, OUTPUT);
pinMode(BPIN, OUTPUT);
if(_type == NeoPixelType_Grbw)
{
pinMode(WPIN, OUTPUT);
#ifdef WLED_USE_5CH_LEDS
pinMode(W2PIN, OUTPUT);
#endif
}
analogWriteRange(255); //same range as one RGB channel
analogWriteFreq(880); //PWM frequency proven as good for LEDs
#endif
}
if (isNeoPixelBus) pBus->Begin();
return true;
}
void show()
{
if (isNeoPixelBus) {
pBus->Show();
} else {
//analog driving
/*
#ifdef ARDUINO_ARCH_ESP32
ledcWrite(0, r);
ledcWrite(1, g);
ledcWrite(2, b);
switch (_type) {
case NeoPixelType_Grb: break;
#ifdef WLED_USE_5CH_LEDS
case NeoPixelType_Grbw: ledcWrite(3, w); ledcWrite(4, w2); break;
#else
case NeoPixelType_Grbw: ledcWrite(3, w); break;
#endif
}
#else // ESP8266
analogWrite(RPIN, r);
analogWrite(GPIN, g);
analogWrite(BPIN, b);
switch (_type) {
case NeoPixelType_Grb: break;
#ifdef WLED_USE_5CH_LEDS
case NeoPixelType_Grbw: analogWrite(WPIN, w); analogWrite(W2PIN, w2); break;
#else
case NeoPixelType_Grbw: analogWrite(WPIN, w); break;
#endif
}
#endif */
}
}
void SetPixelColor(uint16_t indexPixel, RgbwColor color)
{
if (i < iStart) return;
i -= iStart;
if (isNeoPixelBus) {
if (lightType == TYPE_SK6812_RGBW) {
pBus->SetPixelColor(indexPixel, color);
} else {
pBus->SetPixelColor(indexPixel, RgbColor(color.R,color.G,color.B));
}
} else {
if (i > 0) return; //analog, only single index
colorRgbw = (uint32_t) color;
}
}
void setBrightness(byte b)
{
if (isNeoPixelBus) {
pbus->SetBrightness(b);
} else {
brightness = b;
}
}
RgbwColor getPixelColor(uint16_t i) const
{
if (i < iStart) return 0;
i -= iStart;
if (isNeoPixelBus) return pbus->GetPixelColor(i);
if (i > 0) return 0; //analog, only single index
return colorRgbw;
}
uint16_t getLength() const
{
if (isNeoPixelBus) return pbus->PixelCount();
return 1;
}
uint16_t getMemUsage()
{
uint16_t usage = 4;
if (isNeoPixelBus) usage += pbus->PixelsSize();
return usage;
}
private:
byte lightType;
uint16_t iStart = 0;
// have a member for every possible type
union {
NeoPixelBrightnessBus<NeoGrbFeature, NeoWs2801Method >* pbus; //pseudo bus used for all
#ifdef ESP8266
//ESP8266 WS2812 RGB
NeoPixelBrightnessBus<NeoGrbFeature , NeoEsp8266Uart0Ws2813Method >* psr0_rgb0;
NeoPixelBrightnessBus<NeoGrbFeature , NeoEsp8266Uart1Ws2813Method >* psr1_rgb0;
NeoPixelBrightnessBus<NeoGrbFeature , NeoEsp8266Dma800KbpsMethod >* pdma_rgb0;
NeoPixelBrightnessBus<NeoGrbFeature , NeoEsp8266BitBang800KbpsMethod>* pbbg_rgb0;
//ESP8266 WS2812 RGBW
NeoPixelBrightnessBus<NeoGrbwFeature, NeoEsp8266Uart0Ws2813Method >* psr0_rgbw;
NeoPixelBrightnessBus<NeoGrbwFeature, NeoEsp8266Uart1Ws2813Method >* psr1_rgbw;
NeoPixelBrightnessBus<NeoGrbwFeature, NeoEsp8266Dma800KbpsMethod >* pdma_rgbw;
NeoPixelBrightnessBus<NeoGrbwFeature, NeoEsp8266BitBang800KbpsMethod>* pbbg_rgbw;
#else
//ESP32 WS2812 RGB
NeoPixelBrightnessBus<NeoGrbFeature , NeoEsp32Rmt0Ws2812xMethod>* prm0_rgb0;
NeoPixelBrightnessBus<NeoGrbFeature , NeoEsp32Rmt1Ws2812xMethod>* prm1_rgb0;
NeoPixelBrightnessBus<NeoGrbFeature , NeoEsp32Rmt2Ws2812xMethod>* prm2_rgb0;
NeoPixelBrightnessBus<NeoGrbFeature , NeoEsp32Rmt3Ws2812xMethod>* prm3_rgb0;
NeoPixelBrightnessBus<NeoGrbFeature , NeoEsp32Rmt4Ws2812xMethod>* prm4_rgb0;
NeoPixelBrightnessBus<NeoGrbFeature , NeoEsp32Rmt5Ws2812xMethod>* prm5_rgb0;
NeoPixelBrightnessBus<NeoGrbFeature , NeoEsp32Rmt6Ws2812xMethod>* prm6_rgb0;
NeoPixelBrightnessBus<NeoGrbFeature , NeoEsp32Rmt7Ws2812xMethod>* prm7_rgb0;
//ESP32 WS2812 RGBW
NeoPixelBrightnessBus<NeoGrbwFeature, NeoEsp32Rmt0Ws2812xMethod>* prm0_rgbw;
NeoPixelBrightnessBus<NeoGrbwFeature, NeoEsp32Rmt1Ws2812xMethod>* prm1_rgbw;
NeoPixelBrightnessBus<NeoGrbwFeature, NeoEsp32Rmt2Ws2812xMethod>* prm2_rgbw;
NeoPixelBrightnessBus<NeoGrbwFeature, NeoEsp32Rmt3Ws2812xMethod>* prm3_rgbw;
NeoPixelBrightnessBus<NeoGrbwFeature, NeoEsp32Rmt4Ws2812xMethod>* prm4_rgbw;
NeoPixelBrightnessBus<NeoGrbwFeature, NeoEsp32Rmt5Ws2812xMethod>* prm5_rgbw;
NeoPixelBrightnessBus<NeoGrbwFeature, NeoEsp32Rmt6Ws2812xMethod>* prm6_rgbw;
NeoPixelBrightnessBus<NeoGrbwFeature, NeoEsp32Rmt7Ws2812xMethod>* prm7_rgbw;
#endif
//APA102
NeoPixelBrightnessBus<DotStarBgrFeature, DotStarMethod >* pdts_rgb0;
NeoPixelBrightnessBus<DotStarBgrFeature, DotStarSpiMethod>* pdhd_rgb0;
//WS2801
NeoPixelBrightnessBus<NeoGrbFeature, NeoWs2801Method >* pws1_rgb0;
NeoPixelBrightnessBus<NeoGrbFeature, NeoWs2801SpiMethod>* pwhd_rgb0;
//LPD8806
NeoPixelBrightnessBus<Lpd8806GrbFeature, Lpd8806Method >* plpd_rgb0;
NeoPixelBrightnessBus<Lpd8806GrbFeature, Lpd8806SpiMethod>* plhd_rgb0;
//analog PWM
struct {
uint32_t colorRgbw;
uint8_t colorChannel5;
uint8_t brightness;
}
};
bool isNeoPixelBus()
{
switch (lightType)
{
case TYPE_WS2812_RGB :
case TYPE_SK6812_RGBW :
case TYPE_WS2812_WWA :
case TYPE_APA102 :
case TYPE_WS2801 :
case TYPE_LPD8806 : return true;
}
return false;
}
//SPI: data GPIO13 clock GPIO 14
bool isSPI()
{
//spi-like protocol LEDs
if (lightType == TYPE_APA102 || lightType == TYPE_WS2801 || lightType == TYPE_LPD8806)
{
if (pins[0] == 13 && pins[1] == 14) return true;
}
return false;
}
void cleanup()
{
//ledcDetachPin()
if (isNeoPixelBus) delete pbus;
pbus = nullptr;
isNeoPixelBus = false;
lightType = TYPE_NONE;
}
};
#endif
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment