aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/compileAndRun/pythonSupportFiles/LuxcenaNeo/Strip.py163
-rw-r--r--src/compileAndRun/pythonSupportFiles/entry.py4
2 files changed, 160 insertions, 7 deletions
diff --git a/src/compileAndRun/pythonSupportFiles/LuxcenaNeo/Strip.py b/src/compileAndRun/pythonSupportFiles/LuxcenaNeo/Strip.py
index c4ac8c9..f5beaa4 100644
--- a/src/compileAndRun/pythonSupportFiles/LuxcenaNeo/Strip.py
+++ b/src/compileAndRun/pythonSupportFiles/LuxcenaNeo/Strip.py
@@ -1,6 +1,161 @@
+#from neopixel import *
+import atexit
+import _rpi_ws281x as ws
+
class Strip:
- def __init__(self, segments, segmentConfiguration):
- self.segments = segments
- self.segmentConfiguration = segmentConfiguration
- return
+ def __init__(self, stripConf):
+ """Class to represent a NeoPixel/WS281x LED display. Num should be the
+ number of pixels in the display, and pin should be the GPIO pin connected
+ to the display signal line (must be a PWM pin like 18!). Optional
+ parameters are freq, the frequency of the display signal in hertz (default
+ 800khz), dma, the DMA channel to use (default 10), invert, a boolean
+ specifying if the signal line should be inverted (default False), and
+ channel, the PWM channel to use (defaults to 0).
+ """
+ self.SEGMENTS = stripConf["segments"]
+ self.SEGMENT_CONFIG = stripConf["segment_config"]
+
+ self.LED_FREQ_HZ = stripConf["led_freq_hz"] # LED signal frequency in hertz (usually 800khz)
+ self.LED_CHANNEL = stripConf["led_channel"] # Set to '1' for GPIOs 13, 19, 41, 45, 53
+ self.LED_INVERT = stripConf["led_invert"] # True to invert the signal, (when using NPN transistor level shift)
+ self.LED_PIN = stripConf["led_pin"] # 18 uses PWM, 10 uses SPI /dev/spidev0.0
+ self.LED_DMA = stripConf["led_dma"] # DMA channel for generating the signal, on the newer ones, try 10
+ self.LED_COUNT = sum(self.SEGMENTS) # Number of LEDs in strip
+
+
+ self.LED_BRIGHTNESS = 255
+
+ # Create ws2811_t structure and fill in parameters.
+ self._leds = ws.new_ws2811_t()
+
+ # Initialize the channels to zero
+ for channum in range(2):
+ chan = ws.ws2811_channel_get(self._leds, channum)
+ ws.ws2811_channel_t_count_set(chan, 0)
+ ws.ws2811_channel_t_gpionum_set(chan, 0)
+ ws.ws2811_channel_t_invert_set(chan, 0)
+ ws.ws2811_channel_t_brightness_set(chan, 0)
+
+ # Initialize the channel in use
+ self._channel = ws.ws2811_channel_get(self._leds, channel)
+ ws.ws2811_channel_t_count_set(self._channel, num)
+ ws.ws2811_channel_t_gpionum_set(self._channel, pin)
+ ws.ws2811_channel_t_invert_set(self._channel, 0 if not invert else 1)
+ ws.ws2811_channel_t_brightness_set(self._channel, brightness)
+ ws.ws2811_channel_t_strip_type_set(self._channel, strip_type)
+
+ # Initialize the controller
+ ws.ws2811_t_freq_set(self._leds, freq_hz)
+ ws.ws2811_t_dmanum_set(self._leds, dma)
+
+ # Grab the led data array.
+ self._led_data = _LED_Data(self._channel, num)
+
+ # Substitute for __del__, traps an exit condition and cleans up properly
+ atexit.register(self._cleanup)
+
+ def _cleanup(self):
+ # Clean up memory used by the library when not needed anymore.
+ if self._leds is not None:
+ ws.delete_ws2811_t(self._leds)
+ self._leds = None
+ self._channel = None
+
+ def begin(self):
+ """Initialize library, must be called once before other functions are
+ called.
+ """
+ resp = ws.ws2811_init(self._leds)
+ if resp != ws.WS2811_SUCCESS:
+ message = ws.ws2811_get_return_t_str(resp)
+ raise RuntimeError('ws2811_init failed with code {0} ({1})'.format(resp, message))
+
+ def show(self):
+ """Update the display with the data from the LED buffer."""
+ resp = ws.ws2811_render(self._leds)
+ if resp != ws.WS2811_SUCCESS:
+ message = ws.ws2811_get_return_t_str(resp)
+ raise RuntimeError('ws2811_render failed with code {0} ({1})'.format(resp, message))
+
+ def setPixelColor(self, n, color):
+ """Set LED at position n to the provided 24-bit color value (in RGB order).
+ """
+ self._led_data[n] = color
+
+ def setPixelColorRGB(self, n, red, green, blue, white = 0):
+ """Set LED at position n to the provided red, green, and blue color.
+ Each color component should be a value from 0 to 255 (where 0 is the
+ lowest intensity and 255 is the highest intensity).
+ """
+ self.setPixelColor(n, Color(red, green, blue, white))
+
+ def setBrightness(self, brightness):
+ """Scale each LED in the buffer by the provided brightness. A brightness
+ of 0 is the darkest and 255 is the brightest.
+ """
+ ws.ws2811_channel_t_brightness_set(self._channel, brightness)
+
+ def getBrightness(self):
+ """Get the brightness value for each LED in the buffer. A brightness
+ of 0 is the darkest and 255 is the brightest.
+ """
+ return ws.ws2811_channel_t_brightness_get(self._channel)
+
+ def getPixels(self):
+ """Return an object which allows access to the LED display data as if
+ it were a sequence of 24-bit RGB values.
+ """
+ return self._led_data
+
+ def numPixels(self):
+ """Return the number of pixels in the display."""
+ return ws.ws2811_channel_t_count_get(self._channel)
+
+ def getPixelColor(self, n):
+ """Get the 24-bit RGB color value for the LED at position n."""
+ return self._led_data[n]
+
+
+def Color(red, green, blue, white = 0):
+ """Convert the provided red, green, blue color to a 24-bit color value.
+ Each color component should be a value 0-255 where 0 is the lowest intensity
+ and 255 is the highest intensity.
+ """
+ return (white << 24) | (red << 16)| (green << 8) | blue
+
+
+class _LED_Data(object):
+ """Wrapper class which makes a SWIG LED color data array look and feel like
+ a Python list of integers.
+ """
+ def __init__(self, channel, size):
+ self.size = size
+ self.channel = channel
+
+ def __getitem__(self, pos):
+ """Return the 24-bit RGB color value at the provided position or slice
+ of positions.
+ """
+ # Handle if a slice of positions are passed in by grabbing all the values
+ # and returning them in a list.
+ if isinstance(pos, slice):
+ return [ws.ws2811_led_get(self.channel, n) for n in xrange(*pos.indices(self.size))]
+ # Else assume the passed in value is a number to the position.
+ else:
+ return ws.ws2811_led_get(self.channel, pos)
+
+ def __setitem__(self, pos, value):
+ """Set the 24-bit RGB color value at the provided position or slice of
+ positions.
+ """
+ # Handle if a slice of positions are passed in by setting the appropriate
+ # LED data values to the provided values.
+ if isinstance(pos, slice):
+ index = 0
+ for n in xrange(*pos.indices(self.size)):
+ ws.ws2811_led_set(self.channel, n, value[index])
+ index += 1
+ # Else assume the passed in value is a number to the position.
+ else:
+ return ws.ws2811_led_set(self.channel, pos, value)
diff --git a/src/compileAndRun/pythonSupportFiles/entry.py b/src/compileAndRun/pythonSupportFiles/entry.py
index 4ba1031..3dab945 100644
--- a/src/compileAndRun/pythonSupportFiles/entry.py
+++ b/src/compileAndRun/pythonSupportFiles/entry.py
@@ -49,14 +49,12 @@ def main():
print ("> Loading pixel-configuration...")
with open(config_dir + "strip.json", "r") as rawStripConf:
stripConf = json.load(rawStripConf)
- segments = stripConf["segments"]
- segmentConfiguration = stripConf["segmentConfiguration"]
print ("> Initializing script...")
moduleSc = importlib.import_module("script")
if ("LuxcenaNeo" in dir(moduleSc)):
- moduleSc.LuxcenaNeo.strip = moduleSc.LuxcenaNeo.Strip(segments, segmentConfiguration)
+ moduleSc.LuxcenaNeo.strip = moduleSc.LuxcenaNeo.Strip(stripConf)
elif ("neo" in dir(moduleSc)):
moduleSc.neo.strip = moduleSc.neo.Strip(segments, segmentConfiguration)
else: