DMX receiver error message

Hello, I am trying to code my Uno to be a DMX receiver and activate a servo motor depending on the signal it gets from the light console. I got the code online, but I am running into error messages. The device is supposed to be adressable via two buttons, one for 0, another for 1 and together they create a binary address for the device. On the DMX network the devices can be addressed from 1 until 512. A reset button would initiate the addressing.

The error message I get is:

receiver_rev14.cpp: In function 'void setup()':
receiver_rev14:18: error: too few arguments to function 'void Addressing(byte, byte)'
receiver_rev14:84: error: at this point in file

Not sure what that means, theres a whole tab defining how the addressing works. I am currently using IDE 0023 as thats when this code was written and worked for other users. If there are better ways to make my arduino a DMX receiver, please let me know. Thank you!

Main Code:

/*** Addressing variable declarations ***/
#include <EEPROM.h>
#define NUMBER_OF_CHANNELS 8
//the number of channels we want to receive (8 by default).

#define SWITCH_PIN_0 11 //the pin number of our "0" switch
#define SWITCH_PIN_1 12 //the pin number of our "1" switch
unsigned int dmxaddress = 1;
/* The dmx address we will be listening to.  The value of this will be set in the Addressing()
*  function and read from EEPROM addresses 510 and 511.

/*** MAX485 variable declarations ***/

#define RECEIVER_OUTPUT_ENABLE 2
/* receiver output enable (pin2) on the max485.  
*  will be left low to set the max485 to receive data. */

#define DRIVER_OUTPUT_ENABLE 3
/* driver output enable (pin3) on the max485.  
*  will left low to disable driver output. */

#define RX_PIN 0   // serial receive pin, which takes the incoming data from the MAX485.
#define TX_PIN 1   // serial transmission pin

/*** DMX variable declarations ***/

volatile byte i = 0;              
volatile byte dmxreceived = 0;    
volatile unsigned int dmxcurrent = 0;     
volatile byte dmxvalue[NUMBER_OF_CHANNELS];     
/*  stores the DMX values we're interested in using-- 
 *  keep in mind that this is 0-indexed. */
volatile boolean dmxnewvalue = false; 
/*  set to 1 when updated dmx values are received 
 *  (even if they are the same values as the last time). */

/*** Timer2 variable declarations ***/

volatile byte zerocounter = 0;          

void setup() 
{
  
  /*** Max485 configuration ***/
  
  pinMode(RECEIVER_OUTPUT_ENABLE, OUTPUT);
  pinMode(DRIVER_OUTPUT_ENABLE, OUTPUT);
  digitalWrite(RECEIVER_OUTPUT_ENABLE, LOW);
  digitalWrite(DRIVER_OUTPUT_ENABLE, LOW);    //sets pins 3 and 4 to low to enable reciever mode on the MAX485.

  pinMode(RX_PIN, INPUT);  //sets serial pin to receive data

  /*** Addressing subroutine ***/

  pinMode (SWITCH_PIN_0, INPUT);        // sets pin for '0' switch to input
  digitalWrite(SWITCH_PIN_0, HIGH);       //turns on the internal pull-up resistor for '0' switch pin
  pinMode(SWITCH_PIN_1, INPUT);           //sets pin for '1' switch to input  
  digitalWrite(SWITCH_PIN_1, HIGH);       //turns on the internal pull-up resistor for '1' switch pin
 
  /* Call the addressing subroutine.  Three behaviors are possible:
  *  1. Neither switch is pressed, in which case the value previously stored in EEPROM
  *  510 and 511 is recalled,
  *  2. Both switches are pressed, in which case the address is reset to 1.
  *  3. Either switch is pressed (but not both), in which case the new address may 
  *  be entered by the user.
  */
  //set this equal to a constant value if you just want to hardcode the address.
  dmxaddress = Addressing();
  
  /**** USART configuration ***/
  
  Serial.begin(250000);
  /* Each bit is 4uS long, hence 250Kbps baud rate */
  
  cli(); //disable interrupts while we're setting bits in registers
  
  bitClear(UCSR0B, RXCIE0);  //disable USART reception interrupt
  
  /*** Timer2 configuration ***/
  
  //NOTE:  this will disable PWM on pins 3 and 11.
  bitClear(TCCR2A, COM2A1);
  bitClear(TCCR2A, COM2A0); 
  bitClear(TCCR2A, COM2B1);
  bitClear(TCCR2A, COM2B0); 
  bitSet(TCCR2A, WGM21);
  bitClear(TCCR2A, WGM20); 
  
  bitClear(TCCR2B, FOC2A);
  bitClear(TCCR2B, FOC2B);  
  bitClear(TCCR2B, WGM22);  
  bitClear(TCCR2B, CS22);
  bitClear(TCCR2B, CS21);
  bitSet(TCCR2B, CS20);   // no prescaler means the clock will increment every 62.5ns (assuming 16Mhz clock speed).
  
  OCR2A = 64;                
  /* Set output compare register to 64, so that the Output Compare Interrupt will fire
  *  every 4uS.  */
  
  bitClear(TIMSK2, OCIE2B);  
  bitSet(TIMSK2, OCIE2A);    
  bitClear(TIMSK2, TOIE2);             
  
  sei();                     
  
}  //end setup()


