Motor speed control with PWM or Digital pot

Subject says it all :slight_smile:

I have replaced one epson stepper motor with one sanyo step sync motor.
The new motor is quite big but it's working great.

Working voltage of the motor is 4,5 and the current is 1,4A.
The control part is made with schmalzhaus easydriver board.

Description:
This project is basically a combination of rack and pinion and quick return.
The return part should be triggered with button or switch but we can make this later.

This is how this looks now ( with longer delays ).
http://www.robives.com/mechanisms/rackpinion#.VZlHJqHfscc
So, if the point X is left side and point Y right side, then this would like like:

X side = 3 second
move back
Y side = 3 seconds
move forth

My goal is to speed up the return path and to set Y side to 1 second.
Like some controlled quick return mechanism.

How can i do that ? Must i use digital pot or PWM ?
BTW. if i remove delay function, motor is spinning at 2 rpm / second.
I dont know if this is the fastest spin or not...

Steppers? Then just change the step speed.

Digital pots are used with some stepper controllers to set the current limit for the motor. This has absolutely no impact on the speed the motor turns, just the weight it can move.

You may look into your micro-stepping configuration. For slow speeds, use high microsteps. For fast return, use whole steps.

"What steps do you take in an emergency?"

"Big ones, and lots of them."

If you told us which motor control board you have, perhaps we could be more helpful.

Hi !.
I am using schmalzhaus easy driver motor control board V4.2.

It's constant current switching driver, with 700mA per phase ...

On my espon motor i have used the code from Rx7man and it has worked perfect but for some unknown reason this code is not working on step sync. Link to the topic :

http://forum.arduino.cc/index.php?topic=328034.0

//---------------------
You have suggested microstepping. OK. According to your code examples i can try to implement this is Rx7man's code but before that i need to see why is this not working on my sanyo motor.
It looks like as he would spin but instead of that, nothing happens. Delay time looks OK.
So, basically, you can hear that the stepper is working but it wont spin.

If you want help with code then the first step (forgive the pun) is to post your code.

Why are you trying to drive a 1.4 amp motor with a 0.7 amp stepper driver ?
What power supply are you using for your motor (volts and amps).

This simple stepper code can be used for testing

You may find some useful stuff in stepper motor basics

...R

Hi,

Can you please post a copy of your circuit, in CAD or a picture of a hand drawn circuit in jpg, png?

Can you please post a copy of your sketch, using code tags?
They are made with the </> icon in the reply Menu.
See section 7 http://forum.arduino.cc/index.php/topic,148850.0.html

Tom...... :slight_smile:

