pkerspe / ESP-FlexyStepper

This library is used to control one or more stepper motors from an ESP32 device. It is based on the FlexyStepper library by S.Reifel but provides some additional functionality
MIT License
150 stars 32 forks source link

issue with jogging #18

Closed kang2k10 closed 3 years ago

kang2k10 commented 3 years ago

i use softlimit. While buttonLeft is pressed, i use stepper.startJogging(-1); If buttonLeft is relesed, i use stepper.stopJogging(); After, i press buttonSoftLimitLeft, and use stepper.setCurrentPositionInSteps(0); and after this, stepper clear position, and move

13:36:33.042 -> current position=843 // after stop jogging 13:36:33.042 -> set left limit // after press buttonSoftLimitLeft, 13:36:33.042 -> position=843 //print current position 13:36:33.088 -> current position=1 //after setCurrentPositionInSteps(0) stepper is move, and stop after current position=843

kang2k10 commented 3 years ago

I somehow solved the problem i use this construction stepper.setCurrentPositionInSteps(0); stepper.setTargetPositionInSteps(0);

pkerspe commented 3 years ago

I am sorry, but can you explain what your issue is actually? Did you call setCurrentPositionInSteps(0) after the stepper has come to a full stop? (physically)? If not, add a little delay

kang2k10 commented 3 years ago

I am sorry, but can you explain what your issue is actually? Did you call setCurrentPositionInSteps(0) after the stepper has come to a full stop? (physically)? If not, add a little delay

yes. i call setCurrentPositionInSteps(0) after the stepper has come to a full stop. for debbug, i call Serial.println(getCurrentPositionInSteps()); in loop before i call setCurrentPositionInSteps(0) , in serial - 843 after stop move, and call setCurrentPositionInSteps(0); in serial - 0 stepper is running, and in serial 1,2,4...843. after stepper is stop.

imho, issue in TargetPosition. I set currentPosition=0, by library remember TargetPosition=843. And run stepper while currentPosition!=TargetPosition

pkerspe commented 3 years ago

It is a bit hard to follow your explanation, please post your full sketch here so I can reproduce it. Thx

kang2k10 commented 3 years ago
#include <ESP_FlexyStepper.h>
#define dirPinStepper 25
#define stepPinStepper 33

ESP_FlexyStepper stepper;
uint8_t btn_left, old_btn_left, btn_left_end, old_btn_left_end;
uint16_t SpeedInStepsPerSecond = 100;
uint16_t AccelerationInStepsPerSecondPerSecond = SpeedInStepsPerSecond * 4;
uint16_t StepsPerRevolution = 1;
uint16_t steps_PerMillimeter = 100; //количество шагов на миллиметр
uint16_t PositionInPerMillimeter; //текущая позиция в миллиметрах
uint32_t butt_millis;

void setup() {
    stepper.connectToPins(stepPinStepper, dirPinStepper);
    Serial.begin(115200);
    pinMode(35, INPUT);
    pinMode(34, INPUT);
    stepper.setSpeedInStepsPerSecond(SpeedInStepsPerSecond);
    stepper.setAccelerationInStepsPerSecondPerSecond(AccelerationInStepsPerSecondPerSecond);
    stepper.setStepsPerRevolution(StepsPerRevolution);
    stepper.setDecelerationInStepsPerSecondPerSecond(AccelerationInStepsPerSecondPerSecond * 4);
    stepper.startAsService();
}

void loop() {
    Serial.print("curr_position=");
    Serial.println(stepper.getCurrentPositionInSteps());
    btn_left = !digitalRead(35);
    btn_left_end = !digitalRead(34);
    if (btn_left) // press button left
    {
        Serial.println("go left");
        old_btn_left = btn_left;
        stepper.startJogging(-1);
    }

    if ((!btn_left) && (old_btn_left)) // release button left
    {
        Serial.println("Stop go left");
        old_btn_left = btn_left;
        stepper.stopJogging();
    }

    if (btn_left_end) // Left soft limits
    {
        if ((old_btn_left_end != btn_left_end) && (butt_millis == 0))
        {
            butt_millis = millis();
        }
        else if ((old_btn_left_end != btn_left_end) && (millis() - butt_millis >= 50))
        {
            stepper.setCurrentPositionInSteps(0);
            old_btn_left_end = btn_left_end;
        }
    }
    else if ((!btn_left_end) && (old_btn_left_end))
    {
        old_btn_left_end = btn_left_end;
        butt_millis = 0;
    }
}
pkerspe commented 3 years ago

