Skip to content

Instantly share code, notes, and snippets.

@jneilliii
Forked from ElectricImpSampleCode/lightshow.agent.nut
Last active January 3, 2016 06:54
Show Gist options
  • Save jneilliii/9bf4e2d4a6b511d9d846 to your computer and use it in GitHub Desktop.
Save jneilliii/9bf4e2d4a6b511d9d846 to your computer and use it in GitHub Desktop.
Micro Light Show project code
// Agent Code
function getForm(msg){
local effects = ["glow","random","looper","larson","awaiting command"];
// HTML output
local returnValue = @"<!DOCTYPE html>
<html>
<head>
<title>RGB Tail Light Show</title>
<style>
h2 { font-family:Verdana;color:#3B6BB2; }
p { font-family:Verdana;padding-bottom:10px; }
b { color:#3B6BB2; }
</style>
</head>
<body>
<form name='frmPrimary' action='" + http.agenturl() + "' method='get'>";
returnValue += @"<table style='width:100%;border:0px;' cellpadding='3'><tr><td align='center'>
<h2 align='center'>Light Show : " + effects[msg] + "</h2>";
returnValue += @"<table style='border:1px solid #3B6BB2;border-collapse:collapse;' cellpadding='3'>
<tr><td valign='top'>
<select id='effect' name='effect'>
<option value='0'>glow</option>
<option value='1'>random</option>
<option value='2'>looper</option>
<option value='3'>larson</option>
</select></td><td valign='top'><input type='Submit' value='set effect'>
</td></tr>
</form>
<form name='frmSecondary' action='" + http.agenturl() + "' method='get'>";
returnValue += @"<tr><td valign='top'><input type='text' value='0.0.0' id='setcolor' name='setcolor' size='12'></td><td><input type='Submit' value='set color'></td></tr>
</table>
</form>
</body>
</html>";
return returnValue;
}
function requestHandler(request, response) {
try {
//if effect was changed run this code
if("effect" in request.query) {
device.send("seteffect", request.query.effect.tointeger());
response.send(200, getForm(request.query.effect.tointeger()));
return;
//else if color was set run this code
} else if("setcolor" in request.query) {
device.send("setcolor", request.query.setcolor);
response.send(200, getForm("color set to " + request.query.setcolor));
return;
//otherwise just send the form
} else {
response.send(200, getForm(4));
return;
}
} catch (error) {
server.log("Error: " + error);
}
}
// Reqister the handler to deal with incoming requests
http.onrequest(requestHandler);
// Device Code
#require "WS2812.class.nut:2.0.1"
// CONSTANTS
const NUMPIXELS = 5;
const DELAY = 0.1;
const COLORDELTA = 8;
// Instantiate the WS2812s
spi <- hardware.spi257;
spi.configure(MSB_FIRST, 7500);
pixels <- WS2812(spi, NUMPIXELS);
// Light/color data
local redVal = 0;
local greenVal = 0;
local blueVal = 0;
local redDelta = 1;
local greenDelta = 1;
local blueDelta = 1;
local redOn = true;
local greenOn = false;
local blueOn = false;
local timer = null;
local pixel = 0;
local pDelta = 1;
function glowinit(dummy) {
// All the pixels run through the range colors
if (timer != null) imp.cancelwakeup(timer);
redVal = 0; greenVal = 0; blueVal = 0;
redDelta = COLORDELTA; greenDelta = COLORDELTA; blueDelta = COLORDELTA;
redOn = true; greenOn = false; blueOn = false;
// Call the glow effect
glow();
}
function glow() {
// Set the color values of the RGB LEDS
pixels.fill([redVal, greenVal, blueVal]);
// Write the color data to the WS2812s
pixels.draw();
// Adjust the color values for the next frame of the animation
adjustColors();
// Queue up the presentation of the next frame
timer = imp.wakeup(DELAY, glow);
}
function randominit(dummy) {
// A random pixel glows a random color
if (timer != null) imp.cancelwakeup(timer);
random();
}
function random() {
// Clear the current color data and write it to the
// WS2812s to turn them all off
pixels.fill([0,0,0]);
pixels.draw();
// Set random color values
redVal = ran(255); greenVal = ran(255); blueVal = ran(255);
// Pick one of the WS2812s
pixel = ran(NUMPIXELS);
// Write the color data out
pixels.set(pixel, [redVal, greenVal, blueVal]);
pixels.draw();
// Queue up the presentation of the next frame
timer = imp.wakeup(DELAY * 2, random);
}
function looperinit(dummy) {
// The pixels run through all the colors.
// Only one pixel is illuminated at once, in order
if (timer != null) imp.cancelwakeup(timer);
redVal = 0; greenVal = 0; blueVal = 0;
redDelta = COLORDELTA; greenDelta = COLORDELTA; blueDelta = COLORDELTA;
redOn = true; greenOn = false; blueOn = false;
pixel = 0;
looper();
}
function looper() {
// Clear all the WS2812s’ colors then write the current
// color value to the current LED and write it to the hardware
pixels.fill([0,0,0]);
pixels.set(pixel, [redVal, greenVal, blueVal]);
pixels.draw();
// Move on to the next LED, looping round to the first if necessary
pixel++;
if (pixel >= NUMPIXELS) pixel = 0;
// Adjust the color value
adjustColors();
// Queue up the presentation of the next frame
timer = imp.wakeup(DELAY, looper);
}
function larsoninit(dummy) {
if (timer != null) imp.cancelwakeup(timer);
redVal = 64; greenVal = 0; blueVal = 0;
redDelta = COLORDELTA; redOn = true; pixel = 0; pDelta = 1;
larson();
}
function larson() {
// Clear all the WS2812s’ color values to turn them off
pixels.fill([0,0,0]);
pixels.set(pixel, [redVal, 0, 0]);
pixels.draw();
// Get the address of the next LED to color,
// bouncing back from the ends and the center
pixel = pixel + pDelta;
if (pixel == NUMPIXELS) {
pDelta = -1;
pixel = NUMPIXELS - 2;
}
if (pixel < 0) {
pDelta = 1;
pixel = 1;
}
// Adjust the color value
redVal = redVal + redDelta;
if (redVal > 160) {
redVal = 160 - COLORDELTA;
redDelta = COLORDELTA * -1;
} else if (redVal < 64) {
redVal = 64 + COLORDELTA;
redDelta = COLORDELTA;
}
// Queue up the presentation of the next frame
timer = imp.wakeup(DELAY, larson);
}
function ran(max) {
// Generate a pseudorandom number between 0 and (max - 1)
local roll = 1.0 * math.rand() / RAND_MAX;
roll = roll * max;
return roll.tointeger();
}
function adjustColors() {
// Calculate new color values, running from red to green to blue,
// and fading from one into the next
if (redOn) {
redVal = redVal + redDelta;
if (redVal > 254) {
redVal = 256 - COLORDELTA;
redDelta = COLORDELTA * -1;
greenOn = true;
}
if (redVal < 1) {
redDelta = COLORDELTA;
redOn = false;
redVal = 0;
}
}
if (greenOn) {
greenVal = greenVal + greenDelta;
if (greenVal > 254) {
greenDelta = COLORDELTA * -1;
blueOn = true;
greenVal = 256 - COLORDELTA;
}
if (greenVal < 1) {
greenDelta = COLORDELTA;
greenOn = false;
greenVal = 0;
}
}
if (blueOn) {
blueVal = blueVal + blueDelta;
if (blueVal > 254) {
blueDelta = COLORDELTA * -1;
redOn = true;
blueVal = 256 - COLORDELTA;
}
if (blueVal < 1) {
blueDelta = COLORDELTA;
blueOn = false;
blueVal = 0;
}
}
}
function setColor(color) {
if (timer!= null) imp.cancelwakeup(timer);
pixels.fill([0,0,0]);
local colors = split(color, ".");
local red = colors[0].tointeger();
if (red < 0) red = 0;
if (red > 255) red = 255;
local green = colors[1].tointeger();
if (green < 0) green = 0;
if (green > 255) green = 255;
local blue = colors[2].tointeger();
if (blue < 0) blue = 0;
if (blue > 255) blue = 255;
for (local i = 0 ; i < NUMPIXELS ; i++) {
pixels.set(i, [red, green, blue]);
}
pixels.draw();
}
function setEffect(effect) {
switch (effect) {
case 0:
glowinit(true);
break;
case 1:
randominit(true);
break;
case 2:
looperinit(true);
break;
case 3:
larsoninit(true);
}
}
// START OF PROGRAM
// Register handlers for messages from the agent
agent.on("seteffect", setEffect);
agent.on("setcolor", setColor);
// Pick a random effect to begin with
setEffect(ran(4));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment