Giter Club home page Giter Club logo

dendostepper's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

dendostepper's Issues

Output signal of step pin misses one edge per movement

Describe the bug
I noticed that the position of my stepper motor changes over time when I tried turning one full rotation repeatedly. Turns out, the ISR misses one flank per executed movement.

To Reproduce
Use example with any step count (a lower step count makes it more easily visible)
I used the following code:

#include <stdio.h>
#include "DendoStepper.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_log.h"

DendoStepper step;
DendoStepper step1;

extern "C" void app_main(void)
{

    DendoStepper_config_t step_cfg = {
        .stepPin = 2,
        .dirPin = 4,
        .enPin = 5,
        .miStep = MICROSTEP_1,
        .stepAngle = 1.8};

    step.config(&step_cfg);

    step.init();

    step.setSpeed(1000, 50, 50);

    step.setStepsPerMm(10);

    while (1)
    {
        //can't do 1 or 2 steps, it will not move!!
        step.runPos(10);
        vTaskDelay(8000 / portTICK_PERIOD_MS);
    }
}

Expected behavior
One movement produces the exact amunt of negative and positive edges (in my case 10 negative edges).

Screenshots
The existing code causes this behavior:
old

Changing the ISR results in the correction of this issue:
new2

HW (please complete the following information):

  • ESP32 Wroom Devkit (ESP-WROOM-32)
  • Stepper driver: DM542T

Pull Request
See here

Change public API

Is your feature request related to a problem? Please describe.
I find the structure of the library a bit unintuitive. Therefore I propose these changes:

Describe the solution you'd like

  • Separate linear movement functionality from actual motor control into different classes
    The linear movement class could inherit from the actual stepper class.

  • Change properties of motor and motors connected to linear axes
    Change microStepping and stepAngle to stepsPerRot. This would give the user more freedom to decide on microstepping values, as well as being a more descriptive property. The user could set it like (motor_steps_per_turn * controller_microsteps).
    Additionally, I think stepsPerMm mixes properties of linear and stepper functionality. I propose to use feedConstant instead (i.e. mm/turn).

  • Simplify initialization (i.e. init, init(params), config methods)
    Generally, there should be a single method the user calls for initialization. Right now there are 3 methods, which uses might be a bit ambigous.
    I think the best way would be to only use the init struct, as it is more concise and adaptable than passing every config value as a method parameter. I think performing initialization in the constructor is not optimal. The reason is that a possible error during a c'tor call would be less debuggable than a runtime error.

Describe alternatives you've considered

Additional context

Expand async usage possibility

Is your feature request related to a problem? Please describe.
When starting a movement, it will get executed asynchronously (using the gptimer ISR). To check that the movement is completed, however, you need to poll the status.

Describe the solution you'd like
The library should tell the main program that the motor movement finished, by means of a callback of some sorts. Maybe the esp_event library could be used.

Describe alternatives you've considered
FreeRTOS constructs could be used as well, like binary Semaphores, queues or task notifications.

Additional context

Move infinite should allow speed changes while moving, and stop gracefully

Is your feature request related to a problem? Please describe.
I noticed that while a motor is moving using moveInf(direction) that speed changes are not applied. Additionally, there doesn't seem to be a mechanism that allows it to decelerate to a stop, only to stop instantly (emergency stop).

Describe the solution you'd like
I'm not sure how, but ultimately, a way to adjust speed while doing an infinite move may solve both problems, but is really what I need for time based stepper movements, rather than distance. I could just adjust speed to zero to stop it gracefully perhaps. Or a stopInf()? or make stop() aware of if it's moving linearly, or moving infinite?

Additional context
The use case in this case is a milling machine power feed, in which case the distance it moves is not important since it's manually engaged or disengaged by a user. It's only the speed that it moves that's important, and the typical UI allows the user to adjust speed as a cut progresses.

Refactor the library and improve structuring

Is your feature request related to a problem? Please describe.
Related to ideas presented by @cedricwritescode to make the library usage more clear and support more stepping drivers.

Describe the solution you'd like
Refactor current DendoStepper class, maybe implement separate axis class for linear motion. Initialization of pins and other parameters should be in a constructor. Update documentation in README and update the example code.

Additional context
This changes would be breaking backwards compatibility.

TROUBLE MAKING IT WORK WITH TMC2208MOTOR DRIVER

Describe the bug
Hello there I was trying to test the example with the TMC2208 but not able to start the stepper motor.

But a simple gpio control works

The delay between the the high and low pulse should be 250 ms

HW (please complete the following information):

  • ESP32 module: [ESP32S3]
  • Stepper driver: [TMC2208]

Current position variable doesn't actually hold current step position

Describe the bug
When stopping an ongoing movement, the current position variable will reflect the position before the start of the movement, instead of the actual position of the stepper motor.

To Reproduce

#include <stdio.h>
#include "DendoStepper.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_log.h"

DendoStepper step;

extern "C" void app_main(void)
{
    DendoStepper_config_t step_cfg = {
        .stepPin = 2,
        .dirPin = 4,
        .enPin = 5,
        .miStep = MICROSTEP_1,
        .stepAngle = 1.8
    };
    
    step.config(&step_cfg);
    step.init();
    step.setStepsPerMm(40);
    step.setSpeedMm(5, 1000, 1000);

    //Check behavior of position with and without stop getting called
    bool withStop = false;
    while (1)
    {
        ESP_LOGI("main", "Loop run with stop: %s", withStop ? "true" : "false");
        ESP_LOGI("main", "pos 1: %lld", step.getPositionMm());
        step.runPosMm(50);
        vTaskDelay(2500 / portTICK_PERIOD_MS);
        ESP_LOGI("main", "pos 2: %lld", step.getPositionMm());
        vTaskDelay(2500 / portTICK_PERIOD_MS);
        if(withStop) {
            step.stop();
        }
        ESP_LOGI("main", "pos 3: %lld", step.getPositionMm());

        withStop = !withStop;
    }
}

The output looks like this:

I (380) main: Loop run with stop: false
I (380) main: pos 1: 0
I (390) DendoStepper: Enabled
I (390) calc: acc end:25 coastend:1975 stepstogo:2000 speed:200.000000 acc:800.000000 int: 125000
I (2900) main: pos 2: 50
I (5400) main: pos 3: 50

I (5400) main: Loop run with stop: true
I (5400) main: pos 1: 50
W (5400) DendoStepper: Finising previous move, this command will be ignored
I (7900) main: pos 2: 50
I (10400) main: pos 3: 50

I (10400) main: Loop run with stop: false
I (10400) main: pos 1: 50
I (10400) calc: acc end:25 coastend:1975 stepstogo:2000 speed:200.000000 acc:800.000000 int: 125000
I (12910) main: pos 2: 100
I (15410) main: pos 3: 100

I (15410) main: Loop run with stop: true
I (15410) main: pos 1: 100
W (15410) DendoStepper: Finising previous move, this command will be ignored
I (17910) main: pos 2: 100
I (20410) main: pos 3: 100

Expected behavior
The current position should be valid at all times. This is required by the fact that starting a movement is done asynchronously, so the current position could be read at any time.

Screenshots

HW (please complete the following information):

  • ESP32 module: ESP32-WROOM-32
  • Stepper driver: DM542T

Additional context

Permanent rotation with speed/direction controll

Hi!
Thanks so much for the library, it works great!

Please help me with spining the motor all the time and only control the direction and speed.

I have tried the following, but my understanding of timer operation is not enough to relay on my own.
The motor is moving with jerks.

void stepperTask(void *pvParam) {
  static const TickType_t xBlockTime = pdMS_TO_TICKS(50);
  dStep.init(dConfig.step_p, dConfig.dir_p, dConfig.en_p, dConfig.timer_group,
             dConfig.timer_idx, MICROSTEP_1, 200);
  dStep.setSpeed(1000, 1000);
  // ESP_LOGW(STEPPER_TAG, "stepper!");
  bool dir = true;
  uint32_t notify_value;
  while (true) {
    if (xTaskNotifyWait(0, 0, &notify_value, 0) == pdTRUE) {
        ESP_LOGI(STEPPER_TAG, "ENC: %d", value);
        dir = (int16_t)notify_value > 0;
        if (value != 0) {
          dStep.setSpeed(1000 * abs(notify_value), accT);
        }
    }
    dStep.runPermanent(dir);
    vTaskDelay(xBlockTime);
  }
}

// DendoStepper Class function.
esp_err_t DendoStepper::runPermanent(bool dir)
{
    ctrl.status=ACC;
    setDir(dir);
    calc(ctrl.speed, ctrl.acc, abs(1000)); // calculate velocity profile
    // ESP_ERROR_CHECK(timer_set_alarm_value(
    //     conf.timer_group, conf.timer_idx,
    //     ctrl.stepInterval)); // set HW timer alarm to stepinterval
    ESP_ERROR_CHECK(
        timer_start(conf.timer_group, conf.timer_idx)); // start the timer
    return ESP_OK;
}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.