Home > Arduino Projects > Ethernet DMX

Ethernet DMX

Last week I recieved the Arduino Ethernet Shield – http://www.arduino.cc/en/Main/ArduinoEthernetShield
There were all ready complete examples provided, so it was very easy to get started.
Then I thought it would be nice to have a Ethernet DMX Controller, so i could type the IP-Adress of the Ethernet Shield in explorer, and from there control my movinghead (Stairville MV250H)

 

Then I found this page showing how to use an MAX485 and the Arduino as a DMX interface – http://iad.projects.zhdk.ch/physicalcomputing/hardware/arduino/dmx-shield-fur-arduino/
I tried it, and it worked :) – And the Arduino could communicate with my movinghead.

 

Then I combined the Ethernet example and the DMX example, to make a HTML Page where i could click on different buttons to change the DMX values that would be sent to my movinghead.
Try it out yourself… You need a MAX485, follow the link above on how to connect it to the Arduino. Just use pin 3 instead of pin 11, as the Ethernet shield uses Pin 9 to 13!

 

Here is the Arduino code:

#include <Ethernet.h>
#include <stdio.h>

// include pin definition library -----------------------------------------------
#include "pins_arduino.h"

// variable definitions ---------------------------------------------------------
int sig = 3;       // DMX signal pin - DO NOT CHANGE

// network configuration.  gateway and subnet are optional.
byte mac[] = { 0x00, 0x12, 0x34, 0x56, 0x78, 0x90 }; // Change this to the MAC the Ethernet shield should have
byte ip[] = { 192, 168, 1, 1 }; // Change this to the IP-Adress the Ethernet shield should have

byte DMX_Get[]={0,0,0,0,0};
byte Buffer[]={0,0,0,0,0};

Server server = Server(80);
unsigned long time;

// function definitions ---------------------------------------------------------
/* Sends a DMX byte out on a pin.  Assumes a 16 MHz clock.
 * Disables interrupts, which will disrupt the millis() function if used
 * too frequently. */
void shiftDmxOut(int pin, int theByte)
{
  int port_to_output[] = {
    NOT_A_PORT,
    NOT_A_PORT,
    _SFR_IO_ADDR(PORTB),
    _SFR_IO_ADDR(PORTC),
    _SFR_IO_ADDR(PORTD)
    };

    int portNumber = port_to_output[digitalPinToPort(pin)];
  int pinMask = digitalPinToBitMask(pin);

  // the first thing we do is to write te pin to high
  // it will be the mark between bytes. It may be also
  // high from before
  _SFR_BYTE(_SFR_IO8(portNumber)) |= pinMask;
  delayMicroseconds(10);

  // disable interrupts, otherwise the timer 0 overflow interrupt that
  // tracks milliseconds will make us delay longer than we want.
  cli();

  // DMX starts with a start-bit that must always be zero
  _SFR_BYTE(_SFR_IO8(portNumber)) &= ~pinMask;

  // we need a delay of 4us (then one bit is transfered)
  // this seems more stable then using delayMicroseconds
  asm("nop\n nop\n nop\n nop\n nop\n nop\n nop\n nop\n");
  asm("nop\n nop\n nop\n nop\n nop\n nop\n nop\n nop\n");

  asm("nop\n nop\n nop\n nop\n nop\n nop\n nop\n nop\n");
  asm("nop\n nop\n nop\n nop\n nop\n nop\n nop\n nop\n");

  asm("nop\n nop\n nop\n nop\n nop\n nop\n nop\n nop\n");
  asm("nop\n nop\n nop\n nop\n nop\n nop\n nop\n nop\n");

  for (int i = 0; i < 8; i++)
  {
    if (theByte & 01)
    {
      _SFR_BYTE(_SFR_IO8(portNumber)) |= pinMask;
    }
    else
    {
      _SFR_BYTE(_SFR_IO8(portNumber)) &= ~pinMask;
    }

    asm("nop\n nop\n nop\n nop\n nop\n nop\n nop\n nop\n");
    asm("nop\n nop\n nop\n nop\n nop\n nop\n nop\n nop\n");

    asm("nop\n nop\n nop\n nop\n nop\n nop\n nop\n nop\n");
    asm("nop\n nop\n nop\n nop\n nop\n nop\n nop\n nop\n");

    asm("nop\n nop\n nop\n nop\n nop\n nop\n nop\n nop\n");
    asm("nop\n nop\n nop\n nop\n nop\n nop\n nop\n nop\n");

    theByte >>= 1;
  }

  // the last thing we do is to write the pin to high
  // it will be the mark between bytes. (this break is have to be between 8 us and 1 sec)
  _SFR_BYTE(_SFR_IO8(portNumber)) |= pinMask;

  // reenable interrupts.
  sei();
}

