Go Down

Topic: Problem with DMX Example (Read 2850 times) previous topic - next topic

ploenne

Mar 11, 2008, 12:59 am Last Edit: Mar 11, 2008, 01:15 am by ploenne Reason: 1
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

simond

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.

ploenne

#2
Mar 20, 2008, 09:49 pm Last Edit: Mar 20, 2008, 09:51 pm by ploenne Reason: 1
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


Poldi

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

tehboii

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

ploenne

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


jditmarsAPF

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

;)

jditmarsAPF

#7
Feb 24, 2009, 11:10 am Last Edit: Feb 24, 2009, 11:23 am by jditmarsAPF Reason: 1
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...  8-)

Code: [Select]
///////////////////////////////////////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.

VFreriks

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?

Sannin

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

René Knuvers

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!

Go Up