void loop()  {
  // the processor gets parked here while the ISRs are doing their thing. 
  
  if (dmxnewvalue == 1) {    
    action();
    dmxnewvalue = 0;
    dmxcurrent = 0;
    zerocounter = 0;      
    i = 0;
    bitSet(TIMSK2, OCIE2A);   
  }
} //end loop()


//Timer2 compare match interrupt vector handler
ISR(TIMER2_COMPA_vect) {
  if (bitRead(PIND, PIND0)) {  
    zerocounter = 0;
    }
  else {
    zerocounter++;             
    if (zerocounter == 20)     
      {   
      bitClear(TIMSK2, OCIE2A);    
      bitSet(UCSR0B, RXCIE0);
      }
  }
} //end Timer2 ISR


ISR(USART_RX_vect){
  dmxreceived = UDR0;
 
  dmxcurrent++;                        
 
  if(dmxcurrent > dmxaddress) {     
    dmxvalue[i] = dmxreceived;
    i++;
    if(i == NUMBER_OF_CHANNELS) {
      bitClear(UCSR0B, RXCIE0); 
      dmxnewvalue = 1;                        
    } 
  }
}

Here is the Addressing tab

void Addressing(byte switch0, byte switch1)
{
byte bitnumber = 0; //the number of bits recorded so far
boolean blink = 0; //used to blink the pin 13 LED once the address is recorded.

if (switch0 == 0 && switch1 == 0)
  {
  EEPROM.write(510, lowByte(dmxaddress));
  EEPROM.write(511, highByte(dmxaddress));
  //if BOTH addressing switches are held down, the starting address is reset to 1.
  }
    
else if (switch0 == 0 ^ switch1 == 0)
  {
  /* if EITHER switch0 or switch1 is held down (but not both), the addressing subroutine is
  *  run.  Since it writes the new address into EEPROM, there's no need to pass anything
  *  back to the main function. */
  while (bitnumber < 9) //runs 9 times, recording a bit in dmxaddress each time.
    {
    digitalWrite(13, HIGH); //turn on pin 13 to indicate addressing mode.
    
    if (switch0 != digitalRead(SWITCH_PIN_0) || switch1 != digitalRead(SWITCH_PIN_1))
      //execute loop if either switch state has changed
      {
          if (digitalRead(SWITCH_PIN_0) == HIGH && digitalRead(SWITCH_PIN_1) == LOW)
              //execute if 1 pin is pressed
              {
              switch0 = digitalRead(SWITCH_PIN_0);
              switch1 = digitalRead(SWITCH_PIN_1);  //update switch state variables with the new state
              bitSet(dmxaddress, bitnumber);  //write a 0 to the appropriate bit of dmxaddress
              bitnumber++;
              digitalWrite(13, LOW); //flash off pin 13 to indicate bit accepted
              delay(500);
              }

          if (digitalRead(SWITCH_PIN_0) == LOW && digitalRead(SWITCH_PIN_1) == HIGH)
              //execute if 0 pin is pressed
              {
              switch0 = digitalRead(SWITCH_PIN_0);
              switch1 = digitalRead(SWITCH_PIN_1);  //update switch state variables with the new state
              bitClear(dmxaddress, bitnumber);  //write a 0 to the appropriate bit of dmxaddress
              bitnumber++;
              digitalWrite(13, LOW); //turn off pin 13 to indicate bit accepted
              delay(500);
              }
      } //end switch state change if statement
    } //end while loop
  }//end else if addressing subroutine

for (byte i = 0; i < 15; i++) //blink LED 4 times when new address is received.
  {
  digitalWrite(13, blink);
  delay(100);
  blink = ~blink;
  }
  
EEPROM.write(510, lowByte(dmxaddress));//writes the first byte of dmxaddress to EEPROM address 510
EEPROM.write(511, highByte(dmxaddress));//writes the second byte of dmxaddress to EEPROM address 511

return;

}  //end Addressing()

