Hi to all,
I'm using Motor Shield v2.0 by Seeedstudio with my Arduino UNO R3 since I want to control a stepper motor with a rotary encoder.
I'm able to read values from my rotary encoder and I'm also able to control the stepper motor without problems.
What I want to do is to move the stepper motor within a range between 0 to +90 degrees by moving the rotary encoder.
For example, if I move the encoder +4 then the motor should move clockwise +4 and then stops.
At this point, if I move the encoder -4 then the motor should return to its previous position and then stops.
What happens now is that when I move the encoder +4, the motor move forward clockwise but it does not stop and continue to go forward +4 and so on.
What I have to do in order to stop the motor after each command?
I tried to use a temp var (preValue) and to check if the last value from encoder is equals to the current value, but it seems to not work properly.
This is the code I'm using at the moment.
Thank you!
// Demo function:The application method to drive the stepper motor.
// Hareware:Stepper motor - 24BYJ48,Seeed's Motor Shield v2.0
// Author:Frankie.Chu
// Date:20 November, 2012
#define MOTOR_CLOCKWISE 0
#define MOTOR_ANTICLOCKWISE 1
/******Pins definitions*************/
#define MOTORSHIELD_IN1 8
#define MOTORSHIELD_IN2 11
#define MOTORSHIELD_IN3 12
#define MOTORSHIELD_IN4 13
#define CTRLPIN_A 9
#define CTRLPIN_B 10
//these pins can not be changed 2/3 are special pins
int encoderPin1 = 2;
int encoderPin2 = 3;
int preValue = 0;
volatile int lastEncoded = 0;
volatile long encoderValue = 0;
long lastencoderValue = 0;
int lastMSB = 0;
int lastLSB = 0;
const unsigned char stepper_ctrl[]={0x27,0x36,0x1e,0x0f};
struct MotorStruct
{
int8_t speed;
uint8_t direction;
};
MotorStruct stepperMotor;
unsigned int number_of_steps = 200;
/**********************************************************************/
/*Function: Get the stepper motor rotate */
/*Parameter:-int steps,the total steps and the direction the motor rotates.*/
/* if steps > 0,rotates anticlockwise, */
/* if steps < 0,rotates clockwise. */
/*Return: void */
void step(int steps)
{
int steps_left = abs(steps)*4;
int step_number;
int millis_delay = 60L * 1000L /number_of_steps/(stepperMotor.speed + 50);
if (steps > 0)
{
stepperMotor.direction= MOTOR_ANTICLOCKWISE;
step_number = 0;
}
else if (steps < 0)
{
stepperMotor.direction= MOTOR_CLOCKWISE;
step_number = number_of_steps;
}
else return;
while(steps_left > 0)
{
PORTB = stepper_ctrl[step_number%4];
delay(millis_delay);
if(stepperMotor.direction== MOTOR_ANTICLOCKWISE)
{
step_number++;
if (step_number == number_of_steps)
step_number = 0;
}
else
{
step_number--;
if (step_number == 0)
step_number = number_of_steps;
}
steps_left --;
}
}
void initialize()
{
pinMode(MOTORSHIELD_IN1,OUTPUT);
pinMode(MOTORSHIELD_IN2,OUTPUT);
pinMode(MOTORSHIELD_IN3,OUTPUT);
pinMode(MOTORSHIELD_IN4,OUTPUT);
pinMode(CTRLPIN_A,OUTPUT);
pinMode(CTRLPIN_B,OUTPUT);
stop();
stepperMotor.speed = 25;
stepperMotor.direction = MOTOR_CLOCKWISE;
}
/*******************************************/
void stop()
{
/*Unenble the pin, to stop the motor. */
digitalWrite(CTRLPIN_A,LOW);
digitalWrite(CTRLPIN_B,LOW);
}
void setup()
{
initialize();//Initialization for the stepper motor.
Serial.begin (9600);
// pinMode(7, INPUT);
pinMode(encoderPin1, INPUT);
pinMode(encoderPin2, INPUT);
digitalWrite(encoderPin1, HIGH); //turn pullup resistor on
digitalWrite(encoderPin2, HIGH); //turn pullup resistor on
//call updateEncoder() when any high/low changed seen
//on interrupt 0 (pin 2), or interrupt 1 (pin 3)
attachInterrupt(0, updateEncoder, CHANGE);
attachInterrupt(1, updateEncoder, CHANGE);
}
void loop()
{
if (encoderValue >= 15) encoderValue = 15;
if (encoderValue <= -15) encoderValue = -15;
if (preValue == encoderValue)
{
stop();
}
else {
Serial.print("encoderValue: ");
Serial.print(encoderValue);
Serial.print(" preValue: ");
Serial.println(preValue);
step(encoderValue);//Stepper motors rotate anticlockwise 200 steps.
delay(1000);
step(encoderValue);//Stepper motors rotate clockwise 200 steps.
delay(1000);
preValue = encoderValue;
}
}
void updateEncoder(){
int MSB = digitalRead(encoderPin1); //MSB = most significant bit
int LSB = digitalRead(encoderPin2); //LSB = least significant bit
int encoded = (MSB << 1) |LSB; //converting the 2 pin value to single number
int sum = (lastEncoded << 2) | encoded; //adding it to the previous encoded value
if(sum == 0b1101 || sum == 0b0100 || sum == 0b0010 || sum == 0b1011) encoderValue ++;
if(sum == 0b1110 || sum == 0b0111 || sum == 0b0001 || sum == 0b1000) encoderValue --;
lastEncoded = encoded; //store this value for next time
}