Lamp-Da 0.1
A compact lantern project
Loading...
Searching...
No Matches
Adafruit_NeoPixel.h
Go to the documentation of this file.
1
5#ifndef ADAFRUIT_NEOPIXEL_MOCK_H
6#define ADAFRUIT_NEOPIXEL_MOCK_H
7
10
11#include <memory>
12
13using neoPixelType = int;
14
15// RGB NeoPixel permutations; white and red offsets are always same
16// Offset: W R G B
17#define NEO_RGB ((0 << 6) | (0 << 4) | (1 << 2) | (2))
18#define NEO_RBG ((0 << 6) | (0 << 4) | (2 << 2) | (1))
19#define NEO_GRB ((1 << 6) | (1 << 4) | (0 << 2) | (2))
20#define NEO_GBR ((2 << 6) | (2 << 4) | (0 << 2) | (1))
21#define NEO_BRG ((1 << 6) | (1 << 4) | (2 << 2) | (0))
22#define NEO_BGR ((2 << 6) | (2 << 4) | (1 << 2) | (0))
23
24#define NEO_KHZ800 0x0000
25
27{
28public:
29 Adafruit_NeoPixel(size_t n, int16_t pin, neoPixelType t) : begun(false), brightness(0), pixels(NULL)
30 {
31 updateType(t);
32 updateLength(n);
33 };
34
35 ~Adafruit_NeoPixel() { free(pixels); }
36
37 void begin() { begun = true; }
38
39 void show()
40 {
42 }
43
44 uint8_t getBrightness() const { return brightness - 1; }
45
47 void setBrightness(uint8_t b)
48 {
49 // Stored brightness value is different than what's passed.
50 // This simplifies the actual scaling math later, allowing a fast
51 // 8x8-bit multiply and taking the MSB. 'brightness' is a uint8_t,
52 // adding 1 here may (intentionally) roll over...so 0 = max brightness
53 // (color values are interpreted literally; no scaling), 1 = min
54 // brightness (off), 255 = just below max brightness.
55 uint8_t newBrightness = b + 1;
56
57 if (newBrightness != brightness)
58 { // Compare against prior value
59 // Brightness has changed -- re-scale existing data in RAM,
60 // This process is potentially "lossy," especially when increasing
61 // brightness. The tight timing in the WS2811/WS2812 code means there
62 // aren't enough free cycles to perform this scaling on the fly as data
63 // is issued. So we make a pass through the existing color data in RAM
64 // and scale it (subsequent graphics commands also work at this
65 // brightness level). If there's a significant step up in brightness,
66 // the limited number of steps (quantization) in the old data will be
67 // quite visible in the re-scaled version. For a non-destructive
68 // change, you'll need to re-render the full strip data. C'est la vie.
69 uint8_t c, *ptr = pixels,
70 oldBrightness = brightness - 1; // De-wrap old brightness value
71 uint16_t scale;
72 if (oldBrightness == 0)
73 scale = 0; // Avoid /0
74 else if (b == 255)
75 scale = 65535 / oldBrightness;
76 else
77 scale = (((uint16_t)newBrightness << 8) - 1) / oldBrightness;
78 for (uint16_t i = 0; i < numBytes; i++)
79 {
80 c = *ptr;
81 *ptr++ = (c * scale) >> 8;
82 }
83 brightness = newBrightness;
84 }
85 }
86
87 void setPixelColor(uint16_t n, uint32_t c)
88 {
89 if (n < numLEDs)
90 {
91 uint8_t *p, r = (uint8_t)(c >> 16), g = (uint8_t)(c >> 8), b = (uint8_t)c;
92 if (brightness)
93 { // See notes in setBrightness()
94 r = (r * brightness) >> 8;
95 g = (g * brightness) >> 8;
96 b = (b * brightness) >> 8;
97 }
98 if (wOffset == rOffset)
99 {
100 p = &pixels[n * 3];
101 }
102 else
103 {
104 p = &pixels[n * 4];
105 uint8_t w = (uint8_t)(c >> 24);
106 p[wOffset] = brightness ? ((w * brightness) >> 8) : w;
107 }
108 p[rOffset] = r;
109 p[gOffset] = g;
110 p[bOffset] = b;
111 }
112 }
113
114 uint32_t getPixelColor(uint16_t n) const
115 {
116 if (n >= numLEDs)
117 return 0; // Out of bounds, return no color.
118
119 uint8_t* p;
120
121 if (wOffset == rOffset)
122 { // Is RGB-type device
123 p = &pixels[n * 3];
124 if (brightness)
125 {
126 // Stored color was decimated by setBrightness(). Returned value
127 // attempts to scale back to an approximation of the original 24-bit
128 // value used when setting the pixel color, but there will always be
129 // some error -- those bits are simply gone. Issue is most
130 // pronounced at low brightness levels.
131 return (((uint32_t)(p[rOffset] << 8) / brightness) << 16) | (((uint32_t)(p[gOffset] << 8) / brightness) << 8) |
132 ((uint32_t)(p[bOffset] << 8) / brightness);
133 }
134 else
135 {
136 // No brightness adjustment has been made -- return 'raw' color
137 return ((uint32_t)p[rOffset] << 16) | ((uint32_t)p[gOffset] << 8) | (uint32_t)p[bOffset];
138 }
139 }
140 else
141 { // Is RGBW-type device
142 p = &pixels[n * 4];
143 if (brightness)
144 { // Return scaled color
145 return (((uint32_t)(p[wOffset] << 8) / brightness) << 24) | (((uint32_t)(p[rOffset] << 8) / brightness) << 16) |
146 (((uint32_t)(p[gOffset] << 8) / brightness) << 8) | ((uint32_t)(p[bOffset] << 8) / brightness);
147 }
148 else
149 { // Return raw color
150 return ((uint32_t)p[wOffset] << 24) | ((uint32_t)p[rOffset] << 16) | ((uint32_t)p[gOffset] << 8) |
151 (uint32_t)p[bOffset];
152 }
153 }
154 }
155
156 // vars
157 bool begun;
158 uint16_t numLEDs;
159 uint16_t numBytes;
160 uint8_t brightness;
161 uint8_t* pixels;
162 uint8_t rOffset;
163 uint8_t gOffset;
164 uint8_t bOffset;
165 uint8_t wOffset;
166
167private:
168 void updateType(neoPixelType t)
169 {
170 bool oldThreeBytesPerPixel = (wOffset == rOffset); // false if RGBW
171
172 wOffset = (t >> 6) & 0b11; // See notes in header file
173 rOffset = (t >> 4) & 0b11; // regarding R/G/B/W offsets
174 gOffset = (t >> 2) & 0b11;
175 bOffset = t & 0b11;
176
177 // If bytes-per-pixel has changed (and pixel data was previously
178 // allocated), re-allocate to new size. Will clear any data.
179 if (pixels)
180 {
181 bool newThreeBytesPerPixel = (wOffset == rOffset);
182 if (newThreeBytesPerPixel != oldThreeBytesPerPixel)
183 updateLength(numLEDs);
184 }
185 }
186
187 void updateLength(uint16_t n)
188 {
189 free(pixels); // Free existing data (if any)
190
191 // Allocate new data -- note: ALL PIXELS ARE CLEARED
192 numBytes = n * ((wOffset == rOffset) ? 3 : 4);
193 if ((pixels = (uint8_t*)malloc(numBytes)))
194 {
195 memset(pixels, 0, numBytes);
196 numLEDs = n;
197 }
198 else
199 {
200 numLEDs = numBytes = 0;
201 }
202 }
203};
204
205#endif
Definition: Adafruit_NeoPixel.h:27
uint8_t * pixels
Holds LED color values (3 or 4 bytes each)
Definition: Adafruit_NeoPixel.h:161
void setBrightness(uint8_t b)
Implementation similar to Adafruit led strip.
Definition: Adafruit_NeoPixel.h:47
bool begun
true if begin() previously called
Definition: Adafruit_NeoPixel.h:157
uint8_t gOffset
Index of green byte.
Definition: Adafruit_NeoPixel.h:163
uint8_t rOffset
Red index within each 3- or 4-byte pixel.
Definition: Adafruit_NeoPixel.h:162
uint16_t numBytes
Size of 'pixels' buffer below.
Definition: Adafruit_NeoPixel.h:159
uint8_t brightness
Strip brightness 0-255 (stored as +1)
Definition: Adafruit_NeoPixel.h:160
void show()
Definition: Adafruit_NeoPixel.h:39
uint8_t wOffset
Index of white (==rOffset if no white)
Definition: Adafruit_NeoPixel.h:165
uint16_t numLEDs
Number of RGB LEDs in strip.
Definition: Adafruit_NeoPixel.h:158
uint8_t bOffset
Index of blue byte.
Definition: Adafruit_NeoPixel.h:164
Define commonly used color spaces.
Define useful functions.