M5Unit-RGB 0.0.2 git rev:51dfbe6
Loading...
Searching...
No Matches
unit_LED.hpp
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 2025 M5Stack Technology CO LTD
3 *
4 * SPDX-License-Identifier: MIT
5 */
10#ifndef M5_UNIT_RGB_UNIT_LED_HPP
11#define M5_UNIT_RGB_UNIT_LED_HPP
12
13#include <M5UnitComponent.hpp>
14#include <vector>
15
16namespace m5 {
17namespace unit {
18
23namespace rgb {
24
26using wrgb32_color_t = uint32_t;
27
32union Color {
37 explicit constexpr Color(const wrgb32_color_t c = 0) : wrgb{c}
38 {
39 }
47 constexpr Color(const uint8_t rr, const uint8_t gg, const uint8_t bb, const uint8_t ww = 0)
48 : b{bb}, g{gg}, r{rr}, w{ww}
49 {
50 }
55 constexpr operator wrgb32_color_t() const
56 {
57 return wrgb;
58 }
66 static Color fromHSV(const uint8_t h, const uint8_t s, const uint8_t v);
67
69 struct {
70 uint8_t b;
71 uint8_t g;
72 uint8_t r;
73 uint8_t w;
74 };
75 uint8_t a[4];
76};
83constexpr bool operator==(const Color& lhs, const Color& rhs)
84{
85 return lhs.wrgb == rhs.wrgb;
86}
87
92enum class Order : int8_t {
93 unknown = -1,
94 // 24 bits
95 rgb24,
96 rbg24,
97 grb24,
98 gbr24,
99 brg24,
100 bgr24,
101 // 32 bits
102 hasWhite,
103 //
104 wrgb32 = hasWhite,
105 wrbg32,
106 wgrb32,
107 wgbr32,
108 wbrg32,
109 wbgr32,
110 //
111 rwgb32,
112 rwbg32,
113 rgwb32,
114 rgbw32,
115 rbwg32,
116 rbgw32,
117 //
118 gwrb32,
119 gwbr32,
120 grwb32,
121 grbw32,
122 gbwr32,
123 gbrw32,
124 //
125 bwrg32,
126 bwgr32,
127 brwg32,
128 brgw32,
129 bgwr32,
130 bgrw32,
131};
132
138int8_t offsetR(const Order f);
144int8_t offsetG(const Order f);
150int8_t offsetB(const Order f);
156int8_t offsetW(const Order f);
157} // namespace rgb
158
163class UnitLED : public Component {
164 M5_UNIT_COMPONENT_HPP_BUILDER(UnitLED, 0x00);
165
167 class PixelProxy {
168 public:
169 PixelProxy(UnitLED& u, const uint32_t i) : _u(u), _i(i), _c{u.color(i)}
170 {
171 }
172
173 inline operator rgb::Color() const
174 {
175 return _c;
176 }
177
178 PixelProxy& operator=(const rgb::Color& c)
179 {
180 _c = c;
181 _u.setPixelColor(_i, _c);
182 return *this;
183 }
184 PixelProxy& operator=(const PixelProxy& o)
185 {
186 _c = static_cast<rgb::Color>(o);
187 _u.setPixelColor(_i, _c);
188 return *this;
189 }
190
191 private:
192 UnitLED& _u;
193 uint32_t _i;
194 rgb::Color _c; // Color at the time of Proxy creation
195 };
197
198public:
199 using container_type = std::vector<uint8_t>;
200 using item_container_type = std::vector<gpio::m5_rmt_item_t>;
201
206 struct config_t {
207 uint8_t brightness{10};
209 uint8_t mem_blocks{0};
211 bool with_dma{false};
212 };
213
216
221 {
222 return _cfg;
223 }
228 inline void config(const config_t& cfg)
229 {
230 _cfg = cfg;
231 }
233
235 virtual ~UnitLED()
236 {
237 }
238
246 bool add(UnitLED& c, const int16_t channel);
247
252 virtual bool begin() override;
253
256
260 inline uint16_t numPixels() const
261 {
262 return _numPixels;
263 }
269 inline uint8_t brightness() const
270 {
271 return _brightness;
272 }
273
278 inline virtual uint16_t width() const
279 {
280 return numPixels();
281 }
286 inline virtual uint16_t height() const
287 {
288 return 1;
289 }
290
295 inline bool hasWhite() const
296 {
297 return (_order >= rgb::Order::hasWhite);
298 }
303 inline rgb::Order order() const
304 {
305 return _order;
306 }
311 inline int8_t offsetR() const
312 {
313 return _offsetR;
314 }
319 inline int8_t offsetG() const
320 {
321 return _offsetG;
322 }
327 inline int8_t offsetB() const
328 {
329 return _offsetB;
330 }
335 inline int8_t offsetW() const
336 {
337 return _offsetW;
338 }
339
344 const container_type& pixels() const
345 {
346 return _pixels;
347 }
354 inline rgb::Color color(const uint16_t n) const
355 {
356 return (n < _numPixels) ? get_pixel_color(index_of(n)) : rgb::Color();
357 }
364 inline rgb::Color absoluteColor(const uint16_t n) const
365 {
366 return (n < _numPixels) ? get_pixel_color(n) : rgb::Color();
367 }
369
372
376 bool writePixels();
381 inline bool show()
382 {
383 return writePixels();
384 }
386
390
397 inline void setBrightness(const uint8_t b)
398 {
399 _brightness = b;
400 }
411 bool setPixelColor(const uint16_t n, const uint8_t r, const uint8_t g, const uint8_t b);
423 inline bool setPixelColor(const uint16_t n, const uint8_t r, const uint8_t g, const uint8_t b, const uint8_t w)
424 {
425 return setPixelColor(n, rgb::Color(r, g, b, w));
426 }
435 inline bool setPixelColor(const uint16_t n, const rgb::wrgb32_color_t c)
436 {
437 return setPixelColor(n, rgb::Color(c));
438 }
447 inline bool setPixelColor(const uint16_t n, const rgb::Color& c)
448 {
449 if (n >= _numPixels) {
450 return false;
451 }
452 return set_pixel_color(index_of(n), c);
453 }
463 bool fill(const rgb::Color& c, const uint16_t first = 0, const uint16_t count = 0);
468 inline void clear(void)
469 {
470 fill(rgb::Color());
471 }
480 bool fillRainbow(const uint16_t first = 0, const uint16_t count = 0, const uint8_t firstHue = 0);
490 bool fillGradation(const rgb::Color& firstClr, const rgb::Color& lastClr, const uint16_t first = 0,
491 const uint16_t count = 0);
499 bool fillRandom(const uint16_t first = 0, const uint16_t count = 0);
506 inline void shiftLeft(const uint16_t count = 1)
507 {
508 shift_left(count, false);
509 }
516 inline void shiftRight(const uint16_t count = 1)
517 {
518 shift_right(count, false);
519 }
525 inline void rotateLeft(const uint16_t count = 1)
526 {
527 shift_left(count, true);
528 }
534 inline void rotateRight(const uint16_t count = 1)
535 {
536 shift_right(count, true);
537 }
539
545
549 inline virtual uint8_t maxRotation() const
550 {
551 return 2; // 0,180 deg
552 }
557 inline float rotationDegree() const
558 {
559 return 360.f / maxRotation();
560 }
565 inline int8_t rotation() const
566 {
567 return _rot;
568 }
573 void setRotation(const int8_t rot);
575
579
584 rgb::Color operator[](const uint16_t i) const
585 {
586 return color(i);
587 }
593 PixelProxy operator[](const uint16_t i)
594 {
595 return PixelProxy(*this, i);
596 }
598
600 // Class that abstracts the interaction between classes and adapters
601 class Interface {
602 public:
603 explicit Interface(UnitLED& u) : _unit{u}
604 {
605 }
606 virtual ~Interface()
607 {
608 }
609 virtual bool write(const uint8_t*, const uint32_t) = 0;
610 // For items
611 virtual UnitLED::item_container_type items()
612 {
613 return {};
614 }
615 virtual UnitLED::item_container_type items_from_root()
616 {
617 return {};
618 }
619 // For RGB888
620 virtual UnitLED::container_type rgb888_items()
621 {
622 return {};
623 }
624 virtual UnitLED::container_type rgb888_items_from_root()
625 {
626 return {};
627 }
628
630 virtual bool writePixelsDirect()
631 {
632 return false;
633 }
634
635 protected:
636 UnitLED& _unit;
637 };
639
640protected:
641 inline virtual types::category_t unit_category() const override
642 {
643 return types::category_t::UnitLED;
644 }
645 inline virtual gpio::adapter_config_t rmt_config()
646 {
647 return gpio::adapter_config_t{};
648 }
649 inline virtual gpio::m5_rmt_item_t rmt_item_one()
650 {
651 return gpio::m5_rmt_item_t{};
652 }
653 inline virtual gpio::m5_rmt_item_t rmt_item_zero()
654 {
655 return gpio::m5_rmt_item_t{};
656 }
657 inline virtual gpio::m5_rmt_item_t rmt_item_reset()
658 {
659 return gpio::m5_rmt_item_t{};
660 }
661 inline container_type& pixels()
662 {
663 return _pixels;
664 }
665
666 // Not affected by rotation
667 rgb::Color get_pixel_color(const uint16_t n) const;
668 bool set_pixel_color(const uint16_t n, const rgb::Color& c);
669
670 inline uint8_t rotation_of(const int8_t r) const
671 {
672 return (r % maxRotation() + maxRotation()) % maxRotation();
673 }
674
675 inline virtual uint16_t index_of(const uint16_t n) const
676 {
677 // 0 or 180 deg
678 return _rot ? _numPixels - (n % _numPixels) - 1 : n;
679 }
680
681 container_type rgb888_items();
682 item_container_type items();
683
684 void shift_left(const uint16_t count, const bool wrap);
685 void shift_right(const uint16_t count, const bool wrap);
686
687protected:
688 // Protected so only derived types with hardcoded Order (UnitRGB / UnitPuzzle / ...) can construct.
689 explicit UnitLED(const uint16_t num_of_pixels, const rgb::Order order)
690 : Component(0x00), _order{order}, _numPixels{num_of_pixels}
691 {
692 _offsetR = rgb::offsetR(_order);
693 _offsetG = rgb::offsetG(_order);
694 _offsetB = rgb::offsetB(_order);
695 _offsetW = rgb::offsetW(_order);
696 _pixels.resize(_numPixels * (3 + hasWhite()));
697 }
698
699private:
700 rgb::Order _order{rgb::Order::unknown};
701 uint8_t _brightness{10};
702 int8_t _rot{};
703 int8_t _offsetR{-1}, _offsetG{-1}, _offsetB{-1}, _offsetW{-1};
704 uint16_t _numPixels{};
705 bool _ready{false};
706 container_type _pixels{}; // Order by rgb::Order
707 std::unique_ptr<Interface> _interface{};
708 config_t _cfg{};
709
710 friend class InterfaceGPIO;
711 friend class InterfacePbHub;
712};
713
714} // namespace unit
715} // namespace m5
716#endif
LED base unit.
bool fillRandom(const uint16_t first=0, const uint16_t count=0)
Fill the specified range to random color pixels.
Definition unit_LED.cpp:680
bool setPixelColor(const uint16_t n, const rgb::wrgb32_color_t c)
Set pixel color.
Definition unit_LED.hpp:435
int8_t rotation() const
Get the rotation.
Definition unit_LED.hpp:565
void setBrightness(const uint8_t b)
Set the brightness.
Definition unit_LED.hpp:397
int8_t offsetW() const
Offset of white.
Definition unit_LED.hpp:335
rgb::Color color(const uint16_t n) const
Get the Color.
Definition unit_LED.hpp:354
virtual uint16_t height() const
Logical height in pixels.
Definition unit_LED.hpp:286
void rotateRight(const uint16_t count=1)
Rotate pixels right.
Definition unit_LED.hpp:534
std::vector< uint8_t > container_type
pixel container
Definition unit_LED.hpp:199
void shiftRight(const uint16_t count=1)
Shift pixels right.
Definition unit_LED.hpp:516
virtual bool begin() override
Begin the unit.
Definition unit_LED.cpp:530
int8_t offsetB() const
Offset of blue.
Definition unit_LED.hpp:327
PixelProxy operator[](const uint16_t i)
lvalue
Definition unit_LED.hpp:593
int8_t offsetR() const
Offset of red.
Definition unit_LED.hpp:311
bool setPixelColor(const uint16_t n, const rgb::Color &c)
Set pixel color.
Definition unit_LED.hpp:447
bool add(UnitLED &c, const int16_t channel)
Connect an LED unit as a daisy-chained child.
Definition unit_LED.cpp:525
void setRotation(const int8_t rot)
Set the rotation.
Definition unit_LED.cpp:694
int8_t offsetG() const
Offset of green.
Definition unit_LED.hpp:319
bool fill(const rgb::Color &c, const uint16_t first=0, const uint16_t count=0)
Fill the specified range with the specified color.
Definition unit_LED.cpp:624
config_t config()
Gets the configuration.
Definition unit_LED.hpp:220
virtual uint16_t width() const
Logical width in pixels.
Definition unit_LED.hpp:278
bool show()
Write pixel color to LED (alias)
Definition unit_LED.hpp:381
bool hasWhite() const
Has white data?
Definition unit_LED.hpp:295
uint8_t brightness() const
Brightness.
Definition unit_LED.hpp:269
void clear(void)
Clear pixels.
Definition unit_LED.hpp:468
rgb::Color operator[](const uint16_t i) const
rvalue
Definition unit_LED.hpp:584
void config(const config_t &cfg)
Set the configuration.
Definition unit_LED.hpp:228
virtual uint8_t maxRotation() const
Get the max rotation.
Definition unit_LED.hpp:549
bool setPixelColor(const uint16_t n, const uint8_t r, const uint8_t g, const uint8_t b)
Set pixel color (RGB)
Definition unit_LED.cpp:611
void shiftLeft(const uint16_t count=1)
Shift pixels left.
Definition unit_LED.hpp:506
bool fillRainbow(const uint16_t first=0, const uint16_t count=0, const uint8_t firstHue=0)
Fill the specified range to rainbow.
Definition unit_LED.cpp:637
rgb::Color absoluteColor(const uint16_t n) const
Get the Color.
Definition unit_LED.hpp:364
void rotateLeft(const uint16_t count=1)
Rotate pixels left.
Definition unit_LED.hpp:525
rgb::Order order() const
Color order.
Definition unit_LED.hpp:303
uint16_t numPixels() const
Number of the pixels.
Definition unit_LED.hpp:260
bool writePixels()
Write pixel color to LED.
Definition unit_LED.cpp:587
virtual ~UnitLED()
Destructor.
Definition unit_LED.hpp:235
std::vector< gpio::m5_rmt_item_t > item_container_type
item container
Definition unit_LED.hpp:200
const container_type & pixels() const
pixels container
Definition unit_LED.hpp:344
float rotationDegree() const
Get the rotation angle per 1.
Definition unit_LED.hpp:557
bool fillGradation(const rgb::Color &firstClr, const rgb::Color &lastClr, const uint16_t first=0, const uint16_t count=0)
Fill the specified range to gradation pixels.
Definition unit_LED.cpp:655
bool setPixelColor(const uint16_t n, const uint8_t r, const uint8_t g, const uint8_t b, const uint8_t w)
Set pixel color (RGBW)
Definition unit_LED.hpp:423
Top level namespace of M5Stack.
For M5Unit-RGB.
Unit-related namespace.
Settings for begin.
Definition unit_LED.hpp:206
bool with_dma
Use DMA for RMT (RMT v2 only, e.g. ESP32-S3/C6). Ignored via PbHub.
Definition unit_LED.hpp:211
uint8_t mem_blocks
RMT memory blocks (0 = use chip default). Ignored via PbHub.
Definition unit_LED.hpp:209
uint8_t brightness
Definition unit_LED.hpp:207
WRGB 32bits.
Definition unit_LED.hpp:32
uint8_t b
Blue.
Definition unit_LED.hpp:70
wrgb32_color_t wrgb
WRGB 32bits.
Definition unit_LED.hpp:68
uint8_t a[4]
Array.
Definition unit_LED.hpp:75
uint8_t w
White.
Definition unit_LED.hpp:73
uint8_t g
Green.
Definition unit_LED.hpp:71
uint8_t r
Red.
Definition unit_LED.hpp:72
constexpr Color(const uint8_t rr, const uint8_t gg, const uint8_t bb, const uint8_t ww=0)
Constructor from RGB / RGBW components.
Definition unit_LED.hpp:47
constexpr Color(const wrgb32_color_t c=0)
Constructor from packed WRGB.
Definition unit_LED.hpp:37
static Color fromHSV(const uint8_t h, const uint8_t s, const uint8_t v)
Make Color from HSV.
Definition unit_LED.cpp:149
constexpr bool operator==(const Color &lhs, const Color &rhs)
Compare two Colors.
Definition unit_LED.hpp:83
uint32_t wrgb32_color_t
WRGB 32bits.
Definition unit_LED.hpp:26
Order
Color order.
Definition unit_LED.hpp:92