keypad: controlling two stepper motors

The next part of the puzzle is to get the keypad to control the two stepper motors.

The keypad needs to respond (as the layout suggests) as follows:
1 = up and left
2 = up
3 = up and right
4 = left
5 = nothing
6 = right
7 = down and left
8 = down
9 = down and right

I want all this wrapped up in a library so that these functions can be called easily from the main sketch.

The result looks like this.

The Sketch

/*
 * Matrix_Steppers library for capeMirror
 * created by Ben @ cape ealing
 * 4 January 2010
 * 
 * This allows the control of two stepper motors using
 * a matrix keypad.  '1' on the keypad = move 'up and 'left' etc.
 * 
 * The speed is the same for both motors and is set as part of the 
 * set-up process.
 */

// include the library and initialise the class
#include 
Matrix_Steppers myKeypadSteppers = Matrix_Steppers();

// define a variable to hold the keypad read result
int result;

void setup()
{
  // Define the keypad
  myKeypadSteppers.setCols(12, 13, 14);
  myKeypadSteppers.setRows(17, 18, 19);

  // Define the two stepper motors
  myKeypadSteppers.setStepper1(200, 4, 6, 5, 7);
  myKeypadSteppers.setStepper2(200, 8, 10, 9, 11);
  myKeypadSteppers.setMoveSpeeds(10); 
}

void loop()
{
  // read the keypad
  result = myKeypadSteppers.read();
  // move as appropriate
  myKeypadSteppers.moveSteps(result);
}

The

Matrix_Steppers CPP file

/*
  Matrix_Steppers.cpp - Keypad library for capeMirror
  - Version 1.0
 */

#include "WProgram.h"
#include "Matrix_Steppers.h"
/*
 *   Constructor for four-pin stepper motor
 *   Sets which wires should control the motor and
 *   primary variables used by motor.
 */


/*
 *   Initialise the class
 */
Matrix_Steppers::Matrix_Steppers()
{
}


/*
 *   Define the columns
 */
void Matrix_Steppers::setCols(int col1, int col2, int col3)
{
  this->col1 = col1;
  this->col2 = col2;
  this->col3 = col3;

  // set them as outputs
  pinMode(this->col1, OUTPUT);
  pinMode(this->col2, OUTPUT);
  pinMode(this->col3, OUTPUT);
}

/*
 *   Define the rows
 */
void Matrix_Steppers::setRows(int row1, int row2, int row3)
{
  this->row1 = row1;
  this->row2 = row2;
  this->row3 = row3;
}

/*
 *   Define the first motor
 */

void Matrix_Steppers::setStepper1(int number_of_steps1, \
						   int motor1_pin_1, int motor1_pin_2, \
						   int motor1_pin_3, int motor1_pin_4)
{
  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;

  pinMode(this->motor1_pin_1, OUTPUT);
  pinMode(this->motor1_pin_2, OUTPUT);
  pinMode(this->motor1_pin_3, OUTPUT);
  pinMode(this->motor1_pin_4, OUTPUT);

  this->step_number1 = 0;      // which step the motor is on
  this->direction1 = 0;      // motor direction
  this->number_of_steps1 = number_of_steps1;    // total number of steps for this motor
}

/*
 *   Define the second motor
 */

void Matrix_Steppers::setStepper2(int number_of_steps2, \
						   int motor2_pin_1, int motor2_pin_2, \
						   int motor2_pin_3, int motor2_pin_4)
{
  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;

  pinMode(this->motor2_pin_1, OUTPUT);
  pinMode(this->motor2_pin_2, OUTPUT);
  pinMode(this->motor2_pin_3, OUTPUT);
  pinMode(this->motor2_pin_4, OUTPUT);

  this->step_number2 = 0;      // which step the motor is on
  this->direction2 = 0;      // motor direction
  this->number_of_steps2 = number_of_steps2;    // total number of steps for this motor
}

/*
 *   Define the motor speed
 */
void Matrix_Steppers::setMoveSpeeds(long moveSpeed)
{
  this->step_delay1 = 60L * 1000L / this->number_of_steps1 / moveSpeed;
  this->step_delay2 = 60L * 1000L / this->number_of_steps2 / moveSpeed;
}

/*
 *   Read the keypad
 */

int Matrix_Steppers::read(void)
{
  theResult = 0;
  
  // Read the 1st column
  digitalWrite(col1, HIGH);  
  if (digitalRead(row1) == HIGH){theResult = 1;}
  if (digitalRead(row2) == HIGH){theResult = 4;}
  if (digitalRead(row3) == HIGH){theResult = 7;}
  digitalWrite(col1, LOW);  
  if (theResult>0){return theResult;}

  // Read the 2nd column 
  digitalWrite(col2, HIGH);  
  if (digitalRead(row1) == HIGH){theResult = 2;}
  if (digitalRead(row2) == HIGH){theResult = 5;}
  if (digitalRead(row3) == HIGH){theResult = 8;}
  digitalWrite(col2, LOW);  
  if (theResult>0){return theResult;}

  // Read the 3rd column 
  digitalWrite(col3, HIGH);  
  if (digitalRead(row1) == HIGH){theResult = 3;}
  if (digitalRead(row2) == HIGH){theResult = 6;}
  if (digitalRead(row3) == HIGH){theResult = 9;}
  digitalWrite(col3, LOW);
  return theResult;
}

