DMX Shield für Arduino

Diese Version von DMX Arduino Shield basiert auf dem “DMX-shield” von Tomek Ness. Weitere Informationen von Tomek Ness zu DMX und Arduino.
Eine Einführung in das DMX 512 Protokoll

Es ist ein Board, welches auf ein “Arduino 2009″ gesteckt wird und über Pin 11 angesteuert wird. Die restlichen Anschlüsse sind via den zurückversetzten Pinleisten erreichbar. Es gehen also keine Pins verloren. Auf dem Board kommuniziert ein Treiber Chip via 3 Pol XLR Buchse mit dem DMX Universe. Das Shield ist nur DMX Master, kein Slave.

Das DMX Shield für Arduino ist open source und frei für den nicht kommerziellen Gebrauch.
—————————————-
Eagle Files:

Eagle Schema und Board DMX1_2 Schema+Board.zip
Schema als PDF DMX1_2-Schema.pdf
Board als PDF DMX1_2-Board.pdf
—————————————-



—————————————-
Bestückungsliste:

1x Chip RS485 SN75176
1x XLR Buchse NC3FAH2
1x DIL Sockel 8 Pin
entweder 1x Stiftleiste
oder je 1x Buchsenleiste 6 + 8 Pol
1x Widerstand 100 Ohm
—————————————-
Zubehör:

1x XLR Stecker NC3MAY
1x XLR Patch Kabel MECN-100
—————————————-

Beispielcode:

Von Peter Szakal und Gabor Papp von nextlab.hu.
Läuft auf der Hardware “Arduino 2009″ mit der Software “Arduino 12″.
Timing ist wichtig für das DMX Signal. Deshalb wurden delays in Assembler geschrieben.

Bitte verwende die Zip Datei zur weiteren Verwendung. Die Code Darstellung ist nicht sauber.
Zip Datei von untenstehendem Code: DMX Fade on all 512 Adresses

/*
* DMX fade for arduino 008
* based on the code of Tomek Ness and D. Cuartielles
*
* adapted to arduino 008 by Peter Szakal and Gabor Papp
* http://nextlab.hu
*/

#include "pins_arduino.h"

int sig = 11; // signal

int value = 0;
int valueadd = 3;

/* 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 &amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp; 01)
{
_SFR_BYTE(_SFR_IO8(portNumber)) |= pinMask;
}
else
{
_SFR_BYTE(_SFR_IO8(portNumber)) &amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;= ~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 setup()
{
pinMode(sig, OUTPUT);
}

void loop()
{
/***** 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);

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

value += valueadd;
if ((value == 0) || (value == 255))
{
valueadd *= -1;
}
}

Codebeispiel mit externem Input

- An Analog In Pin 0 wird mittels eines Spannungsteilers eine variable Spannung eingelesen. Diese definiert die Helligkeit der roten LED.
- An Digital Pin 3 wird erkannt, ob ein Taster den Kontakt zu Masse schliesst und schaltet dadurch die grüne LED.
- Der Zustand der blauen LED ergibt sich aus der Invertierung der grünen.
- Amber dimmt auf und ab.

Bitte verwende die Zip Datei zur weiteren Verwendung. Die Code Darstellung ist nicht sauber.
Zip Datei von unten stehendem Code: DMX Signal mit externem Input

/*
DMX input example</a>

<a href="http://iad.projects.zhdk.ch/physicalcomputing/wp-content/files/dmx_analogin2.zip"></a><a href="http://iad.projects.zhdk.ch/physicalcomputing/wp-content/files/dmx_analogin2.zip">based on DMX example by Peter Szakal and Gabor Papp http://nextlab.hu
based on the code of Tomek Ness and D. Cuartielles</a>

<a href="http://iad.projects.zhdk.ch/physicalcomputing/wp-content/files/dmx_analogin2.zip"></a><a href="http://iad.projects.zhdk.ch/physicalcomputing/wp-content/files/dmx_analogin2.zip">Pin Layout:
Arduino AIN0 - voltage divider
Arduino DIN3 - pushbutton
*/</a>

<a href="http://iad.projects.zhdk.ch/physicalcomputing/wp-content/files/dmx_analogin2.zip"></a><a href="http://iad.projects.zhdk.ch/physicalcomputing/wp-content/files/dmx_analogin2.zip">// include pin definition library -----------------------------------------------
#include "pins_arduino.h"</a>

<a href="http://iad.projects.zhdk.ch/physicalcomputing/wp-content/files/dmx_analogin2.zip"></a><a href="http://iad.projects.zhdk.ch/physicalcomputing/wp-content/files/dmx_analogin2.zip">// variable definitions ---------------------------------------------------------
int sig = 11;       // DMX signal pin - DO NOT CHANGE</a>

<a href="http://iad.projects.zhdk.ch/physicalcomputing/wp-content/files/dmx_analogin2.zip"></a><a href="http://iad.projects.zhdk.ch/physicalcomputing/wp-content/files/dmx_analogin2.zip">int value = 0;      // variables for color fade
int valueadd = 1;</a>

