├── .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 [](https://github.com/adafruit/Adafruit_NeoPixel/actions)[](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 | 
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 |
--------------------------------------------------------------------------------