Help need with speed adjust

Hello, obviously im a newbie so go easy on me :slight_smile: but Is there a way to adjust the steps taken by the stepper when the bourn encoder is rotated?

long story short im wanting the stepper shaft to move at the same speed / rotation as the bourn encoder,
as in the tutorial the motor does move 1 step per encoder step, but the shaft of the stepper rotates less than the encoder,

im basically wanting to attach the encoder shaft via a coupling connector to another shaft controlled by a dc motor, i want the stepper motor to go at the same rotation as the shaft thats connected to the bourn encoder… reason being i don’t want to touch any of the original electronics and basically piggy back them but instead of using the dc motor to drive, will use the stepper motor

hope that makes sense

/* Control Stepper Motor with 'Bourns EAW' encoder
 
Created by Yvan / https://Brainy-Bits.com

This code is in the public domain...

You can: copy it, use it, modify it, share it or just plain ignore it!
Thx!
*/


#include <LiquidCrystal_I2C.h>  // I2C LCD Library by Francisco Malpartida https://bitbucket.org/fmalpartida/new-liquidcrystal/wiki/Home
#include <AccelStepper.h>  // AccelStepper Library https://www.arduinolibraries.info/libraries/accel-stepper


#define I2C_ADDR 0x27  // I2C address of typical I2C LCD Backpack

// LCD Pins to I2C LCD Backpack - These are default for HD44780 LCD's
#define Rs_pin 0
#define Rw_pin 1
#define En_pin 2
#define BACKLIGHT_PIN 3
#define D4_pin 4
#define D5_pin 5
#define D6_pin 6
#define D7_pin 7

// Create instance for LCD called: i2c_lcd
LiquidCrystal_I2C i2c_lcd(I2C_ADDR,En_pin,Rw_pin,Rs_pin,D4_pin,D5_pin,D6_pin,D7_pin);


const int pinSTEP=11;  // STEP pin of EasyDriver connected to pin 11 of UNO
const int pinDIR=10;  // DIR  pin of EasyDriver connected to pin 10 of UNO

AccelStepper stepper(1, pinSTEP, pinDIR);  // Stepper setup

// Include the Bourns EAW Encoder library and maps
#include <ACE128.h>  // https://github.com/arielnh56/ACE128

#include <ACE128map12345678.h> // mapping for pin order 12345678

// Pin x of UNO connected to pin x of Encoder (example: UNO pin 2 connected to pin 1 of encoder, etc...)
ACE128 myACE(2,3,4,5,6,7,8,9, (uint8_t*)encoderMap_12345678);


int16_t multiturn_encoder_value;  // Variable to hold multiturn value of encoder (-32768 to 32767)


void setup() {
  i2c_lcd.begin (16,2); //  our LCD is a 16x2, change for your LCD if needed
  
  // LCD Backlight ON
  i2c_lcd.setBacklightPin(BACKLIGHT_PIN,POSITIVE);
  i2c_lcd.setBacklight(HIGH);
  
  i2c_lcd.clear(); // Clear the LCD screen

  stepper.setCurrentPosition(0);  // Set current position of stepper at startup to zero
  stepper.setMaxSpeed(1000.0);      // Set Max Speed of stepper
  stepper.setAcceleration(5000.0);  // Acceleration of stepper
  stepper.setSpeed(1000.0);  // Speed of stepper

  myACE.begin();    // initialize the encoder library
}


void loop() {

  multiturn_encoder_value = myACE.mpos();  // get multiturn value from encoder
  stepper.moveTo(multiturn_encoder_value); // set stepper new position to move to
    
  while (stepper.distanceToGo() != 0) {  // if stepper hasn't reached new position
    stepper.runSpeedToPosition();  // move the stepper until new position reached
  }

// Display the encoder multiturn and stepper position on LCD
  i2c_lcd.setCursor(0,0);
  i2c_lcd.print("Encoder: ");
  i2c_lcd.setCursor(9,0);
  i2c_lcd.print(multiturn_encoder_value);
  i2c_lcd.print("      ");
  i2c_lcd.setCursor(0,1);
  i2c_lcd.print("Stepper: ");
  i2c_lcd.setCursor(9,1);
  i2c_lcd.print(stepper.currentPosition()); 
  i2c_lcd.print("      ");  
}

the motor does move 1 step per encoder step, but the shaft of the stepper rotates less than the encoder,

How many steps would the motor need to move to match say 90 degrees of the encoder

Both encoder and stepper reset

90 degree on the encoder = to 32 on the screen for the encoder and stepper

but to get the stepper to 90 degree it has to take 200 steps to 32 of the encoder

