Last active
December 12, 2015 04:28
-
-
Save ejeklint/4714653 to your computer and use it in GitHub Desktop.
Squirrel code for controlling a LED strip with addressable LEDs using the almighty WS2801 driver.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// WS2810 RGB LED Driver Controller and Demo usage | |
// | |
// | |
// A selection of predefined colours. Add to taste. | |
// | |
enum Colour { | |
red = "\xff\x00\x00", | |
green = "\x00\xff\x00", | |
blue = "\x00\x00\xff", | |
yellow = "\xff\xaa\x00", | |
orange = "\xff\x80\x00", | |
purple = "\x80\x00\xff", | |
white = "\xff\xff\xff", | |
off = "\x00\x00\x00" | |
} | |
// | |
// Class that handles an array of WS2801 RGB LED controllers in a LED strip | |
// Uses spi257 so connect the strips clock to pin 5 and data to pin 7 (MOSI) | |
// | |
class WS2801 { | |
ledCount = null; | |
strip = null; | |
// | |
// Constructor. Number of LEDs in the strip must be specified. | |
// | |
constructor(noOfLEDs) { | |
ledCount = noOfLEDs; | |
strip = blob(ledCount * 3); | |
hardware.spi257.configure(SIMPLEX_TX, 5000); // Strip doesn't handle too fast clk. Limit to 5 MHz | |
imp.sleep(0.01); | |
} | |
// | |
// Set colour of entire strip with setColour(Colour.blue) | |
// Set colour of 4th LED with setColour(Colour.blue, 3) | |
// Set colour of several LEDs with setColour(Colour.blue, [1,2,5,8,11]) | |
// Unless a third parameter is true, previous strip colors will be lost. To keep them | |
// call with for example setColour(Colour.blue, [1,2,3], true) | |
// | |
function setColour(colour, index = null, keepValues = false) { | |
if (!keepValues) { | |
// Allocate a new and clean blob (all leds off) | |
strip = blob(ledCount * 3); | |
} | |
if (index == null) { | |
// Set whole strip to same colour | |
for (local i = 0; i < ledCount; i++) { | |
strip[i*3] = colour[0]; | |
strip[i*3+1] = colour[1]; | |
strip[i*3+2] = colour[2]; | |
} | |
} else if (typeof index == "array") { | |
// Set leds in array to colour | |
foreach(i in index) { | |
strip[i*3] = colour[0]; | |
strip[i*3+1] = colour[1]; | |
strip[i*3+2] = colour[2]; | |
} | |
} else { | |
// Set a single led to colour | |
strip[index*3] = colour[0]; | |
strip[index*3+1] = colour[1]; | |
strip[index*3+2] = colour[2]; | |
} | |
writeToStrip(); | |
} | |
// | |
// Fills the strip in a "swipe" manner from first to last LED. | |
// Default wait between each step is 20 ms. | |
// | |
function colourWipe(colour, wait = 0.02) { | |
for (local i = 0; i < ledCount; i++) { | |
strip[i*3] = colour[0]; | |
strip[i*3+1] = colour[1]; | |
strip[i*3+2] = colour[2]; | |
writeToStrip(); | |
imp.sleep(wait); | |
} | |
} | |
// | |
// Loops over all colours in 256 steps. All LEDs have the same colour. | |
// | |
function rainbow(wait = 0.02) { | |
for (local j = 0; j < 256; j++) { | |
for (local i = 0; i < ledCount; i++) { | |
local colour = wheel((i+j) % 255); | |
strip[i*3] = colour[0]; | |
strip[i*3+1] = colour[1]; | |
strip[i*3+2] = colour[2]; | |
} | |
writeToStrip(); | |
imp.sleep(wait); | |
} | |
} | |
// | |
// Fancy effect demo that creates a rainbow distributed over the strip and the cycles the colours. | |
// Default values are 1 cycle and 20 ms between each colour change. Quite tedious, really... | |
// | |
function rainbowCycle(cycles = 1, wait = 0.02) { | |
for (local j = 0; j < 256 * cycles; j++) { | |
for (local i = 0; i < ledCount; i++) { | |
local colour = wheel(((i*256 / ledCount) + j) % 255); | |
strip[i*3] = colour[0]; | |
strip[i*3+1] = colour[1]; | |
strip[i*3+2] = colour[2]; | |
} | |
writeToStrip(); | |
imp.sleep(wait); | |
} | |
} | |
// | |
// Shift the led strip one led per call. | |
// | |
function shift() { | |
// Led 0 should be 1, 1 should be 2 etc | |
local newStrip = blob(ledCount * 3); | |
for (local i = 0; i < ledCount * 3; i++) { | |
newStrip[(i+3)%(ledCount*3)] = strip[i]; | |
} | |
strip = newStrip; | |
writeToStrip(); | |
} | |
// | |
// Rotate strip. | |
// Defaults to one complete turn and delay of 50 ms between each step. | |
// Note that you can rotate fractional turns too! | |
// | |
function rotate(turns = 1.0, stepDelay = 0.05) { | |
for (local i = 0; i < math.floor(turns * ledCount); i++) { | |
shift(); | |
imp.sleep(stepDelay); | |
} | |
} | |
// | |
// Writes out data to strip and assures it latches before execution continues. | |
// | |
function writeToStrip() { | |
hardware.spi257.write(strip); | |
// Wait so strip "latches" | |
imp.sleep(0.001); | |
} | |
// | |
// Returns a colour positioned at 'position' on a colour wheel with 256 steps (I think, nicked this code). | |
// | |
function wheel(position) { | |
local colour = blob(3); | |
if (position < 85) { | |
colour[0] = position * 3; | |
colour[1] = 255 - position * 3; | |
colour[2] = 0; | |
return colour; | |
} else if (position < 170) { | |
position = position - 85; | |
colour[0] = 255 - position * 3; | |
colour[1] = 0; | |
colour[2] = position * 3; | |
return colour; | |
} else { | |
position = position - 170; | |
colour[0] = 0; | |
colour[1] = position * 3; | |
colour[2] = 255 - position * 3; | |
return colour; | |
} | |
} | |
} | |
// | |
// Example use below | |
// | |
server.log("Enjoy the show!"); | |
// Instantiate | |
local strip = WS2801(20); | |
// Set all to off | |
strip.setColour(Colour.off); | |
// Set all to white | |
strip.setColour(Colour.white); | |
imp.sleep(1.0); | |
// Swipe in red to all LEDs | |
strip.colourWipe(Colour.red); | |
// Set first LED to red | |
strip.setColour(Colour.red, 0); | |
imp.sleep(0.5); | |
// Shift the strip 1 LED for each call | |
strip.shift(); | |
imp.sleep(0.5); | |
strip.shift(); | |
imp.sleep(0.5); | |
strip.shift(); | |
imp.sleep(0.5); | |
// Rotate the strip 1.5 times | |
strip.rotate(1.5); | |
// Set all LEDs with even index to orange | |
strip.setColour(Colour.orange, [0,2,4,6,8,10,12,14,16,18]); | |
imp.sleep(1.0); | |
// Set all LEDs with odd index to green and keep the previous setting | |
strip.setColour(Colour.green, [1,3,5,7,9,11,13,15,17,19], true); | |
imp.sleep(1.0); | |
// Set all LEDs with even index to oranga without keeping previous setting | |
strip.setColour(Colour.orange, [0,2,4,6,8,10,12,14,16,18]); | |
imp.sleep(1.0); | |
// Do a fancy rainbow | |
strip.rainbowCycle(2, 0.005); | |
// And rotate it, for the world! | |
strip.rotate(10); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment