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.