Hello all,
currently we're designing a controllerbox based on Arduino Mega 2560 with ethernet shield. The Controller must be able to send out three different WS2812/WS2815 streams. Every data stream is connected to 5 meter WS2815 Led Tape (60led/m). Data is transmitting via ArtNet Unicast to Arduinos IP 2.30.1.1. Universes 1+2 are sending to outPin 11, universes 3+4 to outPin 12 and universes 5+6 to outPin 13. We had created following code:
/*
This example will receive multiple universes via Artnet and control a strip of ws2811 leds via
Adafruit's NeoPixel library: https://github.com/adafruit/Adafruit_NeoPixel
This example may be copied under the terms of the MIT license, see the LICENSE file for details
*/
#include <Artnet.h>
#include <Ethernet.h>
#include <EthernetUdp.h>
#include <SPI.h>
#include <Adafruit_NeoPixel.h>
// Neopixel settings
const int numLeds0 = 300; // change for your setup
const int numLeds1 = 300; // change for your setup
const int numLeds2 = 300; // change for your setup
const int numberOfChannels0 = numLeds0 * 3; // Total number of channels you want to receive (1 led = 3 channels)
const int numberOfChannels1 = numLeds1 * 3; // Total number of channels you want to receive (1 led = 3 channels)
const int numberOfChannels2 = numLeds2 * 3; // Total number of channels you want to receive (1 led = 3 channels)
const byte dataPin0 = 11;
const byte dataPin1 = 12;
const byte dataPin2 = 13;
const bool showleds0 = true;
const bool showleds1 = true;
const bool showleds2 = true;
Adafruit_NeoPixel leds0 = Adafruit_NeoPixel(numLeds0, dataPin0, NEO_GRB + NEO_KHZ800);
//Adafruit_NeoPixel leds1 = leds0;
//Adafruit_NeoPixel leds2 = leds0;
Adafruit_NeoPixel leds1 = Adafruit_NeoPixel(numLeds1, dataPin1, NEO_GRB + NEO_KHZ800);
//Adafruit_NeoPixel leds0 = leds1;
//Adafruit_NeoPixel leds2 = leds1;
Adafruit_NeoPixel leds2 = Adafruit_NeoPixel(numLeds2, dataPin2, NEO_GRB + NEO_KHZ800);
// Artnet settings
Artnet artnet;
const int startUniverse0 = 1; // CHANGE FOR YOUR SETUP most software this is 1, some software send out artnet first universe as 0.
const int startUniverse1 = 3;
const int startUniverse2 = 5;
// Check if we got all universes
const int maxUniverses0 = numberOfChannels0 / 512 + ((numberOfChannels0 % 512) ? 1 : 0);
const int maxUniverses1 = numberOfChannels1 / 512 + ((numberOfChannels1 % 512) ? 1 : 0);
const int maxUniverses2 = numberOfChannels2 / 512 + ((numberOfChannels2 % 512) ? 1 : 0);
bool universesReceived0[maxUniverses0];
bool universesReceived1[maxUniverses1];
bool universesReceived2[maxUniverses2];
bool sendFrame = 1;
int previousDataLength0 = 0;
int previousDataLength1 = 0;
int previousDataLength2 = 0;
long count = 0;
// Change ip and mac address for your setup
byte ip[] = {2, 30, 1, 1};
byte mac[] = {0x08, 0xE9, 0xE5, 0x00, 0x69, 0xEC}; // make sure this is different than any other mac address in your network
void setup()
{
Serial.begin(57600);
artnet.begin(mac, ip);
if(showleds0)
leds0.begin();
if(showleds1)
leds1.begin();
if(showleds2)
leds2.begin();
for(int i=0 ; i < 1 ; i++ )
{
initTest();
delay(500);
}
// this will be called for each packet received
artnet.setArtDmxCallback(onDmxFrame);
}
void loop()
{
// we call the read function inside the loop
artnet.read();
}
void onDmxFrame(uint16_t universe, uint16_t length, uint8_t sequence, uint8_t* data)
{
sendFrame = 1;
count++;
bool activeOut0 = false;
bool activeOut1 = false;
bool activeOut2 = false;
// set brightness of the whole strip
if (universe == 15)
{
leds0.setBrightness(data[0]);
leds0.show();
leds1.setBrightness(data[0]);
leds1.show();
leds2.setBrightness(data[0]);
leds2.show();
}
// Store which universe has got in
if ((universe >= startUniverse0) && (universe < (startUniverse0 + maxUniverses0)))
{
activeOut0 = true;
//if ((universe - startUniverse0) < maxUniverses0)
universesReceived0[universe - startUniverse0] = 1;
}
if ((universe >= startUniverse1) && (universe < (startUniverse1 + maxUniverses1)))
{
activeOut1 = true;
//leds1 = Adafruit_NeoPixel(numLeds1, dataPin1, NEO_GRB + NEO_KHZ800);
//leds1.begin();
//if ((universe - startUniverse1) < maxUniverses1)
universesReceived1[universe - startUniverse1] = 1;
}
if ((universe >= startUniverse2) && (universe < (startUniverse2 + maxUniverses2)))
{
activeOut2 = true;
//if ((universe - startUniverse2) < maxUniverses2)
universesReceived2[universe - startUniverse2] = 1;
}
for (int i = 0 ; i < maxUniverses0 ; i++)
{
if (universesReceived0[i] == 0)
{
//Serial.println("Broke");
//sendFrame = 0;
break;
}
}
// read universe and put into the right part of the display buffer
for (int i = 0; i < length / 3; i++)
{
if ((activeOut0 && showleds0))
{
int led = i + (universe - startUniverse0) * (previousDataLength0 / 3);
if (led < numLeds0)
leds0.setPixelColor(led, data[i * 3], data[i * 3 + 1], data[i * 3 + 2]);
}
if (activeOut1 && showleds1)
{
int led = i + (universe - startUniverse1) * (previousDataLength1 / 3);
if (led < numLeds1)
leds1.setPixelColor(led, data[i * 3], data[i * 3 + 1], data[i * 3 + 2]);
}
if (activeOut2 && showleds2)
{
int led = i + (universe - startUniverse2) * (previousDataLength2 / 3);
if (led < numLeds2)
leds2.setPixelColor(led, data[i * 3], data[i * 3 + 1], data[i * 3 + 2]);
}
}
if(showleds0)
previousDataLength0 = length;
if(showleds1)
previousDataLength1 = length;
if(showleds2)
previousDataLength2 = length;
if (sendFrame)
{
if(activeOut0 && false)
{
leds0.show();
memset(universesReceived0, 0, maxUniverses0);
}
if(activeOut1)
{
leds1.show();
memset(universesReceived1, 0, maxUniverses1);
}
if(activeOut2 && false)
{
leds2.show();
memset(universesReceived2, 0, maxUniverses2);
}
}
}
void initTest()
{
int waitTime = 333;
if(showleds0)
{
for (int i = 0 ; i < numLeds0 ; i++)
leds0.setPixelColor(i, 127, 0, 0);
leds0.show();
delay(waitTime);
for (int i = 0 ; i < numLeds0 ; i++)
leds0.setPixelColor(i, 0, 127, 0);
leds0.show();
delay(waitTime);
for (int i = 0 ; i < numLeds0 ; i++)
leds0.setPixelColor(i, 0, 0, 127);
leds0.show();
delay(waitTime);
for (int i = 0 ; i < numLeds0 ; i++)
leds0.setPixelColor(i, 0, 0, 0);
leds0.show();
}
if(showleds1)
{
for (int i = 0 ; i < numLeds1 ; i++)
leds1.setPixelColor(i, 127, 0, 0);
leds1.show();
delay(waitTime);
for (int i = 0 ; i < numLeds1 ; i++)
leds1.setPixelColor(i, 0, 127, 0);
leds1.show();
delay(waitTime);
for (int i = 0 ; i < numLeds1 ; i++)
leds1.setPixelColor(i, 0, 0, 127);
leds1.show();
delay(waitTime);
for (int i = 0 ; i < numLeds1 ; i++)
leds1.setPixelColor(i, 0, 0, 0);
leds1.show();
}
if(showleds2)
{
for (int i = 0 ; i < numLeds2 ; i++)
leds2.setPixelColor(i, 127, 0, 0);
leds2.show();
delay(waitTime);
for (int i = 0 ; i < numLeds2 ; i++)
leds2.setPixelColor(i, 0, 127, 0);
leds2.show();
delay(waitTime);
for (int i = 0 ; i < numLeds2 ; i++)
leds2.setPixelColor(i, 0, 0, 127);
leds2.show();
delay(waitTime);
for (int i = 0 ; i < numLeds2 ; i++)
leds2.setPixelColor(i, 0, 0, 0);
leds2.show();
}
}
The sketch is based on topic: Arduino Forum
First and second universes are transmitting smooth on pin 11, from 3rd universe refreshing stucks more and more up to blackout. Maybe it becomes overlays, depends on callback-function "Artnet.read". But we think this function schouldnt executed separatly for every pin. We are not sure and a bit desperated meanwhile.
Thank You
Matthias