Skip to content

Instantly share code, notes, and snippets.

@eadmaster
Last active June 23, 2024 00:43
Show Gist options
  • Save eadmaster/dba80b3f1fc1f3c75af4402a73ba533e to your computer and use it in GitHub Desktop.
Save eadmaster/dba80b3f1fc1f3c75af4402a73ba533e to your computer and use it in GitHub Desktop.
control neopixel leds with ConfigurableFirmata (WIP)
import pyfirmata
import time
class SPI:
START_SYSEX = 0xF0
END_SYSEX = 0xF7
SPI_DATA = 0x68
SPI_TRANSFER = 0x02
def __init__(self, port, clock_divider=0, bit_order=0, data_mode=0):
self.board = pyfirmata.Arduino(port)
self.device_id = 0 # Using device 0 by default
self.request_id = 0 # Increment this for each call
self.init_spi(clock_divider, bit_order, data_mode)
def init_spi(self, clock_divider, bit_order, data_mode):
device_id = 0 # Assume using device 0
self.board.send_sysex(self.START_SYSEX, [self.SPI_DATA, 0x00, 0x00, self.END_SYSEX]) # SPI_BEGIN
#self.board.send_sysex(self.START_SYSEX, [self.SPI_DATA, 0x01, device_id, clock_divider & 0x7F, (clock_divider >> 7) & 0x01,bit_order, data_mode, self.END_SYSEX]) # SPI_DEVICE_CONFIG
def encode_data(self, data):
encoded_data = []
for byte in data:
encoded_data.append(byte & 0x7F) # lower 7 bits
encoded_data.append((byte >> 7) & 0x01) # MSB
return encoded_data
def transfer(self, data, deselect_cs_pin=1):
num_words = len(data)
channel = 0 # Assume using channel 0
header = [
self.SPI_DATA, self.SPI_TRANSFER,
channel,
self.request_id,
deselect_cs_pin,
num_words
]
message = header + self.encode_data(data)
self.board.send_sysex(self.START_SYSEX, message + [self.END_SYSEX])
self.request_id = (self.request_id + 1) % 128 # Increment request_id
def close(self):
self.board.exit()
class NeoPixel(list):
def __init__(self, spi, num_pixels):
super().__init__([(0, 0, 0) for _ in range(num_pixels)]) # Initialize list with (0, 0, 0) tuples
self.spi = spi
def __setitem__(self, index, value):
list.__setitem__(self, index, value)
self.show()
def show(self):
data = [0x00] # NeoPixel start frame marker
for pixel in self:
data.extend(pixel)
data.append(0x00) # NeoPixel end frame marker
self.spi.transfer(data)
# Example usage
spi = SPI('/dev/ttyACM0')
num_pixels = 1 # Number of NeoPixels
neo_pixels = NeoPixel(spi, num_pixels)
# Set individual pixel colors
neo_pixels[0] = (50, 0, 0) # Pixel 0, red
time.sleep(1) # Wait a second
neo_pixels[0] = (0, 50, 0) # Pixel 1, green
time.sleep(1) # Wait a second
neo_pixels[0] = (0, 0, 50) # Pixel 2, blue
time.sleep(1) # Wait a second
# Close the SPI connection
spi.close()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment