Controlling a stepper motor with DMX512

Hello,

I am working on a project where I'm getting my Arduino Uno to receive DMX512 data from a lighting controller and then send PWM outputs to control a bi-polar stepper motor based on that information. I have been working with the code and tutorial for DMX reception written by Max Pierson on his website:

http://blog.wingedvictorydesign.com/2009/03/20/receive-dmx-512-with-an-arduino/all/1/

It has been extremely helpful, and I have successfully used it to control 3 different LEDs with DMX information coming from a lighting controller.

I then did a separate project where I set up a bi-polar stepper motor with a 2 control pin configuration, and used the stepper example codes to test it, which it worked fine.

Now I am trying to combine the two codes, by putting the stepper motor on the pins that were controlling the LEDs in my first experiment. The problem is that I am getting an error message that I don't understand when I try to compile the code, and I was wondering if anybody would be able to help me figure out what I'm doing wrong.

I have not gone in to too much detail about the circuits that I am working with because right now because the problem is in the code, but I can go in to more detail about that if it is necessary.

I don't have much knowledge on how the libraries work and if they may conflict with each other, but perhaps that is part of the problem?

Here is what I have right now:

#include <Stepper.h>

#include <EEPROM.h>
#define NUMBER_OF_CHANNELS 2
//the number of channels we want to receive (2 by default).

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.

/******************************* STEPPER declarations *************************************/

Stepper myStepper(200, 9,10);

int previous = 0;

/******************************* 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;              //dummy variable for dmxvalue[]
volatile byte dmxreceived = 0;    //the latest received value
volatile unsigned int dmxcurrent = 0;     //counter variable that is incremented every time we receive a value.
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;          
/* a counter to hold the number of zeros received in sequence on the serial receive pin.  
*  When we've received a minimum of 11 zeros in a row, we must be in a break.  */




void setup() {
  
  myStepper.setSpeed(100);
  
  /******************************* 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 *********************************/
 
  /* 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 = 4;
  
  /******************************* 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); //disable compare match output A mode
  bitClear(TCCR2A, COM2B1);
  bitClear(TCCR2A, COM2B0); //disable compare match output B mode
  bitSet(TCCR2A, WGM21);
  bitClear(TCCR2A, WGM20);  //set mode 2, CTC.  TOP will be set by OCRA.
  
  bitClear(TCCR2B, FOC2A);
  bitClear(TCCR2B, FOC2B);  //disable Force Output Compare A and B.
  bitClear(TCCR2B, WGM22);  //set mode 2, CTC.  TOP will be set by OCRA.
  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);  //Disable Timer/Counter2 Output Compare Match B Interrupt
  bitSet(TIMSK2, OCIE2A);    //Enable Timer/Counter2 Output Compare Match A Interrupt
  bitClear(TIMSK2, TOIE2);   //Disable Timer/Counter2 Overflow Interrupt Enable          
  
  sei();                     //reenable interrupts now that timer2 has been configured. 
  
}  //end setup()


void loop()  {
  // the processor gets parked here while the ISRs are doing their thing. 
  
  if (dmxnewvalue == 1) {    //when a new set of values are received, jump to action loop...
    
    //dmxvalue[0] = map(dmxvalue[0], 0, 255, 0, 720);
    myStepper.step(dmxvalue[0] - previous); 
    previous = dmxvalue[0];
    
    dmxnewvalue = 0;
    dmxcurrent = 0;
    zerocounter = 0;      //and then when finished reset variables and enable timer2 interrupt
    i = 0;
    bitSet(TIMSK2, OCIE2A);    //Enable Timer/Counter2 Output Compare Match A Interrupt
  }
  
  return;
} //end loop()


//Timer2 compare match interrupt vector handler
ISR(TIMER2_COMPA_vect) {
  if (bitRead(PIND, PIND0)) {  // if a one is detected, we're not in a break, reset zerocounter.
    zerocounter = 0;
    }
  else {
    zerocounter++;             // increment zerocounter if a zero is received.
    if (zerocounter == 20)     // if 20 0's are received in a row (80uS break)
      {   
      bitClear(TIMSK2, OCIE2A);    //disable this interrupt and enable reception interrupt now that we're in a break.
      bitSet(UCSR0B, RXCIE0);
      }
  }
} //end Timer2 ISR



ISR(USART_RX_vect){
  dmxreceived = UDR0;
  /* The receive buffer (UDR0) must be read during the reception ISR, or the ISR will just 
  *  execute again immediately upon exiting. */
 
  dmxcurrent++;                        //increment address counter
 
  if(dmxcurrent > dmxaddress) {         //check if the current address is the one we want.
    dmxvalue[i] = dmxreceived;
    i++;
    if(i == NUMBER_OF_CHANNELS) {
      bitClear(UCSR0B, RXCIE0); 
      dmxnewvalue = 1;                        //set newvalue, so that the main code can be executed.
    } 
  }
} // end ISR

Any help is greatly appreciated!

and then send PWM outputs to control a bi-polar stepper motor based on that information.

Send PWM outputs to what? No stepper motor driver I've seen uses PWM.

The problem is that I am getting an error message that I don't understand when I try to compile the code, and I was wondering if anybody would be able to help me figure out what I'm doing wrong.

You tell us what they are, and we'll tell you what they mean. Sound like a fair trade?

It doesn't like this:-

ISR(USART_RX_vect){

That vector must already be defined.

PaulS:

The stepper motor is driven with an L293D, I guess the pins don't necessarily need to be PWM, just digital out.

The error message is "Error Compiling." It won't let me cut and paste, the whole message, but it goes on to say that:

.../hardware/tools/avr/lib/gcc/.../.../avr/include/math.h:439: error: expected unqualified-id before 'double'
.../hardware/tools/avr/lib/gcc/.../.../avr/include/math.h:439: error: expected ')' before 'double'
.../hardware/tools/avr/lib/gcc/.../.../avr/include/math.h:439: error: expected '(' before 'double'

Grumpy_Mike

Thanks for getting me started on the right track. I am pretty new to this, and I was wondering where I might look to fix that? Unfortunately this is part of the code that I copied, so all I know is that it was compiling before I incorporated the stepper motor.

Thanks for your help!

Did this ever get resolved?

Michael_Edwards:
Did this ever get resolved?

This Thread is 2.5 years dead.

Start your own Thread and explain what your problem is. If you have code, please post it. And please use the code button </> so your code looks like this and is easy to copy to a text editor

...R
Stepper Motor Basics

Could you please help me with information about this issue? How to control the stepper motor from the DMX light table.

If you help me with a code I can only get working examples, I love it.

Please post code here

Hi,
Did you ever found the code for controlling stepper motors through dmx and arduino?