Skip to main content

A CircuitPython library for managing segments of NeoPixel strips as independent addressable units (works on CircuitPython and Raspberry Pi)

Project description

CircuitPython Serial NeoPixel

A CircuitPython library that provides a SerialNeoPixel class for managing segments of NeoPixel LED strips as independent addressable units.

Overview

SerialNeoPixel acts as a wrapper around the standard Adafruit CircuitPython NeoPixel library, allowing you to treat a contiguous subset of pixels in a strip as a separate, independently addressable unit. This is particularly useful for projects where you want to logically divide a single physical strip into multiple sections without manually managing global pixel indices.

Key Features

  • Segment-based addressing: Create multiple segments on a single strip, each with its own 0-based indexing
  • Full sequence protocol support: Supports indexing, slicing, negative indices, and len()
  • Pythonic interface: Feels like working with a native NeoPixel object
  • No copying overhead: Direct pass-through to parent strip (no pixel data duplication)
  • Brightness control: Access parent strip's brightness property (affects entire strip)

Installation

From PyPI (when published)

pip install circuitpython-serial-neopixel

Manual Installation

Copy serial_neo.py to your CircuitPython device's lib folder or your project directory.

Requirements

For CircuitPython (microcontrollers)

  • CircuitPython 7.0 or higher
  • adafruit-circuitpython-neopixel library

For Raspberry Pi (standard Python)

  • Python 3.7 or higher
  • adafruit-circuitpython-neopixel library
  • SPI enabled (via raspi-config or /boot/config.txt)
  • NeoPixel DIN connected to GPIO10 (physical pin 19)

Quick Start

CircuitPython Example

import board
import neopixel
from serial_neo import SerialNeoPixel

# Create a NeoPixel strip with 30 LEDs
strip = neopixel.NeoPixel(board.D18, 30, brightness=0.3, auto_write=False)

# Create three segments on the same strip
segment1 = SerialNeoPixel(strip, 0, 10)   # Pixels 0-9
segment2 = SerialNeoPixel(strip, 10, 10)  # Pixels 10-19
segment3 = SerialNeoPixel(strip, 20, 10)  # Pixels 20-29

# Each segment has independent 0-based indexing
segment1[0] = (255, 0, 0)    # Red - affects strip pixel 0
segment2[0] = (0, 255, 0)    # Green - affects strip pixel 10
segment3[0] = (0, 0, 255)    # Blue - affects strip pixel 20

# Update the physical strip
segment1.show()  # Any segment can call show() (affects entire strip)

Raspberry Pi Example (Standard Python)

import board
import neopixel
from serial_neo import SerialNeoPixel

# Create a NeoPixel strip with 30 LEDs on GPIO10 (physical pin 19)
# Note: Requires SPI enabled and sudo-less access configured
strip = neopixel.NeoPixel(board.D10, 30, brightness=0.3, auto_write=False)

# Create segments exactly the same way as CircuitPython
segment1 = SerialNeoPixel(strip, 0, 10)
segment2 = SerialNeoPixel(strip, 10, 10)
segment3 = SerialNeoPixel(strip, 20, 10)

# Same API works on both platforms
segment1[0] = (255, 0, 0)
segment2[0] = (0, 255, 0)
segment3[0] = (0, 0, 255)
segment1.show()

Usage Examples

Basic Indexing

# Set individual pixels
segment[0] = (255, 0, 0)      # First pixel
segment[5] = (0, 255, 0)      # Sixth pixel
segment[-1] = (0, 0, 255)     # Last pixel (negative indexing)

# Get pixel colors
color = segment[0]            # Returns (R, G, B) or (R, G, B, W) tuple
last_color = segment[-1]      # Get last pixel

Slice Operations

# Set multiple pixels at once
segment[0:3] = [(255, 0, 0), (0, 255, 0), (0, 0, 255)]  # First three pixels

# Set a range to the same color
segment[5:10] = [(128, 128, 128)] * 5  # Pixels 5-9 to gray

# Use slice with step
segment[::2] = [(255, 0, 0)] * 5  # Every other pixel to red

# Get multiple pixels
colors = segment[0:5]  # Returns list of color tuples

Fill Operations

# Fill entire segment with one color
segment.fill((255, 0, 0))  # Fill with red

# Clear a segment
segment.fill((0, 0, 0))  # Turn off all pixels

Brightness Control

Important: The brightness property affects the entire parent strip, not just the individual segment.

# Get current brightness
current = segment.brightness  # Returns float 0.0-1.0

# Set brightness (affects ALL segments on the same strip)
segment.brightness = 0.5  # 50% brightness for entire strip

# This also affects all other segments sharing the same parent strip
segment1.brightness = 0.3  # segment2 and segment3 are also affected

Working with Multiple Segments

import board
import neopixel
from serial_neo import SerialNeoPixel

# 60-pixel strip divided into 6 segments of 10 pixels each
strip = neopixel.NeoPixel(board.D18, 60, auto_write=False)
segments = [SerialNeoPixel(strip, i*10, 10) for i in range(6)]

# Animate each segment independently
for i, seg in enumerate(segments):
    seg.fill(colors[i])

strip.show()

Advanced: Overlapping Segments

