Arduino Forum

Using Arduino => Programming Questions => Topic started by: panduga on Jul 23, 2016, 09:16 am

Title: arduino uno with stepper motor
Post by: panduga on Jul 23, 2016, 09:16 am
hi this venkatesh, i am doing a project i.e. controlling 0 to 300 rpm speed of bipolar stepper motor (nema 34,68kg cm,1.8 deg per step ) . For this i have used arduino uno & Bipolar stepper drive with 256 micro stepping. in programming i used only 8 micro stepping. But the problem if the speed more than 200 rpm while starting , jerking is happening. then after the speed was reduced to 30 or 44 rpm .
note : for start , stop, inc & dec pins can be used as pull up resistor.
i am unable to find the solution for above problem.
plz help me and the arduino code is below.

Code: [Select]
//arduino code
//
#include <TimerOne.h>
#include <EEPROM.h>

int digit1 = 10; //PWM Display segment 1
int digit2 = 11; //PWM Display segment 2
int digit3 = 12; //PWM Display segment 3
int digit4 = 13; //PWM Display segment 4

//Pin mapping from Arduino to the ATmega DIP28 if you need it
//http://www.arduino.cc/en/Hacking/PinMapping
int segA = 2; //Display LED A
int segB = 3; //Display LED B
int segC = A4; //Display LED C
int segD = A5; //Display LED D
int segE = 7; //Display LED E
int segF = 8; //Display LED F
int segG = 9; //Display LED G
int rpm;
int initial_rpm;
int dutycycle_time=0;
int stepper_Enable=5; //STEPPER MOTOR  ENABLE PIN : PUL-
int stepper_Pulse=6;  // STEPPER MOTOR PULSE PIN :  PUL-

int address_eeprom=0;


void displayNumber(int);
void lightNumber(int);



void setup()
{                
pinMode(segA, OUTPUT);
pinMode(segB, OUTPUT);
pinMode(segC, OUTPUT);
pinMode(segD, OUTPUT);
pinMode(segE, OUTPUT);
pinMode(segF, OUTPUT);
pinMode(segG, OUTPUT);

pinMode(digit1, OUTPUT);
pinMode(digit2, OUTPUT);
pinMode(digit3, OUTPUT);
pinMode(digit4, OUTPUT);

// pinMode(start_1,INPUT);
// pinMode(stop_1,INPUT);
//Serial.begin(9600);



Timer1.attachInterrupt( timerIsr ); // attach the service routine here
pinMode(stepper_Pulse,OUTPUT); // Analog pin A2 is used for ENABLING the steeper motor
pinMode(stepper_Enable,OUTPUT); // Analog pin A2 is used for DIRECTION the steeper motor
// pinMode(5,OUTPUT); // Analog pin A2 is used for PULSE GENERATING the steeper motor
digitalWrite(stepper_Pulse,HIGH);
digitalWrite(stepper_Enable,LOW);
//digitalWrite(5,HIGH);
//pinMode(13, OUTPUT);
rpm=EEPROM.read(address_eeprom);
}

void loop()
{


while(digitalRead(stepper_Enable)==HIGH){
    displayNumber(rpm);  
   int cycle_freq=(1600/60)*rpm;
   int dutycycle_freq=2*cycle_freq;
   int dutycycle_time=1000000/dutycycle_freq;
    Timer1.initialize(dutycycle_time); // set a timer of length 100000 microseconds (or 0.1 sec - or 10Hz => the led will blink 5 times, 5 cycles of on-and-off, per second)
    if(analogRead(A3)==LOW )  // STOPPING THE STEPPER MOTOR
     {
       digitalWrite(stepper_Enable,LOW);
 
     }
 
}

while(digitalRead(stepper_Enable)==LOW)
{
  int initial_rpm=rpm;
   displayNumber(rpm);    
   EEPROM.write(address_eeprom,rpm);

    if(analogRead(A0)==LOW && rpm<300 ) ///increasing speed of stepper motor
  {
        rpm=rpm+1;
       // delay(100);
   }
  if(analogRead(A1)==LOW && rpm>0) ///decreasing speed of stepper motor
  {
        rpm=rpm-1;
       // delay(100);
  }
  if(analogRead(A2)==LOW ) //STARTING THE STEPPER MOTOR
  {
   digitalWrite(stepper_Enable,HIGH);
  }
}
if(initial_rpm!=rpm){
address_eeprom=address_eeprom+1;}
}

void displayNumber(int toDisplay) {
#define DISPLAY_BRIGHTNESS  500

#define DIGIT_ON  HIGH
#define DIGIT_OFF  LOW

long beginTime = millis();

for(int digit = 4 ; digit > 0 ; digit--) {

  //Turn on a digit for a short amount of time
  switch(digit) {
  case 1:
    digitalWrite(digit1, DIGIT_ON);
    break;
  case 2:
    digitalWrite(digit2, DIGIT_ON);
    break;
  case 3:
    digitalWrite(digit3, DIGIT_ON);
    break;
  case 4:
    digitalWrite(digit4, DIGIT_ON);
    break;
  }

  //Turn on the right segments for this digit
  lightNumber(toDisplay % 10);
  toDisplay /= 10;

  delayMicroseconds(DISPLAY_BRIGHTNESS);
   lightNumber(10);

  //Turn off all digits
  digitalWrite(digit1, DIGIT_OFF);
  digitalWrite(digit2, DIGIT_OFF);
  digitalWrite(digit3, DIGIT_OFF);
  digitalWrite(digit4, DIGIT_OFF);
}

while( (millis() - beginTime) < 20) ;
//Wait for 20ms to pass before we paint the display again
}
void lightNumber(int numberToDisplay) {

#define SEGMENT_ON  HIGH
#define SEGMENT_OFF LOW

switch (numberToDisplay){

case 0:
  digitalWrite(segA, SEGMENT_ON);
  digitalWrite(segB, SEGMENT_ON);
  digitalWrite(segC, SEGMENT_ON);
  digitalWrite(segD, SEGMENT_ON);
  digitalWrite(segE, SEGMENT_ON);
  digitalWrite(segF, SEGMENT_ON);
  digitalWrite(segG, SEGMENT_OFF);
  break;

case 1:
  digitalWrite(segA, SEGMENT_OFF);
  digitalWrite(segB, SEGMENT_ON);
  digitalWrite(segC, SEGMENT_ON);
  digitalWrite(segD, SEGMENT_OFF);
  digitalWrite(segE, SEGMENT_OFF);
  digitalWrite(segF, SEGMENT_OFF);
  digitalWrite(segG, SEGMENT_OFF);
  break;

case 2:
  digitalWrite(segA, SEGMENT_ON);
  digitalWrite(segB, SEGMENT_ON);
  digitalWrite(segC, SEGMENT_OFF);
  digitalWrite(segD, SEGMENT_ON);
  digitalWrite(segE, SEGMENT_ON);
  digitalWrite(segF, SEGMENT_OFF);
  digitalWrite(segG, SEGMENT_ON);
  break;

case 3:
  digitalWrite(segA, SEGMENT_ON);
  digitalWrite(segB, SEGMENT_ON);
  digitalWrite(segC, SEGMENT_ON);
  digitalWrite(segD, SEGMENT_ON);
  digitalWrite(segE, SEGMENT_OFF);
  digitalWrite(segF, SEGMENT_OFF);
  digitalWrite(segG, SEGMENT_ON);
  break;

case 4:
  digitalWrite(segA, SEGMENT_OFF);
  digitalWrite(segB, SEGMENT_ON);
  digitalWrite(segC, SEGMENT_ON);
  digitalWrite(segD, SEGMENT_OFF);
  digitalWrite(segE, SEGMENT_OFF);
  digitalWrite(segF, SEGMENT_ON);
  digitalWrite(segG, SEGMENT_ON);
  break;

case 5:
  digitalWrite(segA, SEGMENT_ON);
  digitalWrite(segB, SEGMENT_OFF);
  digitalWrite(segC, SEGMENT_ON);
  digitalWrite(segD, SEGMENT_ON);
  digitalWrite(segE, SEGMENT_OFF);
  digitalWrite(segF, SEGMENT_ON);
  digitalWrite(segG, SEGMENT_ON);
  break;

case 6:
  digitalWrite(segA, SEGMENT_ON);
  digitalWrite(segB, SEGMENT_OFF);
  digitalWrite(segC, SEGMENT_ON);
  digitalWrite(segD, SEGMENT_ON);
  digitalWrite(segE, SEGMENT_ON);
  digitalWrite(segF, SEGMENT_ON);
  digitalWrite(segG, SEGMENT_ON);
  break;

case 7:
  digitalWrite(segA, SEGMENT_ON);
  digitalWrite(segB, SEGMENT_ON);
  digitalWrite(segC, SEGMENT_ON);
  digitalWrite(segD, SEGMENT_OFF);
  digitalWrite(segE, SEGMENT_OFF);
  digitalWrite(segF, SEGMENT_OFF);
  digitalWrite(segG, SEGMENT_OFF);
  break;

case 8:
  digitalWrite(segA, SEGMENT_ON);
  digitalWrite(segB, SEGMENT_ON);
  digitalWrite(segC, SEGMENT_ON);
  digitalWrite(segD, SEGMENT_ON);
  digitalWrite(segE, SEGMENT_ON);
  digitalWrite(segF, SEGMENT_ON);
  digitalWrite(segG, SEGMENT_ON);
  break;

case 9:
  digitalWrite(segA, SEGMENT_ON);
  digitalWrite(segB, SEGMENT_ON);
  digitalWrite(segC, SEGMENT_ON);
  digitalWrite(segD, SEGMENT_ON);
  digitalWrite(segE, SEGMENT_OFF);
  digitalWrite(segF, SEGMENT_ON);
  digitalWrite(segG, SEGMENT_ON);
  break;

case 10:
  digitalWrite(segA, SEGMENT_OFF);
  digitalWrite(segB, SEGMENT_OFF);
  digitalWrite(segC, SEGMENT_OFF);
  digitalWrite(segD, SEGMENT_OFF);
  digitalWrite(segE, SEGMENT_OFF);
  digitalWrite(segF, SEGMENT_OFF);
  digitalWrite(segG, SEGMENT_OFF);
  break;
}
}
void timerIsr()
{
  // Toggle LED
  digitalWrite( stepper_Pulse, !digitalRead( stepper_Pulse ));
}


