Skip to content

Commit 80ed712

Browse files
Merge pull request #5 from adafruit/esp32s3
Add ESP32S3 support and NeoPXL8HDR class
2 parents c65af94 + b85e20e commit 80ed712

File tree

22 files changed

+3998
-271
lines changed

22 files changed

+3998
-271
lines changed

.github/workflows/githubci.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ jobs:
2020
run: bash ci/actions_install.sh
2121

2222
- name: test platforms
23-
run: python3 ci/build_platform.py feather_m0_express metro_m4 pico_rp2040
23+
run: python3 ci/build_platform.py feather_m0_express_tinyusb metro_m4_tinyusb pico_rp2040_tinyusb feather_esp32s3
2424

2525
- name: clang
2626
run: python3 ci/run-clang-format.py -e "ci/*" -e "bin/*" -r .

Adafruit_NeoPXL8.cpp

Lines changed: 819 additions & 134 deletions
Large diffs are not rendered by default.

Adafruit_NeoPXL8.h

Lines changed: 402 additions & 13 deletions
Large diffs are not rendered by default.

README.md

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# Adafruit_NeoPXL8
2-
DMA-driven 8-way concurrent NeoPixel driver for SAMD21 (M0+), SAMD51 (M4) and RP2040 microcontrollers. Requires latest Adafruit_NeoPixel and Adafruit_ZeroDMA libraries.
2+
DMA-driven 8-way concurrent NeoPixel driver for SAMD21 (M0+), SAMD51 (M4), RP2040 and ESP32S3 microcontrollers. Requires latest Adafruit_NeoPixel and Adafruit_ZeroDMA libraries.
33

44
(Pronounced "NeoPixelate")
55

@@ -43,3 +43,11 @@ Other boards (such as Grand Central) have an altogether different pinout. See th
4343
Pin MUXing is a hairy thing and over time we'll try to build up some ready-to-use examples for different boards and peripherals. You can also try picking your way through the SAMD21/51 datasheet or the NeoPXL8 source code for pin/peripheral assignments.
4444

4545
On RP2040 boards, the pins can be within any 8-pin range (e.g. 0-7, or 4-11, etc.). If using fewer than 8 outputs, they do not need to be contiguous, but the lowest and highest pin number must still be within 8-pin range.
46+
47+
On ESP32S3 boards, go wild...there are no pin restrictions.
48+
49+
## NeoPXL8HDR
50+
51+
Adafruit_NeoPXL8HDR is a subclass of Adafruit_NeoPXL8 with additions for 16-bit color, temporal dithering, gamma correction and frame blending. This requires inordinate RAM, and the need for frequent refreshing makes it best suited for multi-core chips (e.g. RP2040).
52+
53+
See examples/NeoPXL8HDR/strandtest for use.

