Started with wrapper to support dynamic LED counts and pixel features

This commit is contained in:
cschwinne 2018-04-13 00:28:29 +02:00
parent ee6676cd89
commit 7f5671f975
7 changed files with 236 additions and 99 deletions

176
wled00/NpbWrapper.h Normal file
View File

@ -0,0 +1,176 @@
//this code is a modified version of https://github.com/Makuna/NeoPixelBus/issues/103
#define WORKAROUND_ESP32_BITBANG
//see https://github.com/Aircoookie/WLED/issues/2 for flicker free ESP32 support
//uncomment this if red and green are swapped
//#define SWAPRG
//automatically uses the right driver method for each platform
#ifdef ARDUINO_ARCH_ESP32
#ifdef WORKAROUND_ESP32_BITBANG
#define PIXELMETHOD NeoEsp32BitBangWs2813Method
#else
#define PIXELMETHOD NeoEsp32RmtWS2813_V3Method
#endif
#else
#define PIXELMETHOD NeoEsp8266Uart800KbpsMethod
#endif
//handle swapping Red and Green automatically
#ifdef SWAPRG
#define PIXELFEATURE3 NeoRgbFeature
#define PIXELFEATURE4 NeoRgbwFeature
#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, uint8_t pin)
{
cleanup();
_type = type;
switch (_type) {
case NeoPixelType_Grb:
_pGrb = new NeoPixelBrightnessBus<PIXELFEATURE3,PIXELMETHOD>(countPixels, pin);
_pGrb->Begin();
break;
case NeoPixelType_Grbw:
_pGrbw = new NeoPixelBrightnessBus<PIXELFEATURE4,PIXELMETHOD>(countPixels, pin);
_pGrbw->Begin();
break;
}
}
void Show()
{
#ifdef ARDUINO_ARCH_ESP32
#ifdef WORKAROUND_ESP32_BITBANG
delay(1);
portDISABLE_INTERRUPTS(); //this is a workaround to prevent flickering (see https://github.com/adafruit/Adafruit_NeoPixel/issues/139)
#endif
#endif
switch (_type) {
case NeoPixelType_Grb: _pGrb->Show(); break;
case NeoPixelType_Grbw: _pGrbw->Show(); break;
}
#ifdef ARDUINO_ARCH_ESP32
#ifdef WORKAROUND_ESP32_BITBANG
portENABLE_INTERRUPTS();
#endif
#endif
}
bool CanShow() const
{
switch (_type) {
case NeoPixelType_Grb: _pGrb->CanShow(); break;
case NeoPixelType_Grbw: _pGrbw->CanShow(); break;
}
}
void SetPixelColor(uint16_t indexPixel, RgbColor color)
{
switch (_type) {
case NeoPixelType_Grb: _pGrb->SetPixelColor(indexPixel, color); break;
case NeoPixelType_Grbw:_pGrbw->SetPixelColor(indexPixel, color); break;
}
}
void SetPixelColor(uint16_t indexPixel, RgbwColor color)
{
switch (_type) {
case NeoPixelType_Grb: _pGrbw->SetPixelColor(indexPixel, color); break;
case NeoPixelType_Grbw: _pGrbw->SetPixelColor(indexPixel, color); break;
}
}
void SetBrightness(byte b)
{
switch (_type) {
case NeoPixelType_Grb: _pGrb->SetBrightness(b); break;
case NeoPixelType_Grbw:_pGrbw->SetBrightness(b); break;
}
}
RgbColor GetPixelColor(uint16_t indexPixel) const
{
switch (_type) {
case NeoPixelType_Grb: return _pGrb->GetPixelColor(indexPixel); break;
case NeoPixelType_Grbw: /*doesn't support it so we don't return it*/ break;
}
return 0;
}
// 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;
}
void ClearTo(RgbColor color)
{
switch (_type) {
case NeoPixelType_Grb: _pGrb->ClearTo(color); break;
case NeoPixelType_Grbw:_pGrbw->ClearTo(color); break;
}
}
void ClearTo(RgbwColor color)
{
switch (_type) {
case NeoPixelType_Grb: break;
case NeoPixelType_Grbw:_pGrbw->ClearTo(color); break;
}
}
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;
}
}
};

View File

