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();
}
}