Last active
August 29, 2015 14:26
-
-
Save fizx/6d126772664d5295e805 to your computer and use it in GitHub Desktop.
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
#include <Adafruit_NeoPixel.h> | |
#include <lib_dmx.h> // deskontrol library | |
#define DMX512 0 | |
#define PIN 12 // Arduino data pin for the WS2812s | |
#define DELAY 10 // Millis to sleep each loop | |
#define CLUSTER_SIZE 12 // Size of each LED ring | |
#define CLUSTERS_COUNT 30 // Number of LED rings | |
#define DMX_GROUPS 12 // Number of RGB inputs received via DMX... will interpolate these values into the clusters | |
// DMX_CHANNELS = DMX_GROUPS * 3(for RGB) + 1 effect channel | |
#define FIRST_DMX_ADDRESS 1 | |
// Effects | |
#define SPARKLE 0 // Overlay a fast white theatre chase on the normal colors. | |
Adafruit_NeoPixel strip = Adafruit_NeoPixel(CLUSTER_SIZE * CLUSTERS_COUNT, PIN, NEO_GRB + NEO_KHZ400); | |
const float pi = 3.14159265359; | |
const uint32_t WHITE = strip.Color(255, 255, 255); | |
// Values between zero and 2pi, representing the horizontal angular location of the cluster. | |
float offsets[CLUSTERS_COUNT]; | |
int counter = 0; | |
void setup() { | |
pinMode(2, OUTPUT); | |
pinMode(5, OUTPUT); | |
// because the shield uses two output pins from arduino to control the MAX485 | |
digitalWrite(2, LOW); // control of 485 direction (input) | |
digitalWrite(5, LOW); // control of 485 direction (input) | |
// Let's assume for now that the clusters are distributed uniformly in a circle. | |
for (int i = 0; i < CLUSTERS_COUNT; i++) { | |
offsets[i] = i * 2 * pi / CLUSTERS_COUNT; | |
} | |
// You can make manual adjustments to the real light positions. This will hopefully keep the colors uniformly spaced. | |
// offsets[0] = 0.1; // etc | |
strip.begin(); | |
strip.show(); | |
ArduinoDmx0.set_control_pin(-1); | |
ArduinoDmx0.set_rx_address(FIRST_DMX_ADDRESS); | |
ArduinoDmx0.set_rx_channels(DMX_GROUPS * 3 + 1); | |
ArduinoDmx0.init_rx(DMX512); | |
} | |
void loop() { | |
int effectID = ArduinoDmx0.RxBuffer[DMX_GROUPS * 3]; | |
int sparkle = counter % CLUSTER_SIZE; | |
for (int i = 0; i < CLUSTERS_COUNT; i++) { | |
uint32_t color = dmxColor(offsets[i]); | |
for (int j = 0; j < CLUSTER_SIZE; j++) { | |
int pixel = i * CLUSTER_SIZE + j; | |
switch(effectID) { | |
case SPARKLE: | |
if (j == sparkle) { | |
strip.setPixelColor(pixel, WHITE); | |
break; | |
} | |
default: // DMX | |
strip.setPixelColor(pixel, color); | |
} | |
} | |
} | |
strip.show(); | |
delay(DELAY); | |
counter++; | |
} | |
// This function maps a small number of DMX channels to a larger number of LEDs, while smoothing out | |
// the color. | |
uint32_t dmxColor(float offset) { | |
float location = (offset * DMX_GROUPS / 2 / pi); | |
int group = ((int) location) % DMX_GROUPS; | |
int next = (group + 1) % DMX_GROUPS; | |
float interpolation = location - group; | |
int r1 = ArduinoDmx0.RxBuffer[group * 3]; | |
int r2 = ArduinoDmx0.RxBuffer[next * 3]; | |
int r = r1 * interpolation + r2 * (1 - interpolation); | |
int g1 = ArduinoDmx0.RxBuffer[group * 3 + 1]; | |
int g2 = ArduinoDmx0.RxBuffer[next * 3 + 1]; | |
int g = g1 * interpolation + g2 * (1 - interpolation); | |
int b1 = ArduinoDmx0.RxBuffer[group * 3 + 2]; | |
int b2 = ArduinoDmx0.RxBuffer[next * 3 + 2]; | |
int b = b1 * interpolation + b2 * (1 - interpolation); | |
return strip.Color(r, g, b); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment