[DMX512] Arduino + Freestyler?

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? :slight_smile:

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

Hmm.

It looks like all the bytes you are sending from the main loop are 0 bytes, is that what you want ?

In your comments you say "we need a delay of 4us (then one bit is transfert)" but you only call delayMicroseconds(1); 3 times.

Also if you read the Arduino reference the delayMicroseconds() function is not guaranteed to be accuurate with less than 3 microseconds.

PROBLEM SOLVED!

Thank you for your reply.

I found that what this code does is simulate a DMX transitting signal.

What I needed is just to send signals received by USB Serial (Software). So, I just needed to connect the IC input to RX Pin in Arduino.

No code is needed in Arduino.