# Stepper Motor and Encoder Help!

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);
}
``````

jschofield:
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..

Haven't you got the answer right there - don't use floating point maths for values that are never anything but unsigned integers or unsigned longs.

The basic problem seems to be that the steps in your encoder are not a simple multiple of the steps in the motor. You will have to decide which takes priority - the position decided by the encoder or the position decided by counting motor steps - I think they will only repeat their synchronicity every 200 * 1024 steps (or maybe it is 100 * 512) . Either way you need to devise maths that gives an integer answer.

...R

Fixed point arithmetic is the way to go - then you have some fraction part to limit the
rounding errors. Perhaps something like 12.4 or 24.8 fixed point would be appropriate here.

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.

Have you actually printed any values? The results of the calculations are stored in long and int variables, so there is no way that 2511.0351 steps are ever needed.