Problem with DMX Example

I downloaded the DMX Code Examples from the arduino-webseite and try to compile&upload the code ... and get the following error :

In function 'void shiftDmxOut(int, int)': error: 'port_to_output' was not declared in this scope

and

In function 'void shiftDmxOut(int, int)': error: 'digital_pin_to_port' was not declared in this scop

int portNumber = port_to_output[digital_pin_to_port[pin].port]; int pinNumber = digital_pin_to_port[pin].bit;

and i found no remarks in the Arduino Reference what 'port_to_output' could mean .... maybe a outdate file

And the Question is now : What to replace ???

any suggestion .... ??

I running a Mac G5 with 10.4.10. arduino010 alpha arduino NG rev c

and other examples will run fine .... And i was allready compiling the example last year at the same time .. with the same board ... i think with arduino 007 and there was no problem ... so i think some stuff ... programming language or java has change

Looks like pins_atmega8 (which contains port_to_output) was replaced in the build system by pins_arduino (which contains port_to_output_PGM). Try replacing all instances of port_to_output with port_to_output_PGM in the sample code.

Meanwhile i solved the Problem ...

You have to

#include "pins_arduino.h"

and define

int port_to_output[] = { ** NOT_A_PORT,** ** NOT_A_PORT,** ** _SFR_IO_ADDR(PORTB),** ** _SFR_IO_ADDR(PORTC),** ** _SFR_IO_ADDR(PORTD)** ** };**

and

rename

digital_pin_to_port[pin].bit

to

digitalPinToBitMask(pin)

than it will work

Hello there!

Is anybody here who can post the complete sketch?

I would like to use an OpenSoure DMX Software and the arduino as USB to DMX Converter Board.

Thank you for any help!

Poldi

Not the answer you're looking for, but maybe this can be an alternate solution... http://www.usbdmx.com/

A full Example is here :

#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 = 8; // signal

int DEBUG = 1;

int count = 0;

int dmxValue = 0x80;

void setup() {

pinMode(sig, OUTPUT);
digitalWrite(8, HIGH);

pinMode(9, OUTPUT);
pinMode(10, OUTPUT);
pinMode(11, OUTPUT);

if (DEBUG) { // If we want to see the pin values for debugging…
Serial.begin(115200); // …set up the serial ouput on 0004 style
}
}

void loop() {

///////////////////////////////////////////////////////////sending the dmx signal

// sending the break (the break can be between 88us and 1sec)
digitalWrite(sig, LOW);
delay(50);

//sending the start byte
shiftDmxOut(sig,0);

//set all adresses/channel to the swing value
for (count = 1; count<=512; count++)
{

shiftDmxOut(sig, dmxValue);

}

if (DEBUG)
{ // If we want to read the output

Serial.print("\t"); // Print a tab
Serial.print(“DMX Value:”); // Indicate that output is red value
Serial.print(dmxValue);
}

}

/* 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) ;

// 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(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)) &= ~_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 jsut luke
// to get excatly 4us we have do delay 1us 4 times
delayMicroseconds(theDelay);
delayMicroseconds(theDelay);
delayMicroseconds(theDelay);
delayMicroseconds(theDelay);

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(theDelay);
delayMicroseconds(theDelay);
delayMicroseconds(theDelay);
// to write every bit exactly 4 microseconds, we have to waste some time here.
//thats why we are doing a for loop with nothing to do, a delayMicroseonds is not smal enough
for (wasteTime =0; wasteTime <2; wasteTime++) {}

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)) |= _BV(pinNumber);

// reenable interrupts.
sei();
}

Thank you for the updated code! This should really be placed in the playground instead of the old code.

:wink:

Actually I tried for a day to make that code work, and failed. Looking deeper, I found some snippets from other sources, and got something working on the Duemilanove running IDE version 013.

Feel free to post this code in the playground as no code that is currently in the playground is up-to-date!

Please post here if this code is useful to you… :sunglasses:

///////////////////////////////////////Werk5/Interactive-Scape BERLIN/////////////////
// DMX_Shift_Out
//
// Example code to generate a fading heartbeat on all 512 DMX channels
// Works with the nice DMX shield found here:
// http://iad.projects.zhdk.ch/physicalcomputing/hardware/arduino/dmx-shield-fur-arduino/
//
// based on the code of Tomek Ness and D. Cuartielles
// adapted to arduino 008 by Peter Szakal and Gabor Papp http://nextlab.hu
//
// Compiled and checked for arduino 013
// by Jason Ditmars
//
//////////////////////////////////////////////////////////////////////////////////////

// VERSION 05 -- 24 Feb. 2009


/* CONSTANTS */

//#define debug                // use this to send feedback to the serial monitor
#define ledPin 13              // LED built into Arduino Duemilanove platine
#define sig 11                 // DMX signal output pin

/* GLOBAL VARIABLE DECLARATIONS */

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

/* SETUP */
void setup () {
  pinMode(ledPin, OUTPUT);
  pinMode(sig, OUTPUT);
  digitalWrite(sig, HIGH); // changed from 8 to sig
  #ifdef debug
    Serial.begin(9600);        // initialize serial communications
  #endif
}

/* MAIN LOOP */
void loop(){
int i;
  for(i=1;i<=4;i++){            // LED boot sequence -- blinks 4 times
    digitalWrite(ledPin, HIGH);   
    delay(50);
    digitalWrite(ledPin, LOW);
    delay(50);
  }
  
  /* INFINITE LOOP */
  while(1){
    
    /***** 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;
    }
  }
}

Thanks Jason! Your code works like a charm 8-)

I'm using 017 with the Duemilanove.

Thanks alot for that code! It got my DIY arduinoshield working!

Would it be possible to use this code to power different dmx channels seperately instead of all at once?

Are there any code examples where the Arduino DMX is a Slave and not a master?

In fact, there is one: http://blog.wingedvictorydesign.com/2009/07/10/rev13-of-the-arduino-dmx-reception-software-released/ This is a 'slave' application, where Arduino reads the DMX and can do things with the data some DMX master sent!

Note the hardware: RS485 (DMX's low-level hardware spec) is able to both transmit and receive on a single pair of lines. Not full duplex (at the same time), that would be called RS422. This means your 'transmitter' shield should work without much hassle as a receiver too!