Small Arduino/AVR Standalone DMX Stage-Lighting Controller [In-Progress] - Page 1
Forum section: electronics / projects

author: twjdeboer
author_rank: Contributor
timestamp: October 12, 2013, 09:02:15 pm
content: Hi everyone!For my student society I wanted to build a small dmx capable controller. It would have to be able to send the dmx signal over a balanced xlr line, according to a pre-programmed routine. For this I decided to use the Ti SN7515 Dual Line Driver. This did not come from my own experience, but from some research. I would also need some sort of micro controller. I used the Arduino, because it enables me to use the Simple DMX library. This means I don't have to reverse engineer the DMX protocol. I went for the ATmega328, because it has enough ram to control all 512 channels in a DMX universe and was available to me.This is what it looks like in the first stage.This is my code:Code:// dmxControl function //////////////////////////////////////////////////////////////////// //// dmxControl(device, function, shape, velocity, minimum, maximum) //// //// device denotes which device to control //// function denotes which function to control //// shape denotes the type of forcing function (sawtooth, sine, cosine, fixed) //// velocity denotes the time-length of the forcing function. x equals x second //// minimum denotes the minimum DMX value //// maximum denotes the maximum DMX value //// //// example: //// dmxControl(ledpar_1, ledparR, "sine", 2, 0, 255) //// //// This will output a sine wave of 2 second length from [0,255] for the red channel //// on ledpar_1 //// ///////////////////////////////////////////////////////////////////////////////////////////// include the necessary libraries#include <DmxSimple.h>// declare variablesconst int dmxPin = 3 ;const float pi = 3.14 ;int time = 0 ;// declare functionsvoid dmxControl() ;// device function bindings ///////////////////////////////////////////////////////////////////////////////////////////// RGB-par dmx function bindingsconst int ledparR = 1 ; // red channelconst int ledparG = 2 ; // green channelconst int ledparB = 3 ; // blue channelconst int ledparColor = 4 ; // color wheel modulationconst int ledparStrobe = 5 ; // strobe slow -> fastconst int ledparModi = 6 ; // >0, RGB control. >64, 7 color fade. >128, color change. >192, music.// end ////////////////////////////////////////////////////////////////////////////////////////////////////////////////// device starting address ////////////////////////////////////////////////////////////////////////////////////////////const int ledpar_1 = 33 ;const int ledpar_2 = 39 ;const int ledpar_3 = 45 ;const int ledpar_4 = 51 ;const int ledpar_5 = 57 ;const int ledpar_6 = 63 ;const int ledpar_7 = 69 ;const int ledpar_8 = 75 ;// end ////////////////////////////////////////////////////////////////////////////////////////////////////////////////// setup codevoid setup() {DmxSimple.usePin(dmxPin) ; // which pin to use for DMX transmission}// loop codevoid loop() {// enter dmxControl commands here /////////////////////////////////////////////////////////////////////////////////////dmxControl(ledpar_1, ledparModi, "fixed", 10, 0, 0) ;dmxControl(ledpar_2, ledparModi, "fixed", 10, 0, 0) ;dmxControl(ledpar_3, ledparModi, "fixed", 10, 0, 0) ;dmxControl(ledpar_4, ledparModi, "fixed", 10, 0, 0) ;dmxControl(ledpar_5, ledparModi, "fixed", 10, 0, 0) ;dmxControl(ledpar_6, ledparModi, "fixed", 10, 0, 0) ;dmxControl(ledpar_7, ledparModi, "fixed", 10, 0, 0) ;dmxControl(ledpar_8, ledparModi, "fixed", 10, 0, 0) ;dmxControl(ledpar_1, ledparR, "sine", 2, 0, 255) ;dmxControl(ledpar_2, ledparR, "sine", -2, 0, 255) ;dmxControl(ledpar_3, ledparR, "sine", -2, 0, 255) ;dmxControl(ledpar_4, ledparR, "sine", 2, 0, 255) ;dmxControl(ledpar_5, ledparR, "sine", 2, 0, 255) ;dmxControl(ledpar_6, ledparR, "sine", -2, 0, 255) ;dmxControl(ledpar_7, ledparR, "sine", -2, 0, 255) ;dmxControl(ledpar_8, ledparR, "sine", 2, 0, 255) ;dmxControl(ledpar_1, ledparG, "cosine", -4, 0, 255) ;dmxControl(ledpar_2, ledparG, "cosine", 4, 0, 255) ;dmxControl(ledpar_3, ledparG, "cosine", -4, 0, 255) ;dmxControl(ledpar_4, ledparG, "cosine", 4, 0, 255) ;dmxControl(ledpar_5, ledparG, "cosine", -4, 0, 255) ;dmxControl(ledpar_6, ledparG, "cosine", 4, 0, 255) ;dmxControl(ledpar_7, ledparG, "cosine", -4, 0, 255) ;dmxControl(ledpar_8, ledparG, "cosine", 4, 0, 255) ;dmxControl(ledpar_1, ledparB, "sine", -8, 0, 255) ;dmxControl(ledpar_2, ledparB, "sine", 8, 0, 255) ;dmxControl(ledpar_3, ledparB, "sine", 8, 0, 255) ;dmxControl(ledpar_4, ledparB, "sine", -8, 0, 255) ;dmxControl(ledpar_5, ledparB, "sine", -8, 0, 255) ;dmxControl(ledpar_6, ledparB, "sine", -8, 0, 255) ;dmxControl(ledpar_7, ledparB, "sine", 8, 0, 255) ;dmxControl(ledpar_8, ledparB, "sine", 8, 0, 255) ;dmxControl(ledpar_1, ledparStrobe, "square", -10, 0, 120) ;dmxControl(ledpar_2, ledparStrobe, "square", 10, 0, 120) ;dmxControl(ledpar_3, ledparStrobe, "square", -10, 0, 120) ;dmxControl(ledpar_4, ledparStrobe, "square", 10, 0, 120) ;dmxControl(ledpar_5, ledparStrobe, "square", -10, 0, 120) ;dmxControl(ledpar_6, ledparStrobe, "square", 10, 0, 120) ;dmxControl(ledpar_7, ledparStrobe, "square", -10, 0, 120) ;dmxControl(ledpar_8, ledparStrobe, "square", 10, 0, 120) ;// end ////////////////////////////////////////////////////////////////////////////////////////////////////////////////time++ ;delay(50) ;}// dmxControl functionvoid dmxControl(int device, int function, String shape, float velocity, int minimum, int maximum) {int dmxVal;if (shape == "sine") {dmxVal = minimum + (sin(time*(0.05*2*pi)/velocity) + 1)/2 * (maximum - minimum) ;}if (shape == "cosine") {dmxVal = minimum + (cos(time*(0.05*2*pi)/velocity) + 1)/2 * (maximum - minimum) ;}if (shape == "square") {if (round(floor(time*0.05/velocity)) % 2 ) {dmxVal = maximum ;} else {dmxVal = minimum ;}}if (shape == "sawtooth")dmxVal = minimum + time*0.05/velocity * (maximum - minimum) ;while (dmxVal > maximum) {dmxVal = dmxVal - (maximum - minimum) ;}if (shape == "fixed") {dmxVal = maximum ;}DmxSimple.write(device+function-1, dmxVal) ;}There are some changes I wanted to make and need help with:I was wondering if I could make my code use less Floating point calculation to make it sleeker. It runs perfectly as it is now, but if I want to do more complex things it could probably use some better programming.I now program the chip with some headers on the veraboard I connected to an empty arduino. This means I need to open the case if I want to change the program. I need the TX and RX to be accessible from the outside, so I've bought some of these:http://dx.com/p/diy-16mm-6-pin-gx16-aviation-plug-socket-connector-silver-5-pieces-pack-134127I drilled a new hole for this on the spot where the power-jack was, but there wasn't enough room to plug it in properly. I'm still contemplating whether I should buy a new case or hack this one. I also don't know if I need some sort of input protection. I connected the other end of the plug to an USB-FTDI board, also acquired from DX.com .The plug has 6 pins. I use them like this:GND+9V (external psu)+5V (USB power)TXRXDTR/Arduino ResetI would like to hear your critical feedback!