/*
 *   Move the number of steps required by the keypad
 */
	
void Matrix_Steppers::moveSteps(int keyResult)
{
     switch (keyResult) {
      case 0:
      break;
      case 1: // up and left
	  takeSteps(1,1);
      break;
      case 2: // up 
	  takeSteps(0, 1);
      break;
      case 3: // up and right
	  takeSteps(-1, 1);
      break;
      case 4: // left
	  takeSteps(1, 0);
      break;
      case 5: 
		  // do nothing
      break;
      case 6: // right
	  takeSteps(-1, 0);
      break;      
      case 7: // left and down
	  takeSteps(1, -1);
      break;      
      case 8: // down
	  takeSteps(0, -1);
      break;      
      case 9: // right and down
	  takeSteps(-1, -1);
      break;      
    }
}


void Matrix_Steppers::takeSteps(int moveSteps1, int moveSteps2)
{
  int steps_left1 = abs(moveSteps1);
  int steps_left2 = abs(moveSteps2);

  int total_steps_left = steps_left1 + steps_left2;  // total steps to take
  
  // determine direction based on whether steps_to_mode is + or -:
  if (moveSteps1 > 0) {this->direction1 = 1;}
  if (moveSteps1 < 0) {this->direction1 = 0;}
  if (moveSteps2 > 0) {this->direction2 = 1;}
  if (moveSteps2 < 0) {this->direction2 = 0;}

  // this is the loop for both motor
  while(total_steps_left > 0) {

  // FIRST MOTOR
  // move only if the appropriate delay has passed:
  if (steps_left1 > 0) {

	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 direction:
      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--;
      }
      // decrement the steps left:
      steps_left1--;
  	  total_steps_left--;
	  // step the motor to step number 0, 1, 2, or 3:
      stepMotor1(this->step_number1 % 4);
    }
  } // end first motor steps

  // SECOND MOTOR
  // move only if the appropriate delay has passed:
  if (steps_left2 > 0) {

	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 direction:
      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--;
      }
      // decrement the steps left:
      steps_left2--;
  	  total_steps_left--;
	  // step the motor to step number 0, 1, 2, or 3:
      stepMotor2(this->step_number2 % 4);
    }
  } // end first motor steps

  } // end: while


}

void Matrix_Steppers::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;
    } 
}

void Matrix_Steppers::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 Matrix_Steppers::version(void)
{
  return 1;
}

The Header File

/*
  Matrix_Steppers.h - Keypad library for capeMirror
  - Version 1.0
 */

// ensure this library description is only included once
#ifndef Matrix_Stepper_h
#define Matrix_Stepper_h

// library interface description
class Matrix_Steppers {
  public:

	// Initialise the class
	Matrix_Steppers();

	// define the columns
    void setCols(int col1, int col2, int col3);

	// define the rows
    void setRows(int row1, int row2, int row3);

	// define the two stepper motors
	void setStepper1(int number_of_steps1, int motor1_pin_1, \
		int motor1_pin_2, int motor1_pin_3, int motor1_pin_4);
	void setStepper2(int number_of_steps2, int motor2_pin_1, \
		int motor2_pin_2, int motor2_pin_3, int motor2_pin_4);

	// define the speeds for both motors
	void setMoveSpeeds(long moveSpeed);

	// take the steps passed from the keypad
	void moveSteps(int keyResult);

	// read the keypad
	int read(void);

	// return the version if asked
	int version(void);

  private:
	// move the steps desired per key press for both motors
    void takeSteps(int moveSteps1, int moveSteps2);

	// move the stepper motors
	void stepMotor1(int this_step1);
	void stepMotor2(int this_step2);

	// the keypad rows and columns
	int col1;
	int col2;
	int col3;
	int row1;
	int row2;
	int row3;

	// the result of reading the keypad
	int theResult;  

    // motor 1 
    int motor1_pin_1;
    int motor1_pin_2;
    int motor1_pin_3;
	int motor1_pin_4;
    int number_of_steps1;
    int step_number1;
    unsigned long step_delay1;
    int direction1;        
	int moveSteps1;
    long last_step_time1;

    // motor 2
	int motor2_pin_1;
    int motor2_pin_2;
	int motor2_pin_3;
    int motor2_pin_4;
    int number_of_steps2;
    int step_number2;
    unsigned long step_delay2;
    int direction2;        
	int moveSteps2;
    long last_step_time2;

	// both motors together
    int moveSpeed;          
	int total_steps_left; 
};
#endif

The keywords

#######################################
# Syntax Coloring Map For Test
#######################################

#######################################
# Datatypes (KEYWORD1)
#######################################

Matrix_Steppers	KEYWORD1


#######################################
# Methods and Functions (KEYWORD2)
#######################################

setCols	KEYWORD2
setRows	KEYWORD2
keyResult	KEYWORD2
setStepper1	KEYWORD2
setStepper2	KEYWORD2
setMoveSpeeds	KEYWORD2
moveSteps	KEYWORD2
version	KEYWORD2


######################################
# Instances (KEYWORD2)
#######################################

myKeypadSteppers	KEYWORD2

#######################################
# Constants (LITERAL1)
#######################################

Download all the files here.

Ben

post a comment...

you must be logged in to post a comment.