thanks for the code. Some questions:

  1. It seems you do some software debouncing on the limit switch (btn_left_end), but not on the "btn_left" switch, is debouncing done in hardware on this pin?
  2. in your code you are testing the btn_left status independent from the limit switch? which basically allows jogging (Even if just for one step) while the limit switch is pressed. shouldn't any pressing of the limit switch result in an immediate stop of the stepper? The library implements a function to handle limit switch logic: void setLimitSwitchActive(byte limitSwitchType); this effectively will prevent any further step signals to be generated, but it does not implement debouncing
  3. you stated that you read the position after the stepper has come to a full stop. I do not see any position in the example code where you actually read the position and also no code that uses the callback functions for when the motor has come to a full stop (and no more step signals will get issued...how do you determine that the motor has come to a full stop? For operations like this you can use the registerTargetPositionReachedCallback function

And one more remark: you are using very aggressive acceleration values, this might work if your stepper (and potential conencted gears, flywheels or whater) does not have a high inertia, but as soon as you move some load, you might experience overshooting. Might not be a problem in you current setup though and with the rather low speed, just saying. Also it is not the reason for your problem...I think. But unfortunately I still do not understand what your problem actually is. Do you expect a different position than 1? If so what do you expect, is it a 0?

A difference of 1 step count could be due to the way your code is structured...but on the other hand with just 100 steps/second you should have plenty of time for processing between each step.

kang2k10 commented 3 years ago

This code, is simple. My project use MCP23017, and hardware debounce. Sorry, but english not my language. i read current position in: Serial.print("curr_position="); Serial.println(stepper.getCurrentPositionInSteps());

With press button "left" ,motor is jogging in counterclock-wise. ( stepper.startJogging(-1); ) After release button "left", motor is stop ( stepper.stopJogging(); ) After some times, i press button "btn_left_end" (stepper.setCurrentPositionInSteps(0);) and motor is running in CCW

lifankohome commented 3 years ago

I'm sure that 'setCurrentPositionInSteps' wil move the motor unexpected.

Reason: function 'processMovement' monitor the difference of 'targetPosition_InSteps' and 'currentPosition_InSteps'.

if (directionOfMotion == 0)
  {
    distanceToTarget_Signed = targetPosition_InSteps - currentPosition_InSteps;

Function 'setCurrentPositionInSteps' only change the value of 'currentPosition_InSteps':

void ESP_FlexyStepper::setCurrentPositionInSteps(long currentPositionInSteps)
{
  currentPosition_InSteps = currentPositionInSteps;
}

So if the motor is stop, 'distanceToTarget_Signed' would be a value not zero, and the motor will move.

Maybe 'targetPosition_InSteps' should be set the same with 'currentPosition_InSteps'.

pkerspe commented 3 years ago

@lifankohome I do not see how your post is related to this issue.

Also I think you misunderstand the purpose of the setCurrentPositionInSteps() function. The purpose is NOT to stop the stepper motor at the current position, but to tell the ESP Flexy Stepper library at which "position" the stepper currently is. This can be used for setting e.g. a homing position or any other position in some kind of a calibration routine. What you describe is exactly the behaviour that was intended. If you told the stepper to move to e.g. a target position of 800 steps and you tell the stepper that it's current position is 0 steps (or the origin/homing position) it does not void the previous command and the stepper should move to the position 800. You might want to have a look at the documentation. for setCurrentPositionInMillimeters it states for example "set the current position in mm (basically assign a value to the current position)". Same applies for setCurrentPositionInSteps and setCurrentPositionInRevolutions.

What you actually seem to be looking for ist setCurrentPositionAsHomeAndStop() or a combination of setCurrentPositionInSteps(0) and setTargetPositionInSteps(0); For more details please refer to the documentation.

pkerspe commented 3 years ago

I close this issue, since it seems all a misunderstanding of the function to use. As @kang2k10 wrote, the solution to the problem has been provided by himself basically:

I somehow solved the problem i use this construction stepper.setCurrentPositionInSteps(0); stepper.setTargetPositionInSteps(0);

lifankohome commented 3 years ago

I just don't understand the description of Function 'setCurrentPositionInSteps': set the current position of the motor in steps, this does not move the motor And why the motor does move if the function was called :-)

//
// set the current position of the motor in steps, this does not move the motor
// Note: This function should only be called when the motor is stopped
//    Enter:  currentPositionInSteps = the new position of the motor in steps
//
void setCurrentPositionInSteps(long currentPositionInSteps)
pkerspe commented 3 years ago

The purpose of this function is to purely set a position value. It's purpose is not to move the stepper to a specific position. If your target position points to another value than the value given to this function you implicitly trigger a move. Just update your target position to the newly set position value and you will be fine.

pkerspe commented 3 years ago

@lifankohome I updated the documentation for the setCurrentPositionInXXX functions in the Readme and inline documentation to make it clearier for future users: commit cdb6b51