luni64 / TeensyStep

Fast Stepper Motor Library for Teensy boards

Home Page:https://luni64.github.io/TeensyStep/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Teensystep does can achieve 'free prior move' for the target point?

chihoonl opened this issue · comments

Hi Luny, My name is Jihoon from Korea. I would like to thank you first for sharing this wonderful Library.

I've been looking and testing the Teensystep in this last few days for my camera slider. And finally, I completed the test coding to save and return the In and Out target values using serial communication with Teensy3.6 and two motors. The result is successful and works better than expected! It's really wonderful.

#include "TeensyStep.h"
StepControl controller;     // Use default settings

Stepper motor1(3, 2);       // STEP pin: 3, DIR pin: 2
Stepper motor2(7, 6);       // STEP pin: 7, DIR pin: 6

const int ms1 = 11;
const int ms2 = 13;

char s; 

int InandOut = 0; 

int XInPoint = 0; 
int YInPoint = 0;

int XOutPoint = 0; 
int YOutPoint = 0;


void setup() {

  Serial.begin(9600); 

  pinMode (ms1, OUTPUT);
  pinMode (ms2, OUTPUT);
  digitalWrite(ms1, LOW);
  digitalWrite(ms2, HIGH);

  motor1
  .setMaxSpeed(6000)      
  .setAcceleration(6000)
  .setPullInSpeed(200) 
  .setInverseRotation(LOW) 
  .setStepPinPolarity(LOW); 

  motor2
  .setMaxSpeed(6000)
  .setAcceleration(6000)
  .setPullInSpeed(200)
  .setInverseRotation(LOW)
  .setStepPinPolarity(LOW);
}

bool repeat = false;

void loop() {


  if (Serial.available()) {
    s = Serial.read(); 

    if (s == '1') 
    {
      Serial.println("IN_Set!");

      XInPoint = motor1.getPosition(); 
      YInPoint = motor2.getPosition(); /
      delay(200);
      delay(200);
    }

    if (s == '2')
    {
      Serial.println("Out_Set!");

      XOutPoint = motor1.getPosition();
      YOutPoint = motor2.getPosition();
      delay(200);
    }

    if (s == '3')
    {
      Serial.println("Move to IN!");

      motor1.setTargetAbs(XInPoint); 
      motor2.setTargetAbs(YInPoint); 
      controller.move(motor1, motor2);
      delay(200);
    }


    if (s == '4')
    {
      Serial.println("Move to OUT!");
      motor1.setTargetAbs(XOutPoint);
      motor2.setTargetAbs(YOutPoint);

      controller.move(motor1, motor2);
      delay(200);
    }


    if (s == '0')
    {
      Serial.println("Move to Temp!");
      motor1.setTargetAbs(10000); 
      motor2.setTargetAbs(7000); 
      controller.move(motor1, motor2);
      delay(200);
    }



    if (s == '9')
    {
      Serial.println("Set Position!");
      motor1.setPosition(0); 
      motor2.setPosition(0); 

      delay(200);
    }

    if ( s == '7')
    {
      Serial.println("Auto Repeat!");
      repeat = true;

      while (repeat)
      {

        motor1.setTargetAbs(XInPoint);
        motor2.setTargetAbs(YInPoint);

        controller.move(motor1, motor2);

        delay(1000);

        motor1.setTargetAbs(XOutPoint);
        motor2.setTargetAbs(YOutPoint);

        controller.move(motor1, motor2);

        delay(1000);

      }

    }


    Serial.end();
  }
}

My next goal is move the motor to a free target(prior move) using 'RotateControl Class' by two Potentiometer instead the target "Move to Temp!" for InandOut (pls, refer of my code next below.)

To achieve this goal, but I realized that it was impossible to control by the adjust value of speed of the rotate class finally.

So I think, plan to do mapping the analog input of Potentiometer to overrideSpeed in rotateControl Class.. I hope so this way is correct.

Could you please advise on how to solve this problem?

To summarize my questions:

  1. How can I design a 'prior move' by potentiometer using overrideSpeed?

  2. How can I combine the two codes(stepControl with Rotate class) without any problems?

#include "TeensyStep.h"
RotateControl controller;

Stepper motor1(3, 2);     
Stepper motor2(7, 6);       

#define JoyX  A14
#define JoyY  A15

int JoyXPos;
int JoyYPos;

void setup() {

  motor1
  .setMaxSpeed(3000)      
  .setAcceleration(5000);

  motor2
  .setMaxSpeed(3000)
  .setAcceleration(5000);

}

void loop() {

  JoyXPos = analogRead(JoyX);
  JoyYPos = analogRead(JoyY);

  if (JoyXPos > 550) {
    JoyXPos = map(JoyXPos, 550, 1023, 0, 3000);
    motor1.setMaxSpeed(JoyXPos);
  }

  else if (JoyXPos < 420) {
    JoyXPos = map(JoyXPos, 420, 0, 0, 3000);
    motor1.setMaxSpeed(-JoyXPos);
  }

  else {
    motor1.setMaxSpeed(0);
  }
  controller.rotateAsync(motor1);


  if (JoyYPos > 550) {
    JoyYPos = map(JoyYPos, 550, 1023, 0, 3000);
    motor2.setMaxSpeed(JoyYPos);
  }

  else if (JoyYPos < 420) {
    JoyYPos = map(JoyYPos, 420, 1, 0, 3000);
    motor2.setMaxSpeed(-JoyYPos);
  }

  else {
    motor2.setMaxSpeed(0);
  }
  controller.rotateAsync(motor2);

}

