Skip to content

Instantly share code, notes, and snippets.

@Aircoookie
Created January 8, 2020 14:19
Show Gist options
  • Select an option

  • Save Aircoookie/2ff394bf69b086d799af87e28ac4b46c to your computer and use it in GitHub Desktop.

Select an option

Save Aircoookie/2ff394bf69b086d799af87e28ac4b46c to your computer and use it in GitHub Desktop.

Revisions

  1. Aircoookie created this gist Jan 8, 2020.
    301 changes: 301 additions & 0 deletions NpbWrapper.h
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,301 @@
    //this code is a modified version of https://github.com/Makuna/NeoPixelBus/issues/103
    #ifndef NpbWrapper_h
    #define NpbWrapper_h

    //PIN CONFIGURATION
    #define LEDPIN 2 //strip pin. Any for ESP32, gpio2 or 3 is recommended for ESP8266 (gpio2/3 are labeled D4/RX on NodeMCU and Wemos)
    //#define USE_APA102 // Uncomment for using APA102 LEDs.
    #define USE_WS2801 // Uncomment for using WS2801 LEDs.
    //#define USE_LPD8806// Uncomment for using LPD8806
    //#define WLED_USE_ANALOG_LEDS //Uncomment for using "dumb" PWM controlled LEDs (see pins below, default R: gpio5, G: 12, B: 15, W: 13)
    //#define WLED_USE_H801 //H801 controller. Please uncomment #define WLED_USE_ANALOG_LEDS as well
    //#define WLED_USE_5CH //5 Channel H801 for cold and warm white

    #define BTNPIN 0 //button pin. Needs to have pullup (gpio0 recommended)
    #define IR_PIN 4 //infrared pin (-1 to disable) MagicHome: 4, H801 Wifi: 0
    #define RLYPIN 12 //pin for relay, will be set HIGH if LEDs are on (-1 to disable). Also usable for standby leds, triggers,...
    #define AUXPIN -1 //debug auxiliary output pin (-1 to disable)

    #define RLYMDE 1 //mode for relay, 0: LOW if LEDs are on 1: HIGH if LEDs are on

    //END CONFIGURATION

    #if defined(USE_APA102) || defined(USE_WS2801) || defined(USE_LPD8806)
    #define CLKPIN 0
    #define DATAPIN 2
    #if BTNPIN == CLKPIN || BTNPIN == DATAPIN
    #undef BTNPIN // Deactivate button pin if it conflicts with one of the APA102 pins.
    #endif
    #endif

    #ifdef WLED_USE_ANALOG_LEDS
    //PWM pins - PINs 15,13,12,14 (W2 = 04)are used with H801 Wifi LED Controller
    #ifdef WLED_USE_H801
    #define RPIN 15 //R pin for analog LED strip
    #define GPIN 13 //G pin for analog LED strip
    #define BPIN 12 //B pin for analog LED strip
    #define WPIN 14 //W pin for analog LED strip (W1: 14, W2: 04)
    #define W2PIN 04 //W2 pin for analog LED strip
    #undef BTNPIN
    #undef IR_PIN
    #define IR_PIN 0 //infrared pin (-1 to disable) MagicHome: 4, H801 Wifi: 0
    #else
    //PWM pins - PINs 5,12,13,15 are used with Magic Home LED Controller
    #define RPIN 5 //R pin for analog LED strip
    #define GPIN 12 //G pin for analog LED strip
    #define BPIN 15 //B pin for analog LED strip
    #define WPIN 13 //W pin for analog LED strip (W1: 14, W2: 04)
    #endif
    #undef RLYPIN
    #define RLYPIN -1 //disable as pin 12 is used by analog LEDs
    #endif

    //automatically uses the right driver method for each platform
    #ifdef ARDUINO_ARCH_ESP32
    #ifdef USE_APA102
    #define PIXELMETHOD DotStarMethod
    #elif defined(USE_WS2801)
    #define PIXELMETHOD NeoWs2801Method
    #elif defined(USE_LPD8806)
    #define PIXELMETHOD Lpd8806Method
    #else
    #define PIXELMETHOD NeoEsp32Rmt0Ws2812xMethod
    #endif
    #else //esp8266
    //autoselect the right method depending on strip pin
    #ifdef USE_APA102
    #define PIXELMETHOD DotStarMethod
    #elif defined(USE_WS2801)
    #define PIXELMETHOD NeoWs2801Method
    #elif defined(USE_LPD8806)
    #define PIXELMETHOD Lpd8806Method
    #elif LEDPIN == 2
    #define PIXELMETHOD NeoEsp8266Uart1Ws2813Method //if you get an error here, try to change to NeoEsp8266UartWs2813Method or update Neopixelbus
    #elif LEDPIN == 3
    #define PIXELMETHOD NeoEsp8266Dma800KbpsMethod
    #else
    #define PIXELMETHOD NeoEsp8266BitBang800KbpsMethod
    #pragma message "Software BitBang will be used because of your selected LED pin. This may cause flicker. Use GPIO 2 or 3 for best results."
    #endif
    #endif


    //you can now change the color order in the web settings
    #ifdef USE_APA102
    #define PIXELFEATURE3 DotStarBgrFeature
    #define PIXELFEATURE4 DotStarLbgrFeature
    #elif defined(USE_LPD8806)
    #define PIXELFEATURE3 Lpd8806GrbFeature
    #else
    #define PIXELFEATURE3 NeoGrbFeature
    #define PIXELFEATURE4 NeoGrbwFeature
    #endif


    #include <NeoPixelBrightnessBus.h>

    enum NeoPixelType
    {
    NeoPixelType_None = 0,
    NeoPixelType_Grb = 1,
    NeoPixelType_Grbw = 2,
    NeoPixelType_End = 3
    };

    class NeoPixelWrapper
    {
    public:
    NeoPixelWrapper() :
    // initialize each member to null
    _pGrb(NULL),
    _pGrbw(NULL),
    _type(NeoPixelType_None)
    {

    }

    ~NeoPixelWrapper()
    {
    cleanup();
    }

    void Begin(NeoPixelType type, uint16_t countPixels)
    {
    cleanup();
    _type = type;

    switch (_type)
    {
    case NeoPixelType_Grb:
    #if defined(USE_APA102) || defined(USE_WS2801) || defined(USE_LPD8806)
    _pGrb = new NeoPixelBrightnessBus<PIXELFEATURE3,PIXELMETHOD>(countPixels, CLKPIN, DATAPIN);
    #else
    _pGrb = new NeoPixelBrightnessBus<PIXELFEATURE3,PIXELMETHOD>(countPixels, LEDPIN);
    #endif
    _pGrb->Begin();
    break;

    case NeoPixelType_Grbw:
    #if defined(USE_APA102) || defined(USE_WS2801) || defined(USE_LPD8806)
    _pGrbw = new NeoPixelBrightnessBus<PIXELFEATURE4,PIXELMETHOD>(countPixels, CLKPIN, DATAPIN);
    #else
    _pGrbw = new NeoPixelBrightnessBus<PIXELFEATURE4,PIXELMETHOD>(countPixels, LEDPIN);
    #endif
    _pGrbw->Begin();
    break;
    }

    #ifdef WLED_USE_ANALOG_LEDS
    #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 - PINs 5,12,13,15 are used with Magic Home LED Controller
    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
    #endif
    }

    #ifdef WLED_USE_ANALOG_LEDS
    void SetRgbwPwm(uint8_t r, uint8_t g, uint8_t b, uint8_t w, uint8_t w2=0)
    {
    #ifdef ARDUINO_ARCH_ESP32
    ledcWrite(0, r); //RPIN
    ledcWrite(1, g); //GPIN
    ledcWrite(2, b); //BPIN
    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
    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
    }
    #endif

    void Show()
    {
    byte b;
    switch (_type)
    {
    case NeoPixelType_Grb: _pGrb->Show(); break;
    case NeoPixelType_Grbw: _pGrbw->Show(); break;
    }
    }

    void SetPixelColor(uint16_t indexPixel, RgbwColor color)
    {
    switch (_type) {
    case NeoPixelType_Grb: {
    _pGrb->SetPixelColor(indexPixel, RgbColor(color.R,color.G,color.B));
    #ifdef WLED_USE_ANALOG_LEDS
    if (indexPixel != 0) return; //set analog LEDs from first pixel
    byte b = _pGrb->GetBrightness();
    SetRgbwPwm(color.R * b / 255, color.G * b / 255, color.B * b / 255, 0);
    #endif
    }
    break;
    case NeoPixelType_Grbw: {
    _pGrbw->SetPixelColor(indexPixel, color);
    #ifdef WLED_USE_ANALOG_LEDS
    if (indexPixel != 0) return; //set analog LEDs from first pixel
    byte b = _pGrbw->GetBrightness();
    // check color values for Warm / Cold white mix (for RGBW) // EsplanexaDevice.cpp
    #ifdef WLED_USE_5CH_LEDS
    if (color.R == 255 & color.G == 255 && color.B == 255 && color.W == 255) {
    SetRgbwPwm(0, 0, 0, 0, color.W * b / 255);
    } else if (color.R == 127 & color.G == 127 && color.B == 127 && color.W == 255) {
    SetRgbwPwm(0, 0, 0, color.W * b / 512, colorW.W * b / 255);
    } else if (color.R == 0 & color.G == 0 && color.B == 0 && color.W == 255) {
    SetRgbwPwm(0, 0, 0, color.W * b / 255, 0);
    } else if (color.R == 130 & color.G == 90 && color.B == 0 && color.W == 255) {
    SetRgbwPwm(0, 0, 0, color.W * b / 255, color.W * b / 512);
    } else if (color.R == 255 & color.G == 153 && color.B == 0 && color.W == 255) {
    SetRgbwPwm(0, 0, 0, color.W * b / 255, 0);
    } else { // not only white colors
    SetRgbwPwm(color.R * b / 255, colorW.G * b / 255, colorW.B * b / 255, color.W * b / 255);
    }
    #else
    SetRgbwPwm(color.R * b / 255, color.G * b / 255, color.B * b / 255, color.W * b / 255);
    #endif
    #endif
    }
    break;
    }

    }

    void SetBrightness(byte b)
    {
    switch (_type) {
    case NeoPixelType_Grb: _pGrb->SetBrightness(b); break;
    case NeoPixelType_Grbw:_pGrbw->SetBrightness(b); break;
    }
    }

    // NOTE: Due to feature differences, some support RGBW but the method name
    // here needs to be unique, thus GetPixeColorRgbw
    RgbwColor GetPixelColorRgbw(uint16_t indexPixel) const
    {
    switch (_type) {
    case NeoPixelType_Grb: return _pGrb->GetPixelColor(indexPixel); break;
    case NeoPixelType_Grbw: return _pGrbw->GetPixelColor(indexPixel); break;
    }
    return 0;
    }


    private:
    NeoPixelType _type;

    // have a member for every possible type
    NeoPixelBrightnessBus<PIXELFEATURE3,PIXELMETHOD>* _pGrb;
    NeoPixelBrightnessBus<PIXELFEATURE4,PIXELMETHOD>* _pGrbw;

    void cleanup()
    {
    switch (_type) {
    case NeoPixelType_Grb: delete _pGrb ; _pGrb = NULL; break;
    case NeoPixelType_Grbw: delete _pGrbw; _pGrbw = NULL; break;
    }
    }
    };
    #endif