Hello to all.
I'm using an Arduino Uno to control a stepper motor with encoder feed back for my project.
the encoder is an Incremental Quadrature encoder (1024 P/R) with a 12V 200 step per rotation motor.
for the most part everything works. I can turn the motor and read the counts from the encoder fine.
however when I start using the encoder in feedback loop with the motor, the motor will try to move to the desired encoder position. when it gets to the end it will sit there and "jitter" back and forth on the final step.
my math even says that this jittering should happen, since I am using floating points, so when my program calls for a stepper move it will be for example 10.23 steps. witch the stepper cant do. I have tried not using floating points but I haven't been able to get it to work without it. I think I'm missing something small and stupid.
using AccelStepper
Math used.
(goto_position/encoder_pr)*motor_pr
goto_position is the desired encoder position.
encoder_pr is 4096
motor_pr is 200.
example:
(8192/4096)*200=400 steps
in this example the motor will move the 400 steps and stop just fine, as it is an integer
example 2:
(51426/4096)*200=2511.0351 steps.
this example the motor program will attempt to move 2511.03 steps. when it gets to 2511 it moves to 2512 and knows its gone to far and comes back to 2511. and repeats..
/* All motor movement will be baised off the encoder value.
1024 p/r encoder@4x will be 4096 p/r
encoder math:
Encoder pules per Motor Step;
4096 pules / 200 steps per rotation = 20.48 pules/step.
*/
#define ENCODER_USE_INTERRUPTS
#define ENCODER_OPTIMIZE_INTERRUPTS
#define encoder_pr 4096
#define motor_pr 200
#include <Encoder.h>
#include <AccelStepper.h>
#include <AFMotor.h>
Encoder motorEnc(2,3);
AF_Stepper motor2(200, 2);
AccelStepper motor(forwardstep2, backwardstep2);
long motorPosition;
long oldPosition = -999;
int debug = 1; // Serial Debug mode. 1 = debug ,2 = MORE Debug
int lowlimit = -65536;
int highlimit = 65536;
int buttonstate;
int lastbuttonstate;
const int mem1_pin = 14;
// wrappers for the second motor!
void forwardstep2() {
motor2.onestep(FORWARD, SINGLE);
}
void backwardstep2() {
motor2.onestep(BACKWARD, SINGLE);
}
long read_encoder(void){
motorPosition = motorEnc.read();
if(oldPosition < motorPosition){
oldPosition = motorPosition;
if (debug == 2){
Serial.println("Motor is moving Forward.");
}
}
if(oldPosition > motorPosition){
oldPosition = motorPosition;
if (debug == 2){
Serial.println("Motor is moving Backwards");
}
}
return motorPosition;
}
void focus(long goto_position){
// This function will move the Stepper motor and Modify the CurrentPosition baised on the Encoder Position.
// so if the encoder has moved 1404 pulses, this will be (1404/4096(Encoder PPR))*200(Motor SPR)=68.55 Steps on the Motor.
// Encoder to Steper Ration: Encoder PPR/Motor SPR = 20.48:1
long CurrentEncoderPosition;
int _StepsNeeded;
CurrentEncoderPosition = read_encoder();
if (CurrentEncoderPosition != goto_position)
{
// Serial.println("Motor Not in Position");
Serial.println(CurrentEncoderPosition);
_StepsNeeded = ((float)goto_position/(float)encoder_pr)*(float)motor_pr;
motor.setMaxSpeed(600.0);
motor.setAcceleration(100.0);
motor.moveTo(_StepsNeeded);
Serial.println(CurrentEncoderPosition);
CurrentEncoderPosition = ((float)CurrentEncoderPosition/(float)4096)*(float)200; // Convert Encoders Position into Current Steps Moved
motor.setCurrentPosition(CurrentEncoderPosition); // Set current Position baised on encoder Position.
motor.run();
}
else {
// Serial.println("Motor is in position");
//Serial.println(CurrentEncoderPosition);
}
}
void setup(){
Serial.begin(115200);
motor.setCurrentPosition(0); // Zero Motor value.
motorEnc.write(0); // Zero Encoder value.
}
void loop(){
focus(81192);
}