Power feed with stepper motor

Works really good, I’m also able to use the MPG at the same time,

The code below is modified with dual “different” encoders, edit this code from now on👌
also added 3 more buttons, now its just a potentiometer to control the speed

// Lathe003
// Change float encoder counts to long
// Add joystick test with 4 buttons
// Added support for 2 Diffrent Encoders 100p/r and 400p/r (steps_per_pulse_z)

#include <AccelStepper.h>

#define encoder_pin_Ay 2
#define encoder_pin_By 3
#define encoder_pin_Az 4
#define encoder_pin_Bz 5

// Define  input button pins
const int  LEFT_PIN = 44; // Input Pin location on the Arduino, Left Button   Yellow Wire
const int  RIGHT_PIN = 46;// Input Pin location on the Arduino, Right Button  Pink Wire
const int  UP_PIN = 48; // Input Pin location on the Arduino, Left Button   Yellow Wire
const int  DOWN_PIN = 50;// Input Pin location on the Arduino, Right Button  Pink Wire
const int  ENA_PIN = 52;// ENABLE PIN

int encoder_pin_Ay_last = LOW;
int encoder_pin_Az_last = LOW;
long encoder_pos_y = 0;
long encoder_pos_z = 0;
int ny = LOW;
int nz = LOW;
/////////////////////////////////////////////////////////////////////
const int buttonPin = 4;     // the number of the pushbutton pin
int buttonState;             // the current reading from the input pin
int lastButtonState = LOW;   // the previous reading from the input pin
unsigned long lastDebounceTime = 0;  // the last time the output pin was toggled
unsigned long debounceDelay = 50;    // the debounce time; increase if the output flickers
/////////////////////////////////////////////////////////////////////
#define stepper_pin_step_y 8
#define stepper_pin_dir_y  9
#define step_pin_step_z 10
#define step_pin_dir_z  11

// Stepper Driver p/r x1=200 x2=400 x4=800 x8=1600 x16=3200
// Enc have ? steps per revolution. 100/400 Pulses per rev (p/r)
// The motor have 200 steps per revolution at 1x currently set at 2x=400p/r
// Want: 1 encoder rev = 1 stepper rev on channel Z and Y
// 400 / 100 = 4... 100P/R Encoder
// 400 / 400 = 1... 400P/R Encoder
long steps_per_pulse_y = 1;
long steps_per_pulse_z = 1;

AccelStepper stepper_y(AccelStepper::DRIVER, stepper_pin_step_y, stepper_pin_dir_y);
AccelStepper stepper_z(AccelStepper::DRIVER, step_pin_step_z, step_pin_dir_z);

void setup()
{
  stepper_y.setMaxSpeed(3000.0);
  stepper_y.setAcceleration(4000.0);
  stepper_z.setMaxSpeed(3000.0);
  stepper_z.setAcceleration(4000.0);
  pinMode(encoder_pin_Ay, INPUT_PULLUP);
  pinMode(encoder_pin_By, INPUT_PULLUP);
  pinMode(encoder_pin_Az, INPUT_PULLUP);
  pinMode(encoder_pin_Bz, INPUT_PULLUP);
  pinMode(buttonPin, INPUT);
  pinMode(LEFT_PIN, INPUT_PULLUP);
  pinMode(RIGHT_PIN, INPUT_PULLUP);
  pinMode(UP_PIN,   INPUT_PULLUP);
  pinMode(DOWN_PIN, INPUT_PULLUP);
  pinMode(ENA_PIN,  OUTPUT);
}