Title: Re: arduino uno with stepper motor
Post by: rpt007 on Jul 23, 2016, 09:56 am
Start with a simple stepper sketch only as you can find in this forum.
Robin2 has done a great job for stepper newbies. Use the forum search ("simple stepper code", "stepper basics").

Then, when you have succeeded in how to operate your stepper in the desired way, go ahead with your whole sketch. And: pls read and follow the forum rules (e.g. put your sketch in </> brackets).

And: you will find some information about the importance of:
- current limiting
- motor voltage

Post information about
- the stepper,
- the stepper driver and
- your wiring
Title: Re: arduino uno with stepper motor
Post by: Robin2 on Jul 23, 2016, 10:08 am
This is the link to Simple Stepper Code (http://forum.arduino.cc/index.php?topic=277692.0)

See also Stepper Motor Basics (http://forum.arduino.cc/index.php?topic=284828.0)


As far as I can see you have made a simple process very complicated.

Post a link to the datasheet for your stepper motor and a link to the datasheet for your stepper motor driver.


And please modify your post and use the code button </>
Code: [Select]
so your code looks like this and is easy to copy to a text editor. See How to use the Forum (http://forum.arduino.cc/index.php?topic=149014.0)

...R
Title: Re: arduino uno with stepper motor
Post by: panduga on Jul 23, 2016, 02:22 pm
HI robin thanks for replay,
stepper motor and stepper drive details are attached in attachments. and also we designed new arduino board with Atmega 328p ic,28 pin. the schematic also attached in attachments.
the problem  i am facing is :
the increment or decrement of stepper speed can be controlled in stop condition only. But when i am doing  Increasing or decreasing the  speed of stepper motor, then that time stepper motor is jerking. i don't know what was happening.


note: sorry i am unable attach drive details . but web address is.
http://bholanath.in/certificates-files/stepper-drives-TDS/BH-MSD-6A-DRIVE-MANUAL.pdf?180316
Title: Re: arduino uno with stepper motor
Post by: rpt007 on Jul 24, 2016, 08:53 am
This is a very powerful stepper.

What about your power supply?
- voltage?
- max available current?
Title: Re: arduino uno with stepper motor
Post by: rpt007 on Jul 24, 2016, 09:26 am
Quote
For this i have used arduino uno & Bipolar stepper drive with 256 micro stepping
This means, that you need 256 pulses from Arduino to move the stepper 1 FULLSTEP (256 x 1/256 = 1).
So you need 256 x 200 = 51200 pulses to get one revolution!

And if you want to achieve max 300RPM, then you have to turn the stepper 300/60 = 5rev/sec = 256000 pulses/sec.
That is way beyond the capabilities of an Arduino, which works in a range of, let's say 4000 - 5000 pulses/sec.

Even, if you have set to 8 microsteps, that will require 8 x 200 x 5 = 8000 pulses, which is still too high as you have seen in your test.

You have some options:
1. Reduce microstepping to 1/2 or 1/4, that should do
2. Tune the Arduino (the normal UNO goes up to 16MHz, with updated bootloader and quartz -> 20MHz)
3. Buy a faster Arduino / ATMEL chip (Due with 96 MHz, based on Atmel SAM3X8E ARM Cortex-M3 CPU)

Comments to the options:
1. The easiest one which can drive your stepper at higher speed at the cost of being a bit noisy
2. Gives you 25% more speed, but limits microstepping still to 1/4
3. The most radical option; should give you enough room to drive up to 300RPM at higher microstepping (1/16, maybe 1/32)
Title: Re: arduino uno with stepper motor
Post by: panduga on Jul 24, 2016, 10:30 am
hi thanks for reply,
i have smps with output voltage : 48vdc, 6 Amps
                                                             
Title: Re: arduino uno with stepper motor
Post by: Robin2 on Jul 24, 2016, 03:33 pm
That stepper driver should work with my Simple Stepper Code (http://forum.arduino.cc/index.php?topic=277692.0) for testing.

Get it working slowly with full steps (rather than microsteps) to start with. Then you have  solid base from which to experiment.

...R
Title: Re: arduino uno with stepper motor
Post by: rpt007 on Jul 24, 2016, 03:53 pm
Quote
i have smps with output voltage : 48vdc, 6 Amps
That is a good fit and you should get it to work as planned if you follow the last advices.