void SendDMX_Values() {
  /***** sending the dmx signal *****/

  // sending the break (the break can be between 88us and 1sec)
  digitalWrite(sig, LOW);
  delay(10);

  // sending the start byte
  shiftDmxOut(sig, 0);

  shiftDmxOut(sig, DMX_Get[0]); // Pan value
  shiftDmxOut(sig, DMX_Get[1]); // Tilt value
  shiftDmxOut(sig, DMX_Get[2]); // Shutter open
  shiftDmxOut(sig, DMX_Get[3]); // Clear gobo
  shiftDmxOut(sig, DMX_Get[4]); // Color fade

  for (int count = 1; count <= 507; count++)
  {
    shiftDmxOut(sig, 0);
  }
  /***** sending the dmx signal end *****/
}

void setup()
{
  pinMode(sig, OUTPUT);       // data pin to dmx board
  // initialize the ethernet device
  Ethernet.begin(mac, ip);  //, gateway, subnet);
  server.begin();
  Serial.begin(9600);
}

void strcat(char* original, char appended)
{
    while (*original++)
	  ;
    *original++ = appended;
    if (appended)
	  *original = '\0';
} 

void Form_Code(Client client, char type, byte arraynumber, byte number, byte value, char text[15]) {
  char ValueToBePrinted[4];
 // if (type == 'p') {
    server.print("<form name='");
    server.print(type);
    server.print(number+48);
    server.print("' method='get'><input name='");
    server.print(type);
    server.print("' type='hidden' value='");
    sprintf(ValueToBePrinted, "%d", int(value));
    server.print(ValueToBePrinted);
    server.print("'>");
    server.print("<input type='submit' value='");
    server.print(text);
    server.print("'");
    if (DMX_Get[arraynumber] == value) {
      server.print(" disabled='disabled'");
    }
    server.print("></form>");
  //}
}

void loop()
{
  Client client = server.available();
  if (client) {

    server.print("HTTP/1.0 200 OK\r\nServer: arduino\r\nContent-Type: text/html\r\n\r\n");
    server.print("<HTML><HEAD><TITLE>");
    server.print("Arduino Web-Server - ");
    server.print(millis());//to make sure that we habve a new page
    server.print("</TITLE>");
    server.print("<script type=\"text/JavaScript\"><!--function timedRefresh(timeoutPeriod){setTimeout(\"location.reload(true);\",timeoutPeriod);}//--></script>");
    server.print("</HEAD><BODY>");
    capturevariable(client);//dump the headers and recover any values passed in from the form
    server.print("<br><br>");

    server.print("Pan:");
    Form_Code(client, 'p', 0, 1, 0, "0");
    Form_Code(client, 'p', 0, 2, 127, "127");
    Form_Code(client, 'p', 0, 3, 255, "255");
    server.print("Tilt:");
    Form_Code(client, 't', 1, 1, 0, "0");
    Form_Code(client, 't', 1, 2, 127, "127");
    Form_Code(client, 't', 1, 3, 255, "255");
    SendDMX_Values();
    server.print("Color:");
    Form_Code(client, 'c', 4, 1, 0, "White");
    Form_Code(client, 'c', 4, 2, 20, "Green");
    Form_Code(client, 'c', 4, 3, 30, "Magenta");
    Form_Code(client, 'c', 4, 4, 40, "Light Blue");
    Form_Code(client, 'c', 4, 5, 50, "Amber");
    Form_Code(client, 'c', 4, 6, 60, "Red");
    Form_Code(client, 'c', 4, 7, 70, "Blue");
    Form_Code(client, 'c', 4, 8, 80, "UV Purple");
    Form_Code(client, 'c', 4, 9, 90, "Light Green");
    Form_Code(client, 'c', 4, 1, 100, "Orange");
    Form_Code(client, 'c', 4, 2, 110, "Yellow");
    Form_Code(client, 'c', 4, 3, 120, "Pink");
    server.print("Shutter:");
    Form_Code(client, 's', 2, 2, 255, "ON");
    Form_Code(client, 's', 2, 1, 0, "OFF");

    server.print("</BODY></HTML>");
    client.stop();//close the connection with the client
    delay(20);//pause wait  for a new connection
  }   

  SendDMX_Values();

}

