Coder Social home page Coder Social logo

pkerspe / esp-flexystepper Goto Github PK

View Code? Open in Web Editor NEW
138.0 8.0 30.0 101 KB

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

License: MIT License

C++ 100.00%
esp32 arduino-library stepper-motor control positioning motion device-control espressif32

esp-flexystepper's People

Contributors

ameisso avatar codacy-badger avatar houz avatar pkerspe avatar voha888 avatar

Stargazers

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

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

esp-flexystepper's Issues

Guru Meditation Error: Core 1 panic'ed (InstrFetchProhibited). Exception was unhandled.

Hi!

Yesterday i run into the problem below:

08:33:30.981 -> Guru Meditation Error: Core 1 panic'ed (InstrFetchProhibited). Exception was unhandled.
08:33:31.028 -> Core 1 register dump:
08:33:31.028 -> PC : 0x000005dc PS : 0x00060030 A0 : 0x800d14d8 A1 : 0x3ffb8be0
08:33:31.028 -> A2 : 0x3ffbfe78 A3 : 0x000005dc A4 : 0x00000001 A5 : 0xfffffdb3
08:33:31.028 -> A6 : 0x00000003 A7 : 0x00060f23 A8 : 0x800d14a9 A9 : 0x3ffb8bc0
08:33:31.028 -> A10 : 0xfffffdb2 A11 : 0x00000000 A12 : 0x00000000 A13 : 0x00000001
08:33:31.028 -> A14 : 0x00060020 A15 : 0x00000000 SAR : 0x00000005 EXCCAUSE: 0x00000014
08:33:31.028 -> EXCVADDR: 0x000005dc LBEG : 0x400029ac LEND : 0x400029cb LCOUNT : 0x00000000
08:33:31.082 ->
08:33:31.082 -> ELF file SHA256: 0000000000000000

I downloaded the Exception Decoder and here are the results:

PC: 0x000005dc
EXCVADDR: 0x000005dc

Decoding stack results
0x400d14d5: ESP_FlexyStepper::taskRunner(void*) at D:\PGRDrive\Dolly\Arduino_dolly_ESP32_Flexy_SUMD/ESP_FlexyStepper.cpp line 127
0x40086161: vPortTaskWrapper at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/freertos/port.c line 143

I don't know what the core of the error, i see that the line 127 is the "stepperRef->processMovement();" line in Flexystepper.cpp.
I want to use the Flexystepper library with servos that driven by received data from a radio receiver. The receiver communicate with the ESP32 via the RX pin. So i tried to separate the serial read and the servo code to seprate process/core. The error is the same with core 0 and core 1, i tried both of them.

Can You please help me to find a solution or the mistake i made?

Thnaks!

mm or degrees?

Any solution for change the unit from mm to degrees? or reset the position when position is 360.000mm?

Set speed is slow by about 1.94x

I am using a digital tachometer and am finding that setting the speed is off by about 1.94 times. Is this specific to my board's clock speed? It has been difficult to get specifics on my ESP32 board but I believe my clock speed is 240MHz.

Multi axis performance

Hello, this is just a request for clarification, not a real issue.

I have to choose a library to control up to 6 stepper motors at the same time. I do not need interpolation, I only need to start the motors in parallel, possibly with different speeds and different target distances. The acceleration/deceleration ramps will be fixed and equal for all motors.
Now I see that your library is based on the original FlexyStepper, which has a poor performance on the AVR (7 kHz max for a SINGLE motor, while grbl on AVR is capable of 30 kHz with interpolation!).

You do not give any performance figure for your library on the ESP32, do you expect it to be capable of handling 6 axes in parallel? At what maximum frequency?

Of course I could try it but this takes some time to write a test program, checking the output with an oscilloscope etc., so maybe that you already have the answer.

Thank you very much.
Giovanni

moveToPositionInSteps() in constant speed option

Hi,

You did a really good job with this library, thanks a lot for that.
I'm looking a way to adapt your lib to add a moveToPositionInSteps() in constant speed skipping the calculation of acceleration en deceleration. Unfortunately, I'm maybe doing something wrong as my change do not work and result in a non moving motor.

Is there a way to get that really quickly? Maybe I missed something somewhere in your code that would allows me to do so.

Thanks in advance!
Cheers,

lots of jitter on step movements

Hi there,

I was having problems running this as a service at 6khz pulses. There was breaks in the pulses nearly 20ms (6-10ms typical) long! That made for very rough movement of the stage at times... it would jitter and chatter.. not to mention cause vibration.

I've started to try and optimize this a bit. It's much better now -- pretty stable pulses. I'm still seeing some minor bugaboos (slow fall times?) randomly seeing 1ms pulse lengths on the step line. But much much better now.

Before:
https://www.dropbox.com/s/arb881iok61ibbv/stock.png?dl=0
https://www.dropbox.com/s/1k708hg0hwj6nsq/stock2.png?dl=0

After:
https://www.dropbox.com/s/5knigkzt73tjq9a/changes.png?dl=0

