Independent Neopixel option (#19115)

This commit is contained in:
Zachary Annand 2020-08-27 14:18:16 -05:00 committed by GitHub
parent 21070c0aaf
commit 97ec6c1be6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 269 additions and 36 deletions

View file

@ -2362,12 +2362,21 @@
#define NEOPIXEL_PIN 4 // LED driving pin #define NEOPIXEL_PIN 4 // LED driving pin
//#define NEOPIXEL2_TYPE NEOPIXEL_TYPE //#define NEOPIXEL2_TYPE NEOPIXEL_TYPE
//#define NEOPIXEL2_PIN 5 //#define NEOPIXEL2_PIN 5
//#define NEOPIXEL2_INSERIES // Default behavior is NeoPixel 2 in parallel #define NEOPIXEL_PIXELS 30 // Number of LEDs in the strip. (Longest strip when NEOPIXEL2_SEPARATE is disabled.)
#define NEOPIXEL_PIXELS 30 // Number of LEDs in the strip, larger of 2 strips if 2 NeoPixel strips are used
#define NEOPIXEL_IS_SEQUENTIAL // Sequential display for temperature change - LED by LED. Disable to change all LEDs at once. #define NEOPIXEL_IS_SEQUENTIAL // Sequential display for temperature change - LED by LED. Disable to change all LEDs at once.
#define NEOPIXEL_BRIGHTNESS 127 // Initial brightness (0-255) #define NEOPIXEL_BRIGHTNESS 127 // Initial brightness (0-255)
//#define NEOPIXEL_STARTUP_TEST // Cycle through colors at startup //#define NEOPIXEL_STARTUP_TEST // Cycle through colors at startup
// Support for second Adafruit NeoPixel LED driver controlled with M150 S1 ...
//#define NEOPIXEL2_SEPARATE
#if ENABLED(NEOPIXEL2_SEPARATE)
#define NEOPIXEL2_PIXELS 15 // Number of LEDs in the second strip
#define NEOPIXEL2_BRIGHTNESS 127 // Initial brightness (0-255)
#define NEOPIXEL2_STARTUP_TEST // Cycle through colors at startup
#else
//#define NEOPIXEL2_INSERIES // Default behavior is NeoPixel 2 in parallel
#endif
// Use a single NeoPixel LED for static (background) lighting // Use a single NeoPixel LED for static (background) lighting
//#define NEOPIXEL_BKGD_LED_INDEX 0 // Index of the LED to use //#define NEOPIXEL_BKGD_LED_INDEX 0 // Index of the LED to use
//#define NEOPIXEL_BKGD_COLOR { 255, 255, 255, 0 } // R, G, B, W //#define NEOPIXEL_BKGD_COLOR { 255, 255, 255, 0 } // R, G, B, W

View file

@ -1065,6 +1065,7 @@
//#define LED_CONTROL_MENU //#define LED_CONTROL_MENU
#if ENABLED(LED_CONTROL_MENU) #if ENABLED(LED_CONTROL_MENU)
#define LED_COLOR_PRESETS // Enable the Preset Color menu option #define LED_COLOR_PRESETS // Enable the Preset Color menu option
//#define NEO2_COLOR_PRESETS // Enable a second NeoPixel Preset Color menu option
#if ENABLED(LED_COLOR_PRESETS) #if ENABLED(LED_COLOR_PRESETS)
#define LED_USER_PRESET_RED 255 // User defined RED value #define LED_USER_PRESET_RED 255 // User defined RED value
#define LED_USER_PRESET_GREEN 128 // User defined GREEN value #define LED_USER_PRESET_GREEN 128 // User defined GREEN value
@ -1073,6 +1074,14 @@
#define LED_USER_PRESET_BRIGHTNESS 255 // User defined intensity #define LED_USER_PRESET_BRIGHTNESS 255 // User defined intensity
//#define LED_USER_PRESET_STARTUP // Have the printer display the user preset color on startup //#define LED_USER_PRESET_STARTUP // Have the printer display the user preset color on startup
#endif #endif
#if ENABLED(NEO2_COLOR_PRESETS)
#define NEO2_USER_PRESET_RED 255 // User defined RED value
#define NEO2_USER_PRESET_GREEN 128 // User defined GREEN value
#define NEO2_USER_PRESET_BLUE 0 // User defined BLUE value
#define NEO2_USER_PRESET_WHITE 255 // User defined WHITE value
#define NEO2_USER_PRESET_BRIGHTNESS 255 // User defined intensity
//#define NEO2_USER_PRESET_STARTUP // Have the printer display the user preset color on startup for the second strip
#endif
#endif #endif
#endif // HAS_LCD_MENU #endif // HAS_LCD_MENU

View file

@ -995,6 +995,10 @@ void setup() {
SETUP_RUN(leds.setup()); SETUP_RUN(leds.setup());
#endif #endif
#if ENABLED(NEOPIXEL2_SEPARATE)
SETUP_RUN(leds2.setup());
#endif
#if ENABLED(USE_CONTROLLER_FAN) // Set up fan controller to initialize also the default configurations. #if ENABLED(USE_CONTROLLER_FAN) // Set up fan controller to initialize also the default configurations.
SETUP_RUN(controllerFan.setup()); SETUP_RUN(controllerFan.setup());
#endif #endif

View file

@ -44,11 +44,8 @@
#if ENABLED(LED_COLOR_PRESETS) #if ENABLED(LED_COLOR_PRESETS)
const LEDColor LEDLights::defaultLEDColor = MakeLEDColor( const LEDColor LEDLights::defaultLEDColor = MakeLEDColor(
LED_USER_PRESET_RED, LED_USER_PRESET_RED, LED_USER_PRESET_GREEN, LED_USER_PRESET_BLUE,
LED_USER_PRESET_GREEN, LED_USER_PRESET_WHITE, LED_USER_PRESET_BRIGHTNESS
LED_USER_PRESET_BLUE,
LED_USER_PRESET_WHITE,
LED_USER_PRESET_BRIGHTNESS
); );
#endif #endif
@ -117,12 +114,13 @@ void LEDLights::set_color(const LEDColor &incol
// This variant uses 3-4 separate pins for the RGB(W) components. // This variant uses 3-4 separate pins for the RGB(W) components.
// If the pins can do PWM then their intensity will be set. // If the pins can do PWM then their intensity will be set.
#define UPDATE_RGBW(C,c) do { if (PWM_PIN(RGB_LED_##C##_PIN)) \ #define UPDATE_RGBW(C,c) do { \
if (PWM_PIN(RGB_LED_##C##_PIN)) \
analogWrite(pin_t(RGB_LED_##C##_PIN), incol.c); \ analogWrite(pin_t(RGB_LED_##C##_PIN), incol.c); \
else WRITE(RGB_LED_##C##_PIN, incol.c ? HIGH : LOW); }while(0) else \
UPDATE_RGBW(R,r); WRITE(RGB_LED_##C##_PIN, incol.c ? HIGH : LOW); \
UPDATE_RGBW(G,g); }while(0)
UPDATE_RGBW(B,b); UPDATE_RGBW(R,r); UPDATE_RGBW(G,g); UPDATE_RGBW(B,b);
#if ENABLED(RGBW_LED) #if ENABLED(RGBW_LED)
UPDATE_RGBW(W,w); UPDATE_RGBW(W,w);
#endif #endif
@ -158,4 +156,35 @@ void LEDLights::set_color(const LEDColor &incol
#endif #endif
#endif // HAS_COLOR_LEDS #if ENABLED(NEOPIXEL2_SEPARATE)
#if ENABLED(NEO2_COLOR_PRESETS)
const LEDColor LEDLights2::defaultLEDColor = MakeLEDColor(
NEO2_USER_PRESET_RED, NEO2_USER_PRESET_GREEN, NEO2_USER_PRESET_BLUE,
NEO2_USER_PRESET_WHITE, NEO2_USER_PRESET_BRIGHTNESS
);
#endif
#if ENABLED(LED_CONTROL_MENU)
LEDColor LEDLights2::color;
bool LEDLights2::lights_on;
#endif
LEDLights2 leds2;
void LEDLights2::setup() {
neo2.init();
TERN_(NEO2_USER_PRESET_STARTUP, set_default());
}
void LEDLights2::set_color(const LEDColor &incol) {
const uint32_t neocolor = LEDColorWhite() == incol
? neo2.Color(NEO2_WHITE)
: neo2.Color(incol.r, incol.g, incol.b, incol.w);
neo2.set_brightness(incol.i);
neo2.set_color(neocolor);
}
#endif // NEOPIXEL2_SEPARATE
#endif // HAS_COLOR_LEDS

View file

@ -155,11 +155,9 @@ public:
static inline void set_color(uint8_t r, uint8_t g, uint8_t b static inline void set_color(uint8_t r, uint8_t g, uint8_t b
#if HAS_WHITE_LED #if HAS_WHITE_LED
, uint8_t w=0 , uint8_t w=0
#if ENABLED(NEOPIXEL_LED)
, uint8_t i=NEOPIXEL_BRIGHTNESS
#endif
#endif #endif
#if ENABLED(NEOPIXEL_LED) #if ENABLED(NEOPIXEL_LED)
, uint8_t i=NEOPIXEL_BRIGHTNESS
, bool isSequence=false , bool isSequence=false
#endif #endif
) { ) {
@ -212,3 +210,44 @@ public:
}; };
extern LEDLights leds; extern LEDLights leds;
#if ENABLED(NEOPIXEL2_SEPARATE)
class LEDLights2 {
public:
LEDLights2() {}
static void setup(); // init()
static void set_color(const LEDColor &color);
inline void set_color(uint8_t r, uint8_t g, uint8_t b, uint8_t w=0, uint8_t i=NEOPIXEL2_BRIGHTNESS) {
set_color(MakeLEDColor(r, g, b, w, i));
}
static inline void set_off() { set_color(LEDColorOff()); }
static inline void set_green() { set_color(LEDColorGreen()); }
static inline void set_white() { set_color(LEDColorWhite()); }
#if ENABLED(NEO2_COLOR_PRESETS)
static const LEDColor defaultLEDColor;
static inline void set_default() { set_color(defaultLEDColor); }
static inline void set_red() { set_color(LEDColorRed()); }
static inline void set_orange() { set_color(LEDColorOrange()); }
static inline void set_yellow() { set_color(LEDColorYellow()); }
static inline void set_blue() { set_color(LEDColorBlue()); }
static inline void set_indigo() { set_color(LEDColorIndigo()); }
static inline void set_violet() { set_color(LEDColorViolet()); }
#endif
#if ENABLED(LED_CONTROL_MENU)
static LEDColor color; // last non-off color
static bool lights_on; // the last set color was "on"
static void toggle(); // swap "off" with color
static inline void update() { set_color(color); }
#endif
};
extern LEDLights2 leds2;
#endif // NEOPIXEL2_SEPARATE

View file

@ -30,7 +30,7 @@
#include "neopixel.h" #include "neopixel.h"
#if ENABLED(NEOPIXEL_STARTUP_TEST) #if EITHER(NEOPIXEL_STARTUP_TEST, NEOPIXEL2_STARTUP_TEST)
#include "../../core/utility.h" #include "../../core/utility.h"
#endif #endif
@ -38,7 +38,7 @@ Marlin_NeoPixel neo;
int8_t Marlin_NeoPixel::neoindex; int8_t Marlin_NeoPixel::neoindex;
Adafruit_NeoPixel Marlin_NeoPixel::adaneo1(NEOPIXEL_PIXELS, NEOPIXEL_PIN, NEOPIXEL_TYPE + NEO_KHZ800) Adafruit_NeoPixel Marlin_NeoPixel::adaneo1(NEOPIXEL_PIXELS, NEOPIXEL_PIN, NEOPIXEL_TYPE + NEO_KHZ800)
#if EITHER(MULTIPLE_NEOPIXEL_TYPES, NEOPIXEL2_INSERIES) #if CONJOINED_NEOPIXEL
, Marlin_NeoPixel::adaneo2(NEOPIXEL_PIXELS, NEOPIXEL2_PIN, NEOPIXEL2_TYPE + NEO_KHZ800) , Marlin_NeoPixel::adaneo2(NEOPIXEL_PIXELS, NEOPIXEL2_PIN, NEOPIXEL2_TYPE + NEO_KHZ800)
#endif #endif
; ;
@ -120,4 +120,53 @@ bool Marlin_NeoPixel::set_led_color(const uint8_t r, const uint8_t g, const uint
} }
#endif #endif
#if ENABLED(NEOPIXEL2_SEPARATE)
Marlin_NeoPixel2 neo2;
int8_t Marlin_NeoPixel2::neoindex;
Adafruit_NeoPixel Marlin_NeoPixel2::adaneo(NEOPIXEL2_PIXELS, NEOPIXEL2_PIN, NEOPIXEL2_TYPE);
void Marlin_NeoPixel2::set_color(const uint32_t color) {
if (neoindex >= 0) {
set_pixel_color(neoindex, color);
neoindex = -1;
}
else {
for (uint16_t i = 0; i < pixels(); ++i)
set_pixel_color(i, color);
}
show();
}
void Marlin_NeoPixel2::set_color_startup(const uint32_t color) {
for (uint16_t i = 0; i < pixels(); ++i)
set_pixel_color(i, color);
show();
}
void Marlin_NeoPixel2::init() {
neoindex = -1; // -1 .. NEOPIXEL2_PIXELS-1 range
set_brightness(NEOPIXEL2_BRIGHTNESS); // 0 .. 255 range
begin();
show(); // initialize to all off
#if ENABLED(NEOPIXEL2_STARTUP_TEST)
set_color_startup(adaneo.Color(255, 0, 0, 0)); // red
safe_delay(500);
set_color_startup(adaneo.Color(0, 255, 0, 0)); // green
safe_delay(500);
set_color_startup(adaneo.Color(0, 0, 255, 0)); // blue
safe_delay(500);
#endif
#if ENABLED(NEO2_USER_PRESET_STARTUP)
set_color(adaneo.Color(NEO2_USER_PRESET_RED, NEO2_USER_PRESET_GREEN, NEO2_USER_PRESET_BLUE, NEO2_USER_PRESET_WHITE));
#else
set_color(adaneo.Color(0, 0, 0, 0));
#endif
}
#endif // NEOPIXEL2_SEPARATE
#endif // NEOPIXEL_LED #endif // NEOPIXEL_LED

View file

@ -38,10 +38,14 @@
// Defines // Defines
// ------------------------ // ------------------------
#if defined(NEOPIXEL2_TYPE) && NEOPIXEL2_TYPE != NEOPIXEL_TYPE #if defined(NEOPIXEL2_TYPE) && NEOPIXEL2_TYPE != NEOPIXEL_TYPE && DISABLED(NEOPIXEL2_SEPARATE)
#define MULTIPLE_NEOPIXEL_TYPES 1 #define MULTIPLE_NEOPIXEL_TYPES 1
#endif #endif
#if EITHER(MULTIPLE_NEOPIXEL_TYPES, NEOPIXEL2_INSERIES)
#define CONJOINED_NEOPIXEL 1
#endif
#if NEOPIXEL_TYPE == NEO_RGB || NEOPIXEL_TYPE == NEO_RBG || NEOPIXEL_TYPE == NEO_GRB || NEOPIXEL_TYPE == NEO_GBR || NEOPIXEL_TYPE == NEO_BRG || NEOPIXEL_TYPE == NEO_BGR #if NEOPIXEL_TYPE == NEO_RGB || NEOPIXEL_TYPE == NEO_RBG || NEOPIXEL_TYPE == NEO_GRB || NEOPIXEL_TYPE == NEO_GBR || NEOPIXEL_TYPE == NEO_BRG || NEOPIXEL_TYPE == NEO_BGR
#define NEOPIXEL_IS_RGB 1 #define NEOPIXEL_IS_RGB 1
#else #else
@ -61,7 +65,7 @@
class Marlin_NeoPixel { class Marlin_NeoPixel {
private: private:
static Adafruit_NeoPixel adaneo1 static Adafruit_NeoPixel adaneo1
#if EITHER(MULTIPLE_NEOPIXEL_TYPES, NEOPIXEL2_INSERIES) #if CONJOINED_NEOPIXEL
, adaneo2 , adaneo2
#endif #endif
; ;
@ -80,11 +84,7 @@ public:
static inline void begin() { static inline void begin() {
adaneo1.begin(); adaneo1.begin();
#if ENABLED(NEOPIXEL2_INSERIES) TERN_(CONJOINED_NEOPIXEL, adaneo2.begin());
adaneo2.begin();
#else
TERN_(MULTIPLE_NEOPIXEL_TYPES, adaneo2.begin());
#endif
} }
static inline void set_pixel_color(const uint16_t n, const uint32_t c) { static inline void set_pixel_color(const uint16_t n, const uint32_t c) {
@ -93,23 +93,21 @@ public:
else adaneo1.setPixelColor(n, c); else adaneo1.setPixelColor(n, c);
#else #else
adaneo1.setPixelColor(n, c); adaneo1.setPixelColor(n, c);
TERN_(MULTIPLE_NEOPIXEL_TYPES, adaneo2.setPixelColor(n, c)); #if MULTIPLE_NEOPIXEL_TYPES
adaneo2.setPixelColor(n, c);
#endif
#endif #endif
} }
static inline void set_brightness(const uint8_t b) { static inline void set_brightness(const uint8_t b) {
adaneo1.setBrightness(b); adaneo1.setBrightness(b);
#if ENABLED(NEOPIXEL2_INSERIES) TERN_(CONJOINED_NEOPIXEL, adaneo2.setBrightness(b));
adaneo2.setBrightness(b);
#else
TERN_(MULTIPLE_NEOPIXEL_TYPES, adaneo2.setBrightness(b));
#endif
} }
static inline void show() { static inline void show() {
adaneo1.show(); adaneo1.show();
#if PIN_EXISTS(NEOPIXEL2) #if PIN_EXISTS(NEOPIXEL2)
#if EITHER(MULTIPLE_NEOPIXEL_TYPES, NEOPIXEL2_INSERIES) #if CONJOINED_NEOPIXEL
adaneo2.show(); adaneo2.show();
#else #else
adaneo1.setPin(NEOPIXEL2_PIN); adaneo1.setPin(NEOPIXEL2_PIN);
@ -132,3 +130,47 @@ public:
}; };
extern Marlin_NeoPixel neo; extern Marlin_NeoPixel neo;
// Neo pixel channel 2
#if ENABLED(NEOPIXEL2_SEPARATE)
#if NEOPIXEL2_TYPE == NEO_RGB || NEOPIXEL2_TYPE == NEO_RBG || NEOPIXEL2_TYPE == NEO_GRB || NEOPIXEL2_TYPE == NEO_GBR || NEOPIXEL2_TYPE == NEO_BRG || NEOPIXEL2_TYPE == NEO_BGR
#define NEOPIXEL2_IS_RGB 1
#else
#define NEOPIXEL2_IS_RGBW 1
#endif
#if NEOPIXEL2_IS_RGB
#define NEO2_WHITE 255, 255, 255, 0
#else
#define NEO2_WHITE 0, 0, 0, 255
#endif
class Marlin_NeoPixel2 {
private:
static Adafruit_NeoPixel adaneo;
public:
static int8_t neoindex;
static void init();
static void set_color_startup(const uint32_t c);
static void set_color(const uint32_t c);
static inline void begin() { adaneo.begin(); }
static inline void set_pixel_color(const uint16_t n, const uint32_t c) { adaneo.setPixelColor(n, c); }
static inline void set_brightness(const uint8_t b) { adaneo.setBrightness(b); }
static inline void show() { adaneo.show(); }
// Accessors
static inline uint16_t pixels() { return adaneo.numPixels();}
static inline uint8_t brightness() { return adaneo.getBrightness(); }
static inline uint32_t Color(uint8_t r, uint8_t g, uint8_t b, uint8_t w) {
return adaneo.Color(r, g, b, w);
}
};
extern Marlin_NeoPixel2 neo2;
#endif // NEOPIXEL2_SEPARATE

View file

@ -37,6 +37,9 @@
* With NEOPIXEL_LED: * With NEOPIXEL_LED:
* I<index> Set the NeoPixel index to affect. Default: All * I<index> Set the NeoPixel index to affect. Default: All
* *
* With NEOPIXEL2_SEPARATE:
* S<index> The NeoPixel strip to set. Default is index 0.
*
* Examples: * Examples:
* *
* M150 R255 ; Turn LED red * M150 R255 ; Turn LED red
@ -47,18 +50,35 @@
* M150 P127 ; Set LED 50% brightness * M150 P127 ; Set LED 50% brightness
* M150 P ; Set LED full brightness * M150 P ; Set LED full brightness
* M150 I1 R ; Set NEOPIXEL index 1 to red * M150 I1 R ; Set NEOPIXEL index 1 to red
* M150 S1 I1 R ; Set SEPARATE index 1 to red
*/ */
void GcodeSuite::M150() { void GcodeSuite::M150() {
#if ENABLED(NEOPIXEL_LED) #if ENABLED(NEOPIXEL_LED)
neo.neoindex = parser.intval('I', -1); const uint8_t index = parser.intval('I', -1);
#if ENABLED(NEOPIXEL2_SEPARATE)
const uint8_t unit = parser.intval('S'),
brightness = unit ? neo2.brightness() : neo.brightness();
*(unit ? &neo2.neoindex : &neo.neoindex) = index;
#else
const uint8_t brightness = neo.brightness();
neo.neoindex = index;
#endif
#endif #endif
leds.set_color(MakeLEDColor(
const LEDColor color = MakeLEDColor(
parser.seen('R') ? (parser.has_value() ? parser.value_byte() : 255) : 0, parser.seen('R') ? (parser.has_value() ? parser.value_byte() : 255) : 0,
parser.seen('U') ? (parser.has_value() ? parser.value_byte() : 255) : 0, parser.seen('U') ? (parser.has_value() ? parser.value_byte() : 255) : 0,
parser.seen('B') ? (parser.has_value() ? parser.value_byte() : 255) : 0, parser.seen('B') ? (parser.has_value() ? parser.value_byte() : 255) : 0,
parser.seen('W') ? (parser.has_value() ? parser.value_byte() : 255) : 0, parser.seen('W') ? (parser.has_value() ? parser.value_byte() : 255) : 0,
parser.seen('P') ? (parser.has_value() ? parser.value_byte() : 255) : neo.brightness() parser.seen('P') ? (parser.has_value() ? parser.value_byte() : 255) : brightness
)); );
#if ENABLED(NEOPIXEL2_SEPARATE)
if (unit == 1) { leds2.set_color(color); return; }
#endif
leds.set_color(color);
} }
#endif // HAS_COLOR_LEDS #endif // HAS_COLOR_LEDS

View file

@ -780,3 +780,8 @@
#ifndef EXTRUDE_MINTEMP #ifndef EXTRUDE_MINTEMP
#define EXTRUDE_MINTEMP 170 #define EXTRUDE_MINTEMP 170
#endif #endif
// This flag indicates if Neopixel pins are shared or separated
#if EITHER(MULTIPLE_NEOPIXEL_TYPES, NEOPIXEL2_INSERIES)
#define CONJOINED_NEOPIXEL 1
#endif

View file

@ -246,6 +246,28 @@
#endif #endif
#endif #endif
#if BOTH(LED_CONTROL_MENU, NEOPIXEL2_SEPARATE)
#ifndef LED2_USER_PRESET_RED
#define LED2_USER_PRESET_RED 255
#endif
#ifndef LED2_USER_PRESET_GREEN
#define LED2_USER_PRESET_GREEN 255
#endif
#ifndef LED2_USER_PRESET_BLUE
#define LED2_USER_PRESET_BLUE 255
#endif
#ifndef LED2_USER_PRESET_WHITE
#define LED2_USER_PRESET_WHITE 0
#endif
#ifndef LED2_USER_PRESET_BRIGHTNESS
#ifdef NEOPIXEL2_BRIGHTNESS
#define LED2_USER_PRESET_BRIGHTNESS NEOPIXEL2_BRIGHTNESS
#else
#define LED2_USER_PRESET_BRIGHTNESS 255
#endif
#endif
#endif
// If platform requires early initialization of watchdog to properly boot // If platform requires early initialization of watchdog to properly boot
#if ENABLED(USE_WATCHDOG) && defined(ARDUINO_ARCH_SAM) #if ENABLED(USE_WATCHDOG) && defined(ARDUINO_ARCH_SAM)
#define EARLY_WATCHDOG 1 #define EARLY_WATCHDOG 1

View file

@ -2120,7 +2120,12 @@ static_assert(hbm[Z_AXIS] >= 0, "HOMING_BUMP_MM.Z must be greater than or equal
#if !(PIN_EXISTS(NEOPIXEL) && NEOPIXEL_PIXELS > 0) #if !(PIN_EXISTS(NEOPIXEL) && NEOPIXEL_PIXELS > 0)
#error "NEOPIXEL_LED requires NEOPIXEL_PIN and NEOPIXEL_PIXELS." #error "NEOPIXEL_LED requires NEOPIXEL_PIN and NEOPIXEL_PIXELS."
#endif #endif
#elif ENABLED(NEOPIXEL2_SEPARATE)
#if !(PIN_EXISTS(NEOPIXEL2) && NEOPIXEL2_PIXELS > 0)
#error "NEOPIXEL2 requires NEOPIXEL2_PIN and NEOPIXEL2_PIXELS."
#endif
#endif #endif
#undef _RGB_TEST #undef _RGB_TEST
#if DISABLED(NO_COMPILE_TIME_PWM) #if DISABLED(NO_COMPILE_TIME_PWM)