200 / 32 is 6.25 so you need the stepper to move 6.25 steps for each step of the encoder. You could use floating point:

  multiturn_encoder_value = myACE.mpos();  // get multiturn value from encoder
  long int newPosition = (multiturn_encoder_value * 6.25)+0.5;
  stepper.moveTo(newPosition); // set stepper new position to move to

I change this

void loop() {

  multiturn_encoder_value = myACE.mpos();  // get multiturn value from encoder
  stepper.moveTo(multiturn_encoder_value); // set stepper new position to move to
    
  while (stepper.distanceToGo() != 0) {  // if stepper hasn't reached new position
    stepper.runSpeedToPosition();  // move the stepper until new position reached
  }

to this which seems to do the job

multiturn_encoder_value = myACE.mpos();  // get multiturn value from encoder
  long int newPosition = (multiturn_encoder_value * 6.25)+0.5;
  stepper.moveTo(newPosition); // set stepper new position to move to
    
 while (stepper.distanceToGo() != 0) {  // if stepper hasn't reached new position
  stepper.runSpeedToPosition();  // move the stepper until new position reached
  }

But theres a big delay in speed for the stepper to catch up, can i make it so the stepper moves instantly with the encoder ? also without missing steps

it matches when going slow, but when you increase the rotation speed theres a lot of lag/delay with the stepper

Thanks John for helping out

you have to set the speed of the motor to a certain max the motr can still handle without loosing steps.and put accelaration same the motor does still speed up without loosing steps.
It is a electrical / mechanical problem for controlling this.

Wrong approach. You’re using blocking functions. So you can’t count encoder steps that occur while the stepper is moving.

AccelStepper may also be part of the problem. When you give it somewhere to go, it starts from standstill, accelerates, runs, and then slows down to stop at the target. But your encoder is likely still moving. Taking 6 or 7 steps with AccelStepper is probably not the right way to do it.

Start with only allowing the stepper to step at a constant, slow, speed. Like 100 steps per second. Every 10 miliseconds, it’s allowed to take a step forwards or backwards or no step at all.

Use the encoder to set a target. Each click should add or subtract 6.25 to the target.

Every 10ms, see how far away the target is from the current stepper position. Take a step towards the target if necessary.

For more advanced usage, consider the distance to the target sets the speed. If the knob has turned a long way, you want to run the stepper faster to get there. That will automatically slow down as it reaches the target, so you will get smooth stops.

How many counts for 1 complete turn of encoder? Is your motor driver set for microstepping? If so, what level (1/2, 1/4, 1/8...)?

JCA34F:
How many counts for 1 complete turn of encoder? Is your motor driver set for microstepping? If so, what level (1/2, 1/4, 1/8...)?

It's exactly as described in the tutorial https://www.brainy-bits.com/arduino-bourns-eaw-encoder/

I don't want the acceleration / deceleration I just want it to mirror the encoder

Hi,
Can you post links to specs/data of your stepper and encoder please?

Can you please post a copy of your circuit, in CAD or a picture of a hand drawn circuit in jpg, png?

Thanks... Tom... :slight_smile:

I would suggest just taking out the 'while' loop around the stepper.runSpeedToPosition(). The 'while' loop is keeping you from getting new encoder input until the stepper has reached the previous destination.

void loop()
{
  multiturn_encoder_value = myACE.mpos();  // get multiturn value from encoder
  long int newPosition = (multiturn_encoder_value * 6.25)+0.5;
  stepper.moveTo(newPosition); // set stepper new position to move to
   
  stepper.runSpeedToPosition();  // move the stepper until new position reached
}

You could also adjust these parameters to see how fast you can push the stepper:

  stepper.setMaxSpeed(1000.0);      // Set Max Speed of stepper
  stepper.setAcceleration(5000.0);  // Acceleration of stepper
  stepper.setSpeed(1000.0);  // Speed of stepper

johnwasser:
I would suggest just taking out the 'while' loop around the stepper.runSpeedToPosition(). The 'while' loop is keeping you from getting new encoder input until the stepper has reached the previous destination.

void loop()

{
  multiturn_encoder_value = myACE.mpos();  // get multiturn value from encoder
  long int newPosition = (multiturn_encoder_value * 6.25)+0.5;
  stepper.moveTo(newPosition); // set stepper new position to move to
 
  stepper.runSpeedToPosition();  // move the stepper until new position reached
}




You could also adjust these parameters to see how fast you can push the stepper:


stepper.setMaxSpeed(1000.0);      // Set Max Speed of stepper
  stepper.setAcceleration(5000.0);  // Acceleration of stepper
  stepper.setSpeed(1000.0);  // Speed of stepper

Thanks, John, I'll give it a go