Here's what I changed:

    disableCore0WDT(); // we have to disable the Watchdog timer to prevent it from rebooting the ESP all the time another option would be to add a vTaskDelay but it would slow down the stepper
    disableCore1WDT(); // we have to disable the Watchdog timer to prevent it from rebooting the ESP all the time another option would be to add a vTaskDelay but it would slow down the stepper
    xTaskCreatePinnedToCore(
        ESP_FlexyStepper::taskRunner, /* Task function. */
        "FlexyStepper",               /* String with name of task (by default max 16 characters long) */
        2000,                         /* Stack size in bytes. */
        this,                         /* Parameter passed as input of the task */
        1,                            /* Priority of the task, 1 seems to work just fine for us */
        &this->xHandle,              /* Task handle. */
        1  /*  what core? */
    );                          

This forces the step processing onto core1 -- it seems pretty happy there. This may have other bad side effects -- not sure.

Finally, there are some faster digital pin options on the ESP32 -- bitmask style. here's some info on that:

https://www.instructables.com/Faster-ESP32/

It may help drive things even faster.

Best I can tell the library is doing a bunch of stuff between the rising and falling edge of the pulse. Something in here may be causing the existing jitter, but I'm not sure how to best find it.

  // execute the step on the rising edge
  digitalWrite(stepPin, HIGH);

  // update the current position and speed
  currentPosition_InSteps += directionOfMotion;
  currentStepPeriod_InUS = nextStepPeriod_InUS;

  // remember the time that this step occured
  lastStepTime_InUS = currentTime_InUS;

  // figure out how long before the next step
  DeterminePeriodOfNextStep();

  // return the step line low
  digitalWrite(stepPin, LOW);

Here you can see the 1m pause between rising and falling:
https://www.dropbox.com/s/n9lzfshqx4ar0r1/screenshot.png?dl=0

Thanks for the library, it's awesome.

Best,
-3ric Johanson

disableCore1WDT() in ESP32-S2

I am getting compilation error on missing disableCore1WDT(). I'm using ESP32-S2 and I believe there is only 1 core for this module.

