Pages: 1 [2]   Go Down
Author Topic: DMX woes...  (Read 5406 times)
0 Members and 1 Guest are viewing this topic.
0
Offline Offline
Newbie
*
Karma: 0
Posts: 23
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Glad some people are using the code, even if they can't quite make it work yet...

I think your problem is that your Arduino uses an AtMega168 cpu and the code was written for an AtMega8. You've changed all of the register names to match your cpu, but you've missed the interrupt signal name.

I've just had a quick look at "wiring_serial.c", and it contains the following piece of code where the serial interrupt service routine is defined :

Code:
#if defined(__AVR_ATmega168__)
SIGNAL(SIG_USART_RECV)
#else
SIGNAL(SIG_UART_RECV)
#endif

I've had a look at your code, and you are still using SIGNAL(SIG_UART_RECV) which will only work with an AtMega8. If you change this to read SIGNAL(SIG_USART_RECV) your problem should be resolved.  smiley There is nothing wrong with the nested "else...if" statements, though feel free to re-write them if it will make you feel happier  smiley-wink

As to what use there is for receiving DMX, I am using this code to control two TLC5940 LED drivers which drive a 4 by 8 grid of LEDs. I've also made another version which controls 10 Piranha RGB LEDs, though I'm having a slight problem with the wiring at the moment...

Edit : Just had a look at the sn75176a datasheet and I noticed that you haven't connected the DE pin to ground. I use the MAX487 transceiver chip and its datasheet recommends that its DE pin is tied to ground if you are just recieving data. Might be worth trying on your setup.
« Last Edit: February 05, 2009, 09:51:30 am by big_mark_h » Logged

0
Offline Offline
Jr. Member
**
Karma: 0
Posts: 50
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thank you big_mark_h, the code works perfectly. smiley

Here is the finnished code example fot the ATmega 168 arduino:
Code:
         // The DMX reciver
// DMX reciver code for arduino with ATmega 168
// It is based on Hendrik Hoelschers dmx code from http://www.hoelscher-hi.de/hendrik/
// This code was adapted for the ATmega 8 by big_mark_h
// And finaly Gustaf Gagge adapted it for ATmega 168 with lots of help from big_mark_h and Grumpy_Mike



#include <avr/io.h>
#include <stdint.h>
#include <avr/interrupt.h>


// ********************* local definitions *********************
#define DMX_CHANNELS    (32)            //Define the number of DMX values to store

enum {IDLE, BREAK, STARTB, STARTADR};      //DMX states

uint8_t  gDmxState;
uint8_t  *gDmxPnt;
uint16_t DmxCount;

uint8_t  DmxField[DMX_CHANNELS];     //array of DMX vals (raw)
uint16_t DmxAddress;                   //start address

int ledPin = 13;                       // LED connected to digital pin 13

void setup()                           // run once, when the sketch starts
{
  // sets the digital pin as output
  pinMode(ledPin, OUTPUT);

  // Disable interrupts
  cli();

  // 250kbps baud - only works for 16MHz clock frequency. See the ATMega8 datasheet if you are using a different clock speed
  UBRR0H = 0;
  UBRR0L = 3;

  // enable rx and interrupt on complete reception of a byte
  UCSR0B = (1<<RXEN0)|(1<<RXCIE0);
  UCSR0C = (1<<UMSEL01)|(3<<UCSZ00)|(1<<USBS0);

  // Enable interrupts
  sei();

  gDmxState= IDLE;

  uint8_t i;
  for (i=0; i<DMX_CHANNELS; i++)
  {
    DmxField[i]= 0;
  }

  DmxAddress= 10;  //Set the base DMX address. Could use DIP switches for this.
}

void loop()                     // run over and over again
{
  if(DmxField[0] >=127)
  {
    digitalWrite(ledPin, HIGH);   // sets the LED on
  }
  else
  {
    digitalWrite(ledPin, LOW);    // sets the LED off
  }
}

// *************** DMX Reception ISR ****************
SIGNAL(SIG_USART_RECV)
{
uint8_t USARTstate= UCSR0A;                              //get state
uint8_t DmxByte= UDR0;                                    //get data
uint8_t DmxState= gDmxState;                              //just get once from SRAM!!!

if (USARTstate &(1<<FE0))                              //check for break
      {
      UCSR0A &= ~(1<<FE0);                              //reset flag
      DmxCount= DmxAddress;                              //reset frame counter
      gDmxState= BREAK;
      }

else if (DmxState == BREAK)
      {
      if (DmxByte == 0)
            {
            gDmxState= STARTB;                        //normal start code detected
            gDmxPnt= ((uint8_t*)DmxField +1);
            }
      else gDmxState= IDLE;
      }

else if (DmxState == STARTB)
      {
      if (--DmxCount == 0)                              //start address reached?
            {
            gDmxState= STARTADR;
            DmxField[0]= DmxByte;
            }
      }

else if (DmxState == STARTADR)
      {
      uint8_t *DmxPnt;
      DmxPnt= gDmxPnt;
      *DmxPnt= DmxByte;
      if (++DmxPnt >= (DmxField +DMX_CHANNELS))             //all ch received?
            {
            gDmxState= IDLE;
            }
      else gDmxPnt= DmxPnt;
      }
}
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 4
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi I am trying to make this work on a ATmega328 (the newest Duemilanov board), but I don't seen to get it right. The registers all has the same names, it even has the same data sheet. Doe anybody have any suggestions??
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 31
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi every Diyer
i'm a newbie and i would liket to realize a DMX rgb led panel
i would like to know if i can use your DMX code with the TLC5940 library or if i need to change some PIN value
Is it possible to use your dmx Code with the Atmega328?

