I have three libraries (is library the right word?) that I'm using in my Python code:
- An Adafruit NeoPixels library, which comes from the rpi_281x library to control them via PWM, on GPIO pin 18.
- One to control WS2801 Adafruit pixels (which I call "PaleoPixels" in my code. This uses SPI to write to the chips, using MOSI (GPIO pin 10) and SCLK (GPIO pin 11) pins for control.
- A "SuperPixel" library to gang together multiple strands of both types into a super-strand, and control them with a single command set.
All of this works quite well on its own, and I can run animations at a pretty decent frame rate, if I just run a script from the terminal.
My problem seems to start when I try to use GPIO interrupts to detect button presses to trigger different LED patterns. The NeoPixels continue to work, but the SPI-driven PaleoPixels just go haywire. After a little trial and error, it seems to be related to listening for the GPIO interrupts that's somehow conflicting with the PaleoPixel control signal.
I don't have a logic analyzer, so I'm not sure exactly what's going wrong yet, but is there anything in my control script that's an obvious conflict with the SPI ontrol of the PaleoPixels, or something else I'm doing wrong with how I'm handling interrupts?
import RPi.GPIO as GPIO import neopixel import paleopixel from superpixel import * GPIO.setmode(GPIO.BCM) GPIO.setup(23, GPIO.IN, pull_up_down=GPIO.PUD_UP) GPIO.setup(24, GPIO.IN, pull_up_down=GPIO.PUD_UP) GPIO.setup(25, GPIO.IN, pull_up_down=GPIO.PUD_UP) # Set up the strand # My LED strip configurations (for test): NEOPIXEL_COUNT = 244 # Number of NeoPixels in the strand NEOPIXEL_PIN = 18 # GPIO pin connected to the pixels (must support PWM!) PALEOPIXEL_COUNT = 50 # Number of PaleoPixels in the strand # Create pixel strands with appropriate configuration. strand1 = neopixel.Adafruit_NeoPixel(NEOPIXEL_COUNT, NEOPIXEL_PIN) strand2 = paleopixel.PaleoPixel(PALEOPIXEL_COUNT) # Combine them into one SuperPixel strand strand = SuperPixel(strand1, strand2) # Intialize the SuperPixel strand (must be called once, before other # functions, if the SuperPixel strand contains any NeoPixel sub-strands) strand.begin() # FIXME: Setting up these GPIO interrupts seems to be killing the control # stream to the PaleoPixels # Set up our GPIO callbacks def button_white(channel): print("button_white") colorAll(strand, Color(255, 0, 0)) # Set all LEDs to Red def button_amber(channel): print("button_amber") colorAll(strand, Color(0, 255, 0)) # Set all LEDs to Green def button_red(channel): print("button_red") colorAll(strand, Color(0, 0, 255)) # Set all LEDs to Blue # Physical button interrupts GPIO.add_event_detect(23, GPIO.FALLING, callback=button_white, bouncetime=300) GPIO.add_event_detect(24, GPIO.FALLING, callback=button_amber, bouncetime=300) GPIO.add_event_detect(25, GPIO.FALLING, callback=button_red, bouncetime=300) # Idle loop while 1: # Should I be doing something else here? pass GPIO.cleanup()
time.sleep(1)and the WS2801 pixels are now drawing properly. (Some glitches, but that was there before. Now I have other questions about how interrupts work, but I suppose that's for another post. @joan do you want to add that as an answer so I can mark it solved?