Skip to content

Instantly share code, notes, and snippets.

@fizx
Last active August 29, 2015 14:26
Show Gist options
  • Save fizx/6d126772664d5295e805 to your computer and use it in GitHub Desktop.
Save fizx/6d126772664d5295e805 to your computer and use it in GitHub Desktop.
#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