| 302 | template <int DATA_PIN, typename TIMING, EOrder RGB_ORDER = GRB, |
| 303 | int XTRA0 = 0, bool FLIP = false, int WAIT_TIME = 0> |
| 304 | class NeoPixelBusRGBWController : public CPixelLEDController<RGB_ORDER> { |
| 305 | public: |
| 306 | using Method = typename NeoPixelBusMethodSelector<DATA_PIN>::DefaultMethod; |
| 307 | using BusType = NeoPixelBus<NeoGrbwFeature, Method>; // Always use RGBW feature |
| 308 | |
| 309 | private: |
| 310 | fl::unique_ptr<BusType> mPixelBus; |
| 311 | bool mInitialized; |
| 312 | |
| 313 | public: |
| 314 | /// Constructor - creates uninitialized controller |
| 315 | NeoPixelBusRGBWController() : mPixelBus(nullptr), mInitialized(false) {} |
| 316 | |
| 317 | /// Destructor - automatic cleanup via unique_ptr |
| 318 | virtual ~NeoPixelBusRGBWController() = default; |
| 319 | |
| 320 | /// Initialize the controller |
| 321 | virtual void init() FL_NOEXCEPT override { |
| 322 | if (!mInitialized) { |
| 323 | try { |
| 324 | mPixelBus = fl::make_unique<BusType>(0, DATA_PIN); |
| 325 | if (!mPixelBus) { |
| 326 | FL_WARN("Failed to create RGBW NeoPixelBus instance"); |
| 327 | return; |
| 328 | } |
| 329 | |
| 330 | mPixelBus->Begin(); |
| 331 | mInitialized = true; |
| 332 | |
| 333 | onInitialized(); |
| 334 | } catch (...) { |
| 335 | FL_WARN("RGBW NeoPixelBus initialization failed"); |
| 336 | mInitialized = false; |
| 337 | } |
| 338 | } |
| 339 | } |
| 340 | |
| 341 | /// Output pixels to the LED strip with RGBW conversion |
| 342 | virtual void showPixels(PixelController<RGB_ORDER> &pixels) FL_NOEXCEPT override { |
| 343 | if (!mPixelBus || !mInitialized) { |
| 344 | return; |
| 345 | } |
| 346 | |
| 347 | // Update strip length if needed |
| 348 | if (mPixelBus->PixelCount() != pixels.size()) { |
| 349 | mPixelBus.reset(); |
| 350 | mPixelBus = fl::make_unique<BusType>(pixels.size(), DATA_PIN); |
| 351 | if (!mPixelBus) { |
| 352 | FL_WARN("Failed to recreate RGBW NeoPixelBus with new size"); |
| 353 | return; |
| 354 | } |
| 355 | mPixelBus->Begin(); |
| 356 | } |
| 357 | |
| 358 | beforeShow(pixels); |
| 359 | convertAndSetPixels(pixels); |
| 360 | afterConversion(pixels); |
| 361 | |