void loop()
{
  // read encoder
  ny = digitalRead(encoder_pin_Ay);
  if ((encoder_pin_Ay_last == LOW) && (ny == HIGH))
  {
    if (digitalRead(encoder_pin_By) == LOW)
    {
      encoder_pos_y -= steps_per_pulse_y ;
    }
    else
    {
      encoder_pos_y += steps_per_pulse_y ;
    }
    // set stepper to the new calculated position
    stepper_y.moveTo(encoder_pos_y);
  }
  encoder_pin_Ay_last = ny;
  ////////////////////added///////////////////
  nz = digitalRead(encoder_pin_Az);
  if ((encoder_pin_Az_last == LOW) && (nz == HIGH))
  {
    if (digitalRead(encoder_pin_Bz) == LOW)
    {
      encoder_pos_z -= steps_per_pulse_z ;
    }
    else
    {
      encoder_pos_z += steps_per_pulse_z ;
    }
    // set stepper to the new calculated position
    stepper_z.moveTo(encoder_pos_z);
  }
  //////////////////////////////////////////Y-Axis LEFT Button///////////////////////////////////////////////////////
  encoder_pin_Az_last = nz;
  if (digitalRead(LEFT_PIN) == LOW)
  {
    if (stepper_y.currentPosition() == encoder_pos_y) // Stepper is at commanded position
    {
      encoder_pos_y += steps_per_pulse_y ;
      stepper_y.moveTo(encoder_pos_y);
    }
  }
  //////////////////////////////////////////Y-Axis RIGHT Button//////////////////////////////////////////////
  encoder_pin_Az_last = nz;
  if (digitalRead(RIGHT_PIN) == LOW)
  {
    if (stepper_y.currentPosition() == encoder_pos_y) // Stepper is at commanded position
    {
      encoder_pos_y -= steps_per_pulse_y ;
      stepper_y.moveTo(encoder_pos_y);
    }

  }
  ///////////////////////////////////////////Z-Axis Forward Button//////////////////////////////////////////////////

   encoder_pin_Az_last = nz;
  if (digitalRead(UP_PIN) == LOW)
  {
    if (stepper_z.currentPosition() == encoder_pos_z) // Stepper is at commanded position
    {
      encoder_pos_z += steps_per_pulse_z ;
      stepper_z.moveTo(encoder_pos_z);
    }
  }
  //////////////////////////////////////////////Z-Axis Backward Button//////////////////////////////////////////
  encoder_pin_Az_last = nz;
  if (digitalRead(DOWN_PIN) == LOW)
  {
    if (stepper_z.currentPosition() == encoder_pos_z) // Stepper is at commanded position
    {
      encoder_pos_z -= steps_per_pulse_z ;
      stepper_z.moveTo(encoder_pos_z);
    }

  }
  //////////////////////////////////////////////////////////////////////////////////////////////////////////////
  stepper_z.run();
  stepper_y.run();

  ////////////////////////////////////////////////////////////////////////
  // read the state of the switch into a local variable:
  int reading = digitalRead(buttonPin);
  // check to see if you just pressed the button
  // (i.e. the input went from LOW to HIGH), and you've waited long enough
  // since the last press to ignore any noise:
  // If the switch changed, due to noise or pressing:
  if (reading != lastButtonState)
  {
    // reset the debouncing timer
    lastDebounceTime = millis();
  }
  if ((millis() - lastDebounceTime) > debounceDelay)
  {
    // whatever the reading is at, it's been there for longer than the debounce
    // delay, so take it as the actual current state:
    // if the button state has changed:
    if (reading != buttonState)
    {
      buttonState = reading;
      // only toggle the LED if the new button state is HIGH
      if (buttonState == HIGH)
      {
        steps_per_pulse_y = 4;
        steps_per_pulse_z = 4;
      }
      else
      {
        steps_per_pulse_y = 8;
        steps_per_pulse_z = 2;
      }
    }
  }
  // save the reading. Next time through the loop, it'll be the lastButtonState:
  lastButtonState = reading;
}

Excellent - you should be able to extrapolate the code fragments you need for the other buttons.

Is that good or bad?

The extra 3 buttons are already added, now comes the stage to add a potentiometer,

That’s a good thing I think

The pot is tricky.

Should it affect manual jog and joystick?

One thing you could do is to use it to set the value of steps_per_pulse. Maybe between one and four. The trouble with that is that once the value is greater than one, the axis may have steps still to do when you release the joystick.

The other possibility is to use the pot to set speed. I'm not sure that will work with accelstepper though because every stepper move is a single step so the motor won't actually ever accelerate.

The potentiometer should only affect the jog with the joystick,

That’s sad, there is no other way to control the speed? Use another library or something in parallel with accelstepper? Without blocking the code or slow anything down?

