Hi all.
I'm trying to turn Arduino into a OpenDMX interface.
I have installed the driver from Enttec website.
I'm using Freestyler to control the DMX output to Arduino (The RX LED is blinking, so Arduino is receiving DMX signals from Freestyler)
I have uploaded the following code to the board:
#include "pins_arduino.h";
int port_to_output[] = {
NOT_A_PORT,
NOT_A_PORT,
_SFR_IO_ADDR(PORTB),
_SFR_IO_ADDR(PORTC),
_SFR_IO_ADDR(PORTD)
};
int sig = 11; // signal
int DEBUG = 0;
int count = 0;
int dmxValue = 0x80;
void setup() {
pinMode(sig, OUTPUT);
digitalWrite(13, HIGH);
if (DEBUG) { // If we want to see the pin values for debugging...
Serial.begin(9600); // ...set up the serial ouput on 0004 style
}
}
void loop() {
// sending the break (the break can be between 88us and 1sec)
digitalWrite(sig, LOW);
delay(10);
//sending the start byte
shiftDmxOut(sig,0);
for (count = 1; count<=512; count++){ //the rest
shiftDmxOut(sig, 0);
}
}
/* 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 wasteTime = 0;
int theDelay = 1;
int count = 0;
int portNumber = port_to_output[digitalPinToBitMask(pin)];
int pinNumber = digitalPinToBitMask(pin) ;
// disable interrupts, otherwise the timer 0 overflow interrupt that
// tracks milliseconds will make us delay longer than we want.
cli();
// 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)) |= _BV(pinNumber);
//delayMicroseconds(4); //changed from 10 microseconds
// DMX starts with a start-bit that must always be zero
_SFR_BYTE(_SFR_IO8(portNumber)) &= ~_BV(pinNumber);
//we need a delay of 4us (then one bit is transfert)
// at the arduino just the delay for 1us is precise every thing between 2 and 12 is imprecise
// to get excatly 4us we have do delay 1us 4 times
delayMicroseconds(1);
delayMicroseconds(1);
delayMicroseconds(1);
for (wasteTime =0; wasteTime <2; wasteTime++) {}
for (count = 0; count < 8; count++) {
if (theByte & 01) {
_SFR_BYTE(_SFR_IO8(portNumber)) |= _BV(pinNumber);
}
else {
_SFR_BYTE(_SFR_IO8(portNumber)) &= ~_BV(pinNumber);
}
delayMicroseconds(1);
delayMicroseconds(1);
delayMicroseconds(1);
// to write every bit exactly 4 microseconds, we have to waste some time here.
//thats why we are doing some assembly nops
__asm__(
"nop\n\t"
"nop\n\t"
"nop\n\t"
"nop\n\t"
"nop\n\t"
"nop\n\t"
"nop\n\t"
"nop\n\t"
);
theByte>>=1; //bit shifting
}
// the last thing we do is to write the pin to high
// it will be the mark between bytes. (this break has to be between 8 us and 1 sec)
_SFR_BYTE(_SFR_IO8(portNumber)) |= _BV(pinNumber);
delayMicroseconds(8);
// reenable interrupts.
sei();
}
Is there anything wrong with the code?
Or am I trying something impossible?
Shouldn't this code be receiving the Software signals and send them to the Fixture?
I took a picture: http://lh3.ggpht.com/_inn_7Qkw9v8/SUkry7WKr5I/AAAAAAAAANg/FLOlJdNt970/DSC04243.JPG