| 1 | /*! |
| 2 | * @file Adafruit_NeoPixel.h |
| 3 | * |
| 4 | * This is part of Adafruit's NeoPixel library for the Arduino platform, |
| 5 | * allowing a broad range of microcontroller boards (most AVR boards, |
| 6 | * many ARM devices, ESP8266 and ESP32, among others) to control Adafruit |
| 7 | * NeoPixels, FLORA RGB Smart Pixels and compatible devices -- WS2811, |
| 8 | * WS2812, WS2812B, SK6812, etc. |
| 9 | * |
| 10 | * Adafruit invests time and resources providing this open source code, |
| 11 | * please support Adafruit and open-source hardware by purchasing products |
| 12 | * from Adafruit! |
| 13 | * |
| 14 | * Written by Phil "Paint Your Dragon" Burgess for Adafruit Industries, |
| 15 | * with contributions by PJRC, Michael Miller and other members of the |
| 16 | * open source community. |
| 17 | * |
| 18 | * This file is part of the Adafruit_NeoPixel library. |
| 19 | * |
| 20 | * Adafruit_NeoPixel is free software: you can redistribute it and/or |
| 21 | * modify it under the terms of the GNU Lesser General Public License as |
| 22 | * published by the Free Software Foundation, either version 3 of the |
| 23 | * License, or (at your option) any later version. |
| 24 | * |
| 25 | * Adafruit_NeoPixel is distributed in the hope that it will be useful, |
| 26 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 27 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 28 | * GNU Lesser General Public License for more details. |
| 29 | * |
| 30 | * You should have received a copy of the GNU Lesser General Public |
| 31 | * License along with NeoPixel. If not, see |
| 32 | * <http://www.gnu.org/licenses/>. |
| 33 | * |
| 34 | */ |
| 35 | |
| 36 | #ifndef ADAFRUIT_NEOPIXEL_H |
| 37 | #define ADAFRUIT_NEOPIXEL_H |
| 38 | |
| 39 | #ifdef ARDUINO |
| 40 | #include <Arduino.h> |
| 41 | |
| 42 | #ifdef USE_TINYUSB // For Serial when selecting TinyUSB |
| 43 | #include <Adafruit_TinyUSB.h> |
| 44 | #endif |
| 45 | |
| 46 | #endif |
| 47 | |
| 48 | #ifdef TARGET_LPC1768 |
| 49 | #include <Arduino.h> |
| 50 | #endif |
| 51 | |
| 52 | #if defined(ARDUINO_ARCH_RP2040) |
| 53 | #include "hardware/clocks.h" |
| 54 | #include "hardware/pio.h" |
| 55 | #include "rp2040_pio.h" |
| 56 | #include <stdlib.h> |
| 57 | #endif |
| 58 | |
| 59 | // The order of primary colors in the NeoPixel data stream can vary among |
| 60 | // device types, manufacturers and even different revisions of the same |
| 61 | // item. The third parameter to the Adafruit_NeoPixel constructor encodes |
| 62 | // the per-pixel byte offsets of the red, green and blue primaries (plus |
| 63 | // white, if present) in the data stream -- the following #defines provide |
| 64 | // an easier-to-use named version for each permutation. e.g. NEO_GRB |
| 65 | // indicates a NeoPixel-compatible device expecting three bytes per pixel, |
| 66 | // with the first byte transmitted containing the green value, second |
| 67 | // containing red and third containing blue. The in-memory representation |
| 68 | // of a chain of NeoPixels is the same as the data-stream order; no |
| 69 | // re-ordering of bytes is required when issuing data to the chain. |
| 70 | // Most of these values won't exist in real-world devices, but it's done |
| 71 | // this way so we're ready for it (also, if using the WS2811 driver IC, |
| 72 | // one might have their pixels set up in any weird permutation). |
| 73 | |
| 74 | // Bits 5,4 of this value are the offset (0-3) from the first byte of a |
| 75 | // pixel to the location of the red color byte. Bits 3,2 are the green |
| 76 | // offset and 1,0 are the blue offset. If it is an RGBW-type device |
| 77 | // (supporting a white primary in addition to R,G,B), bits 7,6 are the |
| 78 | // offset to the white byte...otherwise, bits 7,6 are set to the same value |
| 79 | // as 5,4 (red) to indicate an RGB (not RGBW) device. |
| 80 | // i.e. binary representation: |
| 81 | // 0bWWRRGGBB for RGBW devices |
| 82 | // 0bRRRRGGBB for RGB |
| 83 | |
| 84 | // RGB NeoPixel permutations; white and red offsets are always same |
| 85 | // Offset: W R G B |
| 86 | #define NEO_RGB ((0 << 6) | (0 << 4) | (1 << 2) | (2)) ///< Transmit as R,G,B |
| 87 | #define NEO_RBG ((0 << 6) | (0 << 4) | (2 << 2) | (1)) ///< Transmit as R,B,G |
| 88 | #define NEO_GRB ((1 << 6) | (1 << 4) | (0 << 2) | (2)) ///< Transmit as G,R,B |
| 89 | #define NEO_GBR ((2 << 6) | (2 << 4) | (0 << 2) | (1)) ///< Transmit as G,B,R |
| 90 | #define NEO_BRG ((1 << 6) | (1 << 4) | (2 << 2) | (0)) ///< Transmit as B,R,G |
| 91 | #define NEO_BGR ((2 << 6) | (2 << 4) | (1 << 2) | (0)) ///< Transmit as B,G,R |
| 92 | |
| 93 | // RGBW NeoPixel permutations; all 4 offsets are distinct |
| 94 | // Offset: W R G B |
| 95 | #define NEO_WRGB ((0 << 6) | (1 << 4) | (2 << 2) | (3)) ///< Transmit as W,R,G,B |
| 96 | #define NEO_WRBG ((0 << 6) | (1 << 4) | (3 << 2) | (2)) ///< Transmit as W,R,B,G |
| 97 | #define NEO_WGRB ((0 << 6) | (2 << 4) | (1 << 2) | (3)) ///< Transmit as W,G,R,B |
| 98 | #define NEO_WGBR ((0 << 6) | (3 << 4) | (1 << 2) | (2)) ///< Transmit as W,G,B,R |
| 99 | #define NEO_WBRG ((0 << 6) | (2 << 4) | (3 << 2) | (1)) ///< Transmit as W,B,R,G |
| 100 | #define NEO_WBGR ((0 << 6) | (3 << 4) | (2 << 2) | (1)) ///< Transmit as W,B,G,R |
| 101 | |
| 102 | #define NEO_RWGB ((1 << 6) | (0 << 4) | (2 << 2) | (3)) ///< Transmit as R,W,G,B |
| 103 | #define NEO_RWBG ((1 << 6) | (0 << 4) | (3 << 2) | (2)) ///< Transmit as R,W,B,G |
| 104 | #define NEO_RGWB ((2 << 6) | (0 << 4) | (1 << 2) | (3)) ///< Transmit as R,G,W,B |
| 105 | #define NEO_RGBW ((3 << 6) | (0 << 4) | (1 << 2) | (2)) ///< Transmit as R,G,B,W |
| 106 | #define NEO_RBWG ((2 << 6) | (0 << 4) | (3 << 2) | (1)) ///< Transmit as R,B,W,G |
| 107 | #define NEO_RBGW ((3 << 6) | (0 << 4) | (2 << 2) | (1)) ///< Transmit as R,B,G,W |
| 108 | |
| 109 | #define NEO_GWRB ((1 << 6) | (2 << 4) | (0 << 2) | (3)) ///< Transmit as G,W,R,B |
| 110 | #define NEO_GWBR ((1 << 6) | (3 << 4) | (0 << 2) | (2)) ///< Transmit as G,W,B,R |
| 111 | #define NEO_GRWB ((2 << 6) | (1 << 4) | (0 << 2) | (3)) ///< Transmit as G,R,W,B |
| 112 | #define NEO_GRBW ((3 << 6) | (1 << 4) | (0 << 2) | (2)) ///< Transmit as G,R,B,W |
| 113 | #define NEO_GBWR ((2 << 6) | (3 << 4) | (0 << 2) | (1)) ///< Transmit as G,B,W,R |
| 114 | #define NEO_GBRW ((3 << 6) | (2 << 4) | (0 << 2) | (1)) ///< Transmit as G,B,R,W |
| 115 | |
| 116 | #define NEO_BWRG ((1 << 6) | (2 << 4) | (3 << 2) | (0)) ///< Transmit as B,W,R,G |
| 117 | #define NEO_BWGR ((1 << 6) | (3 << 4) | (2 << 2) | (0)) ///< Transmit as B,W,G,R |
| 118 | #define NEO_BRWG ((2 << 6) | (1 << 4) | (3 << 2) | (0)) ///< Transmit as B,R,W,G |
| 119 | #define NEO_BRGW ((3 << 6) | (1 << 4) | (2 << 2) | (0)) ///< Transmit as B,R,G,W |
| 120 | #define NEO_BGWR ((2 << 6) | (3 << 4) | (1 << 2) | (0)) ///< Transmit as B,G,W,R |
| 121 | #define NEO_BGRW ((3 << 6) | (2 << 4) | (1 << 2) | (0)) ///< Transmit as B,G,R,W |
| 122 | |
| 123 | // Add NEO_KHZ400 to the color order value to indicate a 400 KHz device. |
| 124 | // All but the earliest v1 NeoPixels expect an 800 KHz data stream, this is |
| 125 | // the default if unspecified. Because flash space is very limited on ATtiny |
| 126 | // devices (e.g. Trinket, Gemma), v1 NeoPixels aren't handled by default on |
| 127 | // those chips, though it can be enabled by removing the ifndef/endif below, |
| 128 | // but code will be bigger. Conversely, can disable the NEO_KHZ400 line on |
| 129 | // other MCUs to remove v1 support and save a little space. |
| 130 | |
| 131 | #define NEO_KHZ800 0x0000 ///< 800 KHz data transmission |
| 132 | #ifndef __AVR_ATtiny85__ |
| 133 | #define NEO_KHZ400 0x0100 ///< 400 KHz data transmission |
| 134 | #endif |
| 135 | |
| 136 | // If 400 KHz support is enabled, the third parameter to the constructor |
| 137 | // requires a 16-bit value (in order to select 400 vs 800 KHz speed). |
| 138 | // If only 800 KHz is enabled (as is default on ATtiny), an 8-bit value |
| 139 | // is sufficient to encode pixel color order, saving some space. |
| 140 | |
| 141 | #ifdef NEO_KHZ400 |
| 142 | typedef uint16_t neoPixelType; ///< 3rd arg to Adafruit_NeoPixel constructor |
| 143 | #else |
| 144 | typedef uint8_t neoPixelType; ///< 3rd arg to Adafruit_NeoPixel constructor |
| 145 | #endif |
| 146 | |
| 147 | // These two tables are declared outside the Adafruit_NeoPixel class |
| 148 | // because some boards may require oldschool compilers that don't |
| 149 | // handle the C++11 constexpr keyword. |
| 150 | |
| 151 | /* A PROGMEM (flash mem) table containing 8-bit unsigned sine wave (0-255). |
| 152 | Copy & paste this snippet into a Python REPL to regenerate: |
| 153 | import math |
| 154 | for x in range(256): |
| 155 | print("{:3},".format(int((math.sin(x/128.0*math.pi)+1.0)*127.5+0.5))), |
| 156 | if x&15 == 15: print |
| 157 | */ |
| 158 | static const uint8_t PROGMEM _NeoPixelSineTable[256] = { |
| 159 | 128, 131, 134, 137, 140, 143, 146, 149, 152, 155, 158, 162, 165, 167, 170, |
| 160 | 173, 176, 179, 182, 185, 188, 190, 193, 196, 198, 201, 203, 206, 208, 211, |
| 161 | 213, 215, 218, 220, 222, 224, 226, 228, 230, 232, 234, 235, 237, 238, 240, |
| 162 | 241, 243, 244, 245, 246, 248, 249, 250, 250, 251, 252, 253, 253, 254, 254, |
| 163 | 254, 255, 255, 255, 255, 255, 255, 255, 254, 254, 254, 253, 253, 252, 251, |
| 164 | 250, 250, 249, 248, 246, 245, 244, 243, 241, 240, 238, 237, 235, 234, 232, |
| 165 | 230, 228, 226, 224, 222, 220, 218, 215, 213, 211, 208, 206, 203, 201, 198, |
| 166 | 196, 193, 190, 188, 185, 182, 179, 176, 173, 170, 167, 165, 162, 158, 155, |
| 167 | 152, 149, 146, 143, 140, 137, 134, 131, 128, 124, 121, 118, 115, 112, 109, |
| 168 | 106, 103, 100, 97, 93, 90, 88, 85, 82, 79, 76, 73, 70, 67, 65, |
| 169 | 62, 59, 57, 54, 52, 49, 47, 44, 42, 40, 37, 35, 33, 31, 29, |
| 170 | 27, 25, 23, 21, 20, 18, 17, 15, 14, 12, 11, 10, 9, 7, 6, |
| 171 | 5, 5, 4, 3, 2, 2, 1, 1, 1, 0, 0, 0, 0, 0, 0, |
| 172 | 0, 1, 1, 1, 2, 2, 3, 4, 5, 5, 6, 7, 9, 10, 11, |
| 173 | 12, 14, 15, 17, 18, 20, 21, 23, 25, 27, 29, 31, 33, 35, 37, |
| 174 | 40, 42, 44, 47, 49, 52, 54, 57, 59, 62, 65, 67, 70, 73, 76, |
| 175 | 79, 82, 85, 88, 90, 93, 97, 100, 103, 106, 109, 112, 115, 118, 121, |
| 176 | 124}; |
| 177 | |
| 178 | /* Similar to above, but for an 8-bit gamma-correction table. |
| 179 | Copy & paste this snippet into a Python REPL to regenerate: |
| 180 | import math |
| 181 | gamma=2.6 |
| 182 | for x in range(256): |
| 183 | print("{:3},".format(int(math.pow((x)/255.0,gamma)*255.0+0.5))), |
| 184 | if x&15 == 15: print |
| 185 | */ |
| 186 | static const uint8_t PROGMEM _NeoPixelGammaTable[256] = { |
| 187 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 188 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, |
| 189 | 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 3, |
| 190 | 3, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 5, 6, |
| 191 | 6, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10, 10, |
| 192 | 11, 11, 11, 12, 12, 13, 13, 13, 14, 14, 15, 15, 16, 16, 17, |
| 193 | 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, 23, 24, 24, 25, |
| 194 | 25, 26, 27, 27, 28, 29, 29, 30, 31, 31, 32, 33, 34, 34, 35, |
| 195 | 36, 37, 38, 38, 39, 40, 41, 42, 42, 43, 44, 45, 46, 47, 48, |
| 196 | 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, |
| 197 | 64, 65, 66, 68, 69, 70, 71, 72, 73, 75, 76, 77, 78, 80, 81, |
| 198 | 82, 84, 85, 86, 88, 89, 90, 92, 93, 94, 96, 97, 99, 100, 102, |
| 199 | 103, 105, 106, 108, 109, 111, 112, 114, 115, 117, 119, 120, 122, 124, 125, |
| 200 | 127, 129, 130, 132, 134, 136, 137, 139, 141, 143, 145, 146, 148, 150, 152, |
| 201 | 154, 156, 158, 160, 162, 164, 166, 168, 170, 172, 174, 176, 178, 180, 182, |
| 202 | 184, 186, 188, 191, 193, 195, 197, 199, 202, 204, 206, 209, 211, 213, 215, |
| 203 | 218, 220, 223, 225, 227, 230, 232, 235, 237, 240, 242, 245, 247, 250, 252, |
| 204 | 255}; |
| 205 | |
| 206 | /* Declare external methods required by the Adafruit_NeoPixel implementation |
| 207 | for specific hardware/library versions |
| 208 | */ |
| 209 | #if defined(ESP32) |
| 210 | #if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0) |
| 211 | extern "C" void espInit(); |
| 212 | #endif |
| 213 | #endif |
| 214 | |
| 215 | /*! |
| 216 | @brief Class that stores state and functions for interacting with |
| 217 | Adafruit NeoPixels and compatible devices. |
| 218 | */ |
| 219 | class Adafruit_NeoPixel { |
| 220 | |
| 221 | public: |
| 222 | // Constructor: number of LEDs, pin number, LED type |
| 223 | Adafruit_NeoPixel(uint16_t n, int16_t pin = 6, |
| 224 | neoPixelType type = NEO_GRB + NEO_KHZ800); |
| 225 | Adafruit_NeoPixel(void); |
| 226 | ~Adafruit_NeoPixel(); |
| 227 | |
| 228 | bool begin(void); |
| 229 | void show(void); |
| 230 | void setPin(int16_t p); |
| 231 | void setPixelColor(uint16_t n, uint8_t r, uint8_t g, uint8_t b); |
| 232 | void setPixelColor(uint16_t n, uint8_t r, uint8_t g, uint8_t b, uint8_t w); |
| 233 | void setPixelColor(uint16_t n, uint32_t c); |
| 234 | void fill(uint32_t c = 0, uint16_t first = 0, uint16_t count = 0); |
| 235 | void setBrightness(uint8_t); |
| 236 | void clear(void); |
| 237 | void updateLength(uint16_t n); |
| 238 | void updateType(neoPixelType t); |
| 239 | /*! |
| 240 | @brief Check whether a call to show() will start sending data |
| 241 | immediately or will 'block' for a required interval. NeoPixels |
| 242 | require a short quiet time (about 300 microseconds) after the |
| 243 | last bit is received before the data 'latches' and new data can |
| 244 | start being received. Usually one's sketch is implicitly using |
| 245 | this time to generate a new frame of animation...but if it |
| 246 | finishes very quickly, this function could be used to see if |
| 247 | there's some idle time available for some low-priority |
| 248 | concurrent task. |
| 249 | @return 1 or true if show() will start sending immediately, 0 or false |
| 250 | if show() would block (meaning some idle time is available). |
| 251 | */ |
| 252 | bool canShow(void) { |
| 253 | // It's normal and possible for endTime to exceed micros() if the |
| 254 | // 32-bit clock counter has rolled over (about every 70 minutes). |
| 255 | // Since both are uint32_t, a negative delta correctly maps back to |
| 256 | // positive space, and it would seem like the subtraction below would |
| 257 | // suffice. But a problem arises if code invokes show() very |
| 258 | // infrequently...the micros() counter may roll over MULTIPLE times in |
| 259 | // that interval, the delta calculation is no longer correct and the |
| 260 | // next update may stall for a very long time. The check below resets |
| 261 | // the latch counter if a rollover has occurred. This can cause an |
| 262 | // extra delay of up to 300 microseconds in the rare case where a |
| 263 | // show() call happens precisely around the rollover, but that's |
| 264 | // neither likely nor especially harmful, vs. other code that might |
| 265 | // stall for 30+ minutes, or having to document and frequently remind |
| 266 | // and/or provide tech support explaining an unintuitive need for |
| 267 | // show() calls at least once an hour. |
| 268 | uint32_t now = micros(); |
| 269 | if (endTime > now) { |
| 270 | endTime = now; |
| 271 | } |
| 272 | return (now - endTime) >= 300L; |
| 273 | } |
| 274 | /*! |
| 275 | @brief Get a pointer directly to the NeoPixel data buffer in RAM. |
| 276 | Pixel data is stored in a device-native format (a la the NEO_* |
| 277 | constants) and is not translated here. Applications that access |
| 278 | this buffer will need to be aware of the specific data format |
| 279 | and handle colors appropriately. |
| 280 | @return Pointer to NeoPixel buffer (uint8_t* array). |
| 281 | @note This is for high-performance applications where calling |
| 282 | setPixelColor() on every single pixel would be too slow (e.g. |
| 283 | POV or light-painting projects). There is no bounds checking |
| 284 | on the array, creating tremendous potential for mayhem if one |
| 285 | writes past the ends of the buffer. Great power, great |
| 286 | responsibility and all that. |
| 287 | */ |
| 288 | uint8_t *getPixels(void) const { return pixels; }; |
| 289 | uint8_t getBrightness(void) const; |
| 290 | /*! |
| 291 | @brief Retrieve the pin number used for NeoPixel data output. |
| 292 | @return Arduino pin number (-1 if not set). |
| 293 | */ |
| 294 | int16_t getPin(void) const { return pin; }; |
| 295 | /*! |
| 296 | @brief Return the number of pixels in an Adafruit_NeoPixel strip object. |
| 297 | @return Pixel count (0 if not set). |
| 298 | */ |
| 299 | uint16_t numPixels(void) const { return numLEDs; } |
| 300 | uint32_t getPixelColor(uint16_t n) const; |
| 301 | /*! |
| 302 | @brief An 8-bit integer sine wave function, not directly compatible |
| 303 | with standard trigonometric units like radians or degrees. |
| 304 | @param x Input angle, 0-255; 256 would loop back to zero, completing |
| 305 | the circle (equivalent to 360 degrees or 2 pi radians). |
| 306 | One can therefore use an unsigned 8-bit variable and simply |
| 307 | add or subtract, allowing it to overflow/underflow and it |
| 308 | still does the expected contiguous thing. |
| 309 | @return Sine result, 0 to 255, or -128 to +127 if type-converted to |
| 310 | a signed int8_t, but you'll most likely want unsigned as this |
| 311 | output is often used for pixel brightness in animation effects. |
| 312 | */ |
| 313 | static uint8_t sine8(uint8_t x) { |
| 314 | return pgm_read_byte(&_NeoPixelSineTable[x]); // 0-255 in, 0-255 out |
| 315 | } |
| 316 | /*! |
| 317 | @brief An 8-bit gamma-correction function for basic pixel brightness |
| 318 | adjustment. Makes color transitions appear more perceptially |
| 319 | correct. |
| 320 | @param x Input brightness, 0 (minimum or off/black) to 255 (maximum). |
| 321 | @return Gamma-adjusted brightness, can then be passed to one of the |
| 322 | setPixelColor() functions. This uses a fixed gamma correction |
| 323 | exponent of 2.6, which seems reasonably okay for average |
| 324 | NeoPixels in average tasks. If you need finer control you'll |
| 325 | need to provide your own gamma-correction function instead. |
| 326 | */ |
| 327 | static uint8_t gamma8(uint8_t x) { |
| 328 | return pgm_read_byte(&_NeoPixelGammaTable[x]); // 0-255 in, 0-255 out |
| 329 | } |
| 330 | /*! |
| 331 | @brief Convert separate red, green and blue values into a single |
| 332 | "packed" 32-bit RGB color. |
| 333 | @param r Red brightness, 0 to 255. |
| 334 | @param g Green brightness, 0 to 255. |
| 335 | @param b Blue brightness, 0 to 255. |
| 336 | @return 32-bit packed RGB value, which can then be assigned to a |
| 337 | variable for later use or passed to the setPixelColor() |
| 338 | function. Packed RGB format is predictable, regardless of |
| 339 | LED strand color order. |
| 340 | */ |
| 341 | static uint32_t Color(uint8_t r, uint8_t g, uint8_t b) { |
| 342 | return ((uint32_t)r << 16) | ((uint32_t)g << 8) | b; |
| 343 | } |
| 344 | /*! |
| 345 | @brief Convert separate red, green, blue and white values into a |
| 346 | single "packed" 32-bit WRGB color. |
| 347 | @param r Red brightness, 0 to 255. |
| 348 | @param g Green brightness, 0 to 255. |
| 349 | @param b Blue brightness, 0 to 255. |
| 350 | @param w White brightness, 0 to 255. |
| 351 | @return 32-bit packed WRGB value, which can then be assigned to a |
| 352 | variable for later use or passed to the setPixelColor() |
| 353 | function. Packed WRGB format is predictable, regardless of |
| 354 | LED strand color order. |
| 355 | */ |
| 356 | static uint32_t Color(uint8_t r, uint8_t g, uint8_t b, uint8_t w) { |
| 357 | return ((uint32_t)w << 24) | ((uint32_t)r << 16) | ((uint32_t)g << 8) | |
| 358 | b; |
| 359 | } |
| 360 | static uint32_t ColorHSV(uint16_t hue, uint8_t sat = 255, |
| 361 | uint8_t val = 255); |
| 362 | /*! |
| 363 | @brief A gamma-correction function for 32-bit packed RGB or WRGB |
| 364 | colors. Makes color transitions appear more perceptially |
| 365 | correct. |
| 366 | @param x 32-bit packed RGB or WRGB color. |
| 367 | @return Gamma-adjusted packed color, can then be passed in one of the |
| 368 | setPixelColor() functions. Like gamma8(), this uses a fixed |
| 369 | gamma correction exponent of 2.6, which seems reasonably okay |
| 370 | for average NeoPixels in average tasks. If you need finer |
| 371 | control you'll need to provide your own gamma-correction |
| 372 | function instead. |
| 373 | */ |
| 374 | static uint32_t gamma32(uint32_t x); |
| 375 | |
| 376 | void rainbow(uint16_t first_hue = 0, int8_t reps = 1, |
| 377 | uint8_t saturation = 255, uint8_t brightness = 255, |
| 378 | bool gammify = true); |
| 379 | |
| 380 | static neoPixelType str2order(const char *v); |
| 381 | |
| 382 | private: |
| 383 | #if defined(ARDUINO_ARCH_RP2040) |
| 384 | bool rp2040claimPIO(void); |
| 385 | void rp2040releasePIO(void); |
| 386 | void rp2040Show(uint8_t *pixels, uint32_t numBytes); |
| 387 | PIO pio = NULL; |
| 388 | uint pio_sm = -1; |
| 389 | uint pio_program_offset = 0; |
| 390 | #endif |
| 391 | |
| 392 | protected: |
| 393 | #ifdef NEO_KHZ400 // If 400 KHz NeoPixel support enabled... |
| 394 | bool is800KHz; ///< true if 800 KHz pixels |
| 395 | #endif |
| 396 | |
| 397 | bool begun; ///< true if begin() previously called successfully |
| 398 | uint16_t numLEDs; ///< Number of RGB LEDs in strip |
| 399 | uint16_t numBytes; ///< Size of 'pixels' buffer below |
| 400 | int16_t pin; ///< Output pin number (-1 if not yet set) |
| 401 | uint8_t brightness; ///< Strip brightness 0-255 (stored as +1) |
| 402 | uint8_t *pixels; ///< Holds LED color values (3 or 4 bytes each) |
| 403 | uint8_t rOffset; ///< Red index within each 3- or 4-byte pixel |
| 404 | uint8_t gOffset; ///< Index of green byte |
| 405 | uint8_t bOffset; ///< Index of blue byte |
| 406 | uint8_t wOffset; ///< Index of white (==rOffset if no white) |
| 407 | uint32_t endTime; ///< Latch timing reference |
| 408 | |
| 409 | #ifdef __AVR__ |
| 410 | volatile uint8_t *port; ///< Output PORT register |
| 411 | uint8_t pinMask; ///< Output PORT bitmask |
| 412 | #endif |
| 413 | |
| 414 | #if defined(ARDUINO_ARCH_STM32) || defined(ARDUINO_ARCH_ARDUINO_CORE_STM32) || \ |
| 415 | defined(ARDUINO_ARCH_CH32) || defined(_PY32_DEF_) |
| 416 | GPIO_TypeDef *gpioPort; ///< Output GPIO PORT |
| 417 | uint32_t gpioPin; ///< Output GPIO PIN |
| 418 | #endif |
| 419 | }; |
| 420 | |
| 421 | #endif // ADAFRUIT_NEOPIXEL_H |