Acceleration is important, I’ll se if I could any find videos or something to show what I want it to do

Watch this one from 14:05 Feed proof of concept14:05

Is this for positioning or cutting?

This is only for cutting, mpg is for positioning,

Let’s say that you want to start a long pass, “cut” then you will engage power feed until you want to stop “that’s when you disengage the power feed

watch this from 4:10 Autofeed/Powerfeed

In the beginning of the video he explained the gearbox range for the feed, typically (pitch) feed per rev, in/rev or mm/rev, that’s what the potentiometer will replace, stepless control of the feed

Note that this potentiometer function should only affect the speed when the joystick is engaged

Then maybe it's setSpeed, based on the pot. But it looks like you're going to be fighting with the library.

I don't understand it well, but I suspect that if you want to accelerate to some speed, you will have to ask for multiple steps. Maybe not though, perhaps it's clever enough to keep track of the last move time and speed up if appropriate.

What happens if you keep the joystick on - does travel speed up?

That’s to advanced for me😂

If I hold the button it rotates in a set “slow” speed, no acceleration at all, direction switch and everything is working fine, I’m thinking about how the encoder is interacting with the arduino:

The faster I rotate the encoder the faster the motor spins, more or less 1:1 if steps per pulse is matching with the encoder and setting on the motor driver,

Let’s say that I have the stepper driver configured to full step, and have a 200p/r encoder and use 1 on steps per pulse,

200 pulses from encoder > arduino > 200 pulses to driver 1:1

The motor does exactly the same thing as the encoder with acceleration and rotating speed of the encoder

The sound is only coming from the stepper motor, encoder is quiet

When I push the button it will continue to rotate just like it does when holding the button for 2-3 seconds

https://www.youtube.com/watch?v=NezBxbg8u80&ab_channel=DiddePettersson

This is why I don't use stepper libraries.

Try changing one of the buttons to do more steps so you can see it accelerate (if it does). I don't know what is a reasonable number of steps for such a test. Make sure you have your hand on E-stop!

You may need to ask for lots of steps to get up to speed and then use stop() when the button is released. Even then, if the stepper is spinning fast, the library may add steps to achieve deceleration within configured limits.

added 2 lines of code, only get a pulsed output rotate__0,5s__rotate__0,5s___rotate and so on, I guess it’s the time for the code to cycle trough,

long steps_per_pulse_ypot = 10;

long steps_per_pulse_zpot = 10;


encoder_pin_Az_last = nz;
  if (digitalRead(LEFT_PIN) == LOW)
  {
    if (stepper_y.currentPosition() == encoder_pos_y) // Stepper is at commanded position
    {
      encoder_pos_y += steps_per_pulse_ypot ;
      stepper_y.moveTo(encoder_pos_y);
    }
  }
  //////////////////////////////////////////Y-Axis RIGHT Button//////////////////////////////////////////////
  encoder_pin_Az_last = nz;
  if (digitalRead(RIGHT_PIN) == LOW)
  {
    if (stepper_y.currentPosition() == encoder_pos_y) // Stepper is at commanded position
    {
      encoder_pos_y -= steps_per_pulse_ypot ;
      stepper_y.moveTo(encoder_pos_y);
    }

I'm not sure ten steps is enough to observe acceleration. Also, I wonder if the motor can run faster than that.

Raised the value to 10000 now the motor accelerates to max speed and runs smooth, but now when releasing the button it continue spinning until it reaches 10000steps, same thing if I just klick the button fast, it will go until 10000steps is reached

Try this:

  if (digitalRead(LEFT_PIN) == LOW)
  {
    if (stepper_y.currentPosition() == encoder_pos_y) // Stepper is at commanded position
    {
      encoder_pos_y += steps_per_pulse_ypot ;
      stepper_y.moveTo(encoder_pos_y);
    }
  }
else
  {
  stepper_y.stop();
  }

Note that it will break manual jog - it's just a test.

Somehow these lines makes the encoder function behave very strange,
Button function does nothing,

Tried lowering speed and acceleration to much lower values

That's expected.

That isn't. I would expect that as long as the button is held down, the stepper will run. Speed and acceleration should make no difference.