void capturevariable(Client client){
  //we get a string like:GET /?p=255&t=100&o=255 we enter here after the ? or the &
  byte count = 0;
  int count_all = 0;

  char c = client.read();
  server.print(c);
  while ((c!= -1) && (c != '?')){
    c = client.read();
    server.print(c); // Debug
    count++;
  }

    count = 0;
    count_all = 0;

    while ((c != -1) && (count_all < 64) && (c != 'H')){
      c = client.read();
      server.print(c); // Debug
      count_all++;

      if(c=='p'){
        Serial.print("P=");
        c = client.read();//skip the =
        server.print(c); // Debug

        count = 0;
        while ((c != -1) && (count < 4) && (c != '&') && (c != ' ')){
          if (c != '&') {
            c = client.read();
            server.print("<b>"); // Debug
            server.print(c); // Debug
            server.print("</b>"); // Debug
            Buffer[count] = c-48;
            count++;
          }
        }
        if (count == 2) {
          DMX_Get[0] = Buffer[0];
        }
        if (count == 3) {
          DMX_Get[0] = Buffer[1];
          DMX_Get[0] = DMX_Get[0] + (Buffer[0] * 10);
        }
        if (count == 4) {
          DMX_Get[0] = Buffer[2];
          DMX_Get[0] = DMX_Get[0] + (Buffer[1] * 10);
          DMX_Get[0] = DMX_Get[0] + (Buffer[0] * 100);
        }
        Serial.print(DMX_Get[0], DEC);
      }

      if(c=='t'){
        Serial.print("T=");
        c = client.read();//skip the =
        server.print(c); // Debug

        count = 0;
        while ((c != -1) && (count < 4) && (c != '&') && (c != ' ')){
          if (c != '&') {
            c = client.read();
            server.print("<b>"); // Debug
            server.print(c); // Debug
            server.print("</b>"); // Debug
            Buffer[count] = c-48;
            count++;
          }
        }
        if (count == 2) {
          DMX_Get[1] = Buffer[0];
        }
        if (count == 3) {
          DMX_Get[1] = Buffer[1];
          DMX_Get[1] = DMX_Get[1] + (Buffer[0] * 10);
        }
        if (count == 4) {
          DMX_Get[1] = Buffer[2];
          DMX_Get[1] = DMX_Get[1] + (Buffer[1] * 10);
          DMX_Get[1] = DMX_Get[1] + (Buffer[0] * 100);
        }
        Serial.print(DMX_Get[1], DEC);
      }   

      if(c=='s'){
        Serial.print("S=");
        c = client.read();//skip the =
        server.print(c); // Debug

        count = 0;
        while ((c != -1) && (count < 4) && (c != '&') && (c != ' ')){
          if (c != '&') {
            c = client.read();
            server.print("<b>"); // Debug
            server.print(c); // Debug
            server.print("</b>"); // Debug
            Buffer[count] = c-48;
            count++;
          }
        }
        if (count == 2) {
          DMX_Get[2] = Buffer[0];
        }
        if (count == 3) {
          DMX_Get[2] = Buffer[2];
          DMX_Get[2] = DMX_Get[2] + (Buffer[0] * 10);
        }
        if (count == 4) {
          DMX_Get[2] = Buffer[2];
          DMX_Get[2] = DMX_Get[2] + (Buffer[1] * 10);
          DMX_Get[2] = DMX_Get[2] + (Buffer[0] * 100);
        }
        Serial.print(DMX_Get[2], DEC);
      }  

      if(c=='c'){
        Serial.print("C=");
        c = client.read();//skip the =
        server.print(c); // Debug

        count = 0;
        while ((c != -1) && (count < 4) && (c != '&') && (c != ' ')){
          if (c != '&') {
            c = client.read();
            server.print("<b>"); // Debug
            server.print(c); // Debug
            server.print("</b>"); // Debug
            Buffer[count] = c-48;
            count++;
          }
        }
        if (count == 2) {
          DMX_Get[4] = Buffer[0];
        }
        if (count == 3) {
          DMX_Get[4] = Buffer[4];
          DMX_Get[4] = DMX_Get[4] + (Buffer[0] * 10);
        }
        if (count == 4) {
          DMX_Get[4] = Buffer[4];
          DMX_Get[4] = DMX_Get[4] + (Buffer[1] * 10);
          DMX_Get[4] = DMX_Get[4] + (Buffer[0] * 100);
        }
        Serial.print(DMX_Get[4], DEC);
      }       

    }

    while ((c != -1)){
      c = client.read();
    }
}