@ -37,9 +37,9 @@
#define CALL_MODE(n) (this->*_mode[n])();
void WS2812FX::init() {
void WS2812FX::init(bool supportWhite, uint16_t countPixels, uint8_t pin) {
for (int i=0; i < _led_count; i++) _locked[i] = false;
begin();
begin(supportWhite,countPixels,pin);
WS2812FX::setBrightness(_brightness);
show();
}
@ -386,7 +386,7 @@ void WS2812FX::mode_breath(void) {
setPixelColor(i, _color); // set all LEDs to selected color
}
int b = map(breath_brightness, 0, 255, 0, _brightness); // keep brightness below brightness set by user
NeoPixelBrightnessBus::SetBrightness(b); // set new brightness to leds
bus->SetBrightness(b); // set new brightness to leds
show();
_mode_color = breath_brightness; // we use _mode_color to store the brightness
@ -1896,11 +1896,6 @@ void WS2812FX::unlockAll()
_locked[x] = false;
}
void WS2812FX::setLedCount(uint16_t i)
{
_led_count = i;
}
void WS2812FX::setFastUpdateMode(bool y)
{
_fastStandard = y;
@ -1935,11 +1930,7 @@ double WS2812FX::getPowerEstimate(byte leds, uint32_t c, byte b)
double _mARequired = 100; //ESP power
double _mul = (double)b/255;
double _sum = ((c & 0xFF000000) >> 24) + ((c & 0x00FF0000) >> 16) + ((c & 0x0000FF00) >> 8) + ((c & 0x000000FF) >> 0);
#ifdef RGBW
_sum /= 1024;
#else
_sum /= 768;
#endif
_sum /= (_rgbwMode)? 1024:768;
double _mAPerLed = 50*(_mul*_sum);
_mARequired += leds*_mAPerLed;
return _mARequired;
@ -2027,11 +2018,13 @@ void WS2812FX::setCustomChase(byte i1, byte i2, byte is, byte np, byte ns, byte
//Added for quick NeoPixelBus compatibility with Adafruit syntax
void WS2812FX::setPixelColorRaw(uint16_t i, byte r, byte g, byte b, byte w)
{
#ifdef RGBW
NeoPixelBrightnessBus::SetPixelColor(i, RgbwColor(r,g,b,w));
#else
NeoPixelBrightnessBus::SetPixelColor(i, RgbColor(r,g,b));
#endif
if (_rgbwMode)
{
bus->SetPixelColor(i, RgbwColor(r,g,b,w));
} else
{
bus->SetPixelColor(i, RgbColor(r,g,b));
}
}
void WS2812FX::setPixelColor(uint16_t i, byte r, byte g, byte b, byte w)
@ -2039,11 +2032,13 @@ void WS2812FX::setPixelColor(uint16_t i, byte r, byte g, byte b, byte w)
if (_reverseMode) i = _led_count - 1 -i;
if (!_cronixieMode)
{
#ifdef RGBW
NeoPixelBrightnessBus::SetPixelColor(i, RgbwColor(r,g,b,w));
#else
NeoPixelBrightnessBus::SetPixelColor(i, RgbColor(r,g,b));
#endif
if (_rgbwMode)
{
bus->SetPixelColor(i, RgbwColor(r,g,b,w));
} else
{
bus->SetPixelColor(i, RgbColor(r,g,b));
}
} else {
if(i>6)return;
byte o = 10*i;
@ -2112,51 +2107,44 @@ uint32_t WS2812FX::getPixelColor(uint16_t i)
default: return 0;
}
}
#ifdef RGBW
RgbwColor lColor = NeoPixelBrightnessBus::GetPixelColor(i);
if (_rgbwMode)
{
RgbwColor lColor = bus->GetPixelColorRgbw(i);
return lColor.W*16777216 + lColor.R*65536 + lColor.G*256 + lColor.B;
#else
RgbColor lColor = NeoPixelBrightnessBus::GetPixelColor(i);
} else {
RgbColor lColor = bus->GetPixelColor(i);
return lColor.R*65536 + lColor.G*256 + lColor.B;
#endif
}
}
void WS2812FX::setBrightness(byte b)
{
_brightness = constrain(b, BRIGHTNESS_MIN, BRIGHTNESS_MAX);
NeoPixelBrightnessBus::SetBrightness(_brightness);
bus->SetBrightness(_brightness);
if (_mode_last_call_time + _mode_delay > millis()+50 || b == 0) show(); //only update right away if long time until next refresh
}
void WS2812FX::show()
{
#ifdef ARDUINO_ARCH_ESP32
#ifdef WORKAROUND_ESP32_BITBANG
delay(1);
portDISABLE_INTERRUPTS(); //this is a workaround to prevent flickering (see https://github.com/adafruit/Adafruit_NeoPixel/issues/139)
#endif
#endif
NeoPixelBrightnessBus::Show();
#ifdef ARDUINO_ARCH_ESP32
#ifdef WORKAROUND_ESP32_BITBANG
portENABLE_INTERRUPTS();
#endif
#endif
bus->Show();
}
void WS2812FX::clear()
{
#ifdef RGBW
NeoPixelBrightnessBus::ClearTo(RgbwColor(0));
#else
NeoPixelBrightnessBus::ClearTo(RgbColor(0));
#endif
bus->ClearTo(RgbColor(0));
}
void WS2812FX::begin()
void WS2812FX::begin(bool supportWhite, uint16_t countPixels, uint8_t pin)
{
NeoPixelBrightnessBus::Begin();
if (supportWhite == _rgbwMode && countPixels == _led_count && _locked != NULL) return;
_rgbwMode = supportWhite;
_led_count = countPixels;
_cc_i2 = _led_count -1;
uint8_t ty = 1;
if (supportWhite) ty =2;
bus->Begin((NeoPixelType)ty, countPixels, pin);
if (_locked != NULL) delete _locked;
_locked = new bool[countPixels];
}
//For some reason min and max are not declared here