thank you for your answer
Logged

0
Offline Offline
Full Member
***
Karma: 0
Posts: 112
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Just for the sake of curiosity, I knew DMX is a protocol to control complex lighting. What can you do by receiving and not sending it?
DMX is a one-way implementation of RS485, with the controller sending a byte value for each of up to 512 channels to be received by up to 32 physical devices on the DMX chain.  So in normal operation, you have one device sending only, and up to 32 devices receiving only, Hence the need for complementary one-way devices to have a functioning DMX network.

Of course, two way communication can be quite valuable, so modern systems sometimes provide for it through RDP, but relegate device->controller communications to a separate pathway.

The spec requires a 5-pin XLR connector with two twisted pairs wired through.  The first pair is used for DMX data, naturally, and originally the second pair was reserved so that a second "universe" (set of 512 channels) could be carried on the same physical network.*  In modern practice however, where the second pair is used at all it's often used for RDP, which allows devices to report status information back to the controller.  That way you get two-way communication, but the first pair is kept to vanilla one-way DMX to avoid confusing less intelligent devices (of which there are many *cough*Leviton DDS packs*cough* on the market).  

* DMX/other control over Ethernet protocols used in modern infrastructure have largely obviated the need for 1024 channels on a single DMX physical interface.  Larger installations generally use an Ethernet 'backbone' and convert to DMX near each gear position.  Some applications may see Ethernet run directly to specific fixtures (such as High End's DL.2) as well.  This left the idndstry pretty much free to find other uses for the second pair, such as RDP.  There might have been some products out there that used the second pair to send power to accessories as well, but the industry has standardized on different cable (one twisted pair for data, and a larger gauge pair for power) terminated with a 4-pin XLR for such things--color scrollers, pattern rotators, motorized irises, to name a few--nowadays.  
« Last Edit: September 16, 2009, 11:37:34 pm by ajb » Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 6
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi all. This is my first post on this site.
I managed to abapt the code on the Macetech site and splice it into the above DMX recive code, enabeling me to run five ShiftBright's. The computer with the code on it is not to hand at the moment, but if anyone is inerested I could post it at a later date. I work in the concert lighting business, I hooked my test bed (that looked like a birdsnest) into the system. The address set in the program was the same as an Led fixture in the rig and they both behaved the same  smiley Sorry I didnt think of taking any photos. I am new at this!
So It it would not be to hard to adapt the code to work with a TLC5940.
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 4
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi
It would be very interesting to see your code. I have bean trying to make a primitive moving head. but it sis not going very well at the moment. but your code might just be what I nead.
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 2
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I also would love to see the code.  Thanks
-jds
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 13
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I know I just posted this in another thread, but hopefully adding it here will help the next person who goes searching for this information.

The interrupt handler for the USART receive signal appears to have changed at some point for the ATMega328 chip.  Starting with gaggenau's code as shown earlier in this thread, change...

this:
SIGNAL(SIG_USART_RECV) {  // for ATMega168
...
}

to this:
SIGNAL(USART_RX_vect) {  // for ATMega328
...
}

Ironically both names seem to work fine for the ATMega168.  I realized something was wrong with the interrupt handler routine because the compiled sketch was staying the same size even when I commented out parts of the routine.

I'm running Arduino-0018.  Hope this helps.


Jeremy
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 1
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi All,

I've been trying to create a DMX receiver using gaggenau's code.

I'm using an Arduino Uno with an ATMega328 chip. I'm using Arduino 0.21. I've made the change suggested by JeremyD.

On the surface, it sort of works. As soon as I send a DMX signal to the appropriate channel, my output goes high. (Should only happen for DMX values above 127.) Moving the DMX value down to 0 does not reset the output to low.

It also seems to respond to me changing other channels on the DMX controller.

Has anyone else seen this sort of activity? Does anyone have any ideas what might be going on?

I'm using a MAX485 transceiver, and I'm fairly confident my breadboard is correct.

Any help appreciated!

~PhilC.
« Last Edit: January 12, 2011, 09:16:26 pm by GeneticGenesis » Logged

Pages: 1 [2]   Go Up
Jump to: