Go Down

Topic: Stepper motors and drivers problem (Read 3680 times) previous topic - next topic

standby

Hello,
I have the following equipment:
1 x Arduino MEGA
3 x Wantai 57BYGH115-003 stepper motors
3 x Wantai DQ-542MA drivers
1 x Wantai PSU 350W 24V/14,4A

Could you give me a wiring/connection diagram for this equipment and tell me how many Volts/Amperes I need to run these motors?
I need the highest possible speed for the motors.
Is it also possible to give me  a simple Arduino code to run these 3 motors but in different speed each other??

I appreciate your help!

Thank you!!! ;)

Msquare

Try entering "57BYGH115-003 " in your google search. That usually gets you several web pages where the specfications (voltage, amperes etc ) are shown.

In your Arduino IDE try the menu File - Examples - Stepper - One revolution. There is the code fo one stepper. You only need to replicate the line defining the Stepper varaible (with a new name) and one call to each steper variable's move at different speeds. I also suggest you Google for "Arduino Stepper nonblocking " to run them simlultaneously.

Running at max speed depends on the load, and a bit of tweaking the (software) acceleration and driver current "curves" (if the DQ-542MA supports that)

standby

Thank you for your reply!

Basically this Driver is a Step/Dir type so I think the Stepper.h library that is used in these examples, don't support it, that's why I am asking for a simple code to run the motors in different speed each other.

The ports of the driver are: PUL+, PUL-, DIR+, DIR-, ENA+, ENA- so... Pulse or Step/Dir type, I think.

Msquare

OK, here is some very simple code I have recently used to drive two steppers at the same time. I do not use any library, prefering to drive them directly. One is a Dir/Step type driver, the other a full H-bridge. The idea here is the StepCoil runs continuously (the MoveSteppers() is called as often) determined by "Slowdown", and the StepWireRatio() calls the other stepper (the one using dir/step) so I get the right kind of diagonal movement.
Code: [Select]
void MoveSteppers() {
analogWrite(CoilPWM,45);
if ( micros()/100-Timer > Slowdown ) {
    Timer=micros()/100 ;
    StepCoil() ;
    StepWireRatio() ;
  }
}

void StepWireRatio() { // Step according to ratio and respect limits
  TFC_Ratio += TFC_Ratio_Nom ;
  if ( TFC_Ratio > TFC_Ratio_Den ) {
    TFC_Ratio -= TFC_Ratio_Den ;
    if (TFC<TFC_Left) TFC_Dir=HIGH ;
    if (TFC>TFC_Right) TFC_Dir=LOW ;
    StepWire() ;
  }
}

void StepWire() { //step always
  digitalWrite(WireDir,TFC_Dir); // adjust direction as needed
  delayMicroseconds(50);
  digitalWrite(WireStp,(TFC%2>0)?HIGH:LOW) ;  // Step the Wire motor
  TFC = (TFC_Dir==HIGH)?TFC+1:TFC-1 ;
  CursorGoto(3,12);
  if (TFC_Dir==HIGH)
    Serial.print(TFC-TFC_Left);
  else
    Serial.print(TFC_Right-TFC) ;
  Kolon();
  Serial.print((TFC-TFC_Left)*100/(TFC_Right-TFC_Left));
  Serial.print(TFC_Dir==LOW?" <":" >");Space(3);
}

void StepCoil() {
  // Change to next Coil state
  TurnState++ ; CursorGoto(2,13);
    Serial.print(TurnState/CoilTickTurn);
    Kolon();
    Serial.print((TurnState%CoilTickTurn)*100/CoilTickTurn);
    Space(2);
  switch (TurnState%4) {
    case 0:    // 1010
      digitalWrite(Coil_A, HIGH);
      digitalWrite(Coil_B, LOW);
      digitalWrite(Coil_C, HIGH);
      digitalWrite(Coil_D, LOW);
      break;
    case 1:    // 0110
      digitalWrite(Coil_A, LOW);
      digitalWrite(Coil_B, HIGH);
      digitalWrite(Coil_C, HIGH);
      digitalWrite(Coil_D, LOW);
      break;
    case 2:    //0101
      digitalWrite(Coil_A, LOW);
      digitalWrite(Coil_B, HIGH);
      digitalWrite(Coil_C, LOW);
      digitalWrite(Coil_D, HIGH);
      break;
    case 3:    //1001
      digitalWrite(Coil_A, HIGH);
      digitalWrite(Coil_B, LOW);
      digitalWrite(Coil_C, LOW);
      digitalWrite(Coil_D, HIGH);
    }
}

You Milage may vary. No Garantees :)

Carsten53T

hi Stanby
I've got some basic code that works on ports
EnA, EnB, I1, I2, I3, I4 (enable A & B are the two outputs/coils ..  1 & 2 for A and 3 & 4 for B (i1 high + i2 low is uppersit direction from i1 low + i2 high)
if you can make a link between these ports and the
PUL+, PUL-, DIR+, DIR-, ENA+, ENA- you've got, then I'll pop my code

standby

Thank you both of you!

Dear Carsten53T,
I have made the following wiring between arduino MEGA and the Drivers:

Digital Pin 2 -> PUL+ (driver 1)
Digital Pin 3 -> DIR+  (driver 1)
Digital Pin 4 -> ENA+ (driver 1)
Digital Pin 5 -> PUL+ (driver 2)
Digital Pin 6 -> DIR+  (driver 2)
Digital Pin 7 -> ENA+ (driver 2)
Digital Pin 8 -> PUL+ (driver 3)
Digital Pin 9 -> DIR+  (driver 3)
Digital Pin 10 -> ENA+ (driver 3)

And the PUL-, DIR- to the Arduino GND and ENA- unconnected.
All 3 motors are connected to A+B- and B+B- each coil.

Is there something wrong in wiring?
I have used digitalwrite directly (LOW->HIGH to start) but the speed is low and also I can't make them run in different speed each other. With accelstepper library the speed is tragically low.

Thank you!

Carsten53T

#6
Jun 08, 2012, 02:24 pm Last Edit: Jun 08, 2012, 02:35 pm by Carsten53T Reason: 1

Thank you both of you!

Dear Carsten53T,
I have made the following wiring between arduino MEGA and the Drivers:

Digital Pin 2 -> PUL+ (driver 1)
Digital Pin 3 -> DIR+  (driver 1)
Digital Pin 4 -> ENA+ (driver 1)
Digital Pin 5 -> PUL+ (driver 2)
Digital Pin 6 -> DIR+  (driver 2)
Digital Pin 7 -> ENA+ (driver 2)
Digital Pin 8 -> PUL+ (driver 3)
Digital Pin 9 -> DIR+  (driver 3)
Digital Pin 10 -> ENA+ (driver 3)

And the PUL-, DIR- to the Arduino GND and ENA- unconnected.
All 3 motors are connected to A+B- and B+B- each coil.

Is there something wrong in wiring?


It sounds reasonable. It runs, so it cann't me much off ;o)
.. maybe it's the unconnected ENA- that slows down the speed. I'm not that much of a specialist, but my impression is that EN takes time. Do you involve EN between each step or just at stepper-start and stepper-stop?

Quote

I have used digitalwrite directly (LOW->HIGH to start) but the speed is low and also I can't make them run in different speed each other. With accelstepper library the speed is tragically low.

Thank you!



About the speed .. if it works as my driver, you deside the 'delay' between each step. If it's short, the steppers steps fast. Notice below the inverse relation between velocity and 'delay' [it's not an Arduino delay(time), but rather time between two visits of cStepper::setTime()]

I'm not sure weather your driver takes care of the details of which pin to pull and what fase to choose, but I can make this code work for mine.

I've combined three steppers to work in unison ( in a cPen-class), but I'm retreating to have only 2 steppers in the pen. The last days it's fooled me and doesn't comply to my wishes. I'm trying to deal with a time discrepency when two motors does equal things .. and to code myself out of burning the drivers off (it happened once). My code is executing fine and I havent got a clue of why the steppers just buzzes instead of moves. The code is rather ugly and pretty lengthy with a lot of redundant code. I can pop part of the geometry-stuff that applies to two steppers that works on a plane if you'r interested.



#include <cStepper.h>

//-------------------------------------------------------------

const int x_EA = 41 ;
const int x_i2 = 39 ;
const int x_i1 = 38 ;  
const int x_EB = 40 ;
const int x_i4 = 37 ;
const int x_i3 = 36 ;

cStepper stpX( x_EA, x_EB, x_i1, x_i2, x_i3, x_i4 ) ;

const int y_EA = 33 ;
const int y_i2 = 31 ;
const int y_i1 = 30 ;  
const int y_EB = 32 ;
const int y_i4 = 29 ;
const int y_i3 = 28 ;

cStepper stpY( y_EA, y_EB, y_i1, y_i2, y_i3, y_i4 ) ;

const int z_EA = 49 ;
const int z_i2 = 47 ;
const int z_i1 = 46 ;
const int z_EB = 48 ;
const int z_i4 = 45 ;
const int z_i3 = 44 ;

cStepper stpZ( z_EA, z_EB, z_i1, z_i2, z_i3, z_i4 ) ;

...............

from class cStepper:

cStepper::cStepper( int EA , int EB , int i1 , int i2 , int i3 , int i4 )
{
   x_i4 = i4 ;
   x_i3 = i3 ;
   x_i2 = i2 ;
   x_i1 = i1 ;
   x_EA = EA ;
   x_EB = EB ;

     pinMode( EA  , OUTPUT ) ;
    pinMode( i2 , OUTPUT ) ;
    pinMode( i1 , OUTPUT ) ;  
   pinMode( EB , OUTPUT ) ;  
    pinMode( i4 , OUTPUT ) ;
    pinMode( i3 , OUTPUT ) ;

   deEnable() ;
   Stop() ;

   position_x = 0.0f ;
   fase = 0 ;
     mVelocity = 0.0f ; // mVelocity and mDelay  are inverse
   mDelay = 1000 ; //unsigned long
    mMinDelay = 2 ; //in millis. test this out!  unsigned long
   mMaxVelocity = 500.0f ; // in steps pr sec (1000 millis )
   oldTime = 0 ;
   mDirection = true ;
   misOn = false ;
     }// end constructor

.... and the most troublesome member: The one that is 'in the loop' and 'listens' for the time ticking:

//-------------------------------------------------------
   void cStepper::setTime(){
      if ( cStepper::misOn ){
         if(  ( (oldTime + mDelay) < millis()) ){
            cStepper::Step() ;
            cStepper::oldTime = millis() ;
         }
      }//
      
   } // end cStepper::setTime

some other members members:

   //velocity in steps pr sec (1000 millis )
   boolean cStepper::setVelocity( float velocity ){
      mVelocity = velocity ;  
      boolean res = false ;
      if( mVelocity < mMaxVelocity ){
         res = true ;
         if(  0 < mVelocity ){   mDelay = long( 1000/mVelocity) ; }
         }
      else{ mDelay = mMinDelay ; }
      return res ;
   }
   //----------------------------------

//-----------------
   void cStepper::Step()// one step at a time!
   {      
       if( cStepper::mDirection == true ){ cStepper::fase  +=1 ; cStepper::position_x += 1 ; }
       else{ cStepper::fase  -=1 ; cStepper::position_x -= 1 ; }

       if( 3 < cStepper::fase ){ cStepper::fase  = 0 ; }
       if( cStepper::fase <0 ){ cStepper::fase  = 3 ; }

       switch( cStepper::fase )
         {
          case 0:
               cStepper::x1_faseOne() ;
               break ;      
          case 1:
               cStepper::x2_faseOne() ;
               break ;      
          case 2:
               cStepper::x1_faseTwo() ;
               break ;
          case 3:
               cStepper::x2_faseTwo() ;
               break ;                
          }// end switch
      }// end Step
//-------------------------------
      void cStepper::x1_faseOne()
      {
          digitalWrite( x_i4 , LOW ) ;
          digitalWrite( x_i3 , LOW ) ;
          digitalWrite( x_i1 , LOW ) ;
          digitalWrite( x_i2 , HIGH ) ;  
      }//A_faseOne
//-------------------------------
      void cStepper::x1_faseTwo()
      {
          digitalWrite( x_i4 , LOW ) ;
          digitalWrite( x_i3 , LOW ) ;
          digitalWrite( x_i2 , LOW ) ;
          digitalWrite( x_i1 ,HIGH ) ;
      }//A_faseTwo
//------------------------------
      void cStepper::x2_faseOne()
      {
          digitalWrite( x_i2 , LOW ) ;
          digitalWrite( x_i1 , LOW ) ;
          digitalWrite( x_i3 , LOW ) ;
          digitalWrite( x_i4 , HIGH ) ;
      }//B_faseOne
//------------------------------
      void cStepper::x2_faseTwo()
      {
          digitalWrite( x_i2 , LOW ) ;
          digitalWrite( x_i1 , LOW ) ;
          digitalWrite( x_i4 , LOW ) ;
          digitalWrite( x_i3 , HIGH ) ;
      }
//------------------------------      
      void cStepper::Enable(){
          analogWrite( x_EA , 255 ) ;
         delay(100) ;
          analogWrite( x_EB , 255 ) ;
         delay(100) ;
         cStepper::misOn  = true ;
      }
      void cStepper::deEnable(){
          analogWrite( x_EA , 0 ) ;
          analogWrite( x_EB , 0 ) ;
         cStepper::mVelocity = 0.0f ;
         cStepper::misOn  = false ;
      }

      void cStepper::Stop(){
          digitalWrite( x_i1 , LOW ) ;
          digitalWrite( x_i2 , LOW ) ;
          digitalWrite( x_i3 , LOW ) ;
          digitalWrite( x_i4 , LOW ) ;
         cStepper::mVelocity = 0.0f ;
      }

//--------------------------
kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk

don't take it granted that this will work exactly (I've got too menĂ½ versions of the code ;o/) :

   //velocity in steps pr sec (1000 millis )
   boolean cStepper::changeSpeed( float change ){
      boolean res = true ;
      mVelocity += change ; 
      if( abs(mVelocity) < mMaxVelocity ){          
          if( 2 < mVelocity ){   
            mDelay = long( 1000/mVelocity) ;
            res = false ;
            mDirection = true ;
         }
         else if( mVelocity < -2 ){
            mDelay = long( 1000/mVelocity) ;
            res = false ;
            mDirection = false ;
         }
         else{  }
      }
      else{
         mDelay = mMinDelay ;
         if( 2 < mVelocity ){ mDirection = true ; }
         if( mVelocity < -2 ){ mDirection = false ; }
         res = false ;
      }
      return res ;
   }// cStepper::changeSpeed
//------------------------------------------------------- ~100


Take note that, if you run two motors in unison and one of them is waiting while it 'works' .. it will likely burn off the driver. Ask in if you need details.

standby

Thank you for your suggestions.
As I am not an expert in programming and I am a little confused, is there someone that can make some changes to my sketch-code so I can run my 3 steppers in different variable speeds?? :~

I also note that when I am running 1 stepper the speed is higher that the overall speed when I am running 3 steppers. Is there a problem with my code or it is just the processor limit that affects the overall speed?


Here is my simple sketch:


int stepM1pin = 2;    // motor 1 step pin
int dirM1pin = 5;     // motor 1 dir pin
int stepM2pin = 3;    // motor 2 step pin
int dirM2pin = 6;     // motor 2 dir pin
int stepM3pin = 4;    // motor 3 step pin
int dirM3pin = 7;     // motor 3 dir pin

int Steps = 10;       // define steps
int Delay = 8;        // define delay microseconds
int i;


void setup() {

pinMode(stepM1pin, OUTPUT);    // motor 1 step pin as output
pinMode(dirM1pin, OUTPUT);     // motor 1 dir pin as output
pinMode(stepM2pin, OUTPUT);    // motor 2 step pin as output
pinMode(dirM2pin, OUTPUT);     // motor 2 dir pin as output
pinMode(stepM3pin, OUTPUT);    // motor 3 step pin as output
pinMode(dirM3pin, OUTPUT);     // motor 3 dir pin as output

}


void loop(){

    digitalWrite(dirM1pin, LOW);    // Change direction of 1st motor.
    digitalWrite(dirM2pin, HIGH);   // Change direction of 2nd motor.
    digitalWrite(dirM3pin, LOW);    // Change direction of 3rd motor.
   
   
    for(i=0; i<Steps; i++){            // motor 1 run
      digitalWrite(stepM1pin, LOW); 
      digitalWrite(stepM1pin, HIGH);
    }
   
    for(i=0; i<Steps; i++){            // motor 2 run
      digitalWrite(stepM2pin, LOW); 
      digitalWrite(stepM2pin, HIGH);
    }

    for(i=0; i<Steps; i++){            // motor 3 run
      digitalWrite(stepM3pin, LOW); 
      digitalWrite(stepM3pin, HIGH);
      delayMicroseconds(Delay);        // ????? This delay affects all the motors so I can't
                                                 // make it run in different speed...
    }
}