examples/NeoPXL8/Fire/Fire.ino

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
// FIRST TIME HERE? START WITH THE NEOPXL8 strandtest EXAMPLE INSTEAD!
2+
// That code explains and helps troubshoot wiring and NeoPixel color format.
3+
4+
#include <Adafruit_NeoPXL8.h>
5+
6+
// CHANGE these to match your strandtest findings or this WILL NOT WORK:
7+
8+
int8_t pins[8] = { 6, 7, 9, 8, 13, 12, 11, 10 };
9+
#define COLOR_ORDER NEO_GRB
10+
11+
// This example is minimally adapted from one in PJRC's OctoWS2811 Library:
12+
13+
// Animated Fire Example - OctoWS2811 Library
14+
// http://www.pjrc.com/teensy/td_libs_OctoWS2811.html
15+
//
16+
// Based on the simple algorithm explained here:
17+
// http://caraesnaur.github.io/fire/
18+
//
19+
// This example code is in the public domain.
20+
21+
const unsigned int width = 30;
22+
const unsigned int height = 16; // Each strand spans two successive rows
23+
24+
// These parameters control the fire appearance
25+
// (try controlling these with knobs / analogRead....)
26+
unsigned int heat = width / 5;
27+
unsigned int focus = 9;
28+
unsigned int cool = 26;
29+
30+
const int ledsPerPin = width * height / 8;
31+
Adafruit_NeoPXL8 leds(ledsPerPin, pins, COLOR_ORDER);
32+
33+
// Arrays for fire animation
34+
unsigned char canvas[width*height];
35+
extern const unsigned int fireColor[100];
36+
37+
// Run setup once
38+
void setup() {
39+
if (!leds.begin()) {
40+
pinMode(LED_BUILTIN, OUTPUT);
41+
for (;;) digitalWrite(LED_BUILTIN, (millis() / 500) & 1);
42+
}
43+
leds.show(); // Clear initial LED state
44+
}
45+
46+
// A simple xy() function to turn display matrix coordinates
47+
// into the index numbers NeoPXL8 requires. If your LEDs
48+
// are arranged differently, edit this code...
49+
unsigned int xy(unsigned int x, unsigned int y) {
50+
if ((y & 1) == 0) {
51+
// even numbered rows (0, 2, 4...) are left to right
52+
return y * width + x;
53+
} else {
54+
// odd numbered rows (1, 3, 5...) are right to left
55+
return y * width + width - 1 - x;
56+
}
57+
}
58+
59+
uint32_t lastTime = 0;
60+
61+
// Run repetitively
62+
void loop() {
63+
uint32_t now = millis();
64+
if (now - lastTime >= 45) {
65+
lastTime = now;
66+
animateFire();
67+
}
68+
}
69+
70+
void animateFire() {
71+
unsigned int i, c, n, x, y;
72+
73+
// Step 1: move all data up one line
74+
memmove(canvas + width, canvas, width * (height - 1));
75+
memset(canvas, 0, width);
76+
77+
// Step 2: draw random heatspots on bottom line
78+
i = heat;
79+
if (i > width-8) i = width-8;
80+
while (i > 0) {
81+
x = random(width - 2) + 1;
82+
if (canvas[x] == 0) {
83+
canvas[x] = 99;
84+
i--;
85+
}
86+
}
87+
88+
// Step 3: interpolate
89+
for (y=0; y < height; y++) {
90+
for (x=0; x < width; x++) {
91+
c = canvas[y * width + x] * focus;
92+
n = focus;
93+
if (x > 0) {
94+
c = c + canvas[y * width + (x - 1)];
95+
n = n + 1;
96+
}
97+
if (x < width-1) {
98+
c = c + canvas[y * width + (x + 1)];
99+
n = n + 1;
100+
}
101+
if (y > 0) {
102+
c = c + canvas[(y -1) * width + x];
103+
n = n + 1;
104+
}
105+
if (y < height-1) {
106+
c = c + canvas[(y + 1) * width + x];
107+
n = n + 1;
108+
}
109+
c = (c + (n / 2)) / n;
110+
i = (random(1000) * cool) / 10000;
111+
if (c > i) {
112+
c = c - i;
113+
} else {
114+
c = 0;
115+
}
116+
canvas[y * width + x] = c;
117+
}
118+
}
119+
120+
// Step 4: render canvas to LEDs
121+
for (y=0; y < height; y++) {
122+
for (x=0; x < width; x++) {
123+
c = canvas[((height - 1) - y) * width + x];
124+
leds.setPixelColor(xy(x, y), leds.gamma32(fireColor[c]));
125+
}
126+
}
127+
leds.show();
128+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
// This is just the linear fireColor[] array from the original OctoWS2811
2+
// Fire example, since NeoPXL8 has its own gamma function.
3+
4+
extern const unsigned int fireColor[100];
5+
6+
#define RGB(r, g, b) (((r) << 16) | ((g) << 8) | (b))
7+
8+
const unsigned int fireColor[100] = {
9+
RGB(0, 0, 0), RGB(5, 0, 0), RGB(10, 0, 0), RGB(14, 0, 0),
10+
RGB(19, 0, 0), RGB(23, 0, 0), RGB(27, 0, 0), RGB(31, 0, 0),
11+
RGB(35, 0, 0), RGB(39, 0, 0), RGB(43, 0, 0), RGB(47, 0, 0),
12+
RGB(51, 0, 0), RGB(55, 0, 0), RGB(59, 0, 0), RGB(63, 0, 0),
13+
RGB(67, 0, 0), RGB(71, 0, 0), RGB(75, 0, 0), RGB(79, 0, 0),
14+
RGB(83, 0, 0), RGB(88, 0, 0), RGB(92, 0, 0), RGB(96, 0, 0),
15+
RGB(100, 0, 0), RGB(104, 0, 0), RGB(108, 0, 0), RGB(112, 0, 0),
16+
RGB(116, 0, 0), RGB(121, 0, 0), RGB(125, 0, 0), RGB(129, 0, 0),
17+
RGB(133, 0, 0), RGB(137, 0, 0), RGB(141, 0, 0), RGB(145, 0, 0),
18+
RGB(149, 0, 0), RGB(153, 0, 0), RGB(157, 0, 0), RGB(161, 0, 0),
19+
RGB(165, 0, 0), RGB(169, 0, 0), RGB(173, 0, 0), RGB(177, 0, 0),
20+
RGB(181, 0, 0), RGB(185, 0, 0), RGB(190, 0, 0), RGB(194, 0, 0),
21+
RGB(198, 0, 0), RGB(202, 0, 0), RGB(205, 2, 0), RGB(207, 6, 0),
22+
RGB(209, 10, 0), RGB(211, 14, 0), RGB(213, 18, 0), RGB(215, 22, 0),
23+
RGB(217, 26, 0), RGB(219, 30, 0), RGB(221, 35, 0), RGB(223, 39, 0),
24+
RGB(225, 43, 0), RGB(227, 47, 0), RGB(229, 51, 0), RGB(231, 55, 0),
25+
RGB(233, 59, 0), RGB(235, 63, 0), RGB(237, 67, 0), RGB(239, 71, 0),
26+
RGB(241, 75, 0), RGB(243, 79, 0), RGB(245, 83, 0), RGB(248, 88, 0),
27+
RGB(250, 92, 0), RGB(252, 96, 0), RGB(254, 100, 0), RGB(255, 105, 1),
28+
RGB(255, 111, 3), RGB(255, 117, 5), RGB(255, 123, 7), RGB(255, 130, 9),
29+
RGB(255, 136, 11), RGB(255, 142, 13), RGB(255, 148, 15), RGB(255, 154, 17),
30+
RGB(255, 160, 19), RGB(255, 166, 21), RGB(255, 172, 23), RGB(255, 179, 25),
31+
RGB(255, 185, 27), RGB(255, 191, 29), RGB(255, 197, 31), RGB(255, 203, 33),
32+
RGB(255, 209, 35), RGB(255, 215, 37), RGB(255, 221, 39), RGB(255, 227, 41),
33+
RGB(255, 234, 44), RGB(255, 240, 46), RGB(255, 246, 48), RGB(255, 252, 50)};
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
// FIRST TIME HERE? START WITH THE NEOPXL8 strandtest EXAMPLE INSTEAD!
2+
// That code explains and helps troubshoot wiring and NeoPixel color format.
3+
4+
#include <Adafruit_NeoPXL8.h>
5+
6+
// CHANGE these to match your strandtest findings or this WILL NOT WORK:
7+
8+
int8_t pins[8] = { 6, 7, 9, 8, 13, 12, 11, 10 };
9+
#define COLOR_ORDER NEO_GRB
10+
11+
// This example is minimally adapted from one in PJRC's OctoWS2811 Library:
12+
13+
//PlazINT - Fast Plasma Generator using Integer Math Only
14+
//Edmund "Skorn" Horn
15+
//March 4,2013
16+
//Version 1.0 adapted for OctoWS2811Lib (tested, working...)
17+
18+
//OctoWS2811 Defn. Stuff
19+
#define COLS_LEDs 30 // all of the following params need to be adjusted for screen size
20+
#define ROWS_LEDs 16 // LED_LAYOUT assumed 0 if ROWS_LEDs > 8
21+
#define LEDS_PER_STRIP (COLS_LEDs * ROWS_LEDs / 8)
22+
23+
Adafruit_NeoPXL8 leds(LEDS_PER_STRIP, pins, COLOR_ORDER);
24+
25+
//Byte val 2PI Cosine Wave, offset by 1 PI
26+
//supports fast trig calcs and smooth LED fading/pulsing.
27+
uint8_t const cos_wave[256] PROGMEM =
28+
{0,0,0,0,1,1,1,2,2,3,4,5,6,6,8,9,10,11,12,14,15,17,18,20,22,23,25,27,29,31,33,35,38,40,42,
29+
45,47,49,52,54,57,60,62,65,68,71,73,76,79,82,85,88,91,94,97,100,103,106,109,113,116,119,
30+
122,125,128,131,135,138,141,144,147,150,153,156,159,162,165,168,171,174,177,180,183,186,
31+
189,191,194,197,199,202,204,207,209,212,214,216,218,221,223,225,227,229,231,232,234,236,
32+
238,239,241,242,243,245,246,247,248,249,250,251,252,252,253,253,254,254,255,255,255,255,
33+
255,255,255,255,254,254,253,253,252,252,251,250,249,248,247,246,245,243,242,241,239,238,
34+
236,234,232,231,229,227,225,223,221,218,216,214,212,209,207,204,202,199,197,194,191,189,
35+
186,183,180,177,174,171,168,165,162,159,156,153,150,147,144,141,138,135,131,128,125,122,
36+
119,116,113,109,106,103,100,97,94,91,88,85,82,79,76,73,71,68,65,62,60,57,54,52,49,47,45,
37+
42,40,38,35,33,31,29,27,25,23,22,20,18,17,15,14,12,11,10,9,8,6,6,5,4,3,2,2,1,1,1,0,0,0,0
38+
};
39+
40+
// Gamma table removed because NeoPixel lib provides this functionality.
41+
42+
void setup() {
43+
if (!leds.begin()) {
44+
pinMode(LED_BUILTIN, OUTPUT);
45+
for (;;) digitalWrite(LED_BUILTIN, (millis() / 500) & 1);
46+
}
47+
leds.setBrightness(100); // Tone it down a little
48+
leds.show(); // Clear initial LED state
49+
}
50+
51+
unsigned long frameCount=25500; // arbitrary seed to calculate the three time displacement variables t,t2,t3
52+
53+
void loop() {
54+
frameCount++ ;
55+
uint16_t t = fastCosineCalc((42 * frameCount)/300); //time displacement - fiddle with these til it looks good...
56+
uint16_t t2 = fastCosineCalc((35 * frameCount)/300);
57+
uint16_t t3 = fastCosineCalc((38 * frameCount)/300);
58+
59+
for (uint8_t y = 0; y < ROWS_LEDs; y++) {
60+
int left2Right, pixelIndex;
61+
if (((y % (ROWS_LEDs/8)) & 1) == 0) {
62+
left2Right = 1;
63+
pixelIndex = y * COLS_LEDs;
64+
} else {
65+
left2Right = -1;
66+
pixelIndex = (y + 1) * COLS_LEDs - 1;
67+
}
68+
for (uint8_t x = 0; x < COLS_LEDs ; x++) {
69+
//Calculate 3 seperate plasma waves, one for each color channel
70+
uint8_t r = fastCosineCalc(((x << 3) + (t >> 1) + fastCosineCalc((t2 + (y << 3)))));
71+
uint8_t g = fastCosineCalc(((y << 3) + t + fastCosineCalc(((t3 >> 2) + (x << 3)))));
72+
uint8_t b = fastCosineCalc(((y << 3) + t2 + fastCosineCalc((t + x + (g >> 2)))));
73+
leds.setPixelColor(pixelIndex, leds.gamma32((r << 16) | (g << 8) | b));
74+
pixelIndex += left2Right;
75+
}
76+
}
77+
leds.show();
78+
}
79+
80+
inline uint8_t fastCosineCalc( uint16_t preWrapVal) {
81+
uint8_t wrapVal = (preWrapVal % 255);
82+
if (wrapVal<0) wrapVal=255+wrapVal;
83+
return (pgm_read_byte_near(cos_wave+wrapVal));
84+
}

examples/NeoPXL8/VideoMSC/.esp32.test.skip

Whitespace-only changes.

0 commit comments

Comments
 (0)