bool ESP_FlexyStepper::startAsService(int coreNumber)
{

  if (coreNumber == 1)
  {
    //disableCore1WDT(); // we have to disable the Watchdog timer to prevent it from rebooting the ESP all the time another option would be to add a vTaskDelay but it would slow down the stepper
  }
  else if (coreNumber == 0)
  {
    disableCore0WDT(); // we have to disable the Watchdog timer to prevent it from rebooting the ESP all the time another option would be to add a vTaskDelay but it would slow down the stepper
  }
  else
  {
    // invalid core number given
    return false;
  }

Using emergencyStop(true) and releaseEmergencyStop

I would like to be able to emergencyStop() in the middle of a "trip" (from 0 to 300mm, for example), then after a pause, releaseEmergencyStop() and have the "trip" pick up where it left off. But I see that processMovement() sets directionOfMotion to 0, and (more important) sets targetPositionInSteps = currentPositionInSteps, which terminates the original "trip".

If I want to just resume where I left off, should I use the callbacks associated with emergencyStop() and releaseEmergencyStop() to store the current position and direction and maybe speed/accel/decel, and then resume that original journey with the callback associated with releaseEmergencyStop()?

Thanks!

[E][esp32-hal-misc.c:111] disableCore1WDT(): Failed to remove Core 1 IDLE task from WDT

Hi,

I'm trying to use this library to just start a servo and rotate it forever and keep getting this error "[E][esp32-hal-misc.c:111] disableCore1WDT(): Failed to remove Core 1 IDLE task from WDT"
and some strange repeated movements. Any idea?
Thank you,
Adrian

void setupStepperMotor() {
Serial.println("Setup Nema ===============");
pinMode(STEP_PIN, OUTPUT);
pinMode(DIR_PIN, OUTPUT);
pinMode(STEPPER_ENABLE_PIN, OUTPUT);
digitalWrite(STEPPER_ENABLE_PIN, LOW);// the signal is active on LOW
pinMode(STEPPER_MICROSTEPPING_M0, OUTPUT);
pinMode(STEPPER_MICROSTEPPING_M1, OUTPUT);
pinMode(STEPPER_MICROSTEPPING_M2, OUTPUT);
setMicrostepping(microstepping);
stepper.connectToPins(STEP_PIN, DIR_PIN);
stepper.setSpeedInStepsPerSecond(1000);
stepper.setAccelerationInStepsPerSecondPerSecond(100);
stepper.startAsService();
//runStepper();
}
void loop() {
stepper.setTargetPositionRelativeInRevolutions(10000);
}

Cannot get rid of slight shakes WiFi adds

First of all, Thanks for a great library!

I was able to get to put together a quick test via Serial for testing this lib with my driver:

    while (Serial.available() > 0) {
      String command = Serial.readStringUntil('\n');
      if (command.toFloat() < 0) stepper.startJogging(-1);
      if (command.toFloat() > 0) stepper.startJogging(1);
      stepper.setSpeedInRevolutionsPerSecond(abs(command.toFloat()));
      Serial.println(command.toFloat());
    }

My next step was to add WiFi functionality to control my stepper motor wirelessly. I notice a tiny bit of vibration has been introduced into the stepper.

I have been messing around changing the core that runs startAsService() and trying to find the best priority for xTaskCreatePinnedToCore(...) in ESP_FlexyStepper.cpp . I was trying to even add another task to setup() rather than using the main loop() to have more control. But I cannot seem to find a way to completely remove the added shakes.

Do you have any recommendations on any additional trick I may try to fix this issue? Thanks in advance!

SetSpeed(0) doesnt stop the motor

hey, id like to use jog functions and change speed on the go, but setting the speed to 0 doesnt stop the motor and it keeps spinning slowly

goToLimitAndSetAsHome and limit switch

hi!

I'm trying to understand the code to understand how this function goToLimitAndSetAsHome uses the limit switch if there is no way to inform the limit switch pin.

I was using the moveToHomeInSteps, but goToLimitAndSetAsHome is a non block function (better for me).
Do I need to check the limit switch in my main loop the same way in this example? https://github.com/pkerspe/ESP-FlexyStepper/blob/master/examples/Example4_Limit_and_latching_EmergencySwitch/Example4_Limit_and_latching_EmergencySwitch.ino

Non-blocking Go Home

Appreciate this library, it's very helpful. I use this library to control multiple motors that has potential to take a while before reaching home limit switch. Having blocking call to moveToHomeInSteps is a challenge.

What's your thoughts on having non-blocking moveToHomeInSteps and is there a reason why it was implemented as blocking (I know that simplicity is probably one of the reason). I am working implementing a wrapper for this library to archive this.

Constant speed

Sorry since this is rather a question, I was wondering how it would be to control a stepper speed without any position information. If I want to run the speed constantly with for example using speedInMillimetersPerSecond or speedInRevolutionsPerSecond

New feature: calibrating between two points (home and max position)

I am trying to calibrate between two points, so limit switches on both sides. This means I will first be calibrating on the home position (which you do have a function for), and then move to the other side, until the limit switch hits, and setting that as MAX_STEPS, so it cannot move any further than that point.
That means if you try to do an absolute or relative-move, and that comes above MAX_STEPS, it will just stop at MAX_STEPS.

You can now use the limit switch feature to get around this nonexistent feature, but the following functions could be implemented:
void startHomeAndLimitCalibration(int beginLimitSwitch, int EndLimitSwitch)
(maybe an extra callback function for when this is finished)
int getMaxSteps()
void setMaxSteps(int maxSteps)
void moveToMaxSteps()
bool isHomeAndLimitCalibrated()

There could be something I am forgetting, but I think this gets you a good idea of what I mean

How to utilize getCurrentPositionInMillimeters() in flexystepper?

Hi,
I am currently using flexystepper to control a single axis for a plasma cutting application. It is all working well except I can not figure out the syntax for the getCurrentPositionInMillimeters() function. I have tried using the following to store the current position in a variable register: CurPos=stepper.getCurrentPositionInMillimeters();. However this does not seem to work? Can anyone provide some guidance on exactly what code is required to get this to work? I am using the command when the stepper is stopped. Thanks, Steve

platformio will not compile example code, says CallAsService expects 0 arguments

I cut and pasted the example code in the Readme.md and added #include <ESP_FlexyStepper.h> but when I try to compile and load it, Platformio gives me the following error:

src\main.cpp: In function 'void setup()':
src\main.cpp:34:27: error: no matching function for call to 'ESP_FlexyStepper::startAsService(int)'
stepper.startAsService(1);
^
In file included from src\main.cpp:1:0:
.pio\libdeps\esp32doit-devkit-v1\ESP-FlexyStepper\src/ESP_FlexyStepper.h:60:8: note: candidate: void ESP_FlexyStepper::startAsService()
void startAsService(void);
^
.pio\libdeps\esp32doit-devkit-v1\ESP-FlexyStepper\src/ESP_FlexyStepper.h:60:8: note: candidate expects 0 arguments, 1 provided
*** [.pio\build\esp32doit-devkit-v1\src\main.cpp.o] Error 1

If I change the line to "stepper.startAsService();" the program compiles, loads, and runs.

Looking at the source code on GitHub I see that startAsService takes an int for an argument but it looks like for some reason Platformio thinks it takes no arguments.

Could Platformio be linked to an older version even though it says "pkerspe/ESP-FlexyStepper@^1.4.4" in the platformio,ini file? I used the library manager to load the ESP-flexyStepper, I am not sure how to do it manually.

Sign Ignored in stepper.moveRelativeInSteps

Hello

Issue using Example1_BasicStepper.ino

  1. Built ESP_FlexyStepper for ESp32_Devkitc_V4 with VSCode, PlatformIO on Ubuntu 18.4, using a TB660 driver. The motor only spins in the same direction with both of the statements stepper.moveRelativeInSteps(200) & stepper.moveRelativeInSteps(-200).

  2. Built FlexyStepper for ESp32_Devkitc_V4 with VSCode, PlatformIO on Ubuntu 18.4, using a TB660 driver. The motor only spins in the same direction with both of the statements stepper.moveRelativeInSteps(200) & stepper.moveRelativeInSteps(-200).

  3. Built FlexyStepper for Arduino ZERO with VSCode, PlatformIO on Ubuntu 18.4, using a TB660 driver. The motor only spins in the same direction with both of the statements stepper.moveRelativeInSteps(200) & stepper.moveRelativeInSteps(-200).

  4. Built FlexyStepper for Arduino UNO with VSCode, PlatformIO on Ubuntu 18.4, using a TB660 driver. The motor spins in opposite directions with stepper.moveRelativeInSteps(200) & stepper.moveRelativeInSteps(-200).

  5. Built FlexyStepper for Arduino UNO & ZERO with Arduino IDE in Windows using a TB660 driver. The motor spins in opposite directions with stepper.moveRelativeInSteps(200) & stepper.moveRelativeInSteps(-200) for both the ZERO & UNO.

Has this situation arisen before with ESP_FlexyStepper? Any suggestions on how to remedy it?

Spinning and spinning and spinning...Jogging function to be added

Hi, your lib is awesome! Thank you very, very much for writing it.
Is there a way to just keep rotating the stepper with a desired speed for very, very long time? Without specifying when to stop? Just keep spinning until the end of time... or a condition is met.

Slow speed seem not to work: Step Frequency lower than 32 Hz not supported

I am working on a project where I need speed of 1 to 100 steps per second. I use the following code in a test:

const int DISTANCE_TO_TRAVEL_IN_STEPS = 2000;

const int SPEED_IN_STEPS_PER_SECOND = 300;
const int ACCELERATION_IN_STEPS_PER_SECOND = 800;
const int DECELERATION_IN_STEPS_PER_SECOND = 800;
...
stepper.connectToPins(MOTOR_STEP_PIN, MOTOR_DIRECTION_PIN);
  stepper.setSpeedInStepsPerSecond(SPEED_IN_STEPS_PER_SECOND);
  stepper.setAccelerationInStepsPerSecondPerSecond(ACCELERATION_IN_STEPS_PER_SECOND);
  stepper.setDecelerationInStepsPerSecondPerSecond(DECELERATION_IN_STEPS_PER_SECOND);
  stepper.startAsService();
.......
stepper.setSpeedInStepsPerSecond(10);
  stepper.setTargetPositionRelativeInSteps(1000);
  SpeedPercent = 10;
  ShowDisplay();
  delay(5000);
  stepper.setSpeedInStepsPerSecond(20);
  stepper.setTargetPositionRelativeInSteps(1000);
  SpeedPercent = 20;
  ShowDisplay();
  delay(5000);
  stepper.setSpeedInStepsPerSecond(50);
  stepper.setTargetPositionRelativeInSteps(1000);
  SpeedPercent = 30;
  ShowDisplay();
  delay(5000);
  stepper.setSpeedInStepsPerSecond(0);
  stepper.setTargetPositionRelativeInSteps(0);
  SpeedPercent = 0;
  ShowDisplay();
  delay(5000);

There is no difference at speed 10, 20 and even with 30 I saw no increase. Only with 50 I saw a slightly fester movement.

Is there a problem with slow speeds?

[E][esp32-hal-misc.c:94] disableCore0WDT(): Failed to remove Core 0 IDLE task from WDT

Hi there, i'm making my own project using your library.
The current setup is: 2 stepper motor with tmc2208 in step/dir confg, the first is set in Rotation and the second is set in Millimeter.

The two big problems is the sync of motion betwen the two stepper and the autio-reset of the esp32 when i sent the
ESP_FlexyStepper::moveRelativeInRevolutions() comand.

The fist error occurred during the startup is:
[E][esp32-hal-misc.c:94] disableCore0WDT(): Failed to remove Core 0 IDLE task from WDT

I set the core on 0 beacuse i use Async_TCP lib which run the task on Core 1

#define DEBUG

#define MICROSTEP_X 2                              
#define STEPS_ROTATION_X 50 * MICROSTEP_X

#define MICROSTEP_Y 16
#define STEPS_MM_Y 100 
#define VELOCITY_MM_S_Y 1
#define ACCELERATION_MM_S_S_Y 50

stepper_x.setStepsPerRevolution(STEPS_ROTATION_X);
stepper_y.setStepsPerMillimeter(STEPS_MM_Y);

  stepper_x.startAsService(0);
  stepper_y.startAsService(0);

After that, when i call the up citated function i had this error log:

E (33315) task_wdt: Task watchdog got triggered. The following tasks did not reset the watchdog in time:
E (33315) task_wdt:  - async_tcp (CPU 1)
E (33315) task_wdt: Tasks currently running:
E (33315) task_wdt: CPU 0: FlexyStepper
E (33315) task_wdt: CPU 1: loopTask
E (33315) task_wdt: Aborting.
abort() was called at PC 0x400e4f07 on core 0

Backtrace: 0x4008c438:0x3ffbe170 0x4008c669:0x3ffbe190 0x400e4f07:0x3ffbe1b0 0x40084775:0x3ffbe1d0 0x4000bfed:0x3ffd2b00 0x40089ced:0x3ffd2b10 0x400e5230:0x3ffd2b30 0x400d3483:0x3ffd2b60 0x400d3689:0x3ffd2b80 0x40088b81:0x3ffd2ba0

Rebooting...
ets Jun  8 2016 00:22:57

rst:0xc (SW_CPU_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:2
load:0x3fff0018,len:4
load:0x3fff001c,len:1044
load:0x40078000,len:8896
load:0x40080400,len:5828
entry 0x400806ac

The calling code is:

void handleRotation(AsyncWebServerRequest *request)
{
    float rot = request->arg("rot").toInt();
    float vel = request->arg("rotvel").toInt();
    #ifdef DEBUG
      Serial.println(rot);
      Serial.println(vel);
    #endif 
if (stepper_x.isStartedAsService()){
  digitalWrite(MOTOR_ENNABLE_PIN, LOW);
  delay(100);
    #ifdef DEBUG
      Serial.println("Started as Service and inside handleRotation");
    #endif  
  stepper_x.setSpeedInRevolutionsPerSecond(vel);
  stepper_x.setAccelerationInMillimetersPerSecondPerSecond(50);
  stepper_x.moveRelativeInRevolutions(rot);
  delay(100);
  digitalWrite(MOTOR_ENNABLE_PIN, HIGH);
}
    request->send(200, "text/plane", "1");
}

issue with jogging

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

Physical button for start and stop

Hi!

Nice software, thank You!
This probably is already possible, but i could not find in the documentation how to start and stop it with a physical button.
I have now used it for motor and driver testing purposes only.
If there was more possibilities, it could be useful in many projects.

  1. Is it possible to start and stop with buttons connected to ESP32 pins?
  2. Is it possible to create, store and run a program with 5-10 operations? like travel 500 steps right, delay 6000ms, travel 1000 steps left delay 1000ms, travel 3000 steps right, delay 6000ms etc.
  3. would it be possible to have a 24h timer. So it could run in a pre programmed time single operation or a series of operations stored.

bluetooth stepper

Hello everyone

I just want to run stepper motor continuous rotation and i am using jogging function i also wnat to change speed via command i am not coading guy but i generate some code can anyone help me with code .

application:

F-500 to rotate motor at 500rpm (cw)
R-500 to rotate motor at 500rpm (ccw)
S - for stop jogging

i share my code if any one can help me please help me


#include <ESP_FlexyStepper.h>
#include "BluetoothSerial.h"

const int MOTOR_STEP_PIN = 23;
const int MOTOR_DIRECTION_PIN = 22;

ESP_FlexyStepper stepper;

BluetoothSerial SerialBT;

bool jogging = false;
int previousDirection = 1;  // Initial direction

void setup() {
  Serial.begin(115200);
  stepper.connectToPins(MOTOR_STEP_PIN, MOTOR_DIRECTION_PIN);

  // Initialize Bluetooth Serial with a custom name
  SerialBT.begin("CustomBluetoothName");

  // Uncomment the line below if you want to change the Bluetooth device name programmatically
  // esp_bt_device_name = "CustomBluetoothName";
}

void loop() {
  // Your main loop code goes here

  // Example: Read data from Bluetooth
  if (SerialBT.available()) {
    char command = SerialBT.read();

    // Process the received command as needed
    processBluetoothCommand(command);
  }
  
  // Additional loop logic, if any
}

void processBluetoothCommand(char command) {
  switch (command) {
    case 'F': // Start jogging forward
      startJogging(1);
      break;
    case 'R': // Toggle direction
      previousDirection *= -1;  // Toggle direction
      digitalWrite(MOTOR_DIRECTION_PIN, previousDirection > 0);
      break;
    case 'S': // Stop jogging
      stopJogging();
      break;
    // Add more cases for other commands if needed
  }
}

void startJogging(signed char direction) {
  // Set the speed and acceleration rates for jogging
  stepper.setSpeedInStepsPerSecond(200);  // Adjust speed as needed
  stepper.setAccelerationInStepsPerSecondPerSecond(200);  // Adjust acceleration as needed

  // Start jogging in the specified direction
  stepper.startJogging(direction);

  jogging = true;
}

void stopJogging() {
  // Stop jogging
  stepper.stopJogging();

  jogging = false;
}

Setting disallowedDirection doesn't work properly

Hi,

I'm currently working on an implementation using one stepper motor and two limit switches (separate inputs) on an ESP-32-CAM-module. In the process I noticed that one of my limit switches wasn't working correctly. After checking my own implementation multiple times, I examined the processMovement() function and I think I found a small mistake in the following section (Line 1144):

this->limitSwitchCheckPeformed = true;
//a limit switch is active, so movement is only allowed in one direction (away from the switch)
if (this->activeLimitSwitch == this->LIMIT_SWITCH_BEGIN)
{
this->disallowedDirection = this->directionTowardsHome;
}
else if (this->activeLimitSwitch == this->LIMIT_SWITCH_END)
{
this->disallowedDirection = this->directionTowardsHome * -1;
}
else if (this->activeLimitSwitch == this->LIMIT_SWITCH_COMBINED_BEGIN_AND_END)
{
//limit switches are paired together, so we need to try to figure out by checking which one it is, by using the last used step direction
if (distanceToTarget_Signed > 0)
{
this->lastStepDirectionBeforeLimitSwitchTrigger = 1;
this->disallowedDirection = 1;
}
else if (distanceToTarget_Signed < 0)
{
this->lastStepDirectionBeforeLimitSwitchTrigger = -1;
this->disallowedDirection = -1;
}
}

When the limit switch ist triggered, I'm calling: myStepper.setLimitSwitchActive(-1);

void ESP_FlexyStepper::setLimitSwitchActive(byte limitSwitchType)
{
if (limitSwitchType == LIMIT_SWITCH_BEGIN || limitSwitchType == LIMIT_SWITCH_END || limitSwitchType == LIMIT_SWITCH_COMBINED_BEGIN_AND_END)
{
this->activeLimitSwitch = limitSwitchType;
this->limitSwitchCheckPeformed = false; //set flag for newly set limit switch trigger
if (this->_limitTriggeredCallback)
{
this->_limitTriggeredCallback(); //TODO: this function is called from within a ISR in ESPStepperMotorServer thus we should try to delay calling of the callback to the backound task / process Steps function
}
}
}

Corresponding to the definition:

static const byte LIMIT_SWITCH_BEGIN = -1;

In line 217 the passed byte value is saved in the variable "this->activeLimitSwitch" of type signed char.

signed char activeLimitSwitch;

I'm not sure, if the following explanation is right, so please correct me, if I'm wrong.

byte can hold numbers between 0 and 255 whereas signed char can hold numbers between -128 and 127.
The passed value of byte = -1 would ussually overflow to a value of 255, but signed char can save it as a value of -1 (see example).

` byte a = -1;

Serial.println(a); //result: 255
signed char b =a;
Serial.println(b); //result: -1
bool c = (a == b);
Serial.println(c); //result: 0
bool d = ((byte)a ==b);
Serial.println(d); //result: 1`

This leads me to the issue in Line 1144 :

if (this->activeLimitSwitch == this->LIMIT_SWITCH_BEGIN)

In the comparison this->activeLimitSwitch has a value of -1 and this->LIMIT_SWITCH_BEGIN has a value of 255. Therefore the condition cannot become true, leading to the limit switch not preventing movement in a certain direction. This behaviour is not noticable in the examples, since the limit switches are connected in series and use the condition in line 1152.

if ((byte)this->activeLimitSwitch == this->LIMIT_SWITCH_BEGIN)

Casting this->activeLimitSwitch to byte in the comparison seems to fix the issues in my case.
Maybe someone could test this potential fix and see, if it works without causing any problems.

Feature Request - Setting for priority and addition to readme

Hi, something that would be helpful to amateurs like myself, could you implement a "stepper.setTaskPriority" along the lines of how core selection was added?

i found bumping this up solved my jittering issues, and reading through some discussion it has helped several other folks. If you know what youre doing, it only takes 2 seconds to find and change the setting, but it took a lot of reading to figure out that changing the setting would be helpful, so maybe a row could be added to the decision matrix.

Stepper motor not stepping all steps with this library

So when I use this library with the following parameters:
StepsPerRevolution : 200
SpeedInStepsPerSecond : 1000 (this corresponds to 500 microseconds in between HIGH and LOW of stepperpin)
AccelerationInStepsPerSecondPerSecond : 2000 (this was my preferred step up and down speed)
AccelerationInStepsPerSecondPerSecond : 2000
I set these values with the corresponding set functions.

I then use stepper.moveToPositionInSteps(200) and stepper.moveToPositionInSteps(0) to move it back and forth, but my stepper does not land at the same position. (So I am just using the Example with some altered values) In fact, it stops earlier than the 200 steps. I don't know what it is, but I would really like to use this library because it has acceleration.

Let me know what I am doing wrong please, or if your library needs an update.

FYI, when I do this:

for(int i = 0; i < 200; i++){
    digitalWrite(MOTOR_STEP_PIN, HIGH);
    delayMicroseconds(500);
    digitalWrite(MOTOR_STEP_PIN, LOW);
    delayMicroseconds(500);
}

It works perfectly fine and lands just on the same spot as before a full rotation.
I also noticed that when I used the default values, my stepper motor just starts grumbling all around, because of the long delay between a HIGH/LOW of the stepperpin. (I am using the "Microstep Driver", just look it up on Google)

So it should be my hardware, or something is wrong in your acceleration, but let me know, I am pretty eager to try a fix.

Strange Movement

I currently try to get my project done with this library (leaved ESP Stepper Motor Server). Looks like working good so far but have a issue on movements of stepper (in loop function). the stepper rotate correct but on reached position he move a little bit back in other direction before stop and reached target position. can you explain what i do wrong?

#include <Arduino.h>
#include <ESP_FlexyStepper.h>

// IO pin assignments
const int MOTOR_STEP_PIN = 2;
const int MOTOR_DIRECTION_PIN = 15;
const int EMERGENCY_STOP_PIN = 13; //define the IO pin the emergency stop switch is connected to
const int LIMIT_SWITCH_PIN = 12;   //define the IO pin where the limit switches are connected to (switches in series in normally closed setup against ground)

// Speed settings
const int DISTANCE_TO_TRAVEL_IN_STEPS = 2000;
const int SPEED_IN_STEPS_PER_SECOND = 300;
const int ACCELERATION_IN_STEPS_PER_SECOND = 800;
const int DECELERATION_IN_STEPS_PER_SECOND = 800;

// create the stepper motor object
ESP_FlexyStepper stepper;

int previousDirection = 1;

//this function gets called whenever the stepper reaches the target position / ends the current movement
//it is registerd in the line "stepperConfiguration->getFlexyStepper()->registerTargetPositionReachedCallback(targetPositionReachedCallback);"
void targetPositionReachedCallback(long position)
{
  Serial.printf("Stepper reached target position %ld\n", position);
}

void EmergencyStopTriggered()
{
  Serial.printf("Emergency Switch triggered\n");
}

void EmergencyStopReleased()
{
  Serial.printf("Emergency Switch released\n");
}

void ICACHE_RAM_ATTR emergencySwitchHandler(){
  stepper.emergencyStop(true);
}

void limitSwitchHandler()
{
}

void HomeReachedCallback()
{
  Serial.printf("Stepper is now on Home Position\n");
}

void setup()
{
  Serial.begin(115200);

  //set the pin for the emegrenxy witch to input with inernal pullup
  //the emergency switch is connected in a Active Low configuraiton in this example, meaning the switch connects the input to ground when closed
  pinMode(EMERGENCY_STOP_PIN, INPUT_PULLUP);
  //attach an interrupt to the IO pin of the switch and specify the handler function 
  attachInterrupt(digitalPinToInterrupt(EMERGENCY_STOP_PIN), emergencySwitchHandler, CHANGE);

  //attach an interrupt to the IO pin of the limit switch and specify the handler function
  attachInterrupt(digitalPinToInterrupt(LIMIT_SWITCH_PIN), limitSwitchHandler, CHANGE);

  // connect and configure the stepper motor to its IO pins
  stepper.connectToPins(MOTOR_STEP_PIN, MOTOR_DIRECTION_PIN);
  // set the speed and acceleration rates for the stepper motor
  stepper.setSpeedInStepsPerSecond(SPEED_IN_STEPS_PER_SECOND);
  stepper.setAccelerationInStepsPerSecondPerSecond(ACCELERATION_IN_STEPS_PER_SECOND);
  stepper.setDecelerationInStepsPerSecondPerSecond(DECELERATION_IN_STEPS_PER_SECOND);

  //register the callback function, to get informed whenever the target postion has been reached
  stepper.registerTargetPositionReachedCallback(targetPositionReachedCallback);
  //you can also register for other events using (these accept currently only functions without any parameters):
  stepper.registerEmergencyStopReleasedCallback(EmergencyStopReleased);
  stepper.registerEmergencyStopTriggeredCallback(EmergencyStopTriggered);
  stepper.registerHomeReachedCallback(HomeReachedCallback);

  // Not start the stepper instance as a service in the "background" as a separate task
  // and the OS of the ESP will take care of invoking the processMovement() task regularily so you can do whatever you want in the loop function
  stepper.startAsService();
  stepper.moveToHomeInSteps(previousDirection,300,5000, LIMIT_SWITCH_PIN);
}

void loop()
{
  // Notice that you can now do whatever you want in the loop function without the need to call processMovement().
  // also you do not have to care if your loop processing times are too long.
  Serial.printf("Actual position is %i\n", stepper.getCurrentPositionInSteps());
  delay(5000);
  stepper.moveRelativeInSteps(400);
  delay(5000);
  stepper.moveRelativeInSteps(400);
  delay(5000);
  stepper.moveToPositionInSteps(0);
}

Non linear stepping speeds

Hello Paul,

I've used your stepper library in the past and it's been very useful and a pleasure to work with.
Just started a new project and I'm running into a problem when trying to run a stepper continuously at certain set speeds. It appears that under lower step speeds, I get the correct expected linear speeds, but at higher input speeds the rpm's stay the same even when higher step values are entered. Then at even higher speeds the rpm's shoot up and very non linear speed behavior is observed.

Here's a snipped of the control speed function in my sketch,

long revolutions = 1000000;
int runMotor1 = (revolutions * 6030) * -1;
int runMotor2 = (revolutions * 800) * rotateDirection;

// Motor at 1 revolution per minute is 6030/60 = 100 steps per second
int rpmM1 = 100;
int motor1Diameter = 203;
float CircumferenceA = (3.1415 * motor1Diameter) / 25.4;
int Motor1Speed = (rpmM1 * inputSpeed * CircumferenceA) / 60;
int SPEED_IN_STEPS_PER_SECOND_M1 = (Motor1Speed);

// Motor2 at 1 revolution per minute is 800/60 = 14 steps per second
int rpmM2 = 14;
int motor2Diameter= 222.25;
float CircumferenceB = (3.1415 * motor2Diameter) / 25.4;
int Motor2Speed = (rpmM2 * inputSpeed * CircumferenceB) / 60;
int SPEED_IN_STEPS_PER_SECOND = (Motor2Speed);

Motor1.setAccelerationInStepsPerSecondPerSecond(AccelSaved * 400);
Motor1.setDecelerationInStepsPerSecondPerSecond(DecelSaved * 400);
Motor2.setAccelerationInStepsPerSecondPerSecond(Accel2Saved * 400);
Motor2.setDecelerationInStepsPerSecondPerSecond(Decel2Saved * 400);

Motor1.setSpeedInStepsPerSecond(SPEED_IN_STEPS_PER_SECOND_M1);
Motor2.setSpeedInStepsPerSecond(SPEED_IN_STEPS_PER_SECOND);
Motor1.setTargetPositionRelativeInSteps(runMotor1);
Motor2.setTargetPositionRelativeInSteps(runMotor2);

The inputSpeed variable ranges from 1 to 60. Motors run at correct speeds up to around inputSpeed of 10, but after that it can vary quite a bit from the correct set speed. Both stepper drivers are set to 800 microsteps. Any help on this would be greatly appreciated.

Thanks in advance!

James

keywords?

Hi, no matter how hard I look, I cannot find any keyword list?
I just want a simple stepper start & stepper stop, for continuous rotation.
I can find emergency stop in an example, but nothing else.
sorry to post here, cannot find any other on-line reference, tutorial for this library.

I like the idea of running it on core 0. Have tries continuous stepper library, but it somehow gets interfered with when the tft screen updates.

Adding stepper without DIR pin

To save the number of free pins, I needed to implement this, but there is no support in the library.
I could do it if the authors of the project allow

Deceleration with position rather than speed.

HI,

Thanks for this awesome project. Am having an issue with the setTargetPositionToStop() function.
I was trying to achieve continuous motion with the library and settled for calling setTargetPositionRelativeInSteps(CONSTANT) so I basically extend the relative position whenever the target is almost reached.
I just realized there is two issues with this.

  1. When I call setTargetPositionToStop() to decelerate to a stop it sometimes takes as much time to stop as It has been running. This, I think is because it uses the position to decelerate instead of the speed.
  2. setTargetPositionRelativeInSteps(CONSTANT) seems to accumulate the relative position and thus could overflow eventually

Is there a way to fix the setTargetPositionToStop() so that it decelerates as per speed not position and is there a better way for continuous motion?

How is the stepper driver enabled?

I am running with TMC2209 drivers and have tried running your example scripts to no avail the stepper does not move am I missing a trick?
I notice that nowhere in the script is there reference to an EN pin to engage/ disengage the driver.
I am currently trying to port my camera motion control system over to the ESP32 but having great difficulty finding a working library.

How to invert the motor direction?

im new in c++ programing,
i use this library for dual wheel robot,
the right wheel is normal direction
but the left wheel is flipped
for moving forward just simply call the function
e.g
motor_right.setTargetPositionInMillimeters(target);
motor_left.setTargetPositionInMillimeters(-target);
for long code im so confusing in - symbol

i think to solve the problem just simply invert the left motor direction, so i can put code in the same target value
e.g
motor_right.setTargetPositionInMillimeters(target);
motor_left.setTargetPositionInMillimeters(target);

how to invert the direction? thanks
thanks

Port for STM32 with HAL library

Hi . I used ESP-Flexy stepper for my position control projects ( Medical Pumps and & CNC axis and etc )which my MCU was ESP32 and I usually designed GUI with LVGL and of course every thing works fine and perfect .
Now I have a project with STM32 and I'm using STM32Cube IDE with Hal library + TouchGFX + FreeRTOS . so I must modify ESP-FlexyStepper library to work with HAL . firstly I edited all bellow functions :
digitalWrite() -> HAL_GPIO_WRITE_PIN();
digitalRead() -> HAL_GPIO_READ_PIN();
micros() -> __HAL_TIM_GET_COUNTER(&htim2); ----> timer 2 configured at 1Mhz clock
delayMicrosecond() -> delay_us(uint16_t us); which is defined as bellow (Not reseting tim2 counter):

void delay_us(uint16_t us) {
uint32_t startUs = __HAL_TIM_GET_COUNTER(&htim2);
while (__HAL_TIM_GET_COUNTER(&htim2) - startUs < us){
; // wait for the counter to reach the us input in the parameter
}
}

secondly in my main program , created a task to call processMovement() :
image
image

In terms of my driver (Lead shine CS-D1008) , minimum pulse width is 2.5 us , I added a delay_us(3) after digitalWrite(stepPin, HIGH) in processMovement() function .
image

In my last test , position control works fine due to accuracy but motor is running with vibration ( not such motion quality and silence motion with ESP32) and I think it's a problem with timing calculations in this functions :

// figure out how long before the next step
DeterminePeriodOfNextStep();

Enhancement: Open drain output option

Currently the driver configures the ESP outputs in push-pull mode, which is great for many use cases. However some stepper drivers operate with an opto-isolated input. These are often best driven with an open drain output. This allows the use of the GPIO pin to be used to switch pull 5v loads to ground, providing sufficient headroom to drive opto-isolators reliably.

Basically this just means the output pin is either floating or connected to ground. In this mode the ESP32 can sink current on a 5v tolerant pin, which it can't do in a push-pull mode.

For step and direction, adding a separate call to configure the output type would make sense without any API breaking changes. The open drain output mode can be set with:
pinMode(stepPin OUTPUT_OPEN_DRAIN);

For the brake pin, I'm not sure the best way.

Exceeding final position when acceleration change in ramp

Hello,

First of all, thank you for the great work, working with the library is a lot of fun, also because of the good documentation.

However, I am experiencing the following problem: I use the library to move a closed-loop servomotor back and forth between two fixed positions. I read in values for the speed and acceleration via two potentiometers, which I enter accordingly via setSpeedInStepsPerSecond and setAccelerationInStepsPerSecondPerSecond and setDecelerationInStepsPerSecondPerSecond. I use the startAsService - mode.

If I now lower the acceleration/deceleration value during the deceleration ramp before reaching the end point, the motor moves past the end point.

Is the error with me or is this a known behavior?

Best regards
tobo

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.