Milling machine power feed: TeensyStep / AccelStepper issues ...

Status
Not open for further replies.

5lives

New member
Hi guys, very first Arduino programming and probably not the easiest to start with, but went for it nevertheless ... did the best I could, so bare with me please ...

The idea is to replicate the control panel of an older milling machine and adding the same function to another machine w/o power feed. Started out on an Arduino Uno, but both displays I've tried were disturbing the running of the stepper motor. Moving to a Teensy 3.2 solved that issue and it basically works as expected, with two quirks:

1. One of the directions, when sign = -1, does not work after moving to Teensy, it worked on the Arduino - stepper runs at some arbitrary speed and cannot be controlled
2. When pushing Fast Forward (FF) the stepper seems to want to start at first in both directions at the same time, so there is maybe halve a second of back and fort struggle, then it is running as it should (added Debounce to that button, but doesn't help the problem)

The control panel involves a joystick switch that sets left or right, then the actual Start button, a Stop button and the FF button. And a pot to set the feed rate, which is being displayed.

Unfortunately I wasn't able to achieve what I wanted by using only one stepper library. Ended up using AccelStepper for the regular feed, since no need for acceleration there. For FastForward, to move the table at max speed left or right, I added Teensystep.

So I'd be happy if somebody can direct me to solve the two listed issues. On top of that, if some additional tuning could be done, that would be a great bonus. Of interest would be:
- setting a different value for deceleration when stopping FF
- transitioning from regular feed to FF and back without the stepper stopping - I assume that's kind of a complete rewrite though
- eventually using just one of the two stepper libraries (doesn't seem to be an issue though, but for the sake of elegance and knowledge)


Code:
#include "TeensyStep.h"
#include <AccelStepper.h>
#include <LedControl.h>
#include "Bounce2.h"

Stepper ff(1, 2);            // TeensyStep STEP pin: 1, DIR pin: 2
RotateControl controller;    // Use default settings 
AccelStepper stepper(1, 1, 2);
LedControl lc=LedControl(11,13,10,1);

// Define analog pot input pin
#define  SPEED_PIN 9

// Define maximum and minimum speed in steps per second (scale pot to these)
#define  MAX_SPEED 2400
#define  MIN_SPEED 240

// switches
#define BUTTON_PIN_1 17
Bounce FFbutton = Bounce(); 


void setup() 
{
  pinMode(18, INPUT_PULLUP);  // Right switch
  pinMode(14, INPUT_PULLUP);  // Left  switch
  pinMode(15, INPUT_PULLUP);  // Stop  button
  pinMode(16, INPUT_PULLUP);  // Start button
  pinMode(BUTTON_PIN_1, INPUT_PULLUP);  // FF    button
  FFbutton.attach(BUTTON_PIN_1);
  FFbutton.interval(30);

  stepper.setMaxSpeed(13300);

  lc.shutdown(0,false);        // MAX72XX wake up
  lc.setIntensity(0,4);        // set brightness 
  lc.clearDisplay(0);

  controller.stop();
}


void loop() 
{
  static float current_speed = 0.0;         // Holds current motor speed in steps/second
  static int feed = 0;                      // Holds current feed speed in mm/min
  static int analog_read_counter = 1000;    // Counts down to 0 to fire analog read
  static char sign = 0;                     // Holds -1, 1 or 0 to turn the motor on/off and control direction
  static int analog_value = 0;              // Holds raw analog value.

  // Update the Bounce instances :
  FFbutton.update();
  // Get the updated value :
  int value1 = FFbutton.read();
 
  // if a switch is pushed down (0), set the sign value appropriately
  if ((digitalRead(18) == 0) && (digitalRead(16) == 0)) {       // Right switch + Start button
    sign = 1;
  }
  else if ((digitalRead(14) == 0) && (digitalRead(16) == 0)) {  // Left switch + Start button  
    sign = -1;
  }
  else if (digitalRead(15) == 0) {                              //  Stop button
    sign = 0;
    controller.stop();                // teensystep stop
  }
  else if ((digitalRead(18) == 1) && (digitalRead(14) == 1)) {  // Right switch + Left Switch off 
    sign = 0;
    controller.stop();                // teensystep stop
  }
  else if ((digitalRead(18) == 0) && value1 == LOW ) {          // Right switch + FF button 
    sign = 0;
    ff.setMaxSpeed(13300);            // teensystep stp/s
    ff.setAcceleration(8000);         // teensystep stp/s^2 
    controller.rotateAsync(ff);       // teensystep start      
  }
  else if ((digitalRead(14) == 0) && value1 == LOW ) {          // Left switch + FF button  
    sign = 0;
    ff.setMaxSpeed(-13300);           // teensystep stp/s
    ff.setAcceleration(8000);         // teensystep stp/s^2 
    controller.rotateAsync(ff);       // teensystep start     
  }

  //  read pot every so often 
  if (analog_read_counter > 0) {    
    analog_read_counter--;
  }
  else {
    analog_read_counter = 1000;
    analog_value = analogRead(SPEED_PIN); // read pot (from 0 to 1023)
    stepper.runSpeed(); // give stepper a chance to step if it needs to
    current_speed = sign * (((analog_value/1023.0) * (MAX_SPEED - MIN_SPEED)) + MIN_SPEED); // calculate stepper speed
    stepper.setSpeed(current_speed); // Update the stepper to run at this new speed
    feed = 0.09 * (((analog_value/1023.0) * (MAX_SPEED - MIN_SPEED)) + MIN_SPEED); // calculate feed rate
    lc.setDigit(0,2,(feed / 100),false);
    lc.setDigit(0,1,((feed % 100) / 10),false); 
    lc.setDigit(0,0,(feed % 10),false); 
  }

  stepper.runSpeed(); // run the stepper at a constant speed   
}
 
I can't comment on AccelStep but there is a conceptual error in the TeensyStep part of your code. You can not change any of the motor parameters (speed, target acceleration...) while the motor runs. The reason for this is that TeensyStep was developed to handle synced movement of more than one motor. Changing the parameters for one motor during movement would mess up the synchronicity.

However, you can override the speed of all motors together using the rotation controller (for your application this doesn't make a difference since you only control one motor)

Here a working example showing how override speed on the fly. For the sake of simplicity, the example doesn't use pins for the speed control but listens on Serial for commands. It should be straight forward to translate the example to your application. The example prints current time, position and speed to Serial. I often use this to check the movement without connecting motors. It is easy to cut/paste the data from sermon to a spread sheet and display the movement.

Code:
#include "TeensyStep.h"

RotateControl rctl;
Stepper s1(0, 1);

float currentSpeedFac = 0.0f;

void setup()
{
    s1.setMaxSpeed(20'000); // set motor params
    s1.setAcceleration(20'000);

    rctl.rotateAsync(s1);                             // start rotation in the background but override speed to zero
    rctl.overrideSpeed(currentSpeedFac);
    s1.setPosition(0);
}

constexpr float deltaV = 0.25f;                     // speed incresase (percent)

void loop()
{
    while (Serial.available())  
    {
        switch (Serial.read())
        {
            case 'u':                                // up
                currentSpeedFac += deltaV;           // increase speed by 25%
                rctl.overrideSpeed(currentSpeedFac); // set new speed
                break;

            case 'd':                                 // down
                currentSpeedFac -= 0.25;
                rctl.overrideSpeed(currentSpeedFac);
                break;

            case 's':                                 // stop
                rctl.overrideSpeed(0.0f);
                break;

            default:
                break;
        }
    }

    display(); // show current position and speed
    delay(25); 
}


// helpers---------------------------------

void display()
{
    u_int32_t time = millis();
    int32_t position = s1.getPosition();
    int32_t speed = rctl.isRunning() ? rctl.getCurrentSpeed() : 0; //workaround a small glitch in getCurrentSpeed

    Serial.printf("%d\t%d\t%d\n", time, position, speed);
}

Here the generated data
Anmerkung 2020-03-06 071245.png

And here the movement graph

Anmerkung 2020-03-06 071208.png
 
Status
Not open for further replies.
Back
Top