View File

@ -1,25 +1,4 @@
//#define RGBW
#define PIN 2 //strip pin. Only change for ESP32
#define WORKAROUND_ESP32_BITBANG
//see https://github.com/Aircoookie/WLED/issues/2 for flicker free ESP32 support
//automatically uses the right driver method for each platform
#ifdef ARDUINO_ARCH_ESP32
#ifdef WORKAROUND_ESP32_BITBANG
#define PIXELMETHOD NeoEsp32BitBangWs2813Method
#else
#define PIXELMETHOD NeoEsp32RmtWS2813_V3Method
#endif
#else
#define PIXELMETHOD NeoEsp8266Uart800KbpsMethod
#endif
//selects correct feature for RGB/RGBW
#ifdef RGBW
#define PIXELFEATURE NeoGrbwFeature
#else
#define PIXELFEATURE NeoGrbFeature
#endif
//pixelmethod now in NpbWrapper.h
/*
WS2812FX.h - Library for WS2812 LED effects.
@ -50,14 +29,14 @@
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
Modified to work with WLED - differs from Github WS2812FX
Heavily modified to work with WLED - differs from Github WS2812FX
*/
#ifndef WS2812FX_h
#define WS2812FX_h
#include "Arduino.h"
#include <NeoPixelBrightnessBus.h>
#include "NpbWrapper.h"
#define DEFAULT_BRIGHTNESS 50
#define DEFAULT_MODE 0
@ -132,10 +111,10 @@
#define FX_MODE_CC_RANDOM 57
class WS2812FX : public NeoPixelBrightnessBus<PIXELFEATURE, PIXELMETHOD> {
class WS2812FX {
typedef void (WS2812FX::*mode_ptr)(void);
public:
WS2812FX(uint16_t n) : NeoPixelBrightnessBus<PIXELFEATURE, PIXELMETHOD>(n,PIN) {
WS2812FX(){
_mode[FX_MODE_STATIC] = &WS2812FX::mode_static;
_mode[FX_MODE_BLINK] = &WS2812FX::mode_blink;
@ -200,7 +179,7 @@ class WS2812FX : public NeoPixelBrightnessBus<PIXELFEATURE, PIXELMETHOD> {
_speed = DEFAULT_SPEED;
_brightness = DEFAULT_BRIGHTNESS;
_running = false;
_led_count = n;
_led_count = 255;
_mode_last_call_time = 0;
_mode_delay = 0;
_color = DEFAULT_COLOR;
@ -211,7 +190,7 @@ class WS2812FX : public NeoPixelBrightnessBus<PIXELFEATURE, PIXELMETHOD> {
_cc_fe = false;
_cc_is = 0;
_cc_i1 = 0;
_cc_i2 = n-1;
_cc_i2 = 254;
_cc_num1 = 5;
_cc_num2 = 5;
_ccStep = 1;
@ -220,15 +199,16 @@ class WS2812FX : public NeoPixelBrightnessBus<PIXELFEATURE, PIXELMETHOD> {
_counter_ccStep = 0;
_fastStandard = false;
_reverseMode = false;
_locked = new bool[n];
_locked = NULL;
_cronixieDigits = new byte[6];
bus = new NeoPixelWrapper();
}
void
show(void),
setPixelColor(uint16_t i, byte r, byte g, byte b),
setPixelColor(uint16_t i, byte r, byte g, byte b, byte w),
init(void),
init(bool supportWhite, uint16_t countPixels, uint8_t pin),
service(void),
start(void),
stop(void),
@ -271,7 +251,6 @@ class WS2812FX : public NeoPixelBrightnessBus<PIXELFEATURE, PIXELMETHOD> {
unlockAll(void),
setFastUpdateMode(bool b),
trigger(void),
setLedCount(uint16_t i),
setFade(int sp);
bool
@ -295,9 +274,10 @@ class WS2812FX : public NeoPixelBrightnessBus<PIXELFEATURE, PIXELMETHOD> {
getSafePowerMultiplier(double safeMilliAmps, byte leds, uint32_t c, byte b);
private:
NeoPixelWrapper *bus;
void
begin(void),
begin(bool supportWhite, uint16_t countPixels, uint8_t pin),
clear(void),
setPixelColor(uint16_t i, uint32_t c),
setPixelColorRaw(uint16_t i, byte r, byte g, byte b, byte w),
@ -367,6 +347,7 @@ class WS2812FX : public NeoPixelBrightnessBus<PIXELFEATURE, PIXELMETHOD> {
bool
_triggered,
_rgbwMode,
_fastStandard,
_reverseMode,
_cronixieMode,

View File

@ -33,7 +33,7 @@
#include "WS2812FX.h"
//version in format yymmddb (b = daily build)
#define VERSION 1804111
#define VERSION 1804121
const String versionString = "0.6.3";
//AP and OTA default passwords (change them!)
@ -50,7 +50,7 @@ bool useRGBW = false;
//#define DEBUG
//Hardware-settings (only changeble via code)
#define LEDCOUNT 255 //maximum, exact count set-able via settings
#define PIN 2 //strip pin. Only change for ESP32
byte buttonPin = 0; //needs pull-up
byte auxPin = 15; //use e.g. for external relay
byte auxDefaultState = 0; //0: input 1: high 2: low
@ -252,7 +252,7 @@ byte ntpPacketBuffer[NTP_PACKET_SIZE];
unsigned long ntpLastSyncTime = 999000000L;
unsigned long ntpPacketSentTime = 999000000L;
WS2812FX strip = WS2812FX(LEDCOUNT);
WS2812FX strip = WS2812FX();
#ifdef DEBUG
#define DEBUG_PRINT(x) Serial.print (x)

View File

@ -259,7 +259,7 @@ void loadSettingsFromEEPROM(bool first)
if (apChannel > 13 || apChannel < 1) apChannel = 1;
apHide = EEPROM.read(228);
if (apHide > 1) apHide = 1;
ledCount = EEPROM.read(229); if (ledCount > LEDCOUNT) ledCount = LEDCOUNT;
ledCount = EEPROM.read(229);
notifyButton = EEPROM.read(230);
notifyTwice = EEPROM.read(231);
buttonEnabled = EEPROM.read(232);

View File

@ -115,8 +115,7 @@ void handleSettingsSet(byte subPage)
if (server.hasArg("LC"))
{
int i = server.arg("LC").toInt();
if (i >= 0 && i <= LEDCOUNT) ledCount = i;
strip.setLedCount(ledCount);
if (i >= 0 && i <= 1200) ledCount = i;
}
if (server.hasArg("IS")) //ignore settings and save current brightness, colors and fx as default
{
@ -383,7 +382,7 @@ void handleSettingsSet(byte subPage)
aOtaEnabled = server.hasArg("AO");
}
}
strip.init(useRGBW,ledCount,PIN);
saveSettingsToEEPROM();
}

View File

@ -5,7 +5,7 @@
void wledInit()
{
EEPROM.begin(EEPSIZE);
if (!EEPROM.read(397)) strip.init(); //quick init
if (!EEPROM.read(397)) strip.init(EEPROM.read(372),EEPROM.read(229),PIN); //quick init
Serial.begin(115200);
Serial.setTimeout(50);
@ -256,8 +256,7 @@ void wledInit()
void initStrip()
{
// Initialize NeoPixel Strip and button
if (initLedsLast) strip.init();
strip.setLedCount(ledCount);
if (initLedsLast) strip.init(useRGBW,ledCount,PIN);
strip.setReverseMode(reverseMode);
strip.setColor(0);
strip.setBrightness(255);
@ -494,12 +493,6 @@ String getBuildInfo()
info += "version: " + versionString + "\r\n";
info += "build: " + (String)VERSION + "\r\n";
info += "eepver: " + String(EEPVER) + "\r\n";
#ifdef RGBW
info += "rgbw: true\r\n";
#else
info += "rgbw: false\r\n";
#endif
info += "max-leds: " + (String)LEDCOUNT + "\r\n";
#ifdef USEFS
info += "spiffs: true\r\n";
#else