orbitronics
Well-known member
Hi,
I have a basic setup, at the moment i'm using an arduino nano, connected to two rotary encoders, and an A4988 stepper driver, that connected to a stepper motor.
i am using one encoder to change the RPM, and the second to manually move the stepper.
I'm running into a peculiar problem, where depending on how great 'steps' is in 'Stepper.move(steps)' for when i'm manually moving the stepper motor with an encoder, turning the knob smoothly in one direction outputs two alternating numbers like:
-8
-7
-8
-7
-6
-7
-6
-5
-6
Making 'steps' lower, even '1' outputs a predicted output (continuously counting in the right direction).
My guess is that the encoder, when actuated, is generating interrupts that is messing with the Stepper objects move function. I've tried to disable interrupts using a locking boolean value when i'm moving the stepper, it's not helping much.
Here's the code
Any ideas ?
Oddly enough, the performance of turning the encoder in one direction outputs a more consistent growing number than in the opposite direction, which tends to alternate between two numbers more.
I have a basic setup, at the moment i'm using an arduino nano, connected to two rotary encoders, and an A4988 stepper driver, that connected to a stepper motor.
i am using one encoder to change the RPM, and the second to manually move the stepper.
I'm running into a peculiar problem, where depending on how great 'steps' is in 'Stepper.move(steps)' for when i'm manually moving the stepper motor with an encoder, turning the knob smoothly in one direction outputs two alternating numbers like:
-8
-7
-8
-7
-6
-7
-6
-5
-6
Making 'steps' lower, even '1' outputs a predicted output (continuously counting in the right direction).
My guess is that the encoder, when actuated, is generating interrupts that is messing with the Stepper objects move function. I've tried to disable interrupts using a locking boolean value when i'm moving the stepper, it's not helping much.
Here's the code
Code:
/*
*/
// This optional setting causes Encoder to use more optimized code,
// It must be defined before Encoder.h is included.
#define ENCODER_OPTIMIZE_INTERRUPTS
#include <Encoder.h>
#include "DRV8825.h"
#define DIR 4
#define STEP 5
#define MAX_RPM 25
#define MIN_RPM 1
#define STOPPER_PIN 6
#define MOTOR_STEPS 4096
#define RPM 10
#define MICROSTEPS 1
boolean is_moving_manually = false;
int debug_flip = 1;
long newPosition0, newPosition1 = 10;
long oldPosition0, oldPosition1 = 10;
DRV8825 stepper(MOTOR_STEPS, DIR, STEP);
Encoder myEnc0(7, 2); // using the two interrupt pins on arduino uno / nano
Encoder myEnc1(8, 3);
void setup() {
Serial.begin(115200);
myEnc0.write(10 * 4);
pinMode(STOPPER_PIN, INPUT_PULLUP);
stepper.begin(RPM, MICROSTEPS);
stepper.enable();
Serial.println("START");
stepper.stop();
// stepper.startMove(100 * MOTOR_STEPS * MICROSTEPS); // in microsteps
// stepper.startRotate(100 * 360); // or in degrees
}
void loop() {
// first, check if stopper was hit
if (digitalRead(STOPPER_PIN) == LOW) {
Serial.println("STOPPER REACHED");
stepper.stop();
stepper.disable();
}
// motor control loop - send pulse and return how long to wait until next pulse
unsigned wait_time_micros = stepper.nextAction();
/**
position
*/
// noInterrupts();
if (is_moving_manually)
noInterrupts();
else
interrupts();
newPosition1 = myEnc1.read() / 4; // YUTAKA, this encoder u got is shit, it does 4 increments at a time so i div by 4
// interrupts();
if (newPosition1 != oldPosition1) {
is_moving_manually = true;
stepper.move((newPosition1 - oldPosition1) * 100); // * 40
is_moving_manually = false;
oldPosition1 = newPosition1;
Serial.println(newPosition1);
}
setRPM_Ben();
// 0 wait time indicates the motor has stopped
if (wait_time_micros <= 0) {
//
// Serial.println("wait_time_micros <= 0");
// debug_flip = debug_flip * -1;
// stepper.startMove(debug_flip * MOTOR_STEPS);
// delay(1000);
}
// (optional) execute other code if we have enough time
if (wait_time_micros > 100) {
// other code here
// Serial.println("wait_time_micros > 100");
setRPM_Ben();
}
}
void setRPM_Ben() {
/**
RPM
*/
long newPosition0 = myEnc0.read() / 4;
if (newPosition0 != oldPosition0) {
if (newPosition0 < MIN_RPM) {
myEnc0.write(MIN_RPM * 4);
newPosition0 = MIN_RPM;
}
if (newPosition0 > MAX_RPM) {
myEnc0.write(MAX_RPM * 4);
newPosition0 = MAX_RPM;
}
oldPosition0 = newPosition0;
Serial.print("RPM re-set to: ");
Serial.print(newPosition0);
stepper.setRPM(newPosition0);
Serial.print(", stepper RPM: "); Serial.println(stepper.getRPM());
}
}
Any ideas ?
Oddly enough, the performance of turning the encoder in one direction outputs a more consistent growing number than in the opposite direction, which tends to alternate between two numbers more.