If I understand correctly, you want to control the motor rotation speed with two pots. Here some code demonstrating how to do this. (Untested but should work, let me know if not). The code calculates an override value from -1.0 to +1.0 from the pot value (using your algorithm to exclude the dead band).
Using this value as speed override will rotate the motor from -maxSpeed to +maxSpeed.

Integrating this into your first sketch should be simple. You would move the starting of the motors from setup to your command detection part in loop. Don't forget to call ctrl.stop() when you leave the prior move mode.

#include "Arduino.h"
#include "TeensyStep.h"

float transformPot(float analogVal) // transforms your pot values ouside the deadband to [-1.0:+1.0]
{
    if (analogVal > 550) return map(analogVal, 550, 1023, 0.0f, 1.0f);
    if (analogVal < 420) return map(analogVal, 0, 420, -1.0f, 0.0f);
    return 0.0f;
}

Stepper motor1(3, 2);
Stepper motor2(7, 6);
RotateControl ctrlX, ctrlY;

constexpr int JoyX = A14;
constexpr int JoyY = A15;

void setup()
{
    while (!Serial) {}

    motor1
        .setMaxSpeed(3000)
        .setAcceleration(5000);

    ctrlX.rotateAsync(motor1);  // "start" motor with speed 0
    ctrlX.overrideSpeed(0);

    motor2
        .setMaxSpeed(3000)
        .setAcceleration(5000);

    ctrlY.rotateAsync(motor1);  // "start" motor with speed 0
    ctrlY.overrideSpeed(0);
}

void loop()
{
    static float oldOvrX = 0.0f;
    static float oldOvrY = 0.0f;

    float ovrX = transformPot(analogRead(JoyX));  // caclulate override value from pot
    if (oldOvrX != ovrX)
    {
        oldOvrX = ovrX;
        ctrlX.overrideSpeed(ovrX);
    }

    float ovrY = transformPot(analogRead(JoyY));   // caclulate override value from pot
    if (oldOvrY != ovrY)
    {
        oldOvrY = ovrY;
        ctrlY.overrideSpeed(ovrY);
    }
}

Thank you very much for your quick and kind reply.
Unfortunately this code doesn't seem to work on my board. I'm a newbie in coding, so I don't know if I'll understand your code properly. Anyway, I wanna test it more, but It is midnight in Korea now. I'll test it again tomorrow and feedback to you.

I'll be away on the weekend but can answer on Monday
Good Night

In setup I changed the 'ctrlY.rotateAsync(motor1)' value of motor 2 to (motor2) and it works fine now.
I will trying combine two code now, Thank you so much. have a great weekend.

If I understand correctly, you want to control the motor rotation speed with two pots. Here some code demonstrating how to do this. (Untested but should work, let me know if not). The code calculates an override value from -1.0 to +1.0 from the pot value (using your algorithm to exclude the dead band).
Using this value as speed override will rotate the motor from -maxSpeed to +maxSpeed.

Integrating this into your first sketch should be simple. You would move the starting of the motors from setup to your command detection part in loop. Don't forget to call ctrl.stop() when you leave the prior move mode.

#include "Arduino.h"
#include "TeensyStep.h"

float transformPot(float analogVal) // transforms your pot values ouside the deadband to [-1.0:+1.0]
{
    if (analogVal > 550) return map(analogVal, 550, 1023, 0.0f, 1.0f);
    if (analogVal < 420) return map(analogVal, 0, 420, -1.0f, 0.0f);
    return 0.0f;
}

Stepper motor1(3, 2);
Stepper motor2(7, 6);
RotateControl ctrlX, ctrlY;

constexpr int JoyX = A14;
constexpr int JoyY = A15;

void setup()
{
    while (!Serial) {}

    motor1
        .setMaxSpeed(3000)
        .setAcceleration(5000);

    ctrlX.rotateAsync(motor1);  // "start" motor with speed 0
    ctrlX.overrideSpeed(0);

    motor2
        .setMaxSpeed(3000)
        .setAcceleration(5000);

    ctrlY.rotateAsync(motor1);  // "start" motor with speed 0
    ctrlY.overrideSpeed(0);
}

void loop()
{
    static float oldOvrX = 0.0f;
    static float oldOvrY = 0.0f;

    float ovrX = transformPot(analogRead(JoyX));  // caclulate override value from pot
    if (oldOvrX != ovrX)
    {
        oldOvrX = ovrX;
        ctrlX.overrideSpeed(ovrX);
    }

    float ovrY = transformPot(analogRead(JoyY));   // caclulate override value from pot
    if (oldOvrY != ovrY)
    {
        oldOvrY = ovrY;
        ctrlY.overrideSpeed(ovrY);
    }
}

Your code worked really well. Thank you very much.
It seems to have finally solved some of the problems that were frustrating when controlling the motor with Accelstepper. Teensystep amazes me.

If you don't mind can I ask you some more question?
I have two questions.

  1. In the code you suggest to me, if I like to adjust the value of '.set Max speed' using hardware(encoder, button, etc..), are those values applied to the motor in real time on the loop?

  2. Can I find the way for emergency stop when the motor blocking running? (example; calling the Interrupt, somthing like this..)

In the code you suggest to me, if I like to adjust the value of '.set Max speed' using hardware(encoder, button, etc..), are those values applied to the motor in real time on the loop?

No, they are not. In rotational mode (using the rotationController) you can adjust the speed with overrideSpeed. In Target Mode (using the StepController) you need to set the max speed before you start the movement.

Can I find the way for emergency stop when the motor blocking running? (example; calling the Interrupt, somthing like this..)

TeensyStep can not know if you motor blocks. It just generates step / dir signals. If you need this feature you should look for motor drivers with "stall detection". E.g. https://www.youtube.com/watch?v=7eCLV7pALig

Okay, I understand. Thanks for your reply.