@Tom George:
I can post a picture but there is not much to see. You have 4 wires connected to the easydriver board (look at the link :
http://www.schmalzhaus.com/EasyDriver/EasyDriver_v42/EasyDriver_v42_sch.pdf ).

This are motor characteristics :

SANYO DENKI.
"STEP-SYN"
Type: 103-820-0241
IBM P/N: 6838068
Lot No. 8504
Made in Japan

DC : 4.5V
Current: 1.4A
6 wires
//------------------------
Colours of the wires:

Blue
White blue
Red
White red
White
Black
//------------------------
Resistance( on 200 Ohm scale ):

Blue
White blue = 06.7

Red
White red = 06.7

Black
Red / Red white = 03.6

White
Blue / White blue = 03.6
//---------------------------

I have connected Blue / white blue and red / white read on the easyboard A/B - A/B ports and white / black wires are not connected. I'm using 12 / 2A power adapter to power the easyboard.
I hope that this part is OK. What do you think ?

@ Robin
No need to apologize! Really. I didn't past the whole code but instead of that i have send a link to topic where the code can be located.

This is the code that is working on espon but not on sanyo stepper:

int IncrementPin = 9;
int DirectionPin = 8;
int ButtonPin = 10; //my wild guess
int CurrentPosition; //Where the stepper motor is now

int Xposition = 0; //may need to swap these if it's backward
int Yposition = 3600;

void setup() {
  pinMode(IncrementPin, OUTPUT);
  pinMode(DirectionPin, OUTPUT);
  pinMode(ButtonPin, INPUT_PULLUP); //I'm going out on a limb here.

  digitalWrite(IncrementPin, LOW);
  digitalWrite(DirectionPin, LOW);

}

void loop() {
  static boolean RunMode = false;
  if (!RunMode) { //RunMode is false until the button is pressed, then doesn't get checked anymore
    //latching RunMode on
    RunMode = digitalRead(!ButtonPin);
  }
  else {
    delay(5000);
    MoveMotor(Yposition);
    delay(1000);
    MoveMotor(Xposition);
    delay(5000);

  }
}
void MoveMotor(int NewPosition) {
  boolean Forward = (NewPosition > CurrentPosition); //sets the direction variable
  int AddValue;  //How much we add to the current position... it will only be 1 or -1
  if (Forward) { // perhaps this is backward and should be NOT forward (!Forward)
    digitalWrite(DirectionPin, HIGH);
    AddValue = 1;
  }
  else {
    digitalWrite(DirectionPin, LOW);
    AddValue = -1;
  }
  //OK, now we have the direction out of the way, the rest of your code should work
  while (CurrentPosition != NewPosition) {
    digitalWrite(9, HIGH);
    delayMicroseconds(100);
    digitalWrite(9, LOW);
    delayMicroseconds(100);

    CurrentPosition += AddValue;  // record this step
    // Using the += operator does the same as what you had
  }
}

And this is the standard demo code that is used by easydriver setup:

int Distance = 0;  // Record the number of steps we've taken


void setup() {               

  pinMode(8, OUTPUT);     

  pinMode(9, OUTPUT);

  digitalWrite(8, LOW);

  digitalWrite(9, LOW);

}


void loop() {

  digitalWrite(9, HIGH);

  delayMicroseconds(100);         

  digitalWrite(9, LOW);

  delayMicroseconds(100);

  Distance = Distance + 1;   // record this step

 

  // Check to see if we are at the end of our move

  if (Distance == 3600)

  {

    // We are! Reverse direction (invert DIR signal)

    if (digitalRead(8) == LOW)

    {

      digitalWrite(8, HIGH);

    }

    else

    {

      digitalWrite(8, LOW);

    }

    // Reset our distance back to zero since we're

    // starting a new move

    Distance = 0;

    // Now pause for half a second

    delay(500);

  }

}

//-----------------------------------------------
The second code is working with sanyo stepper but i am missing the part with speed controlled back/forth spin. Stepper moves as i described in first post so now i need to program the part where i can define a way how to speed up this back and forth movement regarding on button press.

X side = 3 second
move back - fast
Y side - wait for button press
move forth - fast

Future idea is to trigger movement to the X side also with the button press or with some kind of switch.

Regards !

I don't immediately see anything wrong with your own code.
Ad some Serial.println()s so you can see that your variables have the numbers you expect when they are trying to figure out the number of steps.

I suspect you are trying to make the motor move too quickly. Try using this version - 500 steps per second.

 while (CurrentPosition != NewPosition) {
    digitalWrite(9, HIGH);
    digitalWrite(9, LOW);
    delayMicroseconds(2000);

    CurrentPosition += AddValue;  // record this step
    // Using the += operator does the same as what you had
  }

If it works then you can try speeding it up. If it does not work, slow it down further.

For most projects it is better not to use delay() to manage timing. See how millis() is used in several things at a time.

Code will be much easier to understand if you give names to things.

For example digitalWrite(stepPin, HIGH)

...R

@Robin2
Your suggestion has worked.
I have change delayMicroseconds to 400 and stepper is acting almost as it should.

I have tested button sample :

const int buttonPin = 2;     // the number of the pushbutton pin
const int ledPin =  13;      // the number of the LED pin

// variables will change:
int buttonState = 0;         // variable for reading the pushbutton status

void setup() {
  // initialize the LED pin as an output:
  pinMode(ledPin, OUTPUT);      
  // initialize the pushbutton pin as an input:
  pinMode(buttonPin, INPUT);    
}

void loop(){
  // read the state of the pushbutton value:
  buttonState = digitalRead(buttonPin);

  // check if the pushbutton is pressed.
  // if it is, the buttonState is HIGH:
  if (buttonState == HIGH) {    
    // turn LED on:    
    digitalWrite(ledPin, HIGH);  
  }
  else {
    // turn LED off:
    digitalWrite(ledPin, LOW);
  }
}

and it's working but for some strange reason the button part in my code is not working.
I uncomment the runMode code part and tried to add digitalWrite (13,HIGH) - LED to see if something
happens. The part of the code is executed and LED lights but not on button press.

I have replaced INPUT_PULLUPS with just INPUT because sketch wont compile.
Nothing happens when i press the button but the stepper is working OK.

This button press should trigger the back forth spin.
Any idea ?

arnix:
I have replaced INPUT_PULLUPS with just INPUT because sketch wont compile.

The correct syntax is INPUT_PULLUP

Without that (or an external pullup resistor) the I/O pin will have unpredictable values.

...R

I get compiler error when i try to compile with INPUT_PULLUP.
I am using 10K external resistor connected between gnd and pin 2 and that is connected to button.
If i use simple test button code, switch is working ok and the LED is triggered...

arnix:
I get compiler error when i try to compile with INPUT_PULLUP.

Post your code.

...R

I get compiler error when i try to compile with INPUT_PULLUP.

What version of the Arduino IDE are you using?

Hi.
I have updated arduino IDE from 1.0 to 1.6.5 and now there is no problem with compiling.

The problem that is still active is the button press.
I have add the serial monitor but according to the output, button is not responding.
This is what i get ( without pressing on the switch ):

Button not pressed
Button pressed
Button pressed
Button pressed
Button pressed

...

If i press on the button, nothing happens.

The code:

int IncrementPin = 9;
int DirectionPin = 8;
int ButtonPin = 2; 
int CurrentPosition; 

int Xposition = 0; //may need to swap these if it's backward
int Yposition = 800;

void setup() {
  pinMode(IncrementPin, OUTPUT);
  pinMode(DirectionPin, OUTPUT);
  pinMode(ButtonPin, INPUT_PULLUP); 

  digitalWrite(IncrementPin, LOW);
  digitalWrite(DirectionPin, LOW);
  Serial.begin(9600);

}

void loop() {
  static boolean RunMode = false;
  if (!RunMode) { //RunMode is false until the button is pressed, then doesn't get checked anymore
    
    //latching RunMode on
    RunMode = digitalRead(!ButtonPin);
    Serial.println("Button not pressed");
  }
  else {
    Serial.println("Button pressed");
    delay(3000);
    MoveMotor(Yposition);
    delay(1000);
    MoveMotor(Xposition);
    delay(3000);

  }
}
void MoveMotor(int NewPosition) {
  boolean Forward = (NewPosition > CurrentPosition); //sets the direction variable
  int AddValue;  //How much we add to the current position... it will only be 1 or -1
  
  if (Forward) { // perhaps this is backward and should be NOT forward (!Forward)
    digitalWrite(DirectionPin, HIGH);
    AddValue = 1;
  }
  else {
    digitalWrite(DirectionPin, LOW);
    AddValue = -1;
  }
  
  
  while (CurrentPosition != NewPosition) {
    digitalWrite(9, HIGH);
    digitalWrite(9, LOW);
    delayMicroseconds(400);
    CurrentPosition += AddValue;  // record this step
  }
}

Like i wrote before, if i use standard button example, everything is working as it should...

I think this

delayMicroseconds(400);

is intended to create 2500 steps per second.

Will your motor work at that speed?
Have you tried it at a slower speed ?

It is not a good idea to use delay() in your code. The demo several things at a time illustrates the use of millis() to manage timing. The long delay()s will give you the impression that the button is not detected because it will only be detected after 7 seconds, plus the motor run time have elapsed.

The second example in this simple stepper code also uses millis() and micros() for timing.

...R
17 Jul 2015 Edit to add link to several things ...
Apologies for the omission

So what is this line doing?

 RunMode = digitalRead(!ButtonPin);

You are reading the digital input from pin number "not 2". That makes no sense at all. The ! is an inversion operation for booliean variables not for numbers.

Grumpy_Mike:
So what is this line doing?

 RunMode = digitalRead(!ButtonPin);

You are reading the digital input from pin number "not 2". That makes no sense at all. The ! is an inversion operation for booliean variables not for numbers.

I missed that. If you want to invert something the correct code would be

RunMode = ! digitalRead(ButtonPin);

...R

@Robin2 and Grumpy_Mike
I think that video presentation should show the project status :-), so i have uploaded one video showing motor movement + button part. Hold, fast back - forth, hold.

http://tinypic.com/r/dfd5qq/8]View My Video

@Grumpy_Mike
I got this code from a college on this forum and to be honest i didnt look much at this code part till now.
I will make the changes and test new version of the code. Thank you for your observation !

@Robin2
I understand what your saying, but before we go further, please take a look at the video.

There is an awful lot of rubbish on the web page with your video. Just post it on YouTube.

...R

Hmm, strange. TinyPic shows only one banner on the left ( as far as i know ).

I dont have account on yt. You can look at the video on vid.me page.
It's banner free...

If this will not work i will create account on YT.

Sorry I could get nothing from that video. There is no commentary and it is quite dark. You might feel it shows something but to me it simply looks like a motor turns from time to time and the odd LED blinks.

I got this code from a college on this forum

Well you said it works and that code is so silly it could never have worked, so I don't think you are testing things correctly.

What you need to do at this stage is to state what your problem is now because what ever it is then there is no correlation between your current problem and the title of this thread.