<a href="http://iad.projects.zhdk.ch/physicalcomputing/wp-content/files/dmx_analogin2.zip"></a><a href="http://iad.projects.zhdk.ch/physicalcomputing/wp-content/files/dmx_analogin2.zip">byte red = 0;       // variables to hold color values
byte green = 0;
byte blue = 0;
byte amber = 0;</a>

<a href="http://iad.projects.zhdk.ch/physicalcomputing/wp-content/files/dmx_analogin2.zip"></a><a href="http://iad.projects.zhdk.ch/physicalcomputing/wp-content/files/dmx_analogin2.zip">// 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)
};</a>

<a href="http://iad.projects.zhdk.ch/physicalcomputing/wp-content/files/dmx_analogin2.zip"></a><a href="http://iad.projects.zhdk.ch/physicalcomputing/wp-content/files/dmx_analogin2.zip">int portNumber = port_to_output[digitalPinToPort(pin)];
int pinMask = digitalPinToBitMask(pin);</a>

<a href="http://iad.projects.zhdk.ch/physicalcomputing/wp-content/files/dmx_analogin2.zip"></a><a href="http://iad.projects.zhdk.ch/physicalcomputing/wp-content/files/dmx_analogin2.zip">// 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);</a>

<a href="http://iad.projects.zhdk.ch/physicalcomputing/wp-content/files/dmx_analogin2.zip"></a><a href="http://iad.projects.zhdk.ch/physicalcomputing/wp-content/files/dmx_analogin2.zip">// disable interrupts, otherwise the timer 0 overflow interrupt that
// tracks milliseconds will make us delay longer than we want.
cli();</a>

<a href="http://iad.projects.zhdk.ch/physicalcomputing/wp-content/files/dmx_analogin2.zip"></a><a href="http://iad.projects.zhdk.ch/physicalcomputing/wp-content/files/dmx_analogin2.zip">// DMX starts with a start-bit that must always be zero
_SFR_BYTE(_SFR_IO8(portNumber)) &amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;= ~pinMask;</a>

<a href="http://iad.projects.zhdk.ch/physicalcomputing/wp-content/files/dmx_analogin2.zip"></a><a href="http://iad.projects.zhdk.ch/physicalcomputing/wp-content/files/dmx_analogin2.zip">// 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");</a>

<a href="http://iad.projects.zhdk.ch/physicalcomputing/wp-content/files/dmx_analogin2.zip"></a><a href="http://iad.projects.zhdk.ch/physicalcomputing/wp-content/files/dmx_analogin2.zip">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");</a>

<a href="http://iad.projects.zhdk.ch/physicalcomputing/wp-content/files/dmx_analogin2.zip"></a><a href="http://iad.projects.zhdk.ch/physicalcomputing/wp-content/files/dmx_analogin2.zip">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");</a>

<a href="http://iad.projects.zhdk.ch/physicalcomputing/wp-content/files/dmx_analogin2.zip"></a><a href="http://iad.projects.zhdk.ch/physicalcomputing/wp-content/files/dmx_analogin2.zip">for (int i = 0; i < 8; i++)
{
if (theByte &amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp; 01)
{
_SFR_BYTE(_SFR_IO8(portNumber)) |= pinMask;
}
else
{
_SFR_BYTE(_SFR_IO8(portNumber)) &amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;= ~pinMask;
}</a></a>

<a href="http://iad.projects.zhdk.ch/physicalcomputing/wp-content/files/dmx_analogin2.zip"></a><a href="http://iad.projects.zhdk.ch/physicalcomputing/wp-content/files/dmx_analogin2.zip">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");</a>

<a href="http://iad.projects.zhdk.ch/physicalcomputing/wp-content/files/dmx_analogin2.zip"></a><a href="http://iad.projects.zhdk.ch/physicalcomputing/wp-content/files/dmx_analogin2.zip">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");</a>

<a href="http://iad.projects.zhdk.ch/physicalcomputing/wp-content/files/dmx_analogin2.zip"></a><a href="http://iad.projects.zhdk.ch/physicalcomputing/wp-content/files/dmx_analogin2.zip">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");</a>

<a href="http://iad.projects.zhdk.ch/physicalcomputing/wp-content/files/dmx_analogin2.zip"></a><a href="http://iad.projects.zhdk.ch/physicalcomputing/wp-content/files/dmx_analogin2.zip">theByte >>= 1;
}</a>

<a href="http://iad.projects.zhdk.ch/physicalcomputing/wp-content/files/dmx_analogin2.zip"></a><a href="http://iad.projects.zhdk.ch/physicalcomputing/wp-content/files/dmx_analogin2.zip">// 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;</a>

