The mount will need two stepper motors and I want them to both move at the same time – I don’t want to ‘move all the azimuth steps’ and then ‘move all the altitude steps’. And they also need to accelerate / decelerate as in the last post.
So, again, a bit of amendment was necessary to the arduino stepper library.
An example sketch
The end result looks like this:
/* * Two synchronous stepper motors * uses the Stepper_Aclr8_2 library * * created by Ben @ cape ealing * 25 May 2008 * */ // include the library #include// initialise the class Steppers_Aclr8_2 MyTwoSteppers = Steppers_Aclr8_2(); void setup() { // define each stepper motor // (no of steps per rev, pin1, pin2, pin3, pin4) MyTwoSteppers.stepper1(200, 4, 6, 5, 7); MyTwoSteppers.stepper2(200, 8, 10, 9, 11); // define the rates of each motor // (min speed, max speed, steps take to accelerate) MyTwoSteppers.stepper1speeds(5, 30, 200); MyTwoSteppers.stepper2speeds(10, 40, 100); } void loop() { // First motor: 600 steps forward // Second motor: 300 steps back MyTwoSteppers.step(600, -300); delay(2000); // First motor: 300 steps backward // Second motor: 600 steps forward MyTwoSteppers.step(-300, 600); delay(2000); }
The main class
The heart of the library is below:
/*
Steppers_Aclr8_2.cpp
A library for two (synchronous stepper motors
with acceleration and deceleration
for Wiring/Arduino
- Version 1.0
*/
#include "WProgram.h"
#include "Steppers_Aclr8_2.h"
/*
* Initialise the class
*/
Steppers_Aclr8_2::Steppers_Aclr8_2()
{
}
/* First motor
* Constructor for four-pin stepper motor
* Sets which wires should control the motor and
* primary variables used by motor.
*/
void Steppers_Aclr8_2::stepper1(int number_of_steps1, \
int motor1_pin_1, int motor1_pin_2, \
int motor1_pin_3, int motor1_pin_4)
{
// which step the motor is on
this->step_number1 = 0;
// the motor speed1, in revolutions per minute
this->speed1 = 0;
// motor direction1
this->direction1 = 0;
// time stamp in ms of the last step taken
this->last_step_time1 = 0;
// total number of steps for this motor
this->number_of_steps1 = number_of_steps1;
// find the delay nec at 1 rev per min
this->delay_1revpermin1 = 60L * 1000L / number_of_steps1;
// Arduino pins for the motor control connection
this->motor1_pin_1 = motor1_pin_1;
this->motor1_pin_2 = motor1_pin_2;
this->motor1_pin_3 = motor1_pin_3;
this->motor1_pin_4 = motor1_pin_4;
// setup the pins on the microcontroller
pinMode(this->motor1_pin_1, OUTPUT);
pinMode(this->motor1_pin_2, OUTPUT);
pinMode(this->motor1_pin_3, OUTPUT);
pinMode(this->motor1_pin_4, OUTPUT);
}
/* Second motor
* Constructor for four-pin stepper motor
* Sets which wires should control the motor and
* primary variables used by motor.
*/
void Steppers_Aclr8_2::stepper2(int number_of_steps2, \
int motor2_pin_1, int motor2_pin_2, \
int motor2_pin_3, int motor2_pin_4)
{
// which step the motor is on
this->step_number2 = 0;
// the motor speed, in revolutions per minute
this->speed2 = 0;
// motor direction
this->direction2 = 0;
// time stamp in ms of the last step taken
this->last_step_time2 = 0;
// total number of steps for this motor
this->number_of_steps2 = number_of_steps2;
// find the delay nec at 1 rev per min
this->delay_1revpermin2 = 60L * 1000L / number_of_steps2;
// Arduino pins for the motor control connection
this->motor2_pin_1 = motor2_pin_1;
this->motor2_pin_2 = motor2_pin_2;
this->motor2_pin_3 = motor2_pin_3;
this->motor2_pin_4 = motor2_pin_4;
// setup the pins on the microcontroller
pinMode(this->motor2_pin_1, OUTPUT);
pinMode(this->motor2_pin_2, OUTPUT);
pinMode(this->motor2_pin_3, OUTPUT);
pinMode(this->motor2_pin_4, OUTPUT);
}
/* First motor
Set the min speed, max speed, and steps taken to accelerate
*/
void Steppers_Aclr8_2::stepper1speeds(long minSpeed1, long maxSpeed1, double Accel1)
{
this->motorMinSpeed1 = minSpeed1;
this->motorMaxSpeed1 = maxSpeed1;
// Number of steps to accelerate over
this->motorAccSteps1 = Accel1;
// Change in speed1 needed per step
this->motorAccelVal1 = (this->motorMaxSpeed1 -this->motorMinSpeed1) / (Accel1-1);
}
/* Second motor
Set the min speed, max speed, and steps taken to accelerate
*/
void Steppers_Aclr8_2::stepper2speeds(long minSpeed2, long maxSpeed2, double Accel2)
{
this->motorMinSpeed2 = minSpeed2;
this->motorMaxSpeed2 = maxSpeed2;
// Number of steps to accelerate over
this->motorAccSteps2 = Accel2;
// Change in speed1 needed per step
this->motorAccelVal2 = (this->motorMaxSpeed2 -this->motorMinSpeed2) / (Accel2-1);
}
/*
Step method for both motors
*/
void Steppers_Aclr8_2::step(int steps_to_move1, int steps_to_move2)
{
// steps taken
int steps_no1= 1;
int steps_no2= 1;
// Steps for each motor to complete, and the total
// how many steps to take for the motor
int steps_left1 = abs(steps_to_move1);
int steps_left2 = abs(steps_to_move2);
int total_steps_left = steps_left1 + steps_left2;
// determine direction1 based on whether steps_to_mode is + or -:
if (steps_to_move1 > 0) {this->direction1 = 1;}
else
{this->direction1 = 0;}
if (steps_to_move2 > 0) {this->direction2 = 1;}
else
{this->direction2 = 0;}
// reset the motor speed
this->speed1 = this->motorMinSpeed1;
this->speed2 = this->motorMinSpeed2;
// this is the loop for both motor
while(total_steps_left > 0) {
//First motor
//If the motor steps not completed it's steps then
if (steps_left1 > 0) {
//1.a. if in the first third of total steps AND
if ((steps_left1 > abs(steps_to_move1/3)) && \
(steps_left1 > (abs(steps_to_move1/3)*2))) {
// 1.b if not yet at max speed1
if (this->speed1 < this->motorMaxSpeed1){
// get the new speed1
this->speed1 = ((steps_no1 -1) * this->motorAccelVal1) + this->motorMinSpeed1;
// get the new delay
step_delay1 = (this->delay_1revpermin1 / this->speed1);
} // i.b. end if: not yet max speed1
} //1.a. end if: first third of total steps
//2. if in middle third of steps do nothing
//3.a. if in the last third of total steps AND
if (steps_left1 <= (abs(steps_to_move1)/3)) {
//3.b. if within deceleration zone
if (steps_left1 <= this->motorAccSteps1) {
// get the new speed1
this->speed1 = ((steps_left1-1) * this->motorAccelVal1) + this->motorMinSpeed1;
// get the new delay
step_delay1 = (this->delay_1revpermin1 / this->speed1);
} //end if: within deceleration zone
} //3.a. end if: last third of total steps
// move only if the appropriate delay has passed:
if (millis() - this->last_step_time1 >= this->step_delay1) {
// get the timeStamp of when you stepped:
this->last_step_time1 = millis();
// increment or decrement the step number,
// depending on direction1:
if (this->direction1 == 1) {
this->step_number1++;
if (this->step_number1 == this->number_of_steps1) {
this->step_number1 = 0;
}
}
else
{
if (this->step_number1 == 0) {
this->step_number1 = this->number_of_steps1;
}
this->step_number1--;
}
// in/decrement the steps left:
steps_no1++;
steps_left1--;
total_steps_left--;
// step the motor to step number 0, 1, 2, or 3:
stepMotor1(this->step_number1 % 4);
}
} //End: if (steps_left1 > 0)
//Second motor
//If the motor steps not completed it's steps then
if (steps_left2 > 0) {
//1.a. if in the first third of total steps AND
if ((steps_left2 > abs(steps_to_move2/3)) && \
(steps_left2 > (abs(steps_to_move2/3)*2))) {
// 1.b if not yet at max speed1
if (this->speed2 < this->motorMaxSpeed2){
// get the new speed1
this->speed2 = ((steps_no2 -1) * this->motorAccelVal2) + this->motorMinSpeed2;
// get the new delay
step_delay2 = (this->delay_1revpermin2 / this->speed2);
} // i.b. end if: not yet max speed1
} //1.a. end if: first third of total steps
//2. if in middle third of steps do nothing
//3.a. if in the last third of total steps AND
if (steps_left2 <= (abs(steps_to_move2)/3)) {
//3.b. if within deceleration zone
if (steps_left2 <= this->motorAccSteps2) {
// get the new speed1
this->speed2 = ((steps_left2-1) * this->motorAccelVal2) + this->motorMinSpeed2;
// get the new delay
step_delay2 = (this->delay_1revpermin2 / this->speed2);
} //end if: within deceleration zone
} //3.a. end if: last third of total steps
// move only if the appropriate delay has passed:
if (millis() - this->last_step_time2 >= this->step_delay2) {
// get the timeStamp of when you stepped:
this->last_step_time2 = millis();
// increment or decrement the step number,
// depending on direction1:
if (this->direction2 == 1) {
this->step_number2++;
if (this->step_number2 == this->number_of_steps2) {
this->step_number2 = 0;
}
}
else
{
if (this->step_number2 == 0) {
this->step_number2 = this->number_of_steps2;
}
this->step_number2--;
}
// in/decrement the steps left:
steps_no2++;
steps_left2--;
total_steps_left--;
// step the motor to step number 0, 1, 2, or 3:
stepMotor2(this->step_number2 % 4);
}
} //End: if (steps_left1 > 0)
} //End: WHILE statement
} //End: void step()
/* First motor
* Moves the motor forward or backwards
*/
void Steppers_Aclr8_2::stepMotor1(int thisStep1)
{
switch (thisStep1) {
case 0: // 1010
digitalWrite(motor1_pin_1, HIGH);
digitalWrite(motor1_pin_2, LOW);
digitalWrite(motor1_pin_3, HIGH);
digitalWrite(motor1_pin_4, LOW);
break;
case 1: // 0110
digitalWrite(motor1_pin_1, LOW);
digitalWrite(motor1_pin_2, HIGH);
digitalWrite(motor1_pin_3, HIGH);
digitalWrite(motor1_pin_4, LOW);
break;
case 2: //0101
digitalWrite(motor1_pin_1, LOW);
digitalWrite(motor1_pin_2, HIGH);
digitalWrite(motor1_pin_3, LOW);
digitalWrite(motor1_pin_4, HIGH);
break;
case 3: //1001
digitalWrite(motor1_pin_1, HIGH);
digitalWrite(motor1_pin_2, LOW);
digitalWrite(motor1_pin_3, LOW);
digitalWrite(motor1_pin_4, HIGH);
break;
}
}
/* Second motor
* Moves the motor forward or backwards
*/
void Steppers_Aclr8_2::stepMotor2(int thisStep2)
{
switch (thisStep2) {
case 0: // 1010
digitalWrite(motor2_pin_1, HIGH);
digitalWrite(motor2_pin_2, LOW);
digitalWrite(motor2_pin_3, HIGH);
digitalWrite(motor2_pin_4, LOW);
break;
case 1: // 0110
digitalWrite(motor2_pin_1, LOW);
digitalWrite(motor2_pin_2, HIGH);
digitalWrite(motor2_pin_3, HIGH);
digitalWrite(motor2_pin_4, LOW);
break;
case 2: //0101
digitalWrite(motor2_pin_1, LOW);
digitalWrite(motor2_pin_2, HIGH);
digitalWrite(motor2_pin_3, LOW);
digitalWrite(motor2_pin_4, HIGH);
break;
case 3: //1001
digitalWrite(motor2_pin_1, HIGH);
digitalWrite(motor2_pin_2, LOW);
digitalWrite(motor2_pin_3, LOW);
digitalWrite(motor2_pin_4, HIGH);
break;
}
}
/*
version() returns the version of the library:
*/
int Steppers_Aclr8_2::version(void)
{
return 1;
}
The full library can be downloaded here.
Ben









post a comment...
you must be logged in to post a comment.