Oh1/dmx & artnet

I’ve been playing around with the DMX Binding for OH1 and have been able to light a couple neopixel strips over artnet.
I’m using a Arduino Ethernet Shield to receive the commands and pass them on here is some of my code.

.ITEMS

Group YELLOW_Alert (All)
Group RED_Alert (All)
Switch RED_Alert (All)
Switch YELLOW_Alert (All)
Switch all_living_room_leds "Doorbell Flash"	(All) {dmx="CHANNEL[1/480], ON[FADE|0:255,255,255,255:125|0:0,0,255,0:125|0:255,255,255,255:125|0:0,0,255,0:125|0:255,255,255,255:125|0:0,0,255,0:125|0:255,255,255,255:125|0:0,0,255,0:125|0:255,255,255,255:125|0:0,0,255,0:125|0:0,0,0,0:-1]"}
Switch all_living_room_led "Warm White"	(All) {dmx="CHANNEL[1/480:1000], ON[FADE|0:0,0,0,255:125]"}
Color Left_Hatch_Color "Left Hatch Color"	(All) {dmx="CHANNEL[1/480:1000]"}
Switch hatch_1_yellow_alert "Hatch 1 Yellow Alert"	(YELLOW_Alert) {dmx="CHANNEL[1/160], ON[FADE|0:255,255,255,255:500|0:255,200,0,0:300|0:255,255,255,255:500|0:255,200,0,0:300|0:255,255,255,255:500|0:255,200,0,0:300|0:255,255,255,255:500|0:255,200,0,0:300|0:255,255,255,255:500|0:255,200,0,0:300|0:0,0,0,0:-1]"}
Switch hatch_1_red_alert "Hatch 1 Red Alert"	(RED_Alert) {dmx="CHANNEL[1/160], ON[FADE|0:255,255,255,255:500|0:255,0,0,0:300|0:255,255,255,255:500|0:255,0,0,0:300|0:255,255,255,255:500|0:255,0,0,0:300|0:255,255,255,255:500|0:255,0,0,0:300|0:255,255,255,255:500|0:255,0,0,0:300|0:0,0,0,0:-1]"}
Switch hatch_2_yellow_alert "Hatch 2 Yellow Alert"	(YELLOW_Alert) {dmx="CHANNEL[161/160], ON[FADE|0:255,255,255,255:500|0:255,200,0,0:300|0:255,255,255,255:500|0:255,200,0,0:300|0:255,255,255,255:500|0:255,200,0,0:300|0:255,255,255,255:500|0:255,200,0,0:300|0:255,255,255,255:500|0:255,200,0,0:300|0:0,0,0,0:-1]"}
Switch hatch_2_red_alert "Hatch 2 Red Alert"	(RED_Alert) {dmx="CHANNEL[161/160], ON[FADE|0:255,255,255,255:500|0:255,0,0,0:300|0:255,255,255,255:500|0:255,0,0,0:300|0:255,255,255,255:500|0:255,0,0,0:300|0:255,255,255,255:500|0:255,0,0,0:300|0:255,255,255,255:500|0:255,0,0,0:300|0:0,0,0,0:-1]"}
Switch hatch_3_yellow_alert "Hatch 3 Yellow Alert"	(YELLOW_Alert) {dmx="CHANNEL[321/160], ON[FADE|0:255,255,255,255:500|0:255,200,0,0:300|0:255,255,255,255:500|0:255,200,0,0:300|0:255,255,255,255:500|0:255,200,0,0:300|0:255,255,255,255:500|0:255,200,0,0:300|0:255,255,255,255:500|0:255,200,0,0:300|0:0,0,0,0:-1]"}
Switch hatch_3_red_alert "Hatch 3 Red Alert"	(RED_Alert) {dmx="CHANNEL[321/160], ON[FADE|0:255,255,255,255,255,0,0,0:500|0:255,0,0,0,255,255,255,255:300|0:255,255,255,255,255,0,0,0:500|0:255,0,0,0,255,255,255,255:300|0:255,255,255,255,255,0,0,0:500|0:255,0,0,0,255,255,255,255:300|0:255,255,255,255,255,0,0,0:500|0:255,0,0,0,255,255,255,255:300|0:255,255,255,255,255,0,0,0:500|0:255,0,0,0,255,255,255,255:300|0:0,0,0,0:-1]"}
Color Left_Hatch_WWA "Left Hatch WWA"	(All) {dmx="CHANNEL[1/480:1000]"}
Switch Left_Hatch_WWA_WW "WWA Warm White"	(All) {dmx="CHANNEL[1/480:1000], ON[FADE|0:0,0,255,0:125]"}
Switch Left_Hatch_WWA_W "WWA White"	(All) {dmx="CHANNEL[1/480:1000], ON[FADE|0:0,255,0,0:125]"}
Switch Left_Hatch_WWA_A "WWA Amber"	(All) {dmx="CHANNEL[1/480:1000], ON[FADE|0:255,0,0,0:125]"}

The arduino code is from natcl/Artnet with a couple modifications
3 channel strip. because anything over 4 channels registers as RGBW I had to make a way to strip out the 4th channel.

 /*
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
*/
#ifdef __AVR__
  #include <avr/power.h>
#endif
#include <Artnet.h>
#include <Ethernet.h>
#include <EthernetUdp.h>
#include <SPI.h>
#include <Adafruit_NeoPixel.h>

