Hi!
I want to control a WS2812B LED Strip:
with an arduino (nano preferably) that acts as DMX slave.
I use the conceptinetics shield, but that shouldn't matter:
http://www.ebay.com/itm/DMX-Shield-for-Arduino-/330927225562?ssPageName=ADME:L:OC:DE:3160
The problem seems to be that the timing to control that LED Strip has to be very precise (µs?), and the interrupts from the DMX shield (raised every time data is available) interfere with that.
The result are false colors, animation failing (things happening totally randomly, then working a little, then failing again); basically a mess (but you can still see the intended pattern behind the fails ![]()
I've tried every variation in the code I could think off, do you have any other idea than to use 2 arduino MEGAs, and output the ~9 DMX channels I want via PWM and to read them with analogRead from the second one??
Here is my code:
#include "FastLED.h"
#include <Conceptinetics.h>
////////////////////////////////////// LEDS
// How many leds in your strip?
#define NUM_LEDS 240
#define DATA_PIN 22
////////////////////////////////////// DMX
#define DMX_SLAVE_CHANNELS 9
// Define the array of leds
CRGB leds[NUM_LEDS+7];
DMX_Slave dmx_slave ( DMX_SLAVE_CHANNELS );
int red = 0;
int green = 0;
int blue = 0;
int speedBackward = 128;
int speedForward = 0;
int countLights = 2;
int widthLights = 6;
int strobo = 0;
int rainbow = 0;
void setup() {
FastLED.addLeds<WS2812B, DATA_PIN, GRB>(leds, NUM_LEDS);
dmx_slave.enable ();
dmx_slave.setStartAddress (1);
dmx_slave.onReceiveComplete ( OnDMXFrameReceiveComplete );
}
void OnDMXFrameReceiveComplete (void) {
red = dmx_slave.getChannelValue (1);
green = dmx_slave.getChannelValue (2);
blue = dmx_slave.getChannelValue (3);
speedBackward = dmx_slave.getChannelValue (4);
speedForward = dmx_slave.getChannelValue (5);
// if 0 let it be 1, else divide by 10 /maximum number of lights in tube: 25)
countLights = dmx_slave.getChannelValue (6) > 0 ? ceil(dmx_slave.getChannelValue (6) / 10) : 1;
widthLights = dmx_slave.getChannelValue (7) > 0 ? ceil(dmx_slave.getChannelValue (7) / 4) : 1;
strobo = dmx_slave.getChannelValue (8);
rainbow = dmx_slave.getChannelValue (9);
}
void loop() {
// loop over all leds
for(int i = 0; i < NUM_LEDS; i++) {
// do the "current" led, PLUS the ones, equidistant
for (int currentLight = 0; currentLight < countLights; currentLight ++) {
int currentLedBegin = i + (NUM_LEDS / countLights) * currentLight;
// width of the light
for (int ledFromBegin = 0; ledFromBegin < widthLights; ledFromBegin++) {
leds[(currentLedBegin + ledFromBegin) % NUM_LEDS].setRGB(red, green, blue);
}
}
// Show the leds
FastLED.show();
for (int currentLight = 0; currentLight < countLights; currentLight ++) {
int currentLedBegin = i + (NUM_LEDS / countLights) * currentLight;
// width of the light
for (int ledFromBegin = 0; ledFromBegin < widthLights; ledFromBegin++) {
leds[(currentLedBegin + ledFromBegin) % NUM_LEDS] = CRGB::Black;
}
}
// Wait a little bit before we loop around and do it again
//delay(2);
}
// // Now go in the other direction.
// for(int i = NUM_LEDS-1; i >= 0; i--) {
// // Set the i'th led to red
// leds[i] = CRGB::Red;
// // Show the leds
// FastLED.show();
// // now that we've shown the leds, reset the i'th led to black
// leds[i] = CRGB::Black;
// // Wait a little bit before we loop around and do it again
// delay(30);
// }
}