receiver_rev15.zip (7.63 KB)

You need to pass 2 bytes into the Addressing routine at this line here

dmxaddress = Addressing();

This looks like it's setting an address of the module in question so you can probably make them anything you want. it appears if you set both to 0 then that will be sufficient so changing that line to

dmxaddress = Addressing(0x0, 0x0);

should fix the error

Cool! I think that helped somewhat. The next error I get is -

HardwareSerial.cpp.o:(.rodata._ZTV14HardwareSerial+0xe): undefined reference to `HardwareSerial::peek()'

Dont know if those are related, I cant even find that reference looking through the code in the special HardwareSerial.cpp. Am I missing a reference alltogether?

Do you have links to the code you refer to downloading? As it seems to be for a very old version of the IDE you might be better off updating to the current (1.0.6) version and use one of the newer libraries to achieve what you want.

From what you write it appears you need to configure a DMX receive address on the fly using 2 buttons and the value from that DMX channel is used to define where a servo motor is positioned.

I have tried the code with a new IDE, however I also am getting plenty of error messages. You are correct, the really cool part about the gadget is that you can change the DMX address with the two buttons. I would define that address via the buttons if I could only get the code to upload. To get this thing to properly read DMX, you have to trick it to a different signal refresh rate, and the new HardwareSerial that comes in the package (its attached to the original post) is supposed to do that once you replace the one that comes with the IDE with it. The new IDE gives me this error, which doesnt make much sense to me other than some link somewhere is broken-

ardwareSerial.cpp:120: error: prototype for 'HardwareSerial::HardwareSerial(ring_buffer*, volatile uint8_t*, volatile uint8_t*, volatile uint8_t*, volatile uint8_t*, volatile uint8_t*, const HardwareSerial&)' does not match any in class 'HardwareSerial'
/Desktop/Arduino.app/Contents/Resources/Java/hardware/arduino/cores/arduino/HardwareSerial.h:33: error: candidates are: HardwareSerial::HardwareSerial(const HardwareSerial&)
/Desktop/Arduino.app/Contents/Resources/Java/hardware/arduino/cores/arduino/HardwareSerial.h:54: error:                 HardwareSerial::HardwareSerial(ring_buffer*, ring_buffer*, volatile uint8_t*, volatile uint8_t*, volatile uint8_t*, volatile uint8_t*, volatile uint8_t*, volatile uint8_t*, uint8_t, uint8_t, uint8_t, uint8_t, uint8_t)
HardwareSerial.cpp:137: error: prototype for 'void HardwareSerial::begin(long int)' does not match any in class 'HardwareSerial'
/Desktop/Arduino.app/Contents/Resources/Java/hardware/arduino/cores/arduino/HardwareSerial.h:56: error: candidates are: void HardwareSerial::begin(long unsigned int, uint8_t)
/Desktop/Arduino.app/Contents/Resources/Java/hardware/arduino/cores/arduino/HardwareSerial.h:55: error:                 void HardwareSerial::begin(long unsigned int)
HardwareSerial.cpp:181: error: prototype for 'uint8_t HardwareSerial::available()' does not match any in class 'HardwareSerial'
/Desktop/Arduino.app/Contents/Resources/Java/hardware/arduino/cores/arduino/HardwareSerial.h:58: error: candidate is: virtual int HardwareSerial::available()
HardwareSerial.cpp:212: error: prototype for 'void HardwareSerial::write(uint8_t)' does not match any in class 'HardwareSerial'
/Desktop/Arduino.app/Contents/Resources/Java/hardware/arduino/cores/arduino/Print.h:49: error: candidates are: size_t Print::write(const char*)
/Users/alwaysfocused89/Desktop/Arduino.app/Contents/Resources/Java/hardware/arduino/cores/arduino/Print.h:53: error:                 virtual size_t Print::write(const uint8_t*, size_t)
/Desktop/Arduino.app/Contents/Resources/Java/hardware/arduino/cores/arduino/Print.h:54: error:                 size_t Print::write(const char*, size_t)
/Desktop/Arduino.app/Contents/Resources/Java/hardware/arduino/cores/arduino/HardwareSerial.h:66: error:                 size_t HardwareSerial::write(int)
/Desktop/Arduino.app/Contents/Resources/Java/hardware/arduino/cores/arduino/HardwareSerial.h:65: error:                 size_t HardwareSerial::write(unsigned int)
/Desktop/Arduino.app/Contents/Resources/Java/hardware/arduino/cores/arduino/HardwareSerial.h:64: error:                 size_t HardwareSerial::write(long int)
/Desktop/Arduino.app/Contents/Resources/Java/hardware/arduino/cores/arduino/HardwareSerial.h:63: error:                 size_t HardwareSerial::write(long unsigned int)
/Desktop/Arduino.app/Contents/Resources/Java/hardware/arduino/cores/arduino/HardwareSerial.h:62: error:                 virtual size_t HardwareSerial::write(uint8_t)
HardwareSerial.cpp:225: error: no matching function for call to 'HardwareSerial::HardwareSerial(ring_buffer*, volatile uint8_t*, volatile uint8_t*, volatile uint8_t*, volatile uint8_t*, volatile uint8_t*, int, int, int, int, int)'
/Desktop/Arduino.app/Contents/Resources/Java/hardware/arduino/cores/arduino/HardwareSerial.h:54: note: candidates are: HardwareSerial::HardwareSerial(ring_buffer*, ring_buffer*, volatile uint8_t*, volatile uint8_t*, volatile uint8_t*, volatile uint8_t*, volatile uint8_t*, volatile uint8_t*, uint8_t, uint8_t, uint8_t, uint8_t, uint8_t)
/Desktop/Arduino.app/Contents/Resources/Java/hardware/arduino/cores/arduino/HardwareSerial.h:33: note:                 HardwareSerial::HardwareSerial(const HardwareSerial&)

Without links to the code your trying to get working we cannot really help.

Maybe describing what you have and how you want it to work we can use a modern IDE to achieve the same thing.

You have an UNO? with 2x buttons connected that allow you to select the DMX address?
You have a DMX shield or module to receive the DMX signals?
You have a servo connected that move in relation to the selected DMX receive channel?

Allright, well the code can be downloaded via this blog that gives you the run down of what the device does and how:

The direct link to download the packet of the code is here:

http://www.maxpierson.me/wp-content/uploads/2010/10/receiver_rev15.zip

More on the addressing can be found here:

The addressing isnt the issue though, I wont know if its working right until I can get something uploaded.
I have an Uno, hooked up just like the directions on the blog suggest, with the buttons on a separate breadboard and a servo connected to the arduino as well. DMX port mounted also mounted near by. Hardware is not an issue yet as I cannot get the code right. I have two versions of IDE that I am trying this in, both give me different errors. Both errors listed in previous responses. The main issue I am having I think is with the modified HardwareSerial and how the IDE handles it. Not sure what to do next. Thanks for your help!

I just downloaded the 0023 version of the Arduino IDE, swapped out the HardwareSerial.cpp file as instructed in the blog link and the receiver_rev15.ino file loads/compiles without issue? Maybe you have not got the hardware serial file installed correctly?
I also took the liberty of changing the code to work (untested) with a newer DMX library found here. The DMX shield design is slightly different but the old shield (or new code) should easily modify to suit.

sketch_nov06a_DMX.zip (2.65 KB)

did I read that right that you are setting the output compare reg to fire every 4us ??

/* Set output compare register to 64, so that the Output Compare Interrupt will fire every 4uS. */

This doesnt leave very much time for the general processing outside of the interrupt as entering and leaving the interrupt(s) take quite a few cycles

I highly recommend the following DMX rx/tx library, I have been using it for years and it works like a dream

My bad, I just saw that you already found that web page, I didnt see your link above :slight_smile: