Coder Social home page Coder Social logo

adafruit_neopxl8's Introduction

Adafruit_NeoPXL8

DMA-driven 8-way concurrent NeoPixel driver for SAMD21 (M0+), SAMD51 (M4), RP2040 and ESP32S3 microcontrollers. Requires latest Adafruit_NeoPixel and Adafruit_ZeroDMA libraries.

(Pronounced "NeoPixelate")

Constructor is slightly different from Adafruit_NeoPixel. Rather than a pin number, this accepts an array of 8 signed bytes corresponding to pins for data outputs 0-7 (very specific rules apply here, more on this in a moment). Can also pass NULL to use the default pin assignments (digital pins 0-7 on Adafruit Metro Express or Arduino Zero):

Adafruit_NeoPXL8 strip(NUM_LED, NULL, NEO_GRB);

The first argument, strand length, applies to EACH strand. Total NeoPixel count is 8X this. Pixels are addressed (via setPixelColor()) as a single sequential strand. Supposing NUM_LED is 20, the first physical strand would be pixels 0-19, second strand is 20-39, third is 40-59 and so forth, up to pixel #159 on the eighth strand.

Logic Levels

Microcontrollers compatible with this code are all 3.3V devices, while NeoPixels ideally want 5V logic. One solution is a logic level converter such as the 74HCT125N. Alternately, just powering the NeoPixels from a slightly lower voltage (e.g. 4.5V) is sometimes all it takes!

Pin MUXing

Because this library relies on the SAMD21's TCC0 "pattern generator" peripheral, outputs can only be assigned to very specific pins. Fortunately most provide alternate options if the default layout doesn't meet your needs (e.g. on Feather boards).

Pin 0 alternate is 12 Pin 1 alternate is 10 Pin 2 alternates are MOSI or SDA Pin 3 alternate is A4 Pin 4 alternate is A3 Pin 5 alternates are SCK or SCL Pin 6 alternates are 11 or MISO Pin 7 alternate is 13

On the Metro Express and Arduino Zero boards, some of these pins (MOSI, MISO and SCK) are on the 6-pin ICSP header.

Because Feather boards have a pared-down pinout, some of the alternates need to be used. One possible layout might be:

int8_t pins[] = { 13, 12, 11, 10, 5, SDA, A3, A4 };

This keeps the Serial1 and SPI peripherals available, but prevents using I2C. A different arrangement would keep I2C free at the expense of one NeoPixel output:

int8_t pins[] = { 13, 12, 11, 10, 5, -1, A3, A4 };

The '-1' for a pin assignment disables that NeoPixel output (so this would have only 7 concurrent strands), but those pixels still take up memory and positions among the pixel indices.

Other boards (such as Grand Central) have an altogether different pinout. See the example for insights.

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.

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.

On ESP32S3 boards, go wild...there are no pin restrictions.

NeoPXL8HDR

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).

See examples/NeoPXL8HDR/strandtest for use.

adafruit_neopxl8's People

Contributors

evaherrada avatar hoffmannjan avatar ladyada avatar paintyourdragon avatar siddacious avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

adafruit_neopxl8's Issues

ESP32-S3 any pins BUT RP2040 limited to subsequent row of pins?

Hi,

just a quick question:
Is there a special reason why we can "go wild on pins" for an ESP32-S3,
but we're limited to a subsequent row of 8 pins for a generic Raspberry Pi Pico?

Is that a reason of "it's possible, but too much work!"? Or rather "it's just not possible, because..."?

Thanks in advance for any insights you can give!

NeoPXL8 (& HDR) strandtest hangs USB serial on RP2040 SCORPIO

In brief

  • NeoPXL8 and NeoPXL8HDR appear to hang SCORPIO's USB serial connection after a delay
    • Stops responding to USB reset requests within 15 seconds to 10 minutes, hanging USB serial shortly after
    • 8×16 LEDs, well below memory limits (also happens with 8×60 default)
    • Requires pressing the hardware reset button and uploading quickly, or holding boot for bootloader
    • For NeoPXL8HDR, happens regardless of blending and double-buffering
  • Simple USB serial ping does not seem to hang on SCORPIO
    • Runs for over 17 hours and still resets just fine
    • No hang in USB serial output

Details

  • Library version: 1.2.3
  • Pico/SCORPIO/etc board version: 2.7.1
  • Arduino board: Adafruit Feather RP2040 SCORPIO
  • Arduino IDE version (found in Arduino -> About Arduino menu): 2.0.3
  • Operating System: Kubuntu 22.04 LTS 64-bit

Perhaps there is a conflict with the direct memory access technique and some resource the RP2040 uses to handle native USB?

Test case

❌ Broken NeoPXL8 test - PXL8TestSimple.ino

This is a trimmed-down version of the regular NeoPXL8 strandtest.ino, with added serial output for debugging and reducing it to 16 LEDs per strand.

  1. Run this sketch and monitor the serial console
    • Simple option: tio /dev/ttyACM0
  2. Wait 10 or so minutes
    • Sometimes it happens in 15 seconds, sometimes it takes 5+ minutes
    • Appears to be non-deterministic
  3. Try to press the Upload button in the Arduino IDE
  4. See if board automatically software resets into bootloader for new firmware
#include <Adafruit_NeoPXL8.h>
time_t last_print = 0;

#define NUM_LEDS    16      // NeoPixels PER STRAND, total number is 8X this!
#define COLOR_ORDER NEO_GRB // NeoPixel color format (see Adafruit_NeoPixel)

// For the Feather RP2040 SCORPIO, use this list:
int8_t pins[8] = { 16, 17, 18, 19, 20, 21, 22, 23 };

// Here's the global constructor as explained near the start:
Adafruit_NeoPXL8 leds(NUM_LEDS, pins, COLOR_ORDER);

// For this demo we use a table of 8 hues, one for each strand of pixels:
static uint8_t colors[8][3] = {
  255,   0,   0, // Row 0: Red
  255, 160,   0, // Row 1: Orange
  255, 255,   0, // Row 2: Yellow
    0, 255,   0, // Row 3: Green
    0, 255, 255, // Row 4: Cyan
    0,   0, 255, // Row 5: Blue
  192,   0, 255, // Row 6: Purple
  255,   0, 255  // Row 7: Magenta
};

// setup() runs once on program startup:
void setup() {
  // Initialize to the fastest common serial baud rate
  Serial.begin(115200);

  // Start NeoPXL8. If begin() returns false, either an invalid pin list
  // was provided, or requested too many pixels for available RAM.
  if (!leds.begin()) {
    // Blink the onboard LED if that happens.
    pinMode(LED_BUILTIN, OUTPUT);
    for (;;) digitalWrite(LED_BUILTIN, (millis() / 500) & 1);
  }

  // Otherwise, NeoPXL8 is now running, we can continue.
  leds.setBrightness(32); // Tone it down, NeoPixels are BRIGHT!
}

// loop() runs over and over indefinitely. We use this to render each frame
// of a repeating animation cycle based on elapsed time:
void loop() {
  uint32_t now = millis(); // Get time once at start of each frame
  for(uint8_t r=0; r<8; r++) { // For each row...
    for(int p=0; p<NUM_LEDS; p++) { // For each pixel of row...
      leds.setPixelColor(r * NUM_LEDS + p, rain(now, r, p));
    }
  }
  leds.show();

  if (now - last_print > 5000) {
    Serial.print("Seconds: ");
    Serial.println(now / 1000);
    last_print = now;
  }
}

// Given current time in milliseconds, row number (0-7) and pixel number
// along row (0 - (NUM_LEDS-1)), first calculate brightness (b) of pixel,
// then multiply row color by this and run it through NeoPixel library’s
// gamma-correction table.
uint32_t rain(uint32_t now, uint8_t row, int pixelNum) {
  uint8_t frame = now / 4; // uint8_t rolls over for a 0-255 range
  uint16_t b = 256 - ((frame - row * 32 + pixelNum * 256 / NUM_LEDS) & 0xFF);
  return leds.Color(leds.gamma8((colors[row][0] * b) >> 8),
                    leds.gamma8((colors[row][1] * b) >> 8),
                    leds.gamma8((colors[row][2] * b) >> 8));
}