I appreciate your help! :smiley-sweat:
Thank you!!!

Carsten53T

stanby,
If you havn't any coding-experience then you'r far from your goal. You should find some sources that focus on general programming and take your time to delve into it.

The scetch has a Setup() and a Loop() function that is guaranteed to be called on program execution ... the Loop() being repeated over and over.
You need to write your own functions .. and then call them from the Loop() when appropriate.

If you havn't employed any buttons or serial() read/write  you'll have to stiffen up on boolean controle-structures to 'controle' what happens. You can create time-dependant events in code .. as a minimum you need to call your motors steps for each motor and for each step. You test a variable (say millis()+20000 ) in the loop() to see if the 20000 milli seconds has passed. If it has, you execute (call) the particulare function say  'void Step3()' written outside the Loop().
It is possible to write all your code in the Loop(), but you'r bound to loose track of what happens.

You can call a function 'Step2( long aDelay )' with an argument ( aDelay ) that will be available in the body of the function. That way you decide at the time of calling, how fast it will go.

Take an early focus on disbanding the Delay(millis) function and substitute it with the event-thing I wrote above. The Delay() function simply stops the code and waits. Tat way you can only drive one motor at a time.

Good Luck

standby

Thank you for your reply!

Basically I understand what you mean, the project is very simple and based on 3 steppers that, after power ON of the machine, will start running at the same time.
The motor 1 & 2 at the maximum possible speed and the 3rd motor must run in lower speed so I need some help to change the code I made for the speed of the 3rd motor.

I didn't use delays for the motors 1&2 because all the motors will run at the same time and for these I need the max speed.
The change is that the 3rd motor must run at lower speed and when I use delayMicroseconds() in 3rd motors for() it makes all motors speed lower.

Could you give me some help for my code please? A piece of code or my code modified is better for me.

Thank you.

Carsten53T


Here is some pseudo-code:


long oldTime1, oldTime2, oldTime3 ;
long wait1, wait2, wait3 ;


loop()

if( oldTime1 + wait1 < millis() ){
   oldTime1 = millis() ;
   // step Motor1
}
if( oldTime2 + wait2 < millis() ){
   oldTime2 = millis() ;
   // step Motor2
}
if( oldTime3 + wait3 < millis() ){
   oldTime3 = millis() ;
   // step Motor3
}

// end loop

Langov

Hi.
I have controller like you (http://electroprivod.ru/smd-4.2.htm ) and bipolar motor stepper(http://electroprivod.ru/ad-200.htm).
Controller and arduino mega connecting :
Digital Pin 2 -> PUL+ (driver 1)
Digital Pin 3 -> DIR+  (driver 1)
And the PUL-, DIR- to the Arduino GND and ENA- unconnected.

Motoro hums, but does not move(

Use Sketch:
Code: [Select]

int stepM1pin = 22;   
int dirM1pin = 24;   
int enM1pin = 26;

int Steps = 10;
int Delay = 3;    
int i;

void setup() {

pinMode(stepM1pin, OUTPUT);   
pinMode(dirM1pin, OUTPUT);   
pinMode(enM1pin,OUTPUT);

digitalWrite(enM1pin,LOW);
digitalWrite(dirM1pin,LOW);
}

void loop() {
  digitalWrite(stepM1pin, HIGH);
  delayMicroseconds(3);
  digitalWrite(stepM1pin, LOW);
  delayMicroseconds(3);
}


what I'm doing wrong?

ps: sorry for my english )

Msquare

It's got nothing to do with the english - programming code is code
Code: [Select]
void loop() {
  digitalWrite(stepM1pin, HIGH);
  delayMicroseconds(3);
  digitalWrite(stepM1pin, LOW);
  delayMicroseconds(3);
}
You are asking the motor to make a step every 6 microseconds - that is 160Khz or 160000 step a second and for the average stepper that would be 48000 revolutions a second. It can not do that. Increase one of the delays to a few milliseconds so you only give 500 or 20 pulses a second.

Go Up