// Neopixel settings
const int numLeds = 120; // change for your setup
const int numberOfChannels = numLeds * 3; // Total number of channels you want to receive (1 led = 3 channels)
const byte dataPin = 2;
Adafruit_NeoPixel leds = Adafruit_NeoPixel(numLeds, dataPin, NEO_GRB + NEO_KHZ800);

// Artnet settings
Artnet artnet;
const int startUniverse = 0; // CHANGE FOR YOUR SETUP most software this is 1, some software send out artnet first universe as 0.

// Check if we got all universes
const int maxUniverses = numberOfChannels / 512 + ((numberOfChannels % 512) ? 1 : 0);
bool universesReceived[maxUniverses];
bool sendFrame = 1;
int previousDataLength = 0;

// Change ip and mac address for your setup
byte ip[] = {192, 168, 1, 110};
byte mac[] = {0x90, 0xA2, 0xDA, 0x10, 0x27, 0x6B};

void setup()
{
  //Serial.begin(115200);
  artnet.begin(mac, ip);
  leds.begin();
  initTest();

  // 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;
  // set brightness of the whole strip 
  if (universe == 15)
  {
    leds.setBrightness(data[0]);
    leds.show();
  }

  // Store which universe has got in
  if ((universe - startUniverse) < maxUniverses)
    universesReceived[universe - startUniverse] = 1;

  for (int i = 0 ; i < maxUniverses ; i++)
  {
    if (universesReceived[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++)
  {
    int led = i + (universe - startUniverse) * (previousDataLength / 4);
    if (led < numLeds)
      leds.setPixelColor(led, data[i * 4], data[i * 4 + 1], data[i * 4 + 2], data[i * 4 + 3]);
  }
  previousDataLength = length;     
  
  if (sendFrame)
  {
    leds.show();
    // Reset universeReceived to 0
    memset(universesReceived, 0, maxUniverses);
  }
}

void initTest()
{
  for (int i = 0 ; i < numLeds ; i++)
    leds.setPixelColor(i, 127, 0, 0);
  leds.show();
  delay(500);
  for (int i = 0 ; i < numLeds ; i++)
    leds.setPixelColor(i, 0, 127, 0);
  leds.show();
  delay(500);
  for (int i = 0 ; i < numLeds ; i++)
    leds.setPixelColor(i, 0, 0, 127);
  leds.show();
    delay(500);
  for (int i = 0 ; i < numLeds ; i++)
    leds.setPixelColor(i, 0, 0, 0);
  leds.show();
}

Arduino RGBW strip

/*
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 numLeds = 120; // change for your setup
const int numberOfChannels = numLeds * 4; // Total number of channels you want to receive (1 led = 3 channels)
#define dataPin1 7

Adafruit_NeoPixel leds1 = Adafruit_NeoPixel(numLeds, dataPin1, NEO_GRBW + NEO_KHZ800);

// Artnet settings
Artnet artnet;
const int startUniverse = 0; // CHANGE FOR YOUR SETUP most software this is 1, some software send out artnet first universe as 0.

// Check if we got all universes
const int maxUniverses = numberOfChannels / 512 + ((numberOfChannels % 512) ? 1 : 0);
bool universesReceived[maxUniverses];
bool sendFrame = 1;
int previousDataLength = 0;

// Change ip and mac address for your setup
byte ip[] = {192, 168, 1, 109};
byte mac[] = {0x90, 0xA2, 0xDA, 0x10, 0x26, 0x17};

void setup()
{
  Serial.begin(115200);
  artnet.begin(mac, ip);
  leds1.begin();
  leds2.setBrightness(BRIGHTNESS);
  leds2.begin();
  initTest();

  // 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;
  // set brightness of the whole strip 
  if (universe == 15)
  {
    leds1.setBrightness(data[0]);
    leds1.show();
  }

  // Store which universe has got in
  if ((universe - startUniverse) < maxUniverses)
    universesReceived[universe - startUniverse] = 1;

  for (int i = 0 ; i < maxUniverses ; i++)
  {
    if (universesReceived[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 / 4; i++)
  {
    int led = i + (universe - startUniverse) * (previousDataLength / 4);
    if (led < numLeds)
      leds1.setPixelColor(led, data[i * 4], data[i * 4 + 1], data[i * 4 + 2],data[i * 4 + 3]);
  }
  previousDataLength = length;     
  
  if (sendFrame)
  {
    leds1.show();
    // Reset universeReceived to 0
    memset(universesReceived, 0, maxUniverses);
  }
}

void initTest()
{
  for (int i = 0 ; i < numLeds ; i++)
    leds1.setPixelColor(i, 127, 0, 0, 0);
  leds1.show();
  delay(500);
  for (int i = 0 ; i < numLeds ; i++)
    leds1.setPixelColor(i, 0, 127, 0, 0);
  leds1.show();
  delay(500);
  for (int i = 0 ; i < numLeds ; i++)
    leds1.setPixelColor(i, 0, 0, 127, 0);
  leds1.show();
  delay(500);
  for (int i = 0 ; i < numLeds ; i++)
    leds1.setPixelColor(i, 0, 0, 0, 127);
  leds1.show();
  delay(500);
  for (int i = 0 ; i < numLeds ; i++)
    leds1.setPixelColor(i, 0, 0, 0, 0);
  leds1.show();
  
}
1 Like