├── .github ├── ISSUE_TEMPLATE.md ├── PULL_REQUEST_TEMPLATE.md └── workflows │ └── githubci.yml ├── .gitignore ├── Adafruit_NeoPixel.cpp ├── Adafruit_NeoPixel.h ├── Adafruit_Neopixel_RP2.cpp ├── CONTRIBUTING.md ├── COPYING ├── README.md ├── esp.c ├── esp8266.c ├── examples ├── RGBWstrandtest │ ├── .esp8266.test.skip │ ├── .trinket.test.skip │ └── RGBWstrandtest.ino ├── StrandtestArduinoBLE │ ├── .none.test.only │ └── StrandtestArduinoBLE.ino ├── StrandtestArduinoBLECallback │ ├── .none.test.only │ └── StrandtestArduinoBLECallback.ino ├── StrandtestBLE │ ├── .none.test.only │ ├── BLESerial.cpp │ ├── BLESerial.h │ └── StrandtestBLE.ino ├── StrandtestBLE_nodelay │ ├── .none.test.only │ ├── BLESerial.cpp │ ├── BLESerial.h │ └── StrandtestBLE_nodelay.ino ├── buttoncycler │ ├── .esp8266.test.skip │ └── buttoncycler.ino ├── simple │ ├── .esp8266.test.skip │ └── simple.ino ├── simple_new_operator │ ├── .esp8266.test.skip │ └── simple_new_operator.ino ├── strandtest │ ├── .esp8266.test.skip │ └── strandtest.ino ├── strandtest_nodelay │ ├── .esp8266.test.skip │ └── strandtest_nodelay.ino └── strandtest_wheel │ ├── .esp8266.test.skip │ └── strandtest_wheel.ino ├── kendyte_k210.c ├── keywords.txt ├── library.properties └── rp2040_pio.h /.github/ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | Thank you for opening an issue on an Adafruit Arduino library repository. To 2 | improve the speed of resolution please review the following guidelines and 3 | common troubleshooting steps below before creating the issue: 4 | 5 | - **Do not use GitHub issues for troubleshooting projects and issues.** Instead use 6 | the forums at http://forums.adafruit.com to ask questions and troubleshoot why 7 | something isn't working as expected. In many cases the problem is a common issue 8 | that you will more quickly receive help from the forum community. GitHub issues 9 | are meant for known defects in the code. If you don't know if there is a defect 10 | in the code then start with troubleshooting on the forum first. 11 | 12 | - **If following a tutorial or guide be sure you didn't miss a step.** Carefully 13 | check all of the steps and commands to run have been followed. Consult the 14 | forum if you're unsure or have questions about steps in a guide/tutorial. 15 | 16 | - **For Arduino projects check these very common issues to ensure they don't apply**: 17 | 18 | - For uploading sketches or communicating with the board make sure you're using 19 | a **USB data cable** and **not** a **USB charge-only cable**. It is sometimes 20 | very hard to tell the difference between a data and charge cable! Try using the 21 | cable with other devices or swapping to another cable to confirm it is not 22 | the problem. 23 | 24 | - **Be sure you are supplying adequate power to the board.** Check the specs of 25 | your board and plug in an external power supply. In many cases just 26 | plugging a board into your computer is not enough to power it and other 27 | peripherals. 28 | 29 | - **Double check all soldering joints and connections.** Flakey connections 30 | cause many mysterious problems. See the [guide to excellent soldering](https://learn.adafruit.com/adafruit-guide-excellent-soldering/tools) for examples of good solder joints. 31 | 32 | - **Ensure you are using an official Arduino or Adafruit board.** We can't 33 | guarantee a clone board will have the same functionality and work as expected 34 | with this code and don't support them. 35 | 36 | If you're sure this issue is a defect in the code and checked the steps above 37 | please fill in the following fields to provide enough troubleshooting information. 38 | You may delete the guideline and text above to just leave the following details: 39 | 40 | - Arduino board: **INSERT ARDUINO BOARD NAME/TYPE HERE** 41 | 42 | - Arduino IDE version (found in Arduino -> About Arduino menu): **INSERT ARDUINO 43 | VERSION HERE** 44 | 45 | - List the steps to reproduce the problem below (if possible attach a sketch or 46 | copy the sketch code in too): **LIST REPRO STEPS BELOW** 47 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | Thank you for creating a pull request to contribute to Adafruit's GitHub code! 2 | Before you open the request please review the following guidelines and tips to 3 | help it be more easily integrated: 4 | 5 | - **Describe the scope of your change--i.e. what the change does and what parts 6 | of the code were modified.** This will help us understand any risks of integrating 7 | the code. 8 | 9 | - **Describe any known limitations with your change.** For example if the change 10 | doesn't apply to a supported platform of the library please mention it. 11 | 12 | - **Please run any tests or examples that can exercise your modified code.** We 13 | strive to not break users of the code and running tests/examples helps with this 14 | process. 15 | 16 | Thank you again for contributing! We will try to test and integrate the change 17 | as soon as we can, but be aware we have many GitHub repositories to manage and 18 | can't immediately respond to every request. There is no need to bump or check in 19 | on a pull request (it will clutter the discussion of the request). 20 | 21 | Also don't be worried if the request is closed or not integrated--sometimes the 22 | priorities of Adafruit's GitHub code (education, ease of use) might not match the 23 | priorities of the pull request. Don't fret, the open source community thrives on 24 | forks and GitHub makes it easy to keep your changes in a forked repo. 25 | 26 | After reviewing the guidelines above you can delete this text from the pull request. 27 | -------------------------------------------------------------------------------- /.github/workflows/githubci.yml: -------------------------------------------------------------------------------- 1 | name: Arduino Library CI 2 | 3 | on: [pull_request, push, repository_dispatch] 4 | 5 | jobs: 6 | build: 7 | runs-on: ubuntu-latest 8 | 9 | steps: 10 | - uses: actions/setup-python@v4 11 | with: 12 | python-version: '3.x' 13 | - uses: actions/checkout@v3 14 | - uses: actions/checkout@v3 15 | with: 16 | repository: adafruit/ci-arduino 17 | path: ci 18 | 19 | - name: pre-install 20 | run: bash ci/actions_install.sh 21 | 22 | - name: test platforms 23 | run: python3 ci/build_platform.py main_platforms giga 24 | 25 | - name: doxygen 26 | env: 27 | GH_REPO_TOKEN: ${{ secrets.GH_REPO_TOKEN }} 28 | PRETTYNAME : "Adafruit NeoPixel Library" 29 | run: bash ci/doxy_gen_and_deploy.sh 30 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Our handy .gitignore for automation ease 2 | Doxyfile* 3 | doxygen_sqlite3.db 4 | html 5 | -------------------------------------------------------------------------------- /Adafruit_NeoPixel.h: -------------------------------------------------------------------------------- 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 | * . 33 | * 34 | */ 35 | 36 | #ifndef ADAFRUIT_NEOPIXEL_H 37 | #define ADAFRUIT_NEOPIXEL_H 38 | 39 | #ifdef ARDUINO 40 | #include 41 | 42 | #ifdef USE_TINYUSB // For Serial when selecting TinyUSB 43 | #include 44 | #endif 45 | 46 | #endif 47 | 48 | #ifdef TARGET_LPC1768 49 | #include 50 | #endif 51 | 52 | #if defined(TARGET_GIGA) || defined(TARGET_M4) 53 | #include "mbed.h" 54 | #include "pinDefinitions.h" 55 | #endif 56 | 57 | #if defined(ARDUINO_ARCH_RP2040) 58 | #include 59 | #include "hardware/pio.h" 60 | #include "hardware/clocks.h" 61 | #include "rp2040_pio.h" 62 | #endif 63 | 64 | // The order of primary colors in the NeoPixel data stream can vary among 65 | // device types, manufacturers and even different revisions of the same 66 | // item. The third parameter to the Adafruit_NeoPixel constructor encodes 67 | // the per-pixel byte offsets of the red, green and blue primaries (plus 68 | // white, if present) in the data stream -- the following #defines provide 69 | // an easier-to-use named version for each permutation. e.g. NEO_GRB 70 | // indicates a NeoPixel-compatible device expecting three bytes per pixel, 71 | // with the first byte transmitted containing the green value, second 72 | // containing red and third containing blue. The in-memory representation 73 | // of a chain of NeoPixels is the same as the data-stream order; no 74 | // re-ordering of bytes is required when issuing data to the chain. 75 | // Most of these values won't exist in real-world devices, but it's done 76 | // this way so we're ready for it (also, if using the WS2811 driver IC, 77 | // one might have their pixels set up in any weird permutation). 78 | 79 | // Bits 5,4 of this value are the offset (0-3) from the first byte of a 80 | // pixel to the location of the red color byte. Bits 3,2 are the green 81 | // offset and 1,0 are the blue offset. If it is an RGBW-type device 82 | // (supporting a white primary in addition to R,G,B), bits 7,6 are the 83 | // offset to the white byte...otherwise, bits 7,6 are set to the same value 84 | // as 5,4 (red) to indicate an RGB (not RGBW) device. 85 | // i.e. binary representation: 86 | // 0bWWRRGGBB for RGBW devices 87 | // 0bRRRRGGBB for RGB 88 | 89 | // RGB NeoPixel permutations; white and red offsets are always same 90 | // Offset: W R G B 91 | #define NEO_RGB ((0 << 6) | (0 << 4) | (1 << 2) | (2)) ///< Transmit as R,G,B 92 | #define NEO_RBG ((0 << 6) | (0 << 4) | (2 << 2) | (1)) ///< Transmit as R,B,G 93 | #define NEO_GRB ((1 << 6) | (1 << 4) | (0 << 2) | (2)) ///< Transmit as G,R,B 94 | #define NEO_GBR ((2 << 6) | (2 << 4) | (0 << 2) | (1)) ///< Transmit as G,B,R 95 | #define NEO_BRG ((1 << 6) | (1 << 4) | (2 << 2) | (0)) ///< Transmit as B,R,G 96 | #define NEO_BGR ((2 << 6) | (2 << 4) | (1 << 2) | (0)) ///< Transmit as B,G,R 97 | 98 | // RGBW NeoPixel permutations; all 4 offsets are distinct 99 | // Offset: W R G B 100 | #define NEO_WRGB ((0 << 6) | (1 << 4) | (2 << 2) | (3)) ///< Transmit as W,R,G,B 101 | #define NEO_WRBG ((0 << 6) | (1 << 4) | (3 << 2) | (2)) ///< Transmit as W,R,B,G 102 | #define NEO_WGRB ((0 << 6) | (2 << 4) | (1 << 2) | (3)) ///< Transmit as W,G,R,B 103 | #define NEO_WGBR ((0 << 6) | (3 << 4) | (1 << 2) | (2)) ///< Transmit as W,G,B,R 104 | #define NEO_WBRG ((0 << 6) | (2 << 4) | (3 << 2) | (1)) ///< Transmit as W,B,R,G 105 | #define NEO_WBGR ((0 << 6) | (3 << 4) | (2 << 2) | (1)) ///< Transmit as W,B,G,R 106 | 107 | #define NEO_RWGB ((1 << 6) | (0 << 4) | (2 << 2) | (3)) ///< Transmit as R,W,G,B 108 | #define NEO_RWBG ((1 << 6) | (0 << 4) | (3 << 2) | (2)) ///< Transmit as R,W,B,G 109 | #define NEO_RGWB ((2 << 6) | (0 << 4) | (1 << 2) | (3)) ///< Transmit as R,G,W,B 110 | #define NEO_RGBW ((3 << 6) | (0 << 4) | (1 << 2) | (2)) ///< Transmit as R,G,B,W 111 | #define NEO_RBWG ((2 << 6) | (0 << 4) | (3 << 2) | (1)) ///< Transmit as R,B,W,G 112 | #define NEO_RBGW ((3 << 6) | (0 << 4) | (2 << 2) | (1)) ///< Transmit as R,B,G,W 113 | 114 | #define NEO_GWRB ((1 << 6) | (2 << 4) | (0 << 2) | (3)) ///< Transmit as G,W,R,B 115 | #define NEO_GWBR ((1 << 6) | (3 << 4) | (0 << 2) | (2)) ///< Transmit as G,W,B,R 116 | #define NEO_GRWB ((2 << 6) | (1 << 4) | (0 << 2) | (3)) ///< Transmit as G,R,W,B 117 | #define NEO_GRBW ((3 << 6) | (1 << 4) | (0 << 2) | (2)) ///< Transmit as G,R,B,W 118 | #define NEO_GBWR ((2 << 6) | (3 << 4) | (0 << 2) | (1)) ///< Transmit as G,B,W,R 119 | #define NEO_GBRW ((3 << 6) | (2 << 4) | (0 << 2) | (1)) ///< Transmit as G,B,R,W 120 | 121 | #define NEO_BWRG ((1 << 6) | (2 << 4) | (3 << 2) | (0)) ///< Transmit as B,W,R,G 122 | #define NEO_BWGR ((1 << 6) | (3 << 4) | (2 << 2) | (0)) ///< Transmit as B,W,G,R 123 | #define NEO_BRWG ((2 << 6) | (1 << 4) | (3 << 2) | (0)) ///< Transmit as B,R,W,G 124 | #define NEO_BRGW ((3 << 6) | (1 << 4) | (2 << 2) | (0)) ///< Transmit as B,R,G,W 125 | #define NEO_BGWR ((2 << 6) | (3 << 4) | (1 << 2) | (0)) ///< Transmit as B,G,W,R 126 | #define NEO_BGRW ((3 << 6) | (2 << 4) | (1 << 2) | (0)) ///< Transmit as B,G,R,W 127 | 128 | // Add NEO_KHZ400 to the color order value to indicate a 400 KHz device. 129 | // All but the earliest v1 NeoPixels expect an 800 KHz data stream, this is 130 | // the default if unspecified. Because flash space is very limited on ATtiny 131 | // devices (e.g. Trinket, Gemma), v1 NeoPixels aren't handled by default on 132 | // those chips, though it can be enabled by removing the ifndef/endif below, 133 | // but code will be bigger. Conversely, can disable the NEO_KHZ400 line on 134 | // other MCUs to remove v1 support and save a little space. 135 | 136 | #define NEO_KHZ800 0x0000 ///< 800 KHz data transmission 137 | #ifndef __AVR_ATtiny85__ 138 | #define NEO_KHZ400 0x0100 ///< 400 KHz data transmission 139 | #endif 140 | 141 | // If 400 KHz support is enabled, the third parameter to the constructor 142 | // requires a 16-bit value (in order to select 400 vs 800 KHz speed). 143 | // If only 800 KHz is enabled (as is default on ATtiny), an 8-bit value 144 | // is sufficient to encode pixel color order, saving some space. 145 | 146 | #ifdef NEO_KHZ400 147 | typedef uint16_t neoPixelType; ///< 3rd arg to Adafruit_NeoPixel constructor 148 | #else 149 | typedef uint8_t neoPixelType; ///< 3rd arg to Adafruit_NeoPixel constructor 150 | #endif 151 | 152 | // These two tables are declared outside the Adafruit_NeoPixel class 153 | // because some boards may require oldschool compilers that don't 154 | // handle the C++11 constexpr keyword. 155 | 156 | /* A PROGMEM (flash mem) table containing 8-bit unsigned sine wave (0-255). 157 | Copy & paste this snippet into a Python REPL to regenerate: 158 | import math 159 | for x in range(256): 160 | print("{:3},".format(int((math.sin(x/128.0*math.pi)+1.0)*127.5+0.5))), 161 | if x&15 == 15: print 162 | */ 163 | static const uint8_t PROGMEM _NeoPixelSineTable[256] = { 164 | 128, 131, 134, 137, 140, 143, 146, 149, 152, 155, 158, 162, 165, 167, 170, 165 | 173, 176, 179, 182, 185, 188, 190, 193, 196, 198, 201, 203, 206, 208, 211, 166 | 213, 215, 218, 220, 222, 224, 226, 228, 230, 232, 234, 235, 237, 238, 240, 167 | 241, 243, 244, 245, 246, 248, 249, 250, 250, 251, 252, 253, 253, 254, 254, 168 | 254, 255, 255, 255, 255, 255, 255, 255, 254, 254, 254, 253, 253, 252, 251, 169 | 250, 250, 249, 248, 246, 245, 244, 243, 241, 240, 238, 237, 235, 234, 232, 170 | 230, 228, 226, 224, 222, 220, 218, 215, 213, 211, 208, 206, 203, 201, 198, 171 | 196, 193, 190, 188, 185, 182, 179, 176, 173, 170, 167, 165, 162, 158, 155, 172 | 152, 149, 146, 143, 140, 137, 134, 131, 128, 124, 121, 118, 115, 112, 109, 173 | 106, 103, 100, 97, 93, 90, 88, 85, 82, 79, 76, 73, 70, 67, 65, 174 | 62, 59, 57, 54, 52, 49, 47, 44, 42, 40, 37, 35, 33, 31, 29, 175 | 27, 25, 23, 21, 20, 18, 17, 15, 14, 12, 11, 10, 9, 7, 6, 176 | 5, 5, 4, 3, 2, 2, 1, 1, 1, 0, 0, 0, 0, 0, 0, 177 | 0, 1, 1, 1, 2, 2, 3, 4, 5, 5, 6, 7, 9, 10, 11, 178 | 12, 14, 15, 17, 18, 20, 21, 23, 25, 27, 29, 31, 33, 35, 37, 179 | 40, 42, 44, 47, 49, 52, 54, 57, 59, 62, 65, 67, 70, 73, 76, 180 | 79, 82, 85, 88, 90, 93, 97, 100, 103, 106, 109, 112, 115, 118, 121, 181 | 124}; 182 | 183 | /* Similar to above, but for an 8-bit gamma-correction table. 184 | Copy & paste this snippet into a Python REPL to regenerate: 185 | import math 186 | gamma=2.6 187 | for x in range(256): 188 | print("{:3},".format(int(math.pow((x)/255.0,gamma)*255.0+0.5))), 189 | if x&15 == 15: print 190 | */ 191 | static const uint8_t PROGMEM _NeoPixelGammaTable[256] = { 192 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 193 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 194 | 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 3, 195 | 3, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 5, 6, 196 | 6, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10, 10, 197 | 11, 11, 11, 12, 12, 13, 13, 13, 14, 14, 15, 15, 16, 16, 17, 198 | 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, 23, 24, 24, 25, 199 | 25, 26, 27, 27, 28, 29, 29, 30, 31, 31, 32, 33, 34, 34, 35, 200 | 36, 37, 38, 38, 39, 40, 41, 42, 42, 43, 44, 45, 46, 47, 48, 201 | 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 202 | 64, 65, 66, 68, 69, 70, 71, 72, 73, 75, 76, 77, 78, 80, 81, 203 | 82, 84, 85, 86, 88, 89, 90, 92, 93, 94, 96, 97, 99, 100, 102, 204 | 103, 105, 106, 108, 109, 111, 112, 114, 115, 117, 119, 120, 122, 124, 125, 205 | 127, 129, 130, 132, 134, 136, 137, 139, 141, 143, 145, 146, 148, 150, 152, 206 | 154, 156, 158, 160, 162, 164, 166, 168, 170, 172, 174, 176, 178, 180, 182, 207 | 184, 186, 188, 191, 193, 195, 197, 199, 202, 204, 206, 209, 211, 213, 215, 208 | 218, 220, 223, 225, 227, 230, 232, 235, 237, 240, 242, 245, 247, 250, 252, 209 | 255}; 210 | 211 | /* Declare external methods required by the Adafruit_NeoPixel implementation 212 | for specific hardware/library versions 213 | */ 214 | #if defined(ESP32) 215 | #if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0) 216 | extern "C" void espInit(); 217 | #endif 218 | #endif 219 | 220 | /*! 221 | @brief Class that stores state and functions for interacting with 222 | Adafruit NeoPixels and compatible devices. 223 | */ 224 | class Adafruit_NeoPixel { 225 | 226 | public: 227 | // Constructor: number of LEDs, pin number, LED type 228 | Adafruit_NeoPixel(uint16_t n, int16_t pin = 6, 229 | neoPixelType type = NEO_GRB + NEO_KHZ800); 230 | Adafruit_NeoPixel(void); 231 | ~Adafruit_NeoPixel(); 232 | 233 | bool begin(void); 234 | void show(void); 235 | void setPin(int16_t p); 236 | void setPixelColor(uint16_t n, uint8_t r, uint8_t g, uint8_t b); 237 | void setPixelColor(uint16_t n, uint8_t r, uint8_t g, uint8_t b, uint8_t w); 238 | void setPixelColor(uint16_t n, uint32_t c); 239 | void fill(uint32_t c = 0, uint16_t first = 0, uint16_t count = 0); 240 | void setBrightness(uint8_t); 241 | void clear(void); 242 | void updateLength(uint16_t n); 243 | void updateType(neoPixelType t); 244 | /*! 245 | @brief Check whether a call to show() will start sending data 246 | immediately or will 'block' for a required interval. NeoPixels 247 | require a short quiet time (about 300 microseconds) after the 248 | last bit is received before the data 'latches' and new data can 249 | start being received. Usually one's sketch is implicitly using 250 | this time to generate a new frame of animation...but if it 251 | finishes very quickly, this function could be used to see if 252 | there's some idle time available for some low-priority 253 | concurrent task. 254 | @return 1 or true if show() will start sending immediately, 0 or false 255 | if show() would block (meaning some idle time is available). 256 | */ 257 | bool canShow(void) { 258 | // It's normal and possible for endTime to exceed micros() if the 259 | // 32-bit clock counter has rolled over (about every 70 minutes). 260 | // Since both are uint32_t, a negative delta correctly maps back to 261 | // positive space, and it would seem like the subtraction below would 262 | // suffice. But a problem arises if code invokes show() very 263 | // infrequently...the micros() counter may roll over MULTIPLE times in 264 | // that interval, the delta calculation is no longer correct and the 265 | // next update may stall for a very long time. The check below resets 266 | // the latch counter if a rollover has occurred. This can cause an 267 | // extra delay of up to 300 microseconds in the rare case where a 268 | // show() call happens precisely around the rollover, but that's 269 | // neither likely nor especially harmful, vs. other code that might 270 | // stall for 30+ minutes, or having to document and frequently remind 271 | // and/or provide tech support explaining an unintuitive need for 272 | // show() calls at least once an hour. 273 | uint32_t now = micros(); 274 | if (endTime > now) { 275 | endTime = now; 276 | } 277 | return (now - endTime) >= 300L; 278 | } 279 | /*! 280 | @brief Get a pointer directly to the NeoPixel data buffer in RAM. 281 | Pixel data is stored in a device-native format (a la the NEO_* 282 | constants) and is not translated here. Applications that access 283 | this buffer will need to be aware of the specific data format 284 | and handle colors appropriately. 285 | @return Pointer to NeoPixel buffer (uint8_t* array). 286 | @note This is for high-performance applications where calling 287 | setPixelColor() on every single pixel would be too slow (e.g. 288 | POV or light-painting projects). There is no bounds checking 289 | on the array, creating tremendous potential for mayhem if one 290 | writes past the ends of the buffer. Great power, great 291 | responsibility and all that. 292 | */ 293 | uint8_t *getPixels(void) const { return pixels; }; 294 | uint8_t getBrightness(void) const; 295 | /*! 296 | @brief Retrieve the pin number used for NeoPixel data output. 297 | @return Arduino pin number (-1 if not set). 298 | */ 299 | int16_t getPin(void) const { return pin; }; 300 | /*! 301 | @brief Return the number of pixels in an Adafruit_NeoPixel strip object. 302 | @return Pixel count (0 if not set). 303 | */ 304 | uint16_t numPixels(void) const { return numLEDs; } 305 | uint32_t getPixelColor(uint16_t n) const; 306 | /*! 307 | @brief An 8-bit integer sine wave function, not directly compatible 308 | with standard trigonometric units like radians or degrees. 309 | @param x Input angle, 0-255; 256 would loop back to zero, completing 310 | the circle (equivalent to 360 degrees or 2 pi radians). 311 | One can therefore use an unsigned 8-bit variable and simply 312 | add or subtract, allowing it to overflow/underflow and it 313 | still does the expected contiguous thing. 314 | @return Sine result, 0 to 255, or -128 to +127 if type-converted to 315 | a signed int8_t, but you'll most likely want unsigned as this 316 | output is often used for pixel brightness in animation effects. 317 | */ 318 | static uint8_t sine8(uint8_t x) { 319 | return pgm_read_byte(&_NeoPixelSineTable[x]); // 0-255 in, 0-255 out 320 | } 321 | /*! 322 | @brief An 8-bit gamma-correction function for basic pixel brightness 323 | adjustment. Makes color transitions appear more perceptially 324 | correct. 325 | @param x Input brightness, 0 (minimum or off/black) to 255 (maximum). 326 | @return Gamma-adjusted brightness, can then be passed to one of the 327 | setPixelColor() functions. This uses a fixed gamma correction 328 | exponent of 2.6, which seems reasonably okay for average 329 | NeoPixels in average tasks. If you need finer control you'll 330 | need to provide your own gamma-correction function instead. 331 | */ 332 | static uint8_t gamma8(uint8_t x) { 333 | return pgm_read_byte(&_NeoPixelGammaTable[x]); // 0-255 in, 0-255 out 334 | } 335 | /*! 336 | @brief Convert separate red, green and blue values into a single 337 | "packed" 32-bit RGB color. 338 | @param r Red brightness, 0 to 255. 339 | @param g Green brightness, 0 to 255. 340 | @param b Blue brightness, 0 to 255. 341 | @return 32-bit packed RGB value, which can then be assigned to a 342 | variable for later use or passed to the setPixelColor() 343 | function. Packed RGB format is predictable, regardless of 344 | LED strand color order. 345 | */ 346 | static uint32_t Color(uint8_t r, uint8_t g, uint8_t b) { 347 | return ((uint32_t)r << 16) | ((uint32_t)g << 8) | b; 348 | } 349 | /*! 350 | @brief Convert separate red, green, blue and white values into a 351 | single "packed" 32-bit WRGB color. 352 | @param r Red brightness, 0 to 255. 353 | @param g Green brightness, 0 to 255. 354 | @param b Blue brightness, 0 to 255. 355 | @param w White brightness, 0 to 255. 356 | @return 32-bit packed WRGB value, which can then be assigned to a 357 | variable for later use or passed to the setPixelColor() 358 | function. Packed WRGB format is predictable, regardless of 359 | LED strand color order. 360 | */ 361 | static uint32_t Color(uint8_t r, uint8_t g, uint8_t b, uint8_t w) { 362 | return ((uint32_t)w << 24) | ((uint32_t)r << 16) | ((uint32_t)g << 8) | b; 363 | } 364 | static uint32_t ColorHSV(uint16_t hue, uint8_t sat = 255, uint8_t val = 255); 365 | /*! 366 | @brief A gamma-correction function for 32-bit packed RGB or WRGB 367 | colors. Makes color transitions appear more perceptially 368 | correct. 369 | @param x 32-bit packed RGB or WRGB color. 370 | @return Gamma-adjusted packed color, can then be passed in one of the 371 | setPixelColor() functions. Like gamma8(), this uses a fixed 372 | gamma correction exponent of 2.6, which seems reasonably okay 373 | for average NeoPixels in average tasks. If you need finer 374 | control you'll need to provide your own gamma-correction 375 | function instead. 376 | */ 377 | static uint32_t gamma32(uint32_t x); 378 | 379 | void rainbow(uint16_t first_hue = 0, int8_t reps = 1, 380 | uint8_t saturation = 255, uint8_t brightness = 255, 381 | bool gammify = true); 382 | 383 | static neoPixelType str2order(const char *v); 384 | 385 | private: 386 | #if defined(ARDUINO_ARCH_RP2040) 387 | bool rp2040claimPIO(void); 388 | void rp2040releasePIO(void); 389 | void rp2040Show(uint8_t *pixels, uint32_t numBytes); 390 | PIO pio = NULL; 391 | uint pio_sm = -1; 392 | uint pio_program_offset = 0; 393 | #endif 394 | 395 | protected: 396 | #ifdef NEO_KHZ400 // If 400 KHz NeoPixel support enabled... 397 | bool is800KHz; ///< true if 800 KHz pixels 398 | #endif 399 | 400 | bool begun; ///< true if begin() previously called successfully 401 | uint16_t numLEDs; ///< Number of RGB LEDs in strip 402 | uint16_t numBytes; ///< Size of 'pixels' buffer below 403 | int16_t pin; ///< Output pin number (-1 if not yet set) 404 | uint8_t brightness; ///< Strip brightness 0-255 (stored as +1) 405 | uint8_t *pixels; ///< Holds LED color values (3 or 4 bytes each) 406 | uint8_t rOffset; ///< Red index within each 3- or 4-byte pixel 407 | uint8_t gOffset; ///< Index of green byte 408 | uint8_t bOffset; ///< Index of blue byte 409 | uint8_t wOffset; ///< Index of white (==rOffset if no white) 410 | uint32_t endTime; ///< Latch timing reference 411 | 412 | #ifdef __AVR__ 413 | volatile uint8_t *port; ///< Output PORT register 414 | uint8_t pinMask; ///< Output PORT bitmask 415 | #endif 416 | 417 | #if defined(ARDUINO_ARCH_STM32) || \ 418 | defined(ARDUINO_ARCH_ARDUINO_CORE_STM32) || \ 419 | defined(ARDUINO_ARCH_CH32) || \ 420 | defined(_PY32_DEF_) 421 | GPIO_TypeDef *gpioPort; ///< Output GPIO PORT 422 | uint32_t gpioPin; ///< Output GPIO PIN 423 | #endif 424 | 425 | #if defined(TARGET_GIGA) || defined(TARGET_M4) 426 | mbed::DigitalInOut *gpio; 427 | #endif 428 | 429 | }; 430 | 431 | #endif // ADAFRUIT_NEOPIXEL_H 432 | -------------------------------------------------------------------------------- /Adafruit_Neopixel_RP2.cpp: -------------------------------------------------------------------------------- 1 | #if defined(ARDUINO_ARCH_RP2040)// RP2040 specific driver 2 | 3 | #include "Adafruit_NeoPixel.h" 4 | 5 | bool Adafruit_NeoPixel::rp2040claimPIO(void) { 6 | // Find a PIO with enough available space in its instruction memory 7 | pio = NULL; 8 | 9 | if (! pio_claim_free_sm_and_add_program_for_gpio_range(&ws2812_program, 10 | &pio, &pio_sm, &pio_program_offset, 11 | pin, 1, true)) { 12 | pio = NULL; 13 | pio_sm = -1; 14 | pio_program_offset = 0; 15 | return false; // No PIO available 16 | } 17 | 18 | // yay ok! 19 | 20 | if (is800KHz) { 21 | // 800kHz, 8 bit transfers 22 | ws2812_program_init(pio, pio_sm, pio_program_offset, pin, 800000, 8); 23 | } else { 24 | // 400kHz, 8 bit transfers 25 | ws2812_program_init(pio, pio_sm, pio_program_offset, pin, 400000, 8); 26 | } 27 | 28 | return true; 29 | } 30 | 31 | void Adafruit_NeoPixel::rp2040releasePIO(void) { 32 | if (pio == NULL) 33 | return; 34 | 35 | pio_remove_program_and_unclaim_sm(&ws2812_program, pio, pio_sm, pio_program_offset); 36 | } 37 | 38 | 39 | // Private, called from show() 40 | void Adafruit_NeoPixel::rp2040Show(uint8_t *pixels, uint32_t numBytes) 41 | { 42 | // verify we have a valid PIO and state machine 43 | if (! pio || (pio_sm < 0)) { 44 | return; 45 | } 46 | 47 | while(numBytes--) 48 | // Bits for transmission must be shifted to top 8 bits 49 | pio_sm_put_blocking(pio, pio_sm, ((uint32_t)*pixels++)<< 24); 50 | } 51 | #endif 52 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contribution Guidelines 2 | 3 | This library is the culmination of the expertise of many members of the open source community who have dedicated their time and hard work. The best way to ask for help or propose a new idea is to [create a new issue](https://github.com/adafruit/Adafruit_NeoPixel/issues/new) while creating a Pull Request with your code changes allows you to share your own innovations with the rest of the community. 4 | 5 | The following are some guidelines to observe when creating issues or PRs: 6 | 7 | - Be friendly; it is important that we can all enjoy a safe space as we are all working on the same project and it is okay for people to have different ideas 8 | 9 | - [Use code blocks](https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet#code); it helps us help you when we can read your code! On that note also refrain from pasting more than 30 lines of code in a post, instead [create a gist](https://gist.github.com/) if you need to share large snippets 10 | 11 | - Use reasonable titles; refrain from using overly long or capitalized titles as they are usually annoying and do little to encourage others to help :smile: 12 | 13 | - Be detailed; refrain from mentioning code problems without sharing your source code and always give information regarding your board and version of the library 14 | -------------------------------------------------------------------------------- /COPYING: -------------------------------------------------------------------------------- 1 | GNU LESSER GENERAL PUBLIC LICENSE 2 | Version 3, 29 June 2007 3 | 4 | Copyright (C) 2007 Free Software Foundation, Inc. 5 | Everyone is permitted to copy and distribute verbatim copies 6 | of this license document, but changing it is not allowed. 7 | 8 | 9 | This version of the GNU Lesser General Public License incorporates 10 | the terms and conditions of version 3 of the GNU General Public 11 | License, supplemented by the additional permissions listed below. 12 | 13 | 0. Additional Definitions. 14 | 15 | As used herein, "this License" refers to version 3 of the GNU Lesser 16 | General Public License, and the "GNU GPL" refers to version 3 of the GNU 17 | General Public License. 18 | 19 | "The Library" refers to a covered work governed by this License, 20 | other than an Application or a Combined Work as defined below. 21 | 22 | An "Application" is any work that makes use of an interface provided 23 | by the Library, but which is not otherwise based on the Library. 24 | Defining a subclass of a class defined by the Library is deemed a mode 25 | of using an interface provided by the Library. 26 | 27 | A "Combined Work" is a work produced by combining or linking an 28 | Application with the Library. The particular version of the Library 29 | with which the Combined Work was made is also called the "Linked 30 | Version". 31 | 32 | The "Minimal Corresponding Source" for a Combined Work means the 33 | Corresponding Source for the Combined Work, excluding any source code 34 | for portions of the Combined Work that, considered in isolation, are 35 | based on the Application, and not on the Linked Version. 36 | 37 | The "Corresponding Application Code" for a Combined Work means the 38 | object code and/or source code for the Application, including any data 39 | and utility programs needed for reproducing the Combined Work from the 40 | Application, but excluding the System Libraries of the Combined Work. 41 | 42 | 1. Exception to Section 3 of the GNU GPL. 43 | 44 | You may convey a covered work under sections 3 and 4 of this License 45 | without being bound by section 3 of the GNU GPL. 46 | 47 | 2. Conveying Modified Versions. 48 | 49 | If you modify a copy of the Library, and, in your modifications, a 50 | facility refers to a function or data to be supplied by an Application 51 | that uses the facility (other than as an argument passed when the 52 | facility is invoked), then you may convey a copy of the modified 53 | version: 54 | 55 | a) under this License, provided that you make a good faith effort to 56 | ensure that, in the event an Application does not supply the 57 | function or data, the facility still operates, and performs 58 | whatever part of its purpose remains meaningful, or 59 | 60 | b) under the GNU GPL, with none of the additional permissions of 61 | this License applicable to that copy. 62 | 63 | 3. Object Code Incorporating Material from Library Header Files. 64 | 65 | The object code form of an Application may incorporate material from 66 | a header file that is part of the Library. You may convey such object 67 | code under terms of your choice, provided that, if the incorporated 68 | material is not limited to numerical parameters, data structure 69 | layouts and accessors, or small macros, inline functions and templates 70 | (ten or fewer lines in length), you do both of the following: 71 | 72 | a) Give prominent notice with each copy of the object code that the 73 | Library is used in it and that the Library and its use are 74 | covered by this License. 75 | 76 | b) Accompany the object code with a copy of the GNU GPL and this license 77 | document. 78 | 79 | 4. Combined Works. 80 | 81 | You may convey a Combined Work under terms of your choice that, 82 | taken together, effectively do not restrict modification of the 83 | portions of the Library contained in the Combined Work and reverse 84 | engineering for debugging such modifications, if you also do each of 85 | the following: 86 | 87 | a) Give prominent notice with each copy of the Combined Work that 88 | the Library is used in it and that the Library and its use are 89 | covered by this License. 90 | 91 | b) Accompany the Combined Work with a copy of the GNU GPL and this license 92 | document. 93 | 94 | c) For a Combined Work that displays copyright notices during 95 | execution, include the copyright notice for the Library among 96 | these notices, as well as a reference directing the user to the 97 | copies of the GNU GPL and this license document. 98 | 99 | d) Do one of the following: 100 | 101 | 0) Convey the Minimal Corresponding Source under the terms of this 102 | License, and the Corresponding Application Code in a form 103 | suitable for, and under terms that permit, the user to 104 | recombine or relink the Application with a modified version of 105 | the Linked Version to produce a modified Combined Work, in the 106 | manner specified by section 6 of the GNU GPL for conveying 107 | Corresponding Source. 108 | 109 | 1) Use a suitable shared library mechanism for linking with the 110 | Library. A suitable mechanism is one that (a) uses at run time 111 | a copy of the Library already present on the user's computer 112 | system, and (b) will operate properly with a modified version 113 | of the Library that is interface-compatible with the Linked 114 | Version. 115 | 116 | e) Provide Installation Information, but only if you would otherwise 117 | be required to provide such information under section 6 of the 118 | GNU GPL, and only to the extent that such information is 119 | necessary to install and execute a modified version of the 120 | Combined Work produced by recombining or relinking the 121 | Application with a modified version of the Linked Version. (If 122 | you use option 4d0, the Installation Information must accompany 123 | the Minimal Corresponding Source and Corresponding Application 124 | Code. If you use option 4d1, you must provide the Installation 125 | Information in the manner specified by section 6 of the GNU GPL 126 | for conveying Corresponding Source.) 127 | 128 | 5. Combined Libraries. 129 | 130 | You may place library facilities that are a work based on the 131 | Library side by side in a single library together with other library 132 | facilities that are not Applications and are not covered by this 133 | License, and convey such a combined library under terms of your 134 | choice, if you do both of the following: 135 | 136 | a) Accompany the combined library with a copy of the same work based 137 | on the Library, uncombined with any other library facilities, 138 | conveyed under the terms of this License. 139 | 140 | b) Give prominent notice with the combined library that part of it 141 | is a work based on the Library, and explaining where to find the 142 | accompanying uncombined form of the same work. 143 | 144 | 6. Revised Versions of the GNU Lesser General Public License. 145 | 146 | The Free Software Foundation may publish revised and/or new versions 147 | of the GNU Lesser General Public License from time to time. Such new 148 | versions will be similar in spirit to the present version, but may 149 | differ in detail to address new problems or concerns. 150 | 151 | Each version is given a distinguishing version number. If the 152 | Library as you received it specifies that a certain numbered version 153 | of the GNU Lesser General Public License "or any later version" 154 | applies to it, you have the option of following the terms and 155 | conditions either of that published version or of any later version 156 | published by the Free Software Foundation. If the Library as you 157 | received it does not specify a version number of the GNU Lesser 158 | General Public License, you may choose any version of the GNU Lesser 159 | General Public License ever published by the Free Software Foundation. 160 | 161 | If the Library as you received it specifies that a proxy can decide 162 | whether future versions of the GNU Lesser General Public License shall 163 | apply, that proxy's public statement of acceptance of any version is 164 | permanent authorization for you to choose that version for the 165 | Library. 166 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Adafruit NeoPixel Library [![Build Status](https://github.com/adafruit/Adafruit_NeoPixel/workflows/Arduino%20Library%20CI/badge.svg)](https://github.com/adafruit/Adafruit_NeoPixel/actions)[![Documentation](https://github.com/adafruit/ci-arduino/blob/master/assets/doxygen_badge.svg)](http://adafruit.github.io/Adafruit_NeoPixel/html/index.html) 2 | 3 | Arduino library for controlling single-wire-based LED pixels and strip such as the [Adafruit 60 LED/meter Digital LED strip][strip], the [Adafruit FLORA RGB Smart Pixel][flora], the [Adafruit Breadboard-friendly RGB Smart Pixel][pixel], the [Adafruit NeoPixel Stick][stick], and the [Adafruit NeoPixel Shield][shield]. 4 | 5 | After downloading, rename folder to 'Adafruit_NeoPixel' and install in Arduino Libraries folder. Restart Arduino IDE, then open File->Sketchbook->Library->Adafruit_NeoPixel->strandtest sketch. 6 | 7 | Compatibility notes: Port A is not supported on any AVR processors at this time 8 | 9 | [flora]: http://adafruit.com/products/1060 10 | [strip]: http://adafruit.com/products/1138 11 | [pixel]: http://adafruit.com/products/1312 12 | [stick]: http://adafruit.com/products/1426 13 | [shield]: http://adafruit.com/products/1430 14 | 15 | --- 16 | 17 | ## Installation 18 | 19 | ### First Method 20 | 21 | ![image](https://user-images.githubusercontent.com/36513474/68967967-3e37f480-0803-11ea-91d9-601848c306ee.png) 22 | 23 | 1. In the Arduino IDE, navigate to Sketch > Include Library > Manage Libraries 24 | 1. Then the Library Manager will open and you will find a list of libraries that are already installed or ready for installation. 25 | 1. Then search for Neopixel strip using the search bar. 26 | 1. Click on the text area and then select the specific version and install it. 27 | 28 | ### Second Method 29 | 30 | 1. Navigate to the [Releases page](https://github.com/adafruit/Adafruit_NeoPixel/releases). 31 | 1. Download the latest release. 32 | 1. Extract the zip file 33 | 1. In the Arduino IDE, navigate to Sketch > Include Library > Add .ZIP Library 34 | 35 | ## Features 36 | 37 | - ### Simple to use 38 | 39 | Controlling NeoPixels “from scratch” is quite a challenge, so we provide a library letting you focus on the fun and interesting bits. 40 | 41 | - ### Give back 42 | 43 | The library is free; you don’t have to pay for anything. Adafruit invests time and resources providing this open source code, please support Adafruit and open-source hardware by purchasing products from Adafruit! 44 | 45 | - ### Supported Chipsets 46 | 47 | We have included code for the following chips - sometimes these break for exciting reasons that we can't control in which case please open an issue! 48 | 49 | - AVR ATmega and ATtiny (any 8-bit) - 8 MHz, 12 MHz and 16 MHz 50 | - Teensy 3.x and LC 51 | - Arduino Due 52 | - Arduino 101 53 | - Arm® Cortex®-M7/M4 - RENESAS/STM (Arduino UNO R4, Arduino Portenta H7, Arduino Giga R1) 54 | - ATSAMD21 (Arduino Zero/M0 and other SAMD21 boards) @ 48 MHz 55 | - ATSAMD51 @ 120 MHz 56 | - Adafruit STM32 Feather @ 120 MHz 57 | - ESP8266 any speed 58 | - ESP32 any speed 59 | - Nordic nRF52 (Adafruit Feather nRF52), nRF51 (micro:bit) 60 | - Infineon XMC1100 BootKit @ 32 MHz 61 | - Infineon XMC1100 2Go @ 32 MHz 62 | - Infineon XMC1300 BootKit @ 32 MHz 63 | - Infineon XMC4700 RelaxKit, XMC4800 RelaxKit, XMC4800 IoT Amazon FreeRTOS Kit @ 144 MHz 64 | - Sipeed Maix Bit (K210 processor) 65 | 66 | Check forks for other architectures not listed here! 67 | 68 | - ### GNU Lesser General Public License 69 | 70 | Adafruit_NeoPixel is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. 71 | 72 | ## Functions 73 | 74 | - begin() 75 | - updateLength() 76 | - updateType() 77 | - show() 78 | - delay_ns() 79 | - setPin() 80 | - setPixelColor() 81 | - fill() 82 | - ColorHSV() 83 | - getPixelColor() 84 | - setBrightness() 85 | - getBrightness() 86 | - clear() 87 | - gamma32() 88 | 89 | ## Examples 90 | 91 | There are many examples implemented in this library. One of the examples is below. You can find other examples [here](https://github.com/adafruit/Adafruit_NeoPixel/tree/master/examples) 92 | 93 | ### Simple 94 | 95 | ```Cpp 96 | #include 97 | #ifdef __AVR__ 98 | #include 99 | #endif 100 | #define PIN 6 101 | #define NUMPIXELS 16 102 | 103 | Adafruit_NeoPixel pixels(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800); 104 | #define DELAYVAL 500 105 | 106 | void setup() { 107 | #if defined(__AVR_ATtiny85__) && (F_CPU == 16000000) 108 | clock_prescale_set(clock_div_1); 109 | #endif 110 | 111 | pixels.begin(); 112 | } 113 | 114 | void loop() { 115 | pixels.clear(); 116 | 117 | for(int i=0; i 23 | 24 | #if defined(ESP_IDF_VERSION) 25 | #if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 0, 0) 26 | #define HAS_ESP_IDF_4 27 | #endif 28 | #if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0) 29 | #define HAS_ESP_IDF_5 30 | #endif 31 | #endif 32 | 33 | 34 | #ifdef HAS_ESP_IDF_5 35 | 36 | static SemaphoreHandle_t show_mutex = NULL; 37 | 38 | void espShow(uint8_t pin, uint8_t *pixels, uint32_t numBytes, boolean is800KHz) { 39 | // Note: Because rmtPin is shared between all instances, we will 40 | // end up releasing/initializing the RMT channels each time we 41 | // invoke on different pins. This is probably ok, just not 42 | // efficient. led_data is shared between all instances but will 43 | // be allocated with enough space for the largest instance; data 44 | // is not used beyond the mutex lock so this should be fine. 45 | 46 | #define SEMAPHORE_TIMEOUT_MS 50 47 | 48 | static rmt_data_t *led_data = NULL; 49 | static uint32_t led_data_size = 0; 50 | static int rmtPin = -1; 51 | 52 | if (show_mutex && xSemaphoreTake(show_mutex, SEMAPHORE_TIMEOUT_MS / portTICK_PERIOD_MS) == pdTRUE) { 53 | uint32_t requiredSize = numBytes * 8; 54 | if (requiredSize > led_data_size) { 55 | free(led_data); 56 | if (led_data = (rmt_data_t *)malloc(requiredSize * sizeof(rmt_data_t))) { 57 | led_data_size = requiredSize; 58 | } else { 59 | led_data_size = 0; 60 | } 61 | } else if (requiredSize == 0) { 62 | // To release RMT resources (RMT channels and led_data), call 63 | // .updateLength(0) to set number of pixels/bytes to zero, 64 | // then call .show() to invoke this code and free resources. 65 | free(led_data); 66 | led_data = NULL; 67 | if (rmtPin >= 0) { 68 | rmtDeinit(rmtPin); 69 | rmtPin = -1; 70 | } 71 | led_data_size = 0; 72 | } 73 | 74 | if (led_data_size > 0 && requiredSize <= led_data_size) { 75 | if (pin != rmtPin) { 76 | if (rmtPin >= 0) { 77 | rmtDeinit(rmtPin); 78 | rmtPin = -1; 79 | } 80 | if (!rmtInit(pin, RMT_TX_MODE, RMT_MEM_NUM_BLOCKS_1, 10000000)) { 81 | log_e("Failed to init RMT TX mode on pin %d", pin); 82 | return; 83 | } 84 | rmtPin = pin; 85 | } 86 | 87 | if (rmtPin >= 0) { 88 | int i=0; 89 | for (int b=0; b < numBytes; b++) { 90 | for (int bit=0; bit<8; bit++){ 91 | if ( pixels[b] & (1<<(7-bit)) ) { 92 | led_data[i].level0 = 1; 93 | led_data[i].duration0 = 8; 94 | led_data[i].level1 = 0; 95 | led_data[i].duration1 = 4; 96 | } else { 97 | led_data[i].level0 = 1; 98 | led_data[i].duration0 = 4; 99 | led_data[i].level1 = 0; 100 | led_data[i].duration1 = 8; 101 | } 102 | i++; 103 | } 104 | } 105 | 106 | rmtWrite(pin, led_data, numBytes * 8, RMT_WAIT_FOR_EVER); 107 | } 108 | } 109 | 110 | xSemaphoreGive(show_mutex); 111 | } 112 | } 113 | 114 | // To avoid race condition initializing the mutex, all instances of 115 | // Adafruit_NeoPixel must be constructed before launching and child threads 116 | void espInit() { 117 | if (!show_mutex) { 118 | show_mutex = xSemaphoreCreateMutex(); 119 | } 120 | } 121 | 122 | #else 123 | 124 | #include "driver/rmt.h" 125 | 126 | 127 | // This code is adapted from the ESP-IDF v3.4 RMT "led_strip" example, altered 128 | // to work with the Arduino version of the ESP-IDF (3.2) 129 | 130 | #define WS2812_T0H_NS (400) 131 | #define WS2812_T0L_NS (850) 132 | #define WS2812_T1H_NS (800) 133 | #define WS2812_T1L_NS (450) 134 | 135 | #define WS2811_T0H_NS (500) 136 | #define WS2811_T0L_NS (2000) 137 | #define WS2811_T1H_NS (1200) 138 | #define WS2811_T1L_NS (1300) 139 | 140 | static uint32_t t0h_ticks = 0; 141 | static uint32_t t1h_ticks = 0; 142 | static uint32_t t0l_ticks = 0; 143 | static uint32_t t1l_ticks = 0; 144 | 145 | // Limit the number of RMT channels available for the Neopixels. Defaults to all 146 | // channels (8 on ESP32, 4 on ESP32-S2 and S3). Redefining this value will free 147 | // any channels with a higher number for other uses, such as IR send-and-recieve 148 | // libraries. Redefine as 1 to restrict Neopixels to only a single channel. 149 | #define ADAFRUIT_RMT_CHANNEL_MAX RMT_CHANNEL_MAX 150 | 151 | #define RMT_LL_HW_BASE (&RMT) 152 | 153 | bool rmt_reserved_channels[ADAFRUIT_RMT_CHANNEL_MAX]; 154 | 155 | static void IRAM_ATTR ws2812_rmt_adapter(const void *src, rmt_item32_t *dest, size_t src_size, 156 | size_t wanted_num, size_t *translated_size, size_t *item_num) 157 | { 158 | if (src == NULL || dest == NULL) { 159 | *translated_size = 0; 160 | *item_num = 0; 161 | return; 162 | } 163 | const rmt_item32_t bit0 = {{{ t0h_ticks, 1, t0l_ticks, 0 }}}; //Logical 0 164 | const rmt_item32_t bit1 = {{{ t1h_ticks, 1, t1l_ticks, 0 }}}; //Logical 1 165 | size_t size = 0; 166 | size_t num = 0; 167 | uint8_t *psrc = (uint8_t *)src; 168 | rmt_item32_t *pdest = dest; 169 | while (size < src_size && num < wanted_num) { 170 | for (int i = 0; i < 8; i++) { 171 | // MSB first 172 | if (*psrc & (1 << (7 - i))) { 173 | pdest->val = bit1.val; 174 | } else { 175 | pdest->val = bit0.val; 176 | } 177 | num++; 178 | pdest++; 179 | } 180 | size++; 181 | psrc++; 182 | } 183 | *translated_size = size; 184 | *item_num = num; 185 | } 186 | 187 | void espShow(uint8_t pin, uint8_t *pixels, uint32_t numBytes, boolean is800KHz) { 188 | // Reserve channel 189 | rmt_channel_t channel = ADAFRUIT_RMT_CHANNEL_MAX; 190 | for (size_t i = 0; i < ADAFRUIT_RMT_CHANNEL_MAX; i++) { 191 | if (!rmt_reserved_channels[i]) { 192 | rmt_reserved_channels[i] = true; 193 | channel = i; 194 | break; 195 | } 196 | } 197 | if (channel == ADAFRUIT_RMT_CHANNEL_MAX) { 198 | // Ran out of channels! 199 | return; 200 | } 201 | 202 | #if defined(HAS_ESP_IDF_4) 203 | rmt_config_t config = RMT_DEFAULT_CONFIG_TX(pin, channel); 204 | config.clk_div = 2; 205 | #else 206 | // Match default TX config from ESP-IDF version 3.4 207 | rmt_config_t config = { 208 | .rmt_mode = RMT_MODE_TX, 209 | .channel = channel, 210 | .gpio_num = pin, 211 | .clk_div = 2, 212 | .mem_block_num = 1, 213 | .tx_config = { 214 | .carrier_freq_hz = 38000, 215 | .carrier_level = RMT_CARRIER_LEVEL_HIGH, 216 | .idle_level = RMT_IDLE_LEVEL_LOW, 217 | .carrier_duty_percent = 33, 218 | .carrier_en = false, 219 | .loop_en = false, 220 | .idle_output_en = true, 221 | } 222 | }; 223 | #endif 224 | rmt_config(&config); 225 | rmt_driver_install(config.channel, 0, 0); 226 | 227 | // Convert NS timings to ticks 228 | uint32_t counter_clk_hz = 0; 229 | 230 | #if defined(HAS_ESP_IDF_4) 231 | rmt_get_counter_clock(channel, &counter_clk_hz); 232 | #else 233 | // this emulates the rmt_get_counter_clock() function from ESP-IDF 3.4 234 | if (RMT_LL_HW_BASE->conf_ch[config.channel].conf1.ref_always_on == RMT_BASECLK_REF) { 235 | uint32_t div_cnt = RMT_LL_HW_BASE->conf_ch[config.channel].conf0.div_cnt; 236 | uint32_t div = div_cnt == 0 ? 256 : div_cnt; 237 | counter_clk_hz = REF_CLK_FREQ / (div); 238 | } else { 239 | uint32_t div_cnt = RMT_LL_HW_BASE->conf_ch[config.channel].conf0.div_cnt; 240 | uint32_t div = div_cnt == 0 ? 256 : div_cnt; 241 | counter_clk_hz = APB_CLK_FREQ / (div); 242 | } 243 | #endif 244 | 245 | // NS to tick converter 246 | float ratio = (float)counter_clk_hz / 1e9; 247 | 248 | if (is800KHz) { 249 | t0h_ticks = (uint32_t)(ratio * WS2812_T0H_NS); 250 | t0l_ticks = (uint32_t)(ratio * WS2812_T0L_NS); 251 | t1h_ticks = (uint32_t)(ratio * WS2812_T1H_NS); 252 | t1l_ticks = (uint32_t)(ratio * WS2812_T1L_NS); 253 | } else { 254 | t0h_ticks = (uint32_t)(ratio * WS2811_T0H_NS); 255 | t0l_ticks = (uint32_t)(ratio * WS2811_T0L_NS); 256 | t1h_ticks = (uint32_t)(ratio * WS2811_T1H_NS); 257 | t1l_ticks = (uint32_t)(ratio * WS2811_T1L_NS); 258 | } 259 | 260 | // Initialize automatic timing translator 261 | rmt_translator_init(config.channel, ws2812_rmt_adapter); 262 | 263 | // Write and wait to finish 264 | rmt_write_sample(config.channel, pixels, (size_t)numBytes, true); 265 | rmt_wait_tx_done(config.channel, pdMS_TO_TICKS(100)); 266 | 267 | // Free channel again 268 | rmt_driver_uninstall(config.channel); 269 | rmt_reserved_channels[channel] = false; 270 | 271 | gpio_set_direction(pin, GPIO_MODE_OUTPUT); 272 | } 273 | 274 | #endif // ifndef IDF5 275 | 276 | 277 | #endif // ifdef(ESP32) 278 | -------------------------------------------------------------------------------- /esp8266.c: -------------------------------------------------------------------------------- 1 | // This is a mash-up of the Due show() code + insights from Michael Miller's 2 | // ESP8266 work for the NeoPixelBus library: github.com/Makuna/NeoPixelBus 3 | // Needs to be a separate .c file to enforce ICACHE_RAM_ATTR execution. 4 | 5 | #if defined(ESP8266) 6 | 7 | #include 8 | #ifdef ESP8266 9 | #include 10 | #endif 11 | 12 | static uint32_t _getCycleCount(void) __attribute__((always_inline)); 13 | static inline uint32_t _getCycleCount(void) { 14 | uint32_t ccount; 15 | __asm__ __volatile__("rsr %0,ccount":"=a" (ccount)); 16 | return ccount; 17 | } 18 | 19 | #ifdef ESP8266 20 | IRAM_ATTR void espShow( 21 | uint8_t pin, uint8_t *pixels, uint32_t numBytes, __attribute__((unused)) boolean is800KHz) { 22 | #else 23 | void espShow( 24 | uint8_t pin, uint8_t *pixels, uint32_t numBytes, boolean is800KHz) { 25 | #endif 26 | 27 | #define CYCLES_800_T0H (F_CPU / 2500001) // 0.4us 28 | #define CYCLES_800_T1H (F_CPU / 1250001) // 0.8us 29 | #define CYCLES_800 (F_CPU / 800001) // 1.25us per bit 30 | #define CYCLES_400_T0H (F_CPU / 2000000) // 0.5uS 31 | #define CYCLES_400_T1H (F_CPU / 833333) // 1.2us 32 | #define CYCLES_400 (F_CPU / 400000) // 2.5us per bit 33 | 34 | uint8_t *p, *end, pix, mask; 35 | uint32_t t, time0, time1, period, c, startTime; 36 | 37 | #ifdef ESP8266 38 | uint32_t pinMask; 39 | pinMask = _BV(pin); 40 | #endif 41 | 42 | p = pixels; 43 | end = p + numBytes; 44 | pix = *p++; 45 | mask = 0x80; 46 | startTime = 0; 47 | 48 | #ifdef NEO_KHZ400 49 | if(is800KHz) { 50 | #endif 51 | time0 = CYCLES_800_T0H; 52 | time1 = CYCLES_800_T1H; 53 | period = CYCLES_800; 54 | #ifdef NEO_KHZ400 55 | } else { // 400 KHz bitstream 56 | time0 = CYCLES_400_T0H; 57 | time1 = CYCLES_400_T1H; 58 | period = CYCLES_400; 59 | } 60 | #endif 61 | 62 | for(t = time0;; t = time0) { 63 | if(pix & mask) t = time1; // Bit high duration 64 | while(((c = _getCycleCount()) - startTime) < period); // Wait for bit start 65 | #ifdef ESP8266 66 | GPIO_REG_WRITE(GPIO_OUT_W1TS_ADDRESS, pinMask); // Set high 67 | #else 68 | gpio_set_level(pin, HIGH); 69 | #endif 70 | startTime = c; // Save start time 71 | while(((c = _getCycleCount()) - startTime) < t); // Wait high duration 72 | #ifdef ESP8266 73 | GPIO_REG_WRITE(GPIO_OUT_W1TC_ADDRESS, pinMask); // Set low 74 | #else 75 | gpio_set_level(pin, LOW); 76 | #endif 77 | if(!(mask >>= 1)) { // Next bit/byte 78 | if(p >= end) break; 79 | pix = *p++; 80 | mask = 0x80; 81 | } 82 | } 83 | while((_getCycleCount() - startTime) < period); // Wait for last bit 84 | } 85 | 86 | #endif // ESP8266 87 | -------------------------------------------------------------------------------- /examples/RGBWstrandtest/.esp8266.test.skip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adafruit/Adafruit_NeoPixel/70d02aae78fa83d8517c9fb4679a3aa2038369a5/examples/RGBWstrandtest/.esp8266.test.skip -------------------------------------------------------------------------------- /examples/RGBWstrandtest/.trinket.test.skip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adafruit/Adafruit_NeoPixel/70d02aae78fa83d8517c9fb4679a3aa2038369a5/examples/RGBWstrandtest/.trinket.test.skip -------------------------------------------------------------------------------- /examples/RGBWstrandtest/RGBWstrandtest.ino: -------------------------------------------------------------------------------- 1 | // NeoPixel test program showing use of the WHITE channel for RGBW 2 | // pixels only (won't look correct on regular RGB NeoPixel strips). 3 | 4 | #include 5 | #ifdef __AVR__ 6 | #include // Required for 16 MHz Adafruit Trinket 7 | #endif 8 | 9 | // Which pin on the Arduino is connected to the NeoPixels? 10 | // On a Trinket or Gemma we suggest changing this to 1: 11 | #define LED_PIN 6 12 | 13 | // How many NeoPixels are attached to the Arduino? 14 | #define LED_COUNT 60 15 | 16 | // NeoPixel brightness, 0 (min) to 255 (max) 17 | #define BRIGHTNESS 50 // Set BRIGHTNESS to about 1/5 (max = 255) 18 | 19 | // Declare our NeoPixel strip object: 20 | Adafruit_NeoPixel strip(LED_COUNT, LED_PIN, NEO_GRBW + NEO_KHZ800); 21 | // Argument 1 = Number of pixels in NeoPixel strip 22 | // Argument 2 = Arduino pin number (most are valid) 23 | // Argument 3 = Pixel type flags, add together as needed: 24 | // NEO_KHZ800 800 KHz bitstream (most NeoPixel products w/WS2812 LEDs) 25 | // NEO_KHZ400 400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers) 26 | // NEO_GRB Pixels are wired for GRB bitstream (most NeoPixel products) 27 | // NEO_RGB Pixels are wired for RGB bitstream (v1 FLORA pixels, not v2) 28 | // NEO_RGBW Pixels are wired for RGBW bitstream (NeoPixel RGBW products) 29 | 30 | void setup() { 31 | // These lines are specifically to support the Adafruit Trinket 5V 16 MHz. 32 | // Any other board, you can remove this part (but no harm leaving it): 33 | #if defined(__AVR_ATtiny85__) && (F_CPU == 16000000) 34 | clock_prescale_set(clock_div_1); 35 | #endif 36 | // END of Trinket-specific code. 37 | 38 | strip.begin(); // INITIALIZE NeoPixel strip object (REQUIRED) 39 | strip.show(); // Turn OFF all pixels ASAP 40 | strip.setBrightness(BRIGHTNESS); 41 | } 42 | 43 | void loop() { 44 | // Fill along the length of the strip in various colors... 45 | colorWipe(strip.Color(255, 0, 0) , 50); // Red 46 | colorWipe(strip.Color( 0, 255, 0) , 50); // Green 47 | colorWipe(strip.Color( 0, 0, 255) , 50); // Blue 48 | colorWipe(strip.Color( 0, 0, 0, 255), 50); // True white (not RGB white) 49 | 50 | whiteOverRainbow(75, 5); 51 | 52 | pulseWhite(5); 53 | 54 | rainbowFade2White(3, 3, 1); 55 | } 56 | 57 | // Fill strip pixels one after another with a color. Strip is NOT cleared 58 | // first; anything there will be covered pixel by pixel. Pass in color 59 | // (as a single 'packed' 32-bit value, which you can get by calling 60 | // strip.Color(red, green, blue) as shown in the loop() function above), 61 | // and a delay time (in milliseconds) between pixels. 62 | void colorWipe(uint32_t color, int wait) { 63 | for(int i=0; i= strip.numPixels()) whiteLength = strip.numPixels() - 1; 73 | 74 | int head = whiteLength - 1; 75 | int tail = 0; 76 | int loops = 3; 77 | int loopNum = 0; 78 | uint32_t lastTime = millis(); 79 | uint32_t firstPixelHue = 0; 80 | 81 | for(;;) { // Repeat forever (or until a 'break' or 'return') 82 | for(int i=0; i= tail) && (i <= head)) || // If between head & tail... 84 | ((tail > head) && ((i >= tail) || (i <= head)))) { 85 | strip.setPixelColor(i, strip.Color(0, 0, 0, 255)); // Set white 86 | } else { // else set rainbow 87 | int pixelHue = firstPixelHue + (i * 65536L / strip.numPixels()); 88 | strip.setPixelColor(i, strip.gamma32(strip.ColorHSV(pixelHue))); 89 | } 90 | } 91 | 92 | strip.show(); // Update strip with new contents 93 | // There's no delay here, it just runs full-tilt until the timer and 94 | // counter combination below runs out. 95 | 96 | firstPixelHue += 40; // Advance just a little along the color wheel 97 | 98 | if((millis() - lastTime) > whiteSpeed) { // Time to update head/tail? 99 | if(++head >= strip.numPixels()) { // Advance head, wrap around 100 | head = 0; 101 | if(++loopNum >= loops) return; 102 | } 103 | if(++tail >= strip.numPixels()) { // Advance tail, wrap around 104 | tail = 0; 105 | } 106 | lastTime = millis(); // Save time of last movement 107 | } 108 | } 109 | } 110 | 111 | void pulseWhite(uint8_t wait) { 112 | for(int j=0; j<256; j++) { // Ramp up from 0 to 255 113 | // Fill entire strip with white at gamma-corrected brightness level 'j': 114 | strip.fill(strip.Color(0, 0, 0, strip.gamma8(j))); 115 | strip.show(); 116 | delay(wait); 117 | } 118 | 119 | for(int j=255; j>=0; j--) { // Ramp down from 255 to 0 120 | strip.fill(strip.Color(0, 0, 0, strip.gamma8(j))); 121 | strip.show(); 122 | delay(wait); 123 | } 124 | } 125 | 126 | void rainbowFade2White(int wait, int rainbowLoops, int whiteLoops) { 127 | int fadeVal=0, fadeMax=100; 128 | 129 | // Hue of first pixel runs 'rainbowLoops' complete loops through the color 130 | // wheel. Color wheel has a range of 65536 but it's OK if we roll over, so 131 | // just count from 0 to rainbowLoops*65536, using steps of 256 so we 132 | // advance around the wheel at a decent clip. 133 | for(uint32_t firstPixelHue = 0; firstPixelHue < rainbowLoops*65536; 134 | firstPixelHue += 256) { 135 | 136 | for(int i=0; i= ((rainbowLoops-1) * 65536)) { // Last loop, 157 | if(fadeVal > 0) fadeVal--; // fade out 158 | } else { 159 | fadeVal = fadeMax; // Interim loop, make sure fade is at max 160 | } 161 | } 162 | 163 | for(int k=0; k=0; j--) { // Ramp down 255 to 0 171 | strip.fill(strip.Color(0, 0, 0, strip.gamma8(j))); 172 | strip.show(); 173 | } 174 | } 175 | 176 | delay(500); // Pause 1/2 second 177 | } 178 | -------------------------------------------------------------------------------- /examples/StrandtestArduinoBLE/.none.test.only: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adafruit/Adafruit_NeoPixel/70d02aae78fa83d8517c9fb4679a3aa2038369a5/examples/StrandtestArduinoBLE/.none.test.only -------------------------------------------------------------------------------- /examples/StrandtestArduinoBLE/StrandtestArduinoBLE.ino: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | * This example is based on StrandtestBLE example and adapts it to use 3 | * the new ArduinoBLE library. 4 | * 5 | * https://github.com/arduino-libraries/ArduinoBLE 6 | * 7 | * Supported boards: 8 | * Arduino MKR WiFi 1010, Arduino Uno WiFi Rev2 board, Arduino Nano 33 IoT, 9 | Arduino Nano 33 BLE, or Arduino Nano 33 BLE Sense board. 10 | * 11 | * You can use a generic BLE central app, like LightBlue (iOS and Android) or 12 | * nRF Connect (Android), to interact with the services and characteristics 13 | * created in this sketch. 14 | * 15 | * This example code is in the public domain. 16 | * 17 | */ 18 | #include 19 | 20 | #define PIN 15 // Pin where NeoPixels are connected 21 | 22 | // Declare our NeoPixel strip object: 23 | Adafruit_NeoPixel strip(64, PIN, NEO_GRB + NEO_KHZ800); 24 | // Argument 1 = Number of pixels in NeoPixel strip 25 | // Argument 2 = Arduino pin number (most are valid) 26 | // Argument 3 = Pixel type flags, add together as needed: 27 | // NEO_KHZ800 800 KHz bitstream (most NeoPixel products w/WS2812 LEDs) 28 | // NEO_KHZ400 400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers) 29 | // NEO_GRB Pixels are wired for GRB bitstream (most NeoPixel products) 30 | // NEO_RGB Pixels are wired for RGB bitstream (v1 FLORA pixels, not v2) 31 | // NEO_RGBW Pixels are wired for RGBW bitstream (NeoPixel RGBW products) 32 | 33 | // NEOPIXEL BEST PRACTICES for most reliable operation: 34 | // - Add 1000 uF CAPACITOR between NeoPixel strip's + and - connections. 35 | // - MINIMIZE WIRING LENGTH between microcontroller board and first pixel. 36 | // - NeoPixel strip's DATA-IN should pass through a 300-500 OHM RESISTOR. 37 | // - AVOID connecting NeoPixels on a LIVE CIRCUIT. If you must, ALWAYS 38 | // connect GROUND (-) first, then +, then data. 39 | // - When using a 3.3V microcontroller with a 5V-powered NeoPixel strip, 40 | // a LOGIC-LEVEL CONVERTER on the data line is STRONGLY RECOMMENDED. 41 | // (Skipping these may work OK on your workbench but can fail in the field) 42 | 43 | uint8_t rgb_values[3]; 44 | 45 | #include 46 | 47 | BLEService ledService("19B10000-E8F2-537E-4F6C-D104768A1214"); // BLE LED Service 48 | 49 | // BLE LED Switch Characteristic - custom 128-bit UUID, read and writable by central 50 | BLEByteCharacteristic switchCharacteristic("19B10001-E8F2-537E-4F6C-D104768A1214", BLERead | BLEWrite); 51 | 52 | void setup() 53 | { 54 | Serial.begin(115200); 55 | Serial.println("Hello World!"); 56 | 57 | // custom services and characteristics can be added as well 58 | // begin initialization 59 | if (!BLE.begin()) 60 | { 61 | Serial.println("starting BLE failed!"); 62 | 63 | while (1) 64 | ; 65 | } 66 | 67 | Serial.print("Peripheral address: "); 68 | Serial.println(BLE.address()); 69 | 70 | // set advertised local name and service UUID: 71 | BLE.setLocalName("LED"); 72 | BLE.setAdvertisedService(ledService); 73 | 74 | // add the characteristic to the service 75 | ledService.addCharacteristic(switchCharacteristic); 76 | 77 | // add service 78 | BLE.addService(ledService); 79 | 80 | // set the initial value for the characeristic: 81 | switchCharacteristic.writeValue(0); 82 | 83 | // start advertising 84 | BLE.advertise(); 85 | 86 | strip.begin(); // INITIALIZE NeoPixel strip object (REQUIRED) 87 | strip.show(); // Turn OFF all pixels ASAP 88 | 89 | pinMode(PIN, OUTPUT); 90 | digitalWrite(PIN, LOW); 91 | 92 | } 93 | 94 | void loop() 95 | { 96 | BLEDevice central = BLE.central(); 97 | 98 | // if a central is connected to peripheral: 99 | if (central) 100 | { 101 | Serial.print("Connected to central: "); 102 | // print the central's MAC address: 103 | Serial.println(central.address()); 104 | 105 | // while the central is still connected to peripheral: 106 | while (central.connected()) 107 | { 108 | // if the remote device wrote to the characteristic, 109 | // use the value to control the LED: 110 | if (switchCharacteristic.written()) 111 | { 112 | switch (switchCharacteristic.value()) 113 | { 114 | case 'a': 115 | colorWipe(strip.Color(255, 0, 0), 20); // Red 116 | break; 117 | case 'b': 118 | colorWipe(strip.Color(0, 255, 0), 20); // Green 119 | break; 120 | case 'c': 121 | colorWipe(strip.Color(0, 0, 255), 20); // Blue 122 | break; 123 | case 'd': 124 | theaterChase(strip.Color(255, 0, 0), 20); // Red 125 | break; 126 | case 'e': 127 | theaterChase(strip.Color(0, 255, 0), 20); // Green 128 | break; 129 | case 'f': 130 | theaterChase(strip.Color(255, 0, 255), 20); // Cyan 131 | break; 132 | case 'g': 133 | rainbow(10); 134 | break; 135 | case 'h': 136 | theaterChaseRainbow(20); 137 | break; 138 | } 139 | } 140 | } 141 | } 142 | } 143 | 144 | // Fill strip pixels one after another with a color. Strip is NOT cleared 145 | // first; anything there will be covered pixel by pixel. Pass in color 146 | // (as a single 'packed' 32-bit value, which you can get by calling 147 | // strip.Color(red, green, blue) as shown in the loop() function above), 148 | // and a delay time (in milliseconds) between pixels. 149 | void colorWipe(uint32_t color, int wait) 150 | { 151 | for (int i = 0; i < strip.numPixels(); i++) 152 | { // For each pixel in strip... 153 | strip.setPixelColor(i, color); // Set pixel's color (in RAM) 154 | strip.show(); // Update strip to match 155 | delay(wait); // Pause for a moment 156 | } 157 | } 158 | 159 | // Theater-marquee-style chasing lights. Pass in a color (32-bit value, 160 | // a la strip.Color(r,g,b) as mentioned above), and a delay time (in ms) 161 | // between frames. 162 | void theaterChase(uint32_t color, int wait) 163 | { 164 | for (int a = 0; a < 10; a++) 165 | { // Repeat 10 times... 166 | for (int b = 0; b < 3; b++) 167 | { // 'b' counts from 0 to 2... 168 | strip.clear(); // Set all pixels in RAM to 0 (off) 169 | // 'c' counts up from 'b' to end of strip in steps of 3... 170 | for (int c = b; c < strip.numPixels(); c += 3) 171 | { 172 | strip.setPixelColor(c, color); // Set pixel 'c' to value 'color' 173 | } 174 | strip.show(); // Update strip with new contents 175 | delay(wait); // Pause for a moment 176 | } 177 | } 178 | } 179 | 180 | // Rainbow cycle along whole strip. Pass delay time (in ms) between frames. 181 | void rainbow(int wait) 182 | { 183 | // Hue of first pixel runs 5 complete loops through the color wheel. 184 | // Color wheel has a range of 65536 but it's OK if we roll over, so 185 | // just count from 0 to 5*65536. Adding 256 to firstPixelHue each time 186 | // means we'll make 5*65536/256 = 1280 passes through this outer loop: 187 | for (long firstPixelHue = 0; firstPixelHue < 5 * 65536; firstPixelHue += 256) 188 | { 189 | for (int i = 0; i < strip.numPixels(); i++) 190 | { // For each pixel in strip... 191 | // Offset pixel hue by an amount to make one full revolution of the 192 | // color wheel (range of 65536) along the length of the strip 193 | // (strip.numPixels() steps): 194 | int pixelHue = firstPixelHue + (i * 65536L / strip.numPixels()); 195 | // strip.ColorHSV() can take 1 or 3 arguments: a hue (0 to 65535) or 196 | // optionally add saturation and value (brightness) (each 0 to 255). 197 | // Here we're using just the single-argument hue variant. The result 198 | // is passed through strip.gamma32() to provide 'truer' colors 199 | // before assigning to each pixel: 200 | strip.setPixelColor(i, strip.gamma32(strip.ColorHSV(pixelHue))); 201 | } 202 | strip.show(); // Update strip with new contents 203 | delay(wait); // Pause for a moment 204 | } 205 | } 206 | 207 | // Rainbow-enhanced theater marquee. Pass delay time (in ms) between frames. 208 | void theaterChaseRainbow(int wait) 209 | { 210 | int firstPixelHue = 0; // First pixel starts at red (hue 0) 211 | for (int a = 0; a < 30; a++) 212 | { // Repeat 30 times... 213 | for (int b = 0; b < 3; b++) 214 | { // 'b' counts from 0 to 2... 215 | strip.clear(); // Set all pixels in RAM to 0 (off) 216 | // 'c' counts up from 'b' to end of strip in increments of 3... 217 | for (int c = b; c < strip.numPixels(); c += 3) 218 | { 219 | // hue of pixel 'c' is offset by an amount to make one full 220 | // revolution of the color wheel (range 65536) along the length 221 | // of the strip (strip.numPixels() steps): 222 | int hue = firstPixelHue + c * 65536L / strip.numPixels(); 223 | uint32_t color = strip.gamma32(strip.ColorHSV(hue)); // hue -> RGB 224 | strip.setPixelColor(c, color); // Set pixel 'c' to value 'color' 225 | } 226 | strip.show(); // Update strip with new contents 227 | delay(wait); // Pause for a moment 228 | firstPixelHue += 65536 / 90; // One cycle of color wheel over 90 frames 229 | } 230 | } 231 | } 232 | -------------------------------------------------------------------------------- /examples/StrandtestArduinoBLECallback/.none.test.only: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adafruit/Adafruit_NeoPixel/70d02aae78fa83d8517c9fb4679a3aa2038369a5/examples/StrandtestArduinoBLECallback/.none.test.only -------------------------------------------------------------------------------- /examples/StrandtestArduinoBLECallback/StrandtestArduinoBLECallback.ino: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | * This example is based on StrandtestArduinoBLE example to make use of 3 | * callbacks features of the ArduinoBLE library. 4 | * 5 | * https://github.com/arduino-libraries/ArduinoBLE 6 | * 7 | * Supported boards: 8 | * Arduino MKR WiFi 1010, Arduino Uno WiFi Rev2 board, Arduino Nano 33 IoT, 9 | Arduino Nano 33 BLE, or Arduino Nano 33 BLE Sense board. 10 | * 11 | * You can use a generic BLE central app, like LightBlue (iOS and Android) or 12 | * nRF Connect (Android), to interact with the services and characteristics 13 | * created in this sketch. 14 | * 15 | * This example code is in the public domain. 16 | * 17 | */ 18 | #include 19 | 20 | #define PIN 15 // Pin where NeoPixels are connected 21 | 22 | // Declare our NeoPixel strip object: 23 | Adafruit_NeoPixel strip(64, PIN, NEO_GRB + NEO_KHZ800); 24 | // Argument 1 = Number of pixels in NeoPixel strip 25 | // Argument 2 = Arduino pin number (most are valid) 26 | // Argument 3 = Pixel type flags, add together as needed: 27 | // NEO_KHZ800 800 KHz bitstream (most NeoPixel products w/WS2812 LEDs) 28 | // NEO_KHZ400 400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers) 29 | // NEO_GRB Pixels are wired for GRB bitstream (most NeoPixel products) 30 | // NEO_RGB Pixels are wired for RGB bitstream (v1 FLORA pixels, not v2) 31 | // NEO_RGBW Pixels are wired for RGBW bitstream (NeoPixel RGBW products) 32 | 33 | // NEOPIXEL BEST PRACTICES for most reliable operation: 34 | // - Add 1000 uF CAPACITOR between NeoPixel strip's + and - connections. 35 | // - MINIMIZE WIRING LENGTH between microcontroller board and first pixel. 36 | // - NeoPixel strip's DATA-IN should pass through a 300-500 OHM RESISTOR. 37 | // - AVOID connecting NeoPixels on a LIVE CIRCUIT. If you must, ALWAYS 38 | // connect GROUND (-) first, then +, then data. 39 | // - When using a 3.3V microcontroller with a 5V-powered NeoPixel strip, 40 | // a LOGIC-LEVEL CONVERTER on the data line is STRONGLY RECOMMENDED. 41 | // (Skipping these may work OK on your workbench but can fail in the field) 42 | 43 | uint8_t rgb_values[3]; 44 | 45 | #include 46 | 47 | BLEService ledService("19B10000-E8F2-537E-4F6C-D104768A1214"); // BLE LED Service 48 | 49 | // BLE LED Switch Characteristic - custom 128-bit UUID, read and writable by central 50 | BLEByteCharacteristic switchCharacteristic("19B10001-E8F2-537E-4F6C-D104768A1214", BLERead | BLEWrite); 51 | 52 | void setup() 53 | { 54 | Serial.begin(115200); 55 | Serial.println("Hello World!"); 56 | 57 | // custom services and characteristics can be added as well 58 | // begin initialization 59 | if (!BLE.begin()) 60 | { 61 | Serial.println("starting BLE failed!"); 62 | 63 | while (1) 64 | ; 65 | } 66 | 67 | Serial.print("Peripheral address: "); 68 | Serial.println(BLE.address()); 69 | 70 | // set advertised local name and service UUID: 71 | BLE.setLocalName("LEDCallback"); 72 | BLE.setAdvertisedService(ledService); 73 | 74 | // add the characteristic to the service 75 | ledService.addCharacteristic(switchCharacteristic); 76 | 77 | // add service 78 | BLE.addService(ledService); 79 | // assign event handlers for connected, disconnected to peripheral 80 | BLE.setEventHandler(BLEConnected, blePeripheralConnectHandler); 81 | BLE.setEventHandler(BLEDisconnected, blePeripheralDisconnectHandler); 82 | 83 | // assign event handlers for characteristic 84 | switchCharacteristic.setEventHandler(BLEWritten, switchCharacteristicWritten); 85 | // set the initial value for the characeristic: 86 | switchCharacteristic.writeValue(0); 87 | 88 | // start advertising 89 | BLE.advertise(); 90 | 91 | strip.begin(); // INITIALIZE NeoPixel strip object (REQUIRED) 92 | strip.show(); // Turn OFF all pixels ASAP 93 | 94 | pinMode(PIN, OUTPUT); 95 | digitalWrite(PIN, LOW); 96 | } 97 | 98 | void loop() 99 | { 100 | // poll for BLE events 101 | BLE.poll(); 102 | } 103 | 104 | void blePeripheralConnectHandler(BLEDevice central) 105 | { 106 | // central connected event handler 107 | Serial.print("Connected event, central: "); 108 | Serial.println(central.address()); 109 | } 110 | 111 | void blePeripheralDisconnectHandler(BLEDevice central) 112 | { 113 | // central disconnected event handler 114 | Serial.print("Disconnected event, central: "); 115 | Serial.println(central.address()); 116 | } 117 | 118 | void switchCharacteristicWritten(BLEDevice central, BLECharacteristic characteristic) 119 | { 120 | // central wrote new value to characteristic, update LED 121 | Serial.print("Characteristic event, written: "); 122 | 123 | switch (switchCharacteristic.value()) 124 | { 125 | case 'a': 126 | colorWipe(strip.Color(255, 0, 0), 20); // Red 127 | break; 128 | case 'b': 129 | colorWipe(strip.Color(0, 255, 0), 20); // Green 130 | break; 131 | case 'c': 132 | colorWipe(strip.Color(0, 0, 255), 20); // Blue 133 | break; 134 | case 'd': 135 | theaterChase(strip.Color(255, 0, 0), 20); // Red 136 | break; 137 | case 'e': 138 | theaterChase(strip.Color(0, 255, 0), 20); // Green 139 | break; 140 | case 'f': 141 | theaterChase(strip.Color(255, 0, 255), 20); // Cyan 142 | break; 143 | case 'g': 144 | rainbow(10); 145 | break; 146 | case 'h': 147 | theaterChaseRainbow(20); 148 | break; 149 | } 150 | } 151 | 152 | // Fill strip pixels one after another with a color. Strip is NOT cleared 153 | // first; anything there will be covered pixel by pixel. Pass in color 154 | // (as a single 'packed' 32-bit value, which you can get by calling 155 | // strip.Color(red, green, blue) as shown in the loop() function above), 156 | // and a delay time (in milliseconds) between pixels. 157 | void colorWipe(uint32_t color, int wait) 158 | { 159 | for (int i = 0; i < strip.numPixels(); i++) 160 | { // For each pixel in strip... 161 | strip.setPixelColor(i, color); // Set pixel's color (in RAM) 162 | strip.show(); // Update strip to match 163 | delay(wait); // Pause for a moment 164 | } 165 | } 166 | 167 | // Theater-marquee-style chasing lights. Pass in a color (32-bit value, 168 | // a la strip.Color(r,g,b) as mentioned above), and a delay time (in ms) 169 | // between frames. 170 | void theaterChase(uint32_t color, int wait) 171 | { 172 | for (int a = 0; a < 10; a++) 173 | { // Repeat 10 times... 174 | for (int b = 0; b < 3; b++) 175 | { // 'b' counts from 0 to 2... 176 | strip.clear(); // Set all pixels in RAM to 0 (off) 177 | // 'c' counts up from 'b' to end of strip in steps of 3... 178 | for (int c = b; c < strip.numPixels(); c += 3) 179 | { 180 | strip.setPixelColor(c, color); // Set pixel 'c' to value 'color' 181 | } 182 | strip.show(); // Update strip with new contents 183 | delay(wait); // Pause for a moment 184 | } 185 | } 186 | } 187 | 188 | // Rainbow cycle along whole strip. Pass delay time (in ms) between frames. 189 | void rainbow(int wait) 190 | { 191 | // Hue of first pixel runs 5 complete loops through the color wheel. 192 | // Color wheel has a range of 65536 but it's OK if we roll over, so 193 | // just count from 0 to 5*65536. Adding 256 to firstPixelHue each time 194 | // means we'll make 5*65536/256 = 1280 passes through this outer loop: 195 | for (long firstPixelHue = 0; firstPixelHue < 5 * 65536; firstPixelHue += 256) 196 | { 197 | for (int i = 0; i < strip.numPixels(); i++) 198 | { // For each pixel in strip... 199 | // Offset pixel hue by an amount to make one full revolution of the 200 | // color wheel (range of 65536) along the length of the strip 201 | // (strip.numPixels() steps): 202 | int pixelHue = firstPixelHue + (i * 65536L / strip.numPixels()); 203 | // strip.ColorHSV() can take 1 or 3 arguments: a hue (0 to 65535) or 204 | // optionally add saturation and value (brightness) (each 0 to 255). 205 | // Here we're using just the single-argument hue variant. The result 206 | // is passed through strip.gamma32() to provide 'truer' colors 207 | // before assigning to each pixel: 208 | strip.setPixelColor(i, strip.gamma32(strip.ColorHSV(pixelHue))); 209 | } 210 | strip.show(); // Update strip with new contents 211 | delay(wait); // Pause for a moment 212 | } 213 | } 214 | 215 | // Rainbow-enhanced theater marquee. Pass delay time (in ms) between frames. 216 | void theaterChaseRainbow(int wait) 217 | { 218 | int firstPixelHue = 0; // First pixel starts at red (hue 0) 219 | for (int a = 0; a < 30; a++) 220 | { // Repeat 30 times... 221 | for (int b = 0; b < 3; b++) 222 | { // 'b' counts from 0 to 2... 223 | strip.clear(); // Set all pixels in RAM to 0 (off) 224 | // 'c' counts up from 'b' to end of strip in increments of 3... 225 | for (int c = b; c < strip.numPixels(); c += 3) 226 | { 227 | // hue of pixel 'c' is offset by an amount to make one full 228 | // revolution of the color wheel (range 65536) along the length 229 | // of the strip (strip.numPixels() steps): 230 | int hue = firstPixelHue + c * 65536L / strip.numPixels(); 231 | uint32_t color = strip.gamma32(strip.ColorHSV(hue)); // hue -> RGB 232 | strip.setPixelColor(c, color); // Set pixel 'c' to value 'color' 233 | } 234 | strip.show(); // Update strip with new contents 235 | delay(wait); // Pause for a moment 236 | firstPixelHue += 65536 / 90; // One cycle of color wheel over 90 frames 237 | } 238 | } 239 | } 240 | -------------------------------------------------------------------------------- /examples/StrandtestBLE/.none.test.only: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adafruit/Adafruit_NeoPixel/70d02aae78fa83d8517c9fb4679a3aa2038369a5/examples/StrandtestBLE/.none.test.only -------------------------------------------------------------------------------- /examples/StrandtestBLE/BLESerial.cpp: -------------------------------------------------------------------------------- 1 | #include "BLESerial.h" 2 | 3 | // #define BLE_SERIAL_DEBUG 4 | 5 | BLESerial* BLESerial::_instance = NULL; 6 | 7 | BLESerial::BLESerial(unsigned char req, unsigned char rdy, unsigned char rst) : 8 | BLEPeripheral(req, rdy, rst) 9 | { 10 | this->_txCount = 0; 11 | this->_rxHead = this->_rxTail = 0; 12 | this->_flushed = 0; 13 | BLESerial::_instance = this; 14 | 15 | addAttribute(this->_uartService); 16 | addAttribute(this->_uartNameDescriptor); 17 | setAdvertisedServiceUuid(this->_uartService.uuid()); 18 | addAttribute(this->_rxCharacteristic); 19 | addAttribute(this->_rxNameDescriptor); 20 | this->_rxCharacteristic.setEventHandler(BLEWritten, BLESerial::_received); 21 | addAttribute(this->_txCharacteristic); 22 | addAttribute(this->_txNameDescriptor); 23 | } 24 | 25 | void BLESerial::begin(...) { 26 | BLEPeripheral::begin(); 27 | #ifdef BLE_SERIAL_DEBUG 28 | Serial.println(F("BLESerial::begin()")); 29 | #endif 30 | } 31 | 32 | void BLESerial::poll() { 33 | if (millis() < this->_flushed + 100) { 34 | BLEPeripheral::poll(); 35 | } else { 36 | flush(); 37 | } 38 | } 39 | 40 | void BLESerial::end() { 41 | this->_rxCharacteristic.setEventHandler(BLEWritten, NULL); 42 | this->_rxHead = this->_rxTail = 0; 43 | flush(); 44 | BLEPeripheral::disconnect(); 45 | } 46 | 47 | int BLESerial::available(void) { 48 | BLEPeripheral::poll(); 49 | int retval = (this->_rxHead - this->_rxTail + sizeof(this->_rxBuffer)) % sizeof(this->_rxBuffer); 50 | #ifdef BLE_SERIAL_DEBUG 51 | Serial.print(F("BLESerial::available() = ")); 52 | Serial.println(retval); 53 | #endif 54 | return retval; 55 | } 56 | 57 | int BLESerial::peek(void) { 58 | BLEPeripheral::poll(); 59 | if (this->_rxTail == this->_rxHead) return -1; 60 | uint8_t byte = this->_rxBuffer[this->_rxTail]; 61 | #ifdef BLE_SERIAL_DEBUG 62 | Serial.print(F("BLESerial::peek() = ")); 63 | Serial.print((char) byte); 64 | Serial.print(F(" 0x")); 65 | Serial.println(byte, HEX); 66 | #endif 67 | return byte; 68 | } 69 | 70 | int BLESerial::read(void) { 71 | BLEPeripheral::poll(); 72 | if (this->_rxTail == this->_rxHead) return -1; 73 | this->_rxTail = (this->_rxTail + 1) % sizeof(this->_rxBuffer); 74 | uint8_t byte = this->_rxBuffer[this->_rxTail]; 75 | #ifdef BLE_SERIAL_DEBUG 76 | Serial.print(F("BLESerial::read() = ")); 77 | Serial.print((char) byte); 78 | Serial.print(F(" 0x")); 79 | Serial.println(byte, HEX); 80 | #endif 81 | return byte; 82 | } 83 | 84 | void BLESerial::flush(void) { 85 | if (this->_txCount == 0) return; 86 | this->_txCharacteristic.setValue(this->_txBuffer, this->_txCount); 87 | this->_flushed = millis(); 88 | this->_txCount = 0; 89 | BLEPeripheral::poll(); 90 | #ifdef BLE_SERIAL_DEBUG 91 | Serial.println(F("BLESerial::flush()")); 92 | #endif 93 | } 94 | 95 | size_t BLESerial::write(uint8_t byte) { 96 | BLEPeripheral::poll(); 97 | if (this->_txCharacteristic.subscribed() == false) return 0; 98 | this->_txBuffer[this->_txCount++] = byte; 99 | if (this->_txCount == sizeof(this->_txBuffer)) flush(); 100 | #ifdef BLE_SERIAL_DEBUG 101 | Serial.print(F("BLESerial::write(")); 102 | Serial.print((char) byte); 103 | Serial.print(F(" 0x")); 104 | Serial.print(byte, HEX); 105 | Serial.println(F(") = 1")); 106 | #endif 107 | return 1; 108 | } 109 | 110 | BLESerial::operator bool() { 111 | bool retval = BLEPeripheral::connected(); 112 | #ifdef BLE_SERIAL_DEBUG 113 | Serial.print(F("BLESerial::operator bool() = ")); 114 | Serial.println(retval); 115 | #endif 116 | return retval; 117 | } 118 | 119 | void BLESerial::_received(const uint8_t* data, size_t size) { 120 | for (int i = 0; i < size; i++) { 121 | this->_rxHead = (this->_rxHead + 1) % sizeof(this->_rxBuffer); 122 | this->_rxBuffer[this->_rxHead] = data[i]; 123 | } 124 | #ifdef BLE_SERIAL_DEBUG 125 | Serial.print(F("BLESerial::received(")); 126 | for (int i = 0; i < size; i++) Serial.print((char) data[i]); 127 | Serial.println(F(")")); 128 | #endif 129 | } 130 | 131 | void BLESerial::_received(BLECentral& /*central*/, BLECharacteristic& rxCharacteristic) { 132 | BLESerial::_instance->_received(rxCharacteristic.value(), rxCharacteristic.valueLength()); 133 | } 134 | -------------------------------------------------------------------------------- /examples/StrandtestBLE/BLESerial.h: -------------------------------------------------------------------------------- 1 | #ifndef _BLE_SERIAL_H_ 2 | #define _BLE_SERIAL_H_ 3 | 4 | #include 5 | #include 6 | 7 | class BLESerial : public BLEPeripheral, public Stream 8 | { 9 | public: 10 | BLESerial(unsigned char req, unsigned char rdy, unsigned char rst); 11 | 12 | void begin(...); 13 | void poll(); 14 | void end(); 15 | 16 | virtual int available(void); 17 | virtual int peek(void); 18 | virtual int read(void); 19 | virtual void flush(void); 20 | virtual size_t write(uint8_t byte); 21 | using Print::write; 22 | virtual operator bool(); 23 | 24 | private: 25 | unsigned long _flushed; 26 | static BLESerial* _instance; 27 | 28 | size_t _rxHead; 29 | size_t _rxTail; 30 | size_t _rxCount() const; 31 | uint8_t _rxBuffer[BLE_ATTRIBUTE_MAX_VALUE_LENGTH]; 32 | size_t _txCount; 33 | uint8_t _txBuffer[BLE_ATTRIBUTE_MAX_VALUE_LENGTH]; 34 | 35 | BLEService _uartService = BLEService("6E400001-B5A3-F393-E0A9-E50E24DCCA9E"); 36 | BLEDescriptor _uartNameDescriptor = BLEDescriptor("2901", "UART"); 37 | BLECharacteristic _rxCharacteristic = BLECharacteristic("6E400002-B5A3-F393-E0A9-E50E24DCCA9E", BLEWriteWithoutResponse, BLE_ATTRIBUTE_MAX_VALUE_LENGTH); 38 | BLEDescriptor _rxNameDescriptor = BLEDescriptor("2901", "RX - Receive Data (Write)"); 39 | BLECharacteristic _txCharacteristic = BLECharacteristic("6E400003-B5A3-F393-E0A9-E50E24DCCA9E", BLENotify, BLE_ATTRIBUTE_MAX_VALUE_LENGTH); 40 | BLEDescriptor _txNameDescriptor = BLEDescriptor("2901", "TX - Transfer Data (Notify)"); 41 | 42 | void _received(const uint8_t* data, size_t size); 43 | static void _received(BLECentral& /*central*/, BLECharacteristic& rxCharacteristic); 44 | }; 45 | 46 | #endif 47 | -------------------------------------------------------------------------------- /examples/StrandtestBLE/StrandtestBLE.ino: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | * This example was developed by the Hackerspace San Salvador to demonstrate 3 | * the simultaneous use of the NeoPixel library and the Bluetooth SoftDevice. 4 | * To compile this example you'll need to add support for the NRF52 based 5 | * following the instructions at: 6 | * https://github.com/sandeepmistry/arduino-nRF5 7 | * Or adding the following URL to the board manager URLs on Arduino preferences: 8 | * https://sandeepmistry.github.io/arduino-nRF5/package_nRF5_boards_index.json 9 | * Then you can install the BLEPeripheral library avaiable at: 10 | * https://github.com/sandeepmistry/arduino-BLEPeripheral 11 | * To test it, compile this example and use the UART module from the nRF 12 | * Toolbox App for Android. Edit the interface and send the characters 13 | * 'a' to 'i' to switch the animation. 14 | * There is a delay because this example blocks the thread of execution but 15 | * the change will be shown after the current animation ends. (This might 16 | * take a couple of seconds) 17 | * For more info write us at: info _at- teubi.co 18 | */ 19 | #include 20 | #include 21 | #include "BLESerial.h" 22 | #include 23 | 24 | #define PIN 15 // Pin where NeoPixels are connected 25 | 26 | // Declare our NeoPixel strip object: 27 | Adafruit_NeoPixel strip(64, PIN, NEO_GRB + NEO_KHZ800); 28 | // Argument 1 = Number of pixels in NeoPixel strip 29 | // Argument 2 = Arduino pin number (most are valid) 30 | // Argument 3 = Pixel type flags, add together as needed: 31 | // NEO_KHZ800 800 KHz bitstream (most NeoPixel products w/WS2812 LEDs) 32 | // NEO_KHZ400 400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers) 33 | // NEO_GRB Pixels are wired for GRB bitstream (most NeoPixel products) 34 | // NEO_RGB Pixels are wired for RGB bitstream (v1 FLORA pixels, not v2) 35 | // NEO_RGBW Pixels are wired for RGBW bitstream (NeoPixel RGBW products) 36 | 37 | // NEOPIXEL BEST PRACTICES for most reliable operation: 38 | // - Add 1000 uF CAPACITOR between NeoPixel strip's + and - connections. 39 | // - MINIMIZE WIRING LENGTH between microcontroller board and first pixel. 40 | // - NeoPixel strip's DATA-IN should pass through a 300-500 OHM RESISTOR. 41 | // - AVOID connecting NeoPixels on a LIVE CIRCUIT. If you must, ALWAYS 42 | // connect GROUND (-) first, then +, then data. 43 | // - When using a 3.3V microcontroller with a 5V-powered NeoPixel strip, 44 | // a LOGIC-LEVEL CONVERTER on the data line is STRONGLY RECOMMENDED. 45 | // (Skipping these may work OK on your workbench but can fail in the field) 46 | 47 | // define pins (varies per shield/board) 48 | #define BLE_REQ 10 49 | #define BLE_RDY 2 50 | #define BLE_RST 9 51 | 52 | // create ble serial instance, see pinouts above 53 | BLESerial BLESerial(BLE_REQ, BLE_RDY, BLE_RST); 54 | 55 | uint8_t current_state = 0; 56 | uint8_t rgb_values[3]; 57 | 58 | void setup() { 59 | Serial.begin(115200); 60 | Serial.println("Hello World!"); 61 | // custom services and characteristics can be added as well 62 | BLESerial.setLocalName("UART_HS"); 63 | BLESerial.begin(); 64 | 65 | strip.begin(); // INITIALIZE NeoPixel strip object (REQUIRED) 66 | strip.show(); // Turn OFF all pixels ASAP 67 | 68 | //pinMode(PIN, OUTPUT); 69 | //digitalWrite(PIN, LOW); 70 | 71 | current_state = 'a'; 72 | } 73 | 74 | void loop() { 75 | while(BLESerial.available()) { 76 | uint8_t character = BLESerial.read(); 77 | switch(character) { 78 | case 'a': 79 | case 'b': 80 | case 'c': 81 | case 'd': 82 | case 'e': 83 | case 'f': 84 | case 'g': 85 | case 'h': 86 | current_state = character; 87 | break; 88 | }; 89 | } 90 | switch(current_state) { 91 | case 'a': 92 | colorWipe(strip.Color(255, 0, 0), 20); // Red 93 | break; 94 | case 'b': 95 | colorWipe(strip.Color( 0, 255, 0), 20); // Green 96 | break; 97 | case 'c': 98 | colorWipe(strip.Color( 0, 0, 255), 20); // Blue 99 | break; 100 | case 'd': 101 | theaterChase(strip.Color(255, 0, 0), 20); // Red 102 | break; 103 | case 'e': 104 | theaterChase(strip.Color( 0, 255, 0), 20); // Green 105 | break; 106 | case 'f': 107 | theaterChase(strip.Color(255, 0, 255), 20); // Cyan 108 | break; 109 | case 'g': 110 | rainbow(10); 111 | break; 112 | case 'h': 113 | theaterChaseRainbow(20); 114 | break; 115 | } 116 | } 117 | 118 | // Fill strip pixels one after another with a color. Strip is NOT cleared 119 | // first; anything there will be covered pixel by pixel. Pass in color 120 | // (as a single 'packed' 32-bit value, which you can get by calling 121 | // strip.Color(red, green, blue) as shown in the loop() function above), 122 | // and a delay time (in milliseconds) between pixels. 123 | void colorWipe(uint32_t color, int wait) { 124 | for(int i=0; i RGB 185 | strip.setPixelColor(c, color); // Set pixel 'c' to value 'color' 186 | } 187 | strip.show(); // Update strip with new contents 188 | delay(wait); // Pause for a moment 189 | firstPixelHue += 65536 / 90; // One cycle of color wheel over 90 frames 190 | } 191 | } 192 | } 193 | -------------------------------------------------------------------------------- /examples/StrandtestBLE_nodelay/.none.test.only: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /examples/StrandtestBLE_nodelay/BLESerial.cpp: -------------------------------------------------------------------------------- 1 | #include "BLESerial.h" 2 | 3 | // #define BLE_SERIAL_DEBUG 4 | 5 | BLESerial* BLESerial::_instance = NULL; 6 | 7 | BLESerial::BLESerial(unsigned char req, unsigned char rdy, unsigned char rst) : 8 | BLEPeripheral(req, rdy, rst) 9 | { 10 | this->_txCount = 0; 11 | this->_rxHead = this->_rxTail = 0; 12 | this->_flushed = 0; 13 | BLESerial::_instance = this; 14 | 15 | addAttribute(this->_uartService); 16 | addAttribute(this->_uartNameDescriptor); 17 | setAdvertisedServiceUuid(this->_uartService.uuid()); 18 | addAttribute(this->_rxCharacteristic); 19 | addAttribute(this->_rxNameDescriptor); 20 | this->_rxCharacteristic.setEventHandler(BLEWritten, BLESerial::_received); 21 | addAttribute(this->_txCharacteristic); 22 | addAttribute(this->_txNameDescriptor); 23 | } 24 | 25 | void BLESerial::begin(...) { 26 | BLEPeripheral::begin(); 27 | #ifdef BLE_SERIAL_DEBUG 28 | Serial.println(F("BLESerial::begin()")); 29 | #endif 30 | } 31 | 32 | void BLESerial::poll() { 33 | if (millis() < this->_flushed + 100) { 34 | BLEPeripheral::poll(); 35 | } else { 36 | flush(); 37 | } 38 | } 39 | 40 | void BLESerial::end() { 41 | this->_rxCharacteristic.setEventHandler(BLEWritten, NULL); 42 | this->_rxHead = this->_rxTail = 0; 43 | flush(); 44 | BLEPeripheral::disconnect(); 45 | } 46 | 47 | int BLESerial::available(void) { 48 | BLEPeripheral::poll(); 49 | int retval = (this->_rxHead - this->_rxTail + sizeof(this->_rxBuffer)) % sizeof(this->_rxBuffer); 50 | #ifdef BLE_SERIAL_DEBUG 51 | Serial.print(F("BLESerial::available() = ")); 52 | Serial.println(retval); 53 | #endif 54 | return retval; 55 | } 56 | 57 | int BLESerial::peek(void) { 58 | BLEPeripheral::poll(); 59 | if (this->_rxTail == this->_rxHead) return -1; 60 | uint8_t byte = this->_rxBuffer[this->_rxTail]; 61 | #ifdef BLE_SERIAL_DEBUG 62 | Serial.print(F("BLESerial::peek() = ")); 63 | Serial.print((char) byte); 64 | Serial.print(F(" 0x")); 65 | Serial.println(byte, HEX); 66 | #endif 67 | return byte; 68 | } 69 | 70 | int BLESerial::read(void) { 71 | BLEPeripheral::poll(); 72 | if (this->_rxTail == this->_rxHead) return -1; 73 | this->_rxTail = (this->_rxTail + 1) % sizeof(this->_rxBuffer); 74 | uint8_t byte = this->_rxBuffer[this->_rxTail]; 75 | #ifdef BLE_SERIAL_DEBUG 76 | Serial.print(F("BLESerial::read() = ")); 77 | Serial.print((char) byte); 78 | Serial.print(F(" 0x")); 79 | Serial.println(byte, HEX); 80 | #endif 81 | return byte; 82 | } 83 | 84 | void BLESerial::flush(void) { 85 | if (this->_txCount == 0) return; 86 | this->_txCharacteristic.setValue(this->_txBuffer, this->_txCount); 87 | this->_flushed = millis(); 88 | this->_txCount = 0; 89 | BLEPeripheral::poll(); 90 | #ifdef BLE_SERIAL_DEBUG 91 | Serial.println(F("BLESerial::flush()")); 92 | #endif 93 | } 94 | 95 | size_t BLESerial::write(uint8_t byte) { 96 | BLEPeripheral::poll(); 97 | if (this->_txCharacteristic.subscribed() == false) return 0; 98 | this->_txBuffer[this->_txCount++] = byte; 99 | if (this->_txCount == sizeof(this->_txBuffer)) flush(); 100 | #ifdef BLE_SERIAL_DEBUG 101 | Serial.print(F("BLESerial::write(")); 102 | Serial.print((char) byte); 103 | Serial.print(F(" 0x")); 104 | Serial.print(byte, HEX); 105 | Serial.println(F(") = 1")); 106 | #endif 107 | return 1; 108 | } 109 | 110 | BLESerial::operator bool() { 111 | bool retval = BLEPeripheral::connected(); 112 | #ifdef BLE_SERIAL_DEBUG 113 | Serial.print(F("BLESerial::operator bool() = ")); 114 | Serial.println(retval); 115 | #endif 116 | return retval; 117 | } 118 | 119 | void BLESerial::_received(const uint8_t* data, size_t size) { 120 | for (int i = 0; i < size; i++) { 121 | this->_rxHead = (this->_rxHead + 1) % sizeof(this->_rxBuffer); 122 | this->_rxBuffer[this->_rxHead] = data[i]; 123 | } 124 | #ifdef BLE_SERIAL_DEBUG 125 | Serial.print(F("BLESerial::received(")); 126 | for (int i = 0; i < size; i++) Serial.print((char) data[i]); 127 | Serial.println(F(")")); 128 | #endif 129 | } 130 | 131 | void BLESerial::_received(BLECentral& /*central*/, BLECharacteristic& rxCharacteristic) { 132 | BLESerial::_instance->_received(rxCharacteristic.value(), rxCharacteristic.valueLength()); 133 | } 134 | -------------------------------------------------------------------------------- /examples/StrandtestBLE_nodelay/BLESerial.h: -------------------------------------------------------------------------------- 1 | #ifndef _BLE_SERIAL_H_ 2 | #define _BLE_SERIAL_H_ 3 | 4 | #include 5 | #include 6 | 7 | class BLESerial : public BLEPeripheral, public Stream 8 | { 9 | public: 10 | BLESerial(unsigned char req, unsigned char rdy, unsigned char rst); 11 | 12 | void begin(...); 13 | void poll(); 14 | void end(); 15 | 16 | virtual int available(void); 17 | virtual int peek(void); 18 | virtual int read(void); 19 | virtual void flush(void); 20 | virtual size_t write(uint8_t byte); 21 | using Print::write; 22 | virtual operator bool(); 23 | 24 | private: 25 | unsigned long _flushed; 26 | static BLESerial* _instance; 27 | 28 | size_t _rxHead; 29 | size_t _rxTail; 30 | size_t _rxCount() const; 31 | uint8_t _rxBuffer[BLE_ATTRIBUTE_MAX_VALUE_LENGTH]; 32 | size_t _txCount; 33 | uint8_t _txBuffer[BLE_ATTRIBUTE_MAX_VALUE_LENGTH]; 34 | 35 | BLEService _uartService = BLEService("6E400001-B5A3-F393-E0A9-E50E24DCCA9E"); 36 | BLEDescriptor _uartNameDescriptor = BLEDescriptor("2901", "UART"); 37 | BLECharacteristic _rxCharacteristic = BLECharacteristic("6E400002-B5A3-F393-E0A9-E50E24DCCA9E", BLEWriteWithoutResponse, BLE_ATTRIBUTE_MAX_VALUE_LENGTH); 38 | BLEDescriptor _rxNameDescriptor = BLEDescriptor("2901", "RX - Receive Data (Write)"); 39 | BLECharacteristic _txCharacteristic = BLECharacteristic("6E400003-B5A3-F393-E0A9-E50E24DCCA9E", BLENotify, BLE_ATTRIBUTE_MAX_VALUE_LENGTH); 40 | BLEDescriptor _txNameDescriptor = BLEDescriptor("2901", "TX - Transfer Data (Notify)"); 41 | 42 | void _received(const uint8_t* data, size_t size); 43 | static void _received(BLECentral& /*central*/, BLECharacteristic& rxCharacteristic); 44 | }; 45 | 46 | #endif 47 | -------------------------------------------------------------------------------- /examples/StrandtestBLE_nodelay/StrandtestBLE_nodelay.ino: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | * This example was developed by the Hackerspace San Salvador to demonstrate 3 | * the simultaneous use of the NeoPixel library and the Bluetooth SoftDevice. 4 | * To compile this example you'll need to add support for the NRF52 based 5 | * following the instructions at: 6 | * https://github.com/sandeepmistry/arduino-nRF5 7 | * Or adding the following URL to the board manager URLs on Arduino preferences: 8 | * https://sandeepmistry.github.io/arduino-nRF5/package_nRF5_boards_index.json 9 | * Then you can install the BLEPeripheral library avaiable at: 10 | * https://github.com/sandeepmistry/arduino-BLEPeripheral 11 | * To test it, compile this example and use the UART module from the nRF 12 | * Toolbox App for Android. Edit the interface and send the characters 13 | * 'a' to 'i' to switch the animation. 14 | * There is a no delay because this example does not block the threads execution 15 | * so the change will be shown immediately and will not need to wait for the current 16 | * animation to end. 17 | * For more info write us at: info _at- teubi.co 18 | */ 19 | #include 20 | #include 21 | #include "BLESerial.h" 22 | #include 23 | 24 | #define PIN 15 // Pin where NeoPixels are connected 25 | 26 | // Declare our NeoPixel strip object: 27 | Adafruit_NeoPixel strip(64, PIN, NEO_GRB + NEO_KHZ800); 28 | // Argument 1 = Number of pixels in NeoPixel strip 29 | // Argument 2 = Arduino pin number (most are valid) 30 | // Argument 3 = Pixel type flags, add together as needed: 31 | // NEO_KHZ800 800 KHz bitstream (most NeoPixel products w/WS2812 LEDs) 32 | // NEO_KHZ400 400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers) 33 | // NEO_GRB Pixels are wired for GRB bitstream (most NeoPixel products) 34 | // NEO_RGB Pixels are wired for RGB bitstream (v1 FLORA pixels, not v2) 35 | // NEO_RGBW Pixels are wired for RGBW bitstream (NeoPixel RGBW products) 36 | 37 | // NEOPIXEL BEST PRACTICES for most reliable operation: 38 | // - Add 1000 uF CAPACITOR between NeoPixel strip's + and - connections. 39 | // - MINIMIZE WIRING LENGTH between microcontroller board and first pixel. 40 | // - NeoPixel strip's DATA-IN should pass through a 300-500 OHM RESISTOR. 41 | // - AVOID connecting NeoPixels on a LIVE CIRCUIT. If you must, ALWAYS 42 | // connect GROUND (-) first, then +, then data. 43 | // - When using a 3.3V microcontroller with a 5V-powered NeoPixel strip, 44 | // a LOGIC-LEVEL CONVERTER on the data line is STRONGLY RECOMMENDED. 45 | // (Skipping these may work OK on your workbench but can fail in the field) 46 | 47 | // define pins (varies per shield/board) 48 | #define BLE_REQ 10 49 | #define BLE_RDY 2 50 | #define BLE_RST 9 51 | 52 | // create ble serial instance, see pinouts above 53 | BLESerial BLESerial(BLE_REQ, BLE_RDY, BLE_RST); 54 | 55 | uint8_t current_state = 0; 56 | uint8_t rgb_values[3]; 57 | 58 | void setup() { 59 | Serial.begin(115200); 60 | Serial.println("Hello World!"); 61 | // custom services and characteristics can be added as well 62 | BLESerial.setLocalName("UART_HS"); 63 | BLESerial.begin(); 64 | 65 | strip.begin(); // INITIALIZE NeoPixel strip object (REQUIRED) 66 | strip.show(); // Turn OFF all pixels ASAP 67 | 68 | //pinMode(PIN, OUTPUT); 69 | //digitalWrite(PIN, LOW); 70 | 71 | current_state = 'a'; 72 | } 73 | 74 | void loop() { 75 | while(BLESerial.available()) { 76 | uint8_t character = BLESerial.read(); 77 | switch(character) { 78 | case 'a': 79 | case 'b': 80 | case 'c': 81 | case 'd': 82 | case 'e': 83 | case 'f': 84 | case 'g': 85 | case 'h': 86 | current_state = character; 87 | break; 88 | }; 89 | } 90 | switch(current_state) { 91 | case 'a': 92 | colorWipe(strip.Color(255, 0, 0), 20); // Red 93 | break; 94 | case 'b': 95 | colorWipe(strip.Color( 0, 255, 0), 20); // Green 96 | break; 97 | case 'c': 98 | colorWipe(strip.Color( 0, 0, 255), 20); // Blue 99 | break; 100 | case 'd': 101 | theaterChase(strip.Color(255, 0, 0), 20); // Red 102 | break; 103 | case 'e': 104 | theaterChase(strip.Color( 0, 255, 0), 20); // Green 105 | break; 106 | case 'f': 107 | theaterChase(strip.Color(255, 0, 255), 20); // Cyan 108 | break; 109 | case 'g': 110 | rainbow(10); 111 | break; 112 | case 'h': 113 | theaterChaseRainbow(20); 114 | break; 115 | } 116 | } 117 | 118 | // Some functions of our own for creating animated effects ----------------- 119 | 120 | // Fill strip pixels one after another with a color. Strip is NOT cleared 121 | // first; anything there will be covered pixel by pixel. Pass in color 122 | // (as a single 'packed' 32-bit value, which you can get by calling 123 | // strip.Color(red, green, blue) as shown in the loop() function above), 124 | // and a delay time (in milliseconds) between pixels. 125 | void colorWipe(uint32_t color, int wait) { 126 | if(pixelInterval != wait) 127 | pixelInterval = wait; // Update delay time 128 | strip.setPixelColor(pixelCurrent, color); // Set pixel's color (in RAM) 129 | strip.show(); // Update strip to match 130 | pixelCurrent++; // Advance current pixel 131 | if(pixelCurrent >= pixelNumber) // Loop the pattern from the first LED 132 | pixelCurrent = 0; 133 | } 134 | 135 | // Theater-marquee-style chasing lights. Pass in a color (32-bit value, 136 | // a la strip.Color(r,g,b) as mentioned above), and a delay time (in ms) 137 | // between frames. 138 | void theaterChase(uint32_t color, int wait) { 139 | if(pixelInterval != wait) 140 | pixelInterval = wait; // Update delay time 141 | for(int i = 0; i < pixelNumber; i++) { 142 | strip.setPixelColor(i + pixelQueue, color); // Set pixel's color (in RAM) 143 | } 144 | strip.show(); // Update strip to match 145 | for(int i=0; i < pixelNumber; i+3) { 146 | strip.setPixelColor(i + pixelQueue, strip.Color(0, 0, 0)); // Set pixel's color (in RAM) 147 | } 148 | pixelQueue++; // Advance current pixel 149 | if(pixelQueue >= 3) 150 | pixelQueue = 0; // Loop the pattern from the first LED 151 | } 152 | 153 | // Rainbow cycle along whole strip. Pass delay time (in ms) between frames. 154 | void rainbow(uint8_t wait) { 155 | if(pixelInterval != wait) 156 | pixelInterval = wait; 157 | for(uint16_t i=0; i < pixelNumber; i++) { 158 | strip.setPixelColor(i, Wheel((i + pixelCycle) & 255)); // Update delay time 159 | } 160 | strip.show(); // Update strip to match 161 | pixelCycle++; // Advance current cycle 162 | if(pixelCycle >= 256) 163 | pixelCycle = 0; // Loop the cycle back to the begining 164 | } 165 | 166 | //Theatre-style crawling lights with rainbow effect 167 | void theaterChaseRainbow(uint8_t wait) { 168 | if(pixelInterval != wait) 169 | pixelInterval = wait; // Update delay time 170 | for(int i=0; i < pixelNumber; i+3) { 171 | strip.setPixelColor(i + pixelQueue, Wheel((i + pixelCycle) % 255)); // Update delay time 172 | } 173 | strip.show(); 174 | for(int i=0; i < pixelNumber; i+3) { 175 | strip.setPixelColor(i + pixelQueue, strip.Color(0, 0, 0)); // Update delay time 176 | } 177 | pixelQueue++; // Advance current queue 178 | pixelCycle++; // Advance current cycle 179 | if(pixelQueue >= 3) 180 | pixelQueue = 0; // Loop 181 | if(pixelCycle >= 256) 182 | pixelCycle = 0; // Loop 183 | } 184 | 185 | // Input a value 0 to 255 to get a color value. 186 | // The colours are a transition r - g - b - back to r. 187 | uint32_t Wheel(byte WheelPos) { 188 | WheelPos = 255 - WheelPos; 189 | if(WheelPos < 85) { 190 | return strip.Color(255 - WheelPos * 3, 0, WheelPos * 3); 191 | } 192 | if(WheelPos < 170) { 193 | WheelPos -= 85; 194 | return strip.Color(0, WheelPos * 3, 255 - WheelPos * 3); 195 | } 196 | WheelPos -= 170; 197 | return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0); 198 | } 199 | -------------------------------------------------------------------------------- /examples/buttoncycler/.esp8266.test.skip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adafruit/Adafruit_NeoPixel/70d02aae78fa83d8517c9fb4679a3aa2038369a5/examples/buttoncycler/.esp8266.test.skip -------------------------------------------------------------------------------- /examples/buttoncycler/buttoncycler.ino: -------------------------------------------------------------------------------- 1 | // Simple demonstration on using an input device to trigger changes on your 2 | // NeoPixels. Wire a momentary push button to connect from ground to a 3 | // digital IO pin. When the button is pressed it will change to a new pixel 4 | // animation. Initial state has all pixels off -- press the button once to 5 | // start the first animation. As written, the button does not interrupt an 6 | // animation in-progress, it works only when idle. 7 | 8 | #include 9 | #ifdef __AVR__ 10 | #include // Required for 16 MHz Adafruit Trinket 11 | #endif 12 | 13 | // Digital IO pin connected to the button. This will be driven with a 14 | // pull-up resistor so the switch pulls the pin to ground momentarily. 15 | // On a high -> low transition the button press logic will execute. 16 | #define BUTTON_PIN 2 17 | 18 | #define PIXEL_PIN 6 // Digital IO pin connected to the NeoPixels. 19 | 20 | #define PIXEL_COUNT 16 // Number of NeoPixels 21 | 22 | // Declare our NeoPixel strip object: 23 | Adafruit_NeoPixel strip(PIXEL_COUNT, PIXEL_PIN, NEO_GRB + NEO_KHZ800); 24 | // Argument 1 = Number of pixels in NeoPixel strip 25 | // Argument 2 = Arduino pin number (most are valid) 26 | // Argument 3 = Pixel type flags, add together as needed: 27 | // NEO_KHZ800 800 KHz bitstream (most NeoPixel products w/WS2812 LEDs) 28 | // NEO_KHZ400 400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers) 29 | // NEO_GRB Pixels are wired for GRB bitstream (most NeoPixel products) 30 | // NEO_RGB Pixels are wired for RGB bitstream (v1 FLORA pixels, not v2) 31 | // NEO_RGBW Pixels are wired for RGBW bitstream (NeoPixel RGBW products) 32 | 33 | boolean oldState = HIGH; 34 | int mode = 0; // Currently-active animation mode, 0-9 35 | 36 | void setup() { 37 | pinMode(BUTTON_PIN, INPUT_PULLUP); 38 | strip.begin(); // Initialize NeoPixel strip object (REQUIRED) 39 | strip.show(); // Initialize all pixels to 'off' 40 | } 41 | 42 | void loop() { 43 | // Get current button state. 44 | boolean newState = digitalRead(BUTTON_PIN); 45 | 46 | // Check if state changed from high to low (button press). 47 | if((newState == LOW) && (oldState == HIGH)) { 48 | // Short delay to debounce button. 49 | delay(20); 50 | // Check if button is still low after debounce. 51 | newState = digitalRead(BUTTON_PIN); 52 | if(newState == LOW) { // Yes, still low 53 | if(++mode > 8) mode = 0; // Advance to next mode, wrap around after #8 54 | switch(mode) { // Start the new animation... 55 | case 0: 56 | colorWipe(strip.Color( 0, 0, 0), 50); // Black/off 57 | break; 58 | case 1: 59 | colorWipe(strip.Color(255, 0, 0), 50); // Red 60 | break; 61 | case 2: 62 | colorWipe(strip.Color( 0, 255, 0), 50); // Green 63 | break; 64 | case 3: 65 | colorWipe(strip.Color( 0, 0, 255), 50); // Blue 66 | break; 67 | case 4: 68 | theaterChase(strip.Color(127, 127, 127), 50); // White 69 | break; 70 | case 5: 71 | theaterChase(strip.Color(127, 0, 0), 50); // Red 72 | break; 73 | case 6: 74 | theaterChase(strip.Color( 0, 0, 127), 50); // Blue 75 | break; 76 | case 7: 77 | rainbow(10); 78 | break; 79 | case 8: 80 | theaterChaseRainbow(50); 81 | break; 82 | } 83 | } 84 | } 85 | 86 | // Set the last-read button state to the old state. 87 | oldState = newState; 88 | } 89 | 90 | // Fill strip pixels one after another with a color. Strip is NOT cleared 91 | // first; anything there will be covered pixel by pixel. Pass in color 92 | // (as a single 'packed' 32-bit value, which you can get by calling 93 | // strip.Color(red, green, blue) as shown in the loop() function above), 94 | // and a delay time (in milliseconds) between pixels. 95 | void colorWipe(uint32_t color, int wait) { 96 | for(int i=0; i RGB 157 | strip.setPixelColor(c, color); // Set pixel 'c' to value 'color' 158 | } 159 | strip.show(); // Update strip with new contents 160 | delay(wait); // Pause for a moment 161 | firstPixelHue += 65536 / 90; // One cycle of color wheel over 90 frames 162 | } 163 | } 164 | } 165 | -------------------------------------------------------------------------------- /examples/simple/.esp8266.test.skip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adafruit/Adafruit_NeoPixel/70d02aae78fa83d8517c9fb4679a3aa2038369a5/examples/simple/.esp8266.test.skip -------------------------------------------------------------------------------- /examples/simple/simple.ino: -------------------------------------------------------------------------------- 1 | // NeoPixel Ring simple sketch (c) 2013 Shae Erisson 2 | // Released under the GPLv3 license to match the rest of the 3 | // Adafruit NeoPixel library 4 | 5 | #include 6 | #ifdef __AVR__ 7 | #include // Required for 16 MHz Adafruit Trinket 8 | #endif 9 | 10 | // Which pin on the Arduino is connected to the NeoPixels? 11 | #define PIN 6 // On Trinket or Gemma, suggest changing this to 1 12 | 13 | // How many NeoPixels are attached to the Arduino? 14 | #define NUMPIXELS 16 // Popular NeoPixel ring size 15 | 16 | // When setting up the NeoPixel library, we tell it how many pixels, 17 | // and which pin to use to send signals. Note that for older NeoPixel 18 | // strips you might need to change the third parameter -- see the 19 | // strandtest example for more information on possible values. 20 | Adafruit_NeoPixel pixels(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800); 21 | 22 | #define DELAYVAL 500 // Time (in milliseconds) to pause between pixels 23 | 24 | void setup() { 25 | // These lines are specifically to support the Adafruit Trinket 5V 16 MHz. 26 | // Any other board, you can remove this part (but no harm leaving it): 27 | #if defined(__AVR_ATtiny85__) && (F_CPU == 16000000) 28 | clock_prescale_set(clock_div_1); 29 | #endif 30 | // END of Trinket-specific code. 31 | 32 | pixels.begin(); // INITIALIZE NeoPixel strip object (REQUIRED) 33 | } 34 | 35 | void loop() { 36 | pixels.clear(); // Set all pixel colors to 'off' 37 | 38 | // The first NeoPixel in a strand is #0, second is 1, all the way up 39 | // to the count of pixels minus one. 40 | for(int i=0; i 9 | #ifdef __AVR__ 10 | #include // Required for 16 MHz Adafruit Trinket 11 | #endif 12 | 13 | // Which pin on the Arduino is connected to the NeoPixels? 14 | int pin = 6; // On Trinket or Gemma, suggest changing this to 1 15 | 16 | // How many NeoPixels are attached to the Arduino? 17 | int numPixels = 16; // Popular NeoPixel ring size 18 | 19 | // NeoPixel color format & data rate. See the strandtest example for 20 | // information on possible values. 21 | int pixelFormat = NEO_GRB + NEO_KHZ800; 22 | 23 | // Rather than declaring the whole NeoPixel object here, we just create 24 | // a pointer for one, which we'll then allocate later... 25 | Adafruit_NeoPixel *pixels; 26 | 27 | #define DELAYVAL 500 // Time (in milliseconds) to pause between pixels 28 | 29 | void setup() { 30 | // These lines are specifically to support the Adafruit Trinket 5V 16 MHz. 31 | // Any other board, you can remove this part (but no harm leaving it): 32 | #if defined(__AVR_ATtiny85__) && (F_CPU == 16000000) 33 | clock_prescale_set(clock_div_1); 34 | #endif 35 | // END of Trinket-specific code. 36 | 37 | // Right about here is where we could read 'pin', 'numPixels' and/or 38 | // 'pixelFormat' from EEPROM or a file on SD or whatever. This is a simple 39 | // example and doesn't do that -- those variables are just set to fixed 40 | // values at the top of this code -- but this is where it would happen. 41 | 42 | // Then create a new NeoPixel object dynamically with these values: 43 | pixels = new Adafruit_NeoPixel(numPixels, pin, pixelFormat); 44 | 45 | // Going forward from here, code works almost identically to any other 46 | // NeoPixel example, but instead of the dot operator on function calls 47 | // (e.g. pixels.begin()), we instead use pointer indirection (->) like so: 48 | pixels->begin(); // INITIALIZE NeoPixel strip object (REQUIRED) 49 | // You'll see more of this in the loop() function below. 50 | } 51 | 52 | void loop() { 53 | pixels->clear(); // Set all pixel colors to 'off' 54 | 55 | // The first NeoPixel in a strand is #0, second is 1, all the way up 56 | // to the count of pixels minus one. 57 | for(int i=0; iColor() takes RGB values, from 0,0,0 up to 255,255,255 60 | // Here we're using a moderately bright green color: 61 | pixels->setPixelColor(i, pixels->Color(0, 150, 0)); 62 | 63 | pixels->show(); // Send the updated pixel colors to the hardware. 64 | 65 | delay(DELAYVAL); // Pause before next pass through loop 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /examples/strandtest/.esp8266.test.skip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adafruit/Adafruit_NeoPixel/70d02aae78fa83d8517c9fb4679a3aa2038369a5/examples/strandtest/.esp8266.test.skip -------------------------------------------------------------------------------- /examples/strandtest/strandtest.ino: -------------------------------------------------------------------------------- 1 | // A basic everyday NeoPixel strip test program. 2 | 3 | // NEOPIXEL BEST PRACTICES for most reliable operation: 4 | // - Add 1000 uF CAPACITOR between NeoPixel strip's + and - connections. 5 | // - MINIMIZE WIRING LENGTH between microcontroller board and first pixel. 6 | // - NeoPixel strip's DATA-IN should pass through a 300-500 OHM RESISTOR. 7 | // - AVOID connecting NeoPixels on a LIVE CIRCUIT. If you must, ALWAYS 8 | // connect GROUND (-) first, then +, then data. 9 | // - When using a 3.3V microcontroller with a 5V-powered NeoPixel strip, 10 | // a LOGIC-LEVEL CONVERTER on the data line is STRONGLY RECOMMENDED. 11 | // (Skipping these may work OK on your workbench but can fail in the field) 12 | 13 | #include 14 | #ifdef __AVR__ 15 | #include // Required for 16 MHz Adafruit Trinket 16 | #endif 17 | 18 | // Which pin on the Arduino is connected to the NeoPixels? 19 | // On a Trinket or Gemma we suggest changing this to 1: 20 | #define LED_PIN 6 21 | 22 | // How many NeoPixels are attached to the Arduino? 23 | #define LED_COUNT 60 24 | 25 | // Declare our NeoPixel strip object: 26 | Adafruit_NeoPixel strip(LED_COUNT, LED_PIN, NEO_GRB + NEO_KHZ800); 27 | // Argument 1 = Number of pixels in NeoPixel strip 28 | // Argument 2 = Arduino pin number (most are valid) 29 | // Argument 3 = Pixel type flags, add together as needed: 30 | // NEO_KHZ800 800 KHz bitstream (most NeoPixel products w/WS2812 LEDs) 31 | // NEO_KHZ400 400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers) 32 | // NEO_GRB Pixels are wired for GRB bitstream (most NeoPixel products) 33 | // NEO_RGB Pixels are wired for RGB bitstream (v1 FLORA pixels, not v2) 34 | // NEO_RGBW Pixels are wired for RGBW bitstream (NeoPixel RGBW products) 35 | 36 | 37 | // setup() function -- runs once at startup -------------------------------- 38 | 39 | void setup() { 40 | // These lines are specifically to support the Adafruit Trinket 5V 16 MHz. 41 | // Any other board, you can remove this part (but no harm leaving it): 42 | #if defined(__AVR_ATtiny85__) && (F_CPU == 16000000) 43 | clock_prescale_set(clock_div_1); 44 | #endif 45 | // END of Trinket-specific code. 46 | 47 | strip.begin(); // INITIALIZE NeoPixel strip object (REQUIRED) 48 | strip.show(); // Turn OFF all pixels ASAP 49 | strip.setBrightness(50); // Set BRIGHTNESS to about 1/5 (max = 255) 50 | } 51 | 52 | 53 | // loop() function -- runs repeatedly as long as board is on --------------- 54 | 55 | void loop() { 56 | // Fill along the length of the strip in various colors... 57 | colorWipe(strip.Color(255, 0, 0), 50); // Red 58 | colorWipe(strip.Color( 0, 255, 0), 50); // Green 59 | colorWipe(strip.Color( 0, 0, 255), 50); // Blue 60 | 61 | // Do a theater marquee effect in various colors... 62 | theaterChase(strip.Color(127, 127, 127), 50); // White, half brightness 63 | theaterChase(strip.Color(127, 0, 0), 50); // Red, half brightness 64 | theaterChase(strip.Color( 0, 0, 127), 50); // Blue, half brightness 65 | 66 | rainbow(10); // Flowing rainbow cycle along the whole strip 67 | theaterChaseRainbow(50); // Rainbow-enhanced theaterChase variant 68 | } 69 | 70 | 71 | // Some functions of our own for creating animated effects ----------------- 72 | 73 | // Fill strip pixels one after another with a color. Strip is NOT cleared 74 | // first; anything there will be covered pixel by pixel. Pass in color 75 | // (as a single 'packed' 32-bit value, which you can get by calling 76 | // strip.Color(red, green, blue) as shown in the loop() function above), 77 | // and a delay time (in milliseconds) between pixels. 78 | void colorWipe(uint32_t color, int wait) { 79 | for(int i=0; i RGB 136 | strip.setPixelColor(c, color); // Set pixel 'c' to value 'color' 137 | } 138 | strip.show(); // Update strip with new contents 139 | delay(wait); // Pause for a moment 140 | firstPixelHue += 65536 / 90; // One cycle of color wheel over 90 frames 141 | } 142 | } 143 | } 144 | -------------------------------------------------------------------------------- /examples/strandtest_nodelay/.esp8266.test.skip: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /examples/strandtest_nodelay/strandtest_nodelay.ino: -------------------------------------------------------------------------------- 1 | // A non-blocking everyday NeoPixel strip test program. 2 | 3 | // NEOPIXEL BEST PRACTICES for most reliable operation: 4 | // - Add 1000 uF CAPACITOR between NeoPixel strip's + and - connections. 5 | // - MINIMIZE WIRING LENGTH between microcontroller board and first pixel. 6 | // - NeoPixel strip's DATA-IN should pass through a 300-500 OHM RESISTOR. 7 | // - AVOID connecting NeoPixels on a LIVE CIRCUIT. If you must, ALWAYS 8 | // connect GROUND (-) first, then +, then data. 9 | // - When using a 3.3V microcontroller with a 5V-powered NeoPixel strip, 10 | // a LOGIC-LEVEL CONVERTER on the data line is STRONGLY RECOMMENDED. 11 | // (Skipping these may work OK on your workbench but can fail in the field) 12 | 13 | #include 14 | #ifdef __AVR__ 15 | #include // Required for 16 MHz Adafruit Trinket 16 | #endif 17 | 18 | // Which pin on the Arduino is connected to the NeoPixels? 19 | // On a Trinket or Gemma we suggest changing this to 1: 20 | #ifdef ESP32 21 | // Cannot use 6 as output for ESP. Pins 6-11 are connected to SPI flash. Use 16 instead. 22 | #define LED_PIN 16 23 | #else 24 | #define LED_PIN 6 25 | #endif 26 | 27 | // How many NeoPixels are attached to the Arduino? 28 | #define LED_COUNT 60 29 | 30 | // Declare our NeoPixel strip object: 31 | Adafruit_NeoPixel strip(LED_COUNT, LED_PIN, NEO_GRB + NEO_KHZ800); 32 | // Argument 1 = Number of pixels in NeoPixel strip 33 | // Argument 2 = Arduino pin number (most are valid) 34 | // Argument 3 = Pixel type flags, add together as needed: 35 | // NEO_KHZ800 800 KHz bitstream (most NeoPixel products w/WS2812 LEDs) 36 | // NEO_KHZ400 400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers) 37 | // NEO_GRB Pixels are wired for GRB bitstream (most NeoPixel products) 38 | // NEO_RGB Pixels are wired for RGB bitstream (v1 FLORA pixels, not v2) 39 | // NEO_RGBW Pixels are wired for RGBW bitstream (NeoPixel RGBW products) 40 | 41 | unsigned long pixelPrevious = 0; // Previous Pixel Millis 42 | unsigned long patternPrevious = 0; // Previous Pattern Millis 43 | int patternCurrent = 0; // Current Pattern Number 44 | int patternInterval = 5000; // Pattern Interval (ms) 45 | bool patternComplete = false; 46 | 47 | int pixelInterval = 50; // Pixel Interval (ms) 48 | int pixelQueue = 0; // Pattern Pixel Queue 49 | int pixelCycle = 0; // Pattern Pixel Cycle 50 | uint16_t pixelNumber = LED_COUNT; // Total Number of Pixels 51 | 52 | // setup() function -- runs once at startup -------------------------------- 53 | void setup() { 54 | // These lines are specifically to support the Adafruit Trinket 5V 16 MHz. 55 | // Any other board, you can remove this part (but no harm leaving it): 56 | #if defined(__AVR_ATtiny85__) && (F_CPU == 16000000) 57 | clock_prescale_set(clock_div_1); 58 | #endif 59 | // END of Trinket-specific code. 60 | 61 | strip.begin(); // INITIALIZE NeoPixel strip object (REQUIRED) 62 | strip.show(); // Turn OFF all pixels ASAP 63 | strip.setBrightness(50); // Set BRIGHTNESS to about 1/5 (max = 255) 64 | } 65 | 66 | // loop() function -- runs repeatedly as long as board is on --------------- 67 | void loop() { 68 | unsigned long currentMillis = millis(); // Update current time 69 | if( patternComplete || (currentMillis - patternPrevious) >= patternInterval) { // Check for expired time 70 | patternComplete = false; 71 | patternPrevious = currentMillis; 72 | patternCurrent++; // Advance to next pattern 73 | if(patternCurrent >= 7) 74 | patternCurrent = 0; 75 | } 76 | 77 | if(currentMillis - pixelPrevious >= pixelInterval) { // Check for expired time 78 | pixelPrevious = currentMillis; // Run current frame 79 | switch (patternCurrent) { 80 | case 7: 81 | theaterChaseRainbow(50); // Rainbow-enhanced theaterChase variant 82 | break; 83 | case 6: 84 | rainbow(10); // Flowing rainbow cycle along the whole strip 85 | break; 86 | case 5: 87 | theaterChase(strip.Color(0, 0, 127), 50); // Blue 88 | break; 89 | case 4: 90 | theaterChase(strip.Color(127, 0, 0), 50); // Red 91 | break; 92 | case 3: 93 | theaterChase(strip.Color(127, 127, 127), 50); // White 94 | break; 95 | case 2: 96 | colorWipe(strip.Color(0, 0, 255), 50); // Blue 97 | break; 98 | case 1: 99 | colorWipe(strip.Color(0, 255, 0), 50); // Green 100 | break; 101 | default: 102 | colorWipe(strip.Color(255, 0, 0), 50); // Red 103 | break; 104 | } 105 | } 106 | } 107 | 108 | // Some functions of our own for creating animated effects ----------------- 109 | 110 | // Fill strip pixels one after another with a color. Strip is NOT cleared 111 | // first; anything there will be covered pixel by pixel. Pass in color 112 | // (as a single 'packed' 32-bit value, which you can get by calling 113 | // strip.Color(red, green, blue) as shown in the loop() function above), 114 | // and a delay time (in milliseconds) between pixels. 115 | void colorWipe(uint32_t color, int wait) { 116 | static uint16_t current_pixel = 0; 117 | pixelInterval = wait; // Update delay time 118 | strip.setPixelColor(current_pixel++, color); // Set pixel's color (in RAM) 119 | strip.show(); // Update strip to match 120 | if(current_pixel >= pixelNumber) { // Loop the pattern from the first LED 121 | current_pixel = 0; 122 | patternComplete = true; 123 | } 124 | } 125 | 126 | // Theater-marquee-style chasing lights. Pass in a color (32-bit value, 127 | // a la strip.Color(r,g,b) as mentioned above), and a delay time (in ms) 128 | // between frames. 129 | void theaterChase(uint32_t color, int wait) { 130 | static uint32_t loop_count = 0; 131 | static uint16_t current_pixel = 0; 132 | 133 | pixelInterval = wait; // Update delay time 134 | 135 | strip.clear(); 136 | 137 | for(int c=current_pixel; c < pixelNumber; c += 3) { 138 | strip.setPixelColor(c, color); 139 | } 140 | strip.show(); 141 | 142 | current_pixel++; 143 | if (current_pixel >= 3) { 144 | current_pixel = 0; 145 | loop_count++; 146 | } 147 | 148 | if (loop_count >= 10) { 149 | current_pixel = 0; 150 | loop_count = 0; 151 | patternComplete = true; 152 | } 153 | } 154 | 155 | // Rainbow cycle along whole strip. Pass delay time (in ms) between frames. 156 | void rainbow(uint8_t wait) { 157 | if(pixelInterval != wait) 158 | pixelInterval = wait; 159 | for(uint16_t i=0; i < pixelNumber; i++) { 160 | strip.setPixelColor(i, Wheel((i + pixelCycle) & 255)); // Update delay time 161 | } 162 | strip.show(); // Update strip to match 163 | pixelCycle++; // Advance current cycle 164 | if(pixelCycle >= 256) 165 | pixelCycle = 0; // Loop the cycle back to the begining 166 | } 167 | 168 | //Theatre-style crawling lights with rainbow effect 169 | void theaterChaseRainbow(uint8_t wait) { 170 | if(pixelInterval != wait) 171 | pixelInterval = wait; // Update delay time 172 | for(int i=0; i < pixelNumber; i+=3) { 173 | strip.setPixelColor(i + pixelQueue, Wheel((i + pixelCycle) % 255)); // Update delay time 174 | } 175 | strip.show(); 176 | for(int i=0; i < pixelNumber; i+=3) { 177 | strip.setPixelColor(i + pixelQueue, strip.Color(0, 0, 0)); // Update delay time 178 | } 179 | pixelQueue++; // Advance current queue 180 | pixelCycle++; // Advance current cycle 181 | if(pixelQueue >= 3) 182 | pixelQueue = 0; // Loop 183 | if(pixelCycle >= 256) 184 | pixelCycle = 0; // Loop 185 | } 186 | 187 | // Input a value 0 to 255 to get a color value. 188 | // The colours are a transition r - g - b - back to r. 189 | uint32_t Wheel(byte WheelPos) { 190 | WheelPos = 255 - WheelPos; 191 | if(WheelPos < 85) { 192 | return strip.Color(255 - WheelPos * 3, 0, WheelPos * 3); 193 | } 194 | if(WheelPos < 170) { 195 | WheelPos -= 85; 196 | return strip.Color(0, WheelPos * 3, 255 - WheelPos * 3); 197 | } 198 | WheelPos -= 170; 199 | return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0); 200 | } 201 | -------------------------------------------------------------------------------- /examples/strandtest_wheel/.esp8266.test.skip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adafruit/Adafruit_NeoPixel/70d02aae78fa83d8517c9fb4679a3aa2038369a5/examples/strandtest_wheel/.esp8266.test.skip -------------------------------------------------------------------------------- /examples/strandtest_wheel/strandtest_wheel.ino: -------------------------------------------------------------------------------- 1 | #include 2 | #ifdef __AVR__ 3 | #include 4 | #endif 5 | 6 | #define PIN 6 7 | 8 | // Parameter 1 = number of pixels in strip 9 | // Parameter 2 = Arduino pin number (most are valid) 10 | // Parameter 3 = pixel type flags, add together as needed: 11 | // NEO_KHZ800 800 KHz bitstream (most NeoPixel products w/WS2812 LEDs) 12 | // NEO_KHZ400 400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers) 13 | // NEO_GRB Pixels are wired for GRB bitstream (most NeoPixel products) 14 | // NEO_RGB Pixels are wired for RGB bitstream (v1 FLORA pixels, not v2) 15 | // NEO_RGBW Pixels are wired for RGBW bitstream (NeoPixel RGBW products) 16 | Adafruit_NeoPixel strip = Adafruit_NeoPixel(60, PIN, NEO_GRB + NEO_KHZ800); 17 | 18 | // IMPORTANT: To reduce NeoPixel burnout risk, add 1000 uF capacitor across 19 | // pixel power leads, add 300 - 500 Ohm resistor on first pixel's data input 20 | // and minimize distance between Arduino and first pixel. Avoid connecting 21 | // on a live circuit...if you must, connect GND first. 22 | 23 | void setup() { 24 | // This is for Trinket 5V 16MHz, you can remove these three lines if you are not using a Trinket 25 | #if defined (__AVR_ATtiny85__) 26 | if (F_CPU == 16000000) clock_prescale_set(clock_div_1); 27 | #endif 28 | // End of trinket special code 29 | 30 | strip.begin(); 31 | strip.setBrightness(50); 32 | strip.show(); // Initialize all pixels to 'off' 33 | } 34 | 35 | void loop() { 36 | // Some example procedures showing how to display to the pixels: 37 | colorWipe(strip.Color(255, 0, 0), 50); // Red 38 | colorWipe(strip.Color(0, 255, 0), 50); // Green 39 | colorWipe(strip.Color(0, 0, 255), 50); // Blue 40 | //colorWipe(strip.Color(0, 0, 0, 255), 50); // White RGBW 41 | // Send a theater pixel chase in... 42 | theaterChase(strip.Color(127, 127, 127), 50); // White 43 | theaterChase(strip.Color(127, 0, 0), 50); // Red 44 | theaterChase(strip.Color(0, 0, 127), 50); // Blue 45 | 46 | rainbow(20); 47 | rainbowCycle(20); 48 | theaterChaseRainbow(50); 49 | } 50 | 51 | // Fill the dots one after the other with a color 52 | void colorWipe(uint32_t c, uint8_t wait) { 53 | for(uint16_t i=0; i 11 | #include "sysctl.h" 12 | 13 | void k210Show( 14 | uint8_t pin, uint8_t *pixels, uint32_t numBytes, boolean is800KHz) 15 | { 16 | 17 | #define CYCLES_800_T0H (sysctl_clock_get_freq(SYSCTL_CLOCK_CPU) / 2500000) // 0.4us 18 | #define CYCLES_800_T1H (sysctl_clock_get_freq(SYSCTL_CLOCK_CPU) / 1250000) // 0.8us 19 | #define CYCLES_800 (sysctl_clock_get_freq(SYSCTL_CLOCK_CPU) / 800000) // 1.25us per bit 20 | #define CYCLES_400_T0H (sysctl_clock_get_freq(SYSCTL_CLOCK_CPU) / 2000000) // 0.5uS 21 | #define CYCLES_400_T1H (sysctl_clock_get_freq(SYSCTL_CLOCK_CPU) / 833333) // 1.2us 22 | #define CYCLES_400 (sysctl_clock_get_freq(SYSCTL_CLOCK_CPU) / 400000) // 2.5us per bit 23 | 24 | uint8_t *p, *end, pix, mask; 25 | uint32_t t, time0, time1, period, c, startTime; 26 | 27 | p = pixels; 28 | end = p + numBytes; 29 | pix = *p++; 30 | mask = 0x80; 31 | startTime = 0; 32 | 33 | #ifdef NEO_KHZ400 34 | if (is800KHz) 35 | { 36 | #endif 37 | time0 = CYCLES_800_T0H; 38 | time1 = CYCLES_800_T1H; 39 | period = CYCLES_800; 40 | #ifdef NEO_KHZ400 41 | } 42 | else 43 | { // 400 KHz bitstream 44 | time0 = CYCLES_400_T0H; 45 | time1 = CYCLES_400_T1H; 46 | period = CYCLES_400; 47 | } 48 | #endif 49 | 50 | for (t = time0;; t = time0) 51 | { 52 | if (pix & mask) 53 | t = time1; // Bit high duration 54 | while (((c = read_cycle()) - startTime) < period) 55 | ; // Wait for bit start 56 | digitalWrite(pin, HIGH); 57 | startTime = c; // Save start time 58 | while (((c = read_cycle()) - startTime) < t) 59 | ; // Wait high duration 60 | digitalWrite(pin, LOW); 61 | 62 | if (!(mask >>= 1)) 63 | { // Next bit/byte 64 | if (p >= end) 65 | break; 66 | pix = *p++; 67 | mask = 0x80; 68 | } 69 | } 70 | while ((read_cycle() - startTime) < period) 71 | ; // Wait for last bit 72 | } 73 | 74 | #endif // KENDRYTE_K210 75 | -------------------------------------------------------------------------------- /keywords.txt: -------------------------------------------------------------------------------- 1 | ####################################### 2 | # Syntax Coloring Map For Adafruit_NeoPixel 3 | ####################################### 4 | # Class 5 | ####################################### 6 | 7 | Adafruit_NeoPixel KEYWORD1 8 | 9 | ####################################### 10 | # Methods and Functions 11 | ####################################### 12 | 13 | begin KEYWORD2 14 | show KEYWORD2 15 | setPin KEYWORD2 16 | setPixelColor KEYWORD2 17 | fill KEYWORD2 18 | setBrightness KEYWORD2 19 | clear KEYWORD2 20 | updateLength KEYWORD2 21 | updateType KEYWORD2 22 | canShow KEYWORD2 23 | getPixels KEYWORD2 24 | getBrightness KEYWORD2 25 | getPin KEYWORD2 26 | numPixels KEYWORD2 27 | getPixelColor KEYWORD2 28 | sine8 KEYWORD2 29 | gamma8 KEYWORD2 30 | Color KEYWORD2 31 | ColorHSV KEYWORD2 32 | gamma32 KEYWORD2 33 | 34 | ####################################### 35 | # Constants 36 | ####################################### 37 | 38 | NEO_COLMASK LITERAL1 39 | NEO_SPDMASK LITERAL1 40 | NEO_KHZ800 LITERAL1 41 | NEO_KHZ400 LITERAL1 42 | NEO_RGB LITERAL1 43 | NEO_RBG LITERAL1 44 | NEO_GRB LITERAL1 45 | NEO_GBR LITERAL1 46 | NEO_BRG LITERAL1 47 | NEO_BGR LITERAL1 48 | NEO_WRGB LITERAL1 49 | NEO_WRBG LITERAL1 50 | NEO_WGRB LITERAL1 51 | NEO_WGBR LITERAL1 52 | NEO_WBRG LITERAL1 53 | NEO_WBGR LITERAL1 54 | NEO_RWGB LITERAL1 55 | NEO_RWBG LITERAL1 56 | NEO_RGWB LITERAL1 57 | NEO_RGBW LITERAL1 58 | NEO_RBWG LITERAL1 59 | NEO_RBGW LITERAL1 60 | NEO_GWRB LITERAL1 61 | NEO_GWBR LITERAL1 62 | NEO_GRWB LITERAL1 63 | NEO_GRBW LITERAL1 64 | NEO_GBWR LITERAL1 65 | NEO_GBRW LITERAL1 66 | NEO_BWRG LITERAL1 67 | NEO_BWGR LITERAL1 68 | NEO_BRWG LITERAL1 69 | NEO_BRGW LITERAL1 70 | NEO_BGWR LITERAL1 71 | NEO_BGRW LITERAL1 72 | 73 | -------------------------------------------------------------------------------- /library.properties: -------------------------------------------------------------------------------- 1 | name=Adafruit NeoPixel 2 | version=1.15.1 3 | author=Adafruit 4 | maintainer=Adafruit 5 | sentence=Arduino library for controlling single-wire-based LED pixels and strip. 6 | paragraph=Arduino library for controlling single-wire-based LED pixels and strip. 7 | category=Display 8 | url=https://github.com/adafruit/Adafruit_NeoPixel 9 | architectures=* 10 | includes=Adafruit_NeoPixel.h 11 | -------------------------------------------------------------------------------- /rp2040_pio.h: -------------------------------------------------------------------------------- 1 | // -------------------------------------------------- // 2 | // This file is autogenerated by pioasm; do not edit! // 3 | // -------------------------------------------------- // 4 | 5 | // Unless you know what you are doing... 6 | // Lines 47 and 52 have been edited to set transmit bit count 7 | 8 | #if !PICO_NO_HARDWARE 9 | #include "hardware/pio.h" 10 | #endif 11 | 12 | // ------ // 13 | // ws2812 // 14 | // ------ // 15 | 16 | #define ws2812_wrap_target 0 17 | #define ws2812_wrap 3 18 | 19 | #define ws2812_T1 2 20 | #define ws2812_T2 5 21 | #define ws2812_T3 3 22 | 23 | static const uint16_t ws2812_program_instructions[] = { 24 | // .wrap_target 25 | 0x6221, // 0: out x, 1 side 0 [2] 26 | 0x1123, // 1: jmp !x, 3 side 1 [1] 27 | 0x1400, // 2: jmp 0 side 1 [4] 28 | 0xa442, // 3: nop side 0 [4] 29 | // .wrap 30 | }; 31 | 32 | #if !PICO_NO_HARDWARE 33 | static const struct pio_program ws2812_program = { 34 | .instructions = ws2812_program_instructions, 35 | .length = 4, 36 | .origin = -1, 37 | }; 38 | 39 | static inline pio_sm_config ws2812_program_get_default_config(uint offset) { 40 | pio_sm_config c = pio_get_default_sm_config(); 41 | sm_config_set_wrap(&c, offset + ws2812_wrap_target, offset + ws2812_wrap); 42 | sm_config_set_sideset(&c, 1, false, false); 43 | return c; 44 | } 45 | 46 | #include "hardware/clocks.h" 47 | static inline void ws2812_program_init(PIO pio, uint sm, uint offset, uint pin, 48 | float freq, uint bits) { 49 | pio_gpio_init(pio, pin); 50 | pio_sm_set_consecutive_pindirs(pio, sm, pin, 1, true); 51 | pio_sm_config c = ws2812_program_get_default_config(offset); 52 | sm_config_set_sideset_pins(&c, pin); 53 | sm_config_set_out_shift(&c, false, true, 54 | bits); // <----<<< Length changed to "bits" 55 | sm_config_set_fifo_join(&c, PIO_FIFO_JOIN_TX); 56 | int cycles_per_bit = ws2812_T1 + ws2812_T2 + ws2812_T3; 57 | float div = clock_get_hz(clk_sys) / (freq * cycles_per_bit); 58 | sm_config_set_clkdiv(&c, div); 59 | pio_sm_init(pio, sm, offset, &c); 60 | pio_sm_set_enabled(pio, sm, true); 61 | } 62 | 63 | #endif 64 | --------------------------------------------------------------------------------