✅ Working simple serial test - PXL8TestSerialOnly.ino

  1. Run this sketch and monitor the serial console
    • Simple option: tio /dev/ttyACM0
  2. Wait 10 or so minutes
    • In my case, I waited 17 hours
  3. Try to press the Upload button in the Arduino IDE
  4. See if board automatically software resets into bootloader for new firmware
time_t last_print = 0;

// setup() runs once on program startup:
void setup() {
  // Initialize to the fastest common serial baud rate
  Serial.begin(115200);
}

// loop() runs over and over indefinitely. We use this to render each frame
// of a repeating animation cycle based on elapsed time:
void loop() {
  uint32_t now = millis(); // Get time once at start of each frame
  
  if (now - last_print > 5000) {
    Serial.print("Seconds: ");
    Serial.println(now / 1000);
    last_print = now;
  }
}

The SCORPIO still properly reset after printing this line to the serial console: Seconds: 63857

No output on Circuit Playground Express

Hello,

I am using a Circuit Playground Express (CPX) for its collection of onboard sensors, but I would also like to drive multiple strands of neopixels with low CPU overhead. NeoPXL8 seems like the perfect solution, however I cannot seem to get any output from the physical pins when I run the demo Strandtest.ino file.

I have modified the instantiation of the 'leds' object to use the pins available on the CPX (based on my reading from the older NeoPXL8 documentation).

Here is the modified line of code. All other code is unchanged from the demo.

int8_t LED_Pins[8] = { 0, 1, 2, 3, A3, -1, 6, -1}; // CPX
Adafruit_NeoPXL8 leds(NUM_LED, LED_Pins, NEO_GRBW);

I did make sure to select the correct board from the boards manager.

Neopixel strips I'm using are RGBW strips, running on their own 4V supplies. All grounds are tied together. All strips work fine when driven from other code.

I tried running the Strandtest.ino code on a "Trinket M0", and I was able to get working output from pins D0 and D2. I don't have a feather M0 or M4 on-hand to try.

Any help greatly appreciated!

Adafruit_NeoPXL8 together with Pico-DMX not working

Hi,
I try to develop pixel LED driver board controlled by DMX: https://github.com/jostlowe/Pico-DMX
I connected 4 trips to rpi-pico board by this pin alignment: int8_t pins[8] = { 2, 3, 4, 5, -1, -1,-1, -1 };
and starting LEDs: leds.begin(true, pio0)
for start receive DMX this config: dmxInput.begin(13, START_CHANNEL, NUM_CHANNELS,pio1);

Both libraries separately working OK, but together NO, I using different PIO state machines, but i think issue is with DMA because both libraries using DMA.

How to align DMA recourses to use different DMA channels for Adafruit_NeoPXL8?

Working with Adafruit Feather M4 Express

Hello,
I'm trying to port a previous teensy+w5500 project to feather M4+w5500. (see https://imgur.com/a/bVoNvQq)

I moved the reset pin on the w5500 featherwing to A0, so I freed the pin 10.
Now I'm trying to use the 8 outputs of my 74HC245 but I have some glitches (like flashes on the whole strip).

Here the pins I use:

int8_t pins[8] = { 5, 6, 10, 11, 12, -1, -1, -1 };

What would be the last 3 I can use ? I tried 13, 0, 1, and 9 but they generates some glitches

Any idea?

PS: I don't use the Adafruit NeoPXL8 FeatherWing

Regards

Xavier

NeoPXL8 Library on RP2040 does not stop state machine on destruction

  • Arduino board: INSERT ARDUINO BOARD NAME/TYPE HERE
    Raspberry Pi Pico

  • Arduino IDE version (found in Arduino -> About Arduino menu): INSERT ARDUINO
    VERSION HERE

    Arduino IDE 2.0.4

  • List the steps to reproduce the problem below (if possible attach a sketch or
    copy the sketch code in too): LIST REPRO STEPS BELOW
    When instantiating a NeoPXL8 object, a pio sm is claimed and started, the sm program is written, and a DMA IRQ handler is added.
    Upon destruction, the reverse of this process has been left out.
    MarcusEdit NeoPXL8.zip
    See edits to library files for a fix that seems to work for me.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.