<a href="http://iad.projects.zhdk.ch/physicalcomputing/wp-content/files/dmx_analogin2.zip"></a><a href="http://iad.projects.zhdk.ch/physicalcomputing/wp-content/files/dmx_analogin2.zip">// reenable interrupts.
sei();
}</a>

<a href="http://iad.projects.zhdk.ch/physicalcomputing/wp-content/files/dmx_analogin2.zip"></a><a href="http://iad.projects.zhdk.ch/physicalcomputing/wp-content/files/dmx_analogin2.zip">// program setup (executed once before program start) ---------------------------
void setup()
{
pinMode(sig, OUTPUT);       // data pin to dmx board</a>

<a href="http://iad.projects.zhdk.ch/physicalcomputing/wp-content/files/dmx_analogin2.zip"></a><a href="http://iad.projects.zhdk.ch/physicalcomputing/wp-content/files/dmx_analogin2.zip">pinMode(3, INPUT);          // button input
digitalWrite(3, HIGH);      // use internal pull up resistor
}</a>

<a href="http://iad.projects.zhdk.ch/physicalcomputing/wp-content/files/dmx_analogin2.zip"></a><a href="http://iad.projects.zhdk.ch/physicalcomputing/wp-content/files/dmx_analogin2.zip">// the program loop -------------------------------------------------------------
void loop()
{
/***** processing input START *****/
red = analogRead(0);         // red: read analog input pin 0
red = red/4;                 // analog input goes from 0 - 1023
// our output goes from 0 - 255
// therefore we have to divide by 4</a>

<a href="http://iad.projects.zhdk.ch/physicalcomputing/wp-content/files/dmx_analogin2.zip"></a><a href="http://iad.projects.zhdk.ch/physicalcomputing/wp-content/files/dmx_analogin2.zip">green = digitalRead(3);      // green: read a switch on digital pin 3
green = green * 255;         // switch green full on</a>

<a href="http://iad.projects.zhdk.ch/physicalcomputing/wp-content/files/dmx_analogin2.zip"></a><a href="http://iad.projects.zhdk.ch/physicalcomputing/wp-content/files/dmx_analogin2.zip">blue = ~green;               // blue: inverted value of green</a>

<a href="http://iad.projects.zhdk.ch/physicalcomputing/wp-content/files/dmx_analogin2.zip"></a><a href="http://iad.projects.zhdk.ch/physicalcomputing/wp-content/files/dmx_analogin2.zip">value += valueadd;           // amber: fade up and down
if ((value == 0) || (value == 255))
{
valueadd *= -1;
}
amber = value;
/***** processing input END *****/</a>

<a href="http://iad.projects.zhdk.ch/physicalcomputing/wp-content/files/dmx_analogin2.zip"></a><a href="http://iad.projects.zhdk.ch/physicalcomputing/wp-content/files/dmx_analogin2.zip">/***** sending the dmx signal START *****/
// sending the break (the break can be between 88us and 1sec)
digitalWrite(sig, LOW);
delay(10);</a>

<a href="http://iad.projects.zhdk.ch/physicalcomputing/wp-content/files/dmx_analogin2.zip"></a><a href="http://iad.projects.zhdk.ch/physicalcomputing/wp-content/files/dmx_analogin2.zip">// sending the start byte
shiftDmxOut(sig, 0);</a>

<a href="http://iad.projects.zhdk.ch/physicalcomputing/wp-content/files/dmx_analogin2.zip"></a><a href="http://iad.projects.zhdk.ch/physicalcomputing/wp-content/files/dmx_analogin2.zip">// rgba modul i am testing with has addresses
// Red:    20
// Green:  21
// Blue:   22
// Amber:  23
// therefore we send the first 19 bytes as '0'
for (int addressbyte = 1; addressbyte < = 19; addressbyte++)
{
shiftDmxOut(sig, 0);
}</a></a>

<a href="http://iad.projects.zhdk.ch/physicalcomputing/wp-content/files/dmx_analogin2.zip"></a><a href="http://iad.projects.zhdk.ch/physicalcomputing/wp-content/files/dmx_analogin2.zip">// then comes the message RGBA:
shiftDmxOut(sig, red);
shiftDmxOut(sig, green);
shiftDmxOut(sig, blue);
shiftDmxOut(sig, amber);</a>

<a href="http://iad.projects.zhdk.ch/physicalcomputing/wp-content/files/dmx_analogin2.zip"></a><a href="http://iad.projects.zhdk.ch/physicalcomputing/wp-content/files/dmx_analogin2.zip">// send the rest of the total 512 dmx messages
for (int count = 1; count < = 490; count++)
{
shiftDmxOut(sig, 0);
}
/***** sending the dmx signal END *****/</a></a>

<a href="http://iad.projects.zhdk.ch/physicalcomputing/wp-content/files/dmx_analogin2.zip"></a><a href="http://iad.projects.zhdk.ch/physicalcomputing/wp-content/files/dmx_analogin2.zip">delay(20);
}