You can create overlapping segments if needed (though use carefully):

full_strip = SerialNeoPixel(strip, 0, 30)   # All 30 pixels
left_half = SerialNeoPixel(strip, 0, 15)    # First 15 pixels
right_half = SerialNeoPixel(strip, 15, 15)  # Last 15 pixels
center = SerialNeoPixel(strip, 10, 10)      # Middle 10 pixels (overlaps both halves)

API Reference

SerialNeoPixel(strip, pixel_start, pixel_count)

Create a new segment wrapper.

Parameters:

  • strip: Parent NeoPixel strip object
  • pixel_start: Starting index in parent strip (0-based)
  • pixel_count: Number of pixels in this segment

Methods

fill(color)

Fill all pixels in the segment with the specified color.

Parameters:

  • color: RGB tuple (r, g, b) or RGBW tuple (r, g, b, w) with values 0-255

show()

Update the physical LED strip to display current pixel colors. Affects the entire parent strip.

Properties

brightness

Get or set the brightness of the parent strip (0.0 to 1.0).

Warning: This affects the entire parent strip, not just this segment. All segments sharing the same parent will be affected.

Sequence Protocol

The class implements Python's sequence protocol:

  • len(segment): Returns number of pixels in segment
  • segment[i]: Get/set pixel at index i (supports negative indices)
  • segment[start:stop:step]: Get/set slice of pixels
  • repr(segment): String representation showing start position and count

Platform Compatibility

This library works on both:

  1. CircuitPython microcontrollers: Circuit Playground Express, Raspberry Pi Pico, Metro M4, etc.
  2. Raspberry Pi with standard Python: Pi 3, Pi 4, Pi 5, Pi Zero W, etc.

The same code works on both platforms with only minor hardware pin differences (e.g., board.D18 vs board.D10).

Raspberry Pi Setup

To use NeoPixels on Raspberry Pi, you need to:

  1. Enable SPI via raspi-config:

    sudo raspi-config
    # Navigate to: Interfacing Options -> SPI -> Enable
    
  2. Install the library:

    pip3 install circuitpython-serial-neopixel
    
  3. Connect your NeoPixel strip:

    • DIN (Data In) → GPIO10 (physical pin 19)
    • 5V → 5V power
    • GND → Ground
  4. Configure sudo-less access (optional, for running without sudo): See Adafruit's documentation for detailed setup.

Limitations and Caveats

  1. Brightness is strip-wide: The brightness property affects the entire parent strip, not individual segments. If multiple segments share a parent strip, changing brightness on one affects all.

  2. No bounds checking between segments: You can create overlapping segments. The library doesn't prevent this, as it might be intentional for some use cases.

  3. show() updates entire strip: Calling show() on any segment updates the entire physical strip, not just that segment's pixels.

  4. Requires parent strip compatibility: The parent strip object must support the standard NeoPixel interface (__getitem__, __setitem__, show(), brightness).

  5. Auto-write behavior inherited: If the parent strip has auto_write=True, changes may appear immediately. For better performance with segments, use auto_write=False on the parent strip and call show() manually.

Performance Tips

  1. Use auto_write=False: Create the parent strip with auto_write=False and call show() manually after batch updates:
strip = neopixel.NeoPixel(board.D18, 30, auto_write=False)
segment = SerialNeoPixel(strip, 0, 10)

# Make multiple changes
segment[0] = (255, 0, 0)
segment[1] = (0, 255, 0)
segment[2] = (0, 0, 255)

# Update once
segment.show()
  1. Use fill() for uniform colors: It's more efficient than setting pixels individually.

  2. Batch slice operations: Use slice assignment instead of loops when possible:

# Good
segment[0:5] = [(255, 0, 0)] * 5

# Less efficient
for i in range(5):
    segment[i] = (255, 0, 0)

Examples

See the examples directory for more detailed usage examples (coming soon).

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

License

MIT License - see LICENSE file for details.

Credits

Built on top of the Adafruit CircuitPython NeoPixel library.

Support

For bugs and feature requests, please open an issue on GitHub.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

circuitpython_serial_neopixel-1.0.0.tar.gz (7.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

File details

Details for the file circuitpython_serial_neopixel-1.0.0.tar.gz.

File metadata

File hashes

Hashes for circuitpython_serial_neopixel-1.0.0.tar.gz
Algorithm Hash digest
SHA256 a3ca7190b1ebce5aaf82575904c17d280eae2c36b7ef8709f2b7d5416ccf0447
MD5 b5d990513d1c9fc9f5db2ea8d4c32b06
BLAKE2b-256 8aa30a0c50f7d1c65a2b255c2963773a897c2ad393b73f099b2e2fd473c7777e

See more details on using hashes here.

File details

Details for the file circuitpython_serial_neopixel-1.0.0-py3-none-any.whl.

File metadata

File hashes

Hashes for circuitpython_serial_neopixel-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 5925ccd22021e771c979bc81f8f3610295e47429dd2688f37293b1b3e35e6644
MD5 467c65adbeaf3545e54ef225518b249c
BLAKE2b-256 fbafb11c9442c32f0555eade24e211d8c7f0eeb7456289495c1bdf92634e1b6d

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page