Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Inconsistent Pulse Output on ESP32 #240

Closed
Samthecoolman opened this issue Mar 20, 2024 · 8 comments
Closed

Inconsistent Pulse Output on ESP32 #240

Samthecoolman opened this issue Mar 20, 2024 · 8 comments

Comments

@Samthecoolman
Copy link

Howdy,

While playing around with the fastAccel library I found that I was getting inconsistent step outputs from my ESP32 dev board. Switching to different dev boards results in the same issue, have not tested on AVR.

Using a scope to probe the step output I can verify this issue is not my servo motor (Yellow is step output, blue is enable):
scope

I only have a moderate understanding of Cpp so I am sure there could be an issue with my code, however after spending countless hours trying to debug I have no clue where to proceed from here.

Here is the snippit of my code (Modified example sketch);

#include "FastAccelStepper.h"

// As in StepperDemo for Motor 1 on AVR
//#define dirPinStepper    5
//#define enablePinStepper 6
//#define stepPinStepper   9  // OC1A in case of AVR

// As in StepperDemo for Motor 1 on ESP32
#define dirPinStepper 18
#define enablePinStepper 26
#define stepPinStepper 19

FastAccelStepperEngine engine = FastAccelStepperEngine();
FastAccelStepper *stepper = NULL;

void setup() {
  Serial.begin(115200);
  engine.init();
  stepper = engine.stepperConnectToPin(stepPinStepper);
  if (stepper) {
    stepper->setDirectionPin(dirPinStepper);
    stepper->setEnablePin(enablePinStepper);
    stepper->setAutoEnable(true);

    // If auto enable/disable need delays, just add (one or both):
    stepper->setDelayToEnable(50);
    stepper->setDelayToDisable(50);

    stepper->setSpeedInHz(5000);  
    stepper->setAcceleration(100000);

  }
}

void loop() {

  stepper -> moveTo(1600);
  while(stepper -> isRunning()) {Serial.println(stepper->getCurrentPosition());}
  delay(50);

  stepper -> moveTo(0);
  while(stepper -> isRunning()) {Serial.println(stepper->getCurrentPosition());}
  delay(50);

}

Any help would be greatly appriciated!

  • Sam
@gin66
Copy link
Owner

gin66 commented Mar 20, 2024

Your code looks good and the result is surprising.

Questions:

  • Which FastAccelStepper version do you use ? Arduino library manager is stuck at 0.30.0
  • From the picture it seems, that the stepper switches between few and many pulses depending on the direction. Can you confirm this ?
  • Any different behavior, if stepper->setAutoEnable(true); is changed to false?
  • what is the output at the serial console ? Is the position deviating, too ?
  • plain esp32 or esp32s2/s3/… ?

@Samthecoolman
Copy link
Author

Thanks for the quick reply!

  • Version is 0.30.0, I am using arduino IDE, looking at the issue link you provided this sounds like the cause
  • Direction does not appear to affect step output, it does look like a pattern in the picture I provided though it is not consistant
  • Same behavior is observed regardless of autoEnable state
  • Position does not deviate, serial output counts up and down to desired setpoint
  • Tested on plain esp32 as well as esp32s3

Something else that is interesting is that after running for ~30 minutes the steps become consistant?

@gin66
Copy link
Owner

gin66 commented Mar 20, 2024

could you please upgrade to 0.30.10 ? Even the Changelog does not list a related issue, it is better to use the latest version.

@Samthecoolman
Copy link
Author

Upgraded my version and the inconsistancy appears to have been resolved, however there is slight drift in setpoints over time. I am waiting on some level shifters to arrive, so missed steps here could be chalked up to my servo needing 5 instead of 3.3 volts.

@gin66
Copy link
Owner

gin66 commented Mar 20, 2024

sounds good and thanks for support.

With an esp32 you could use a free pulse counter using stepper-> attachToPulseCounter((7). This allows to verify, if pulses are lost on uC side or not. expectation is: no pulses lost

@Samthecoolman
Copy link
Author

Had some time to continue working on this project and the issue is still present; attatching a pulse counter verifies that steps were lost during movement, inconsistency is present in both directions. Code is here:

#include "FastAccelStepper.h"

// As in StepperDemo for Motor 1 on AVR
//#define dirPinStepper    5
//#define enablePinStepper 6
//#define stepPinStepper   9  // OC1A in case of AVR

// As in StepperDemo for Motor 1 on ESP32
#define dirPinStepper 18
#define enablePinStepper 26
#define stepPinStepper 19

FastAccelStepperEngine engine = FastAccelStepperEngine();
FastAccelStepper *stepper = NULL;

void setup() {
  Serial.begin(115200);
  engine.init();
  stepper = engine.stepperConnectToPin(stepPinStepper);
  if (stepper) {
    stepper->setDirectionPin(dirPinStepper);
    stepper->setEnablePin(enablePinStepper);
    stepper->setAutoEnable(true);

    // If auto enable/disable need delays, just add (one or both):
    stepper->setDelayToEnable(50);
    stepper->setDelayToDisable(50);

    stepper->setSpeedInHz(5000);  
    stepper->setAcceleration(10000);
    stepper-> attachToPulseCounter(7);


  }
}

void loop() {

  stepper -> moveTo(1600);
  while(stepper -> isRunning()) {Serial.println(stepper->getCurrentPosition());}
  Serial.println(stepper -> readPulseCounter());
  delay(500);


  stepper -> moveTo(0);
  while(stepper -> isRunning()) {Serial.println(stepper->getCurrentPosition());}
  Serial.println(stepper -> readPulseCounter());
  delay(500);

}

@gin66
Copy link
Owner

gin66 commented Mar 24, 2024

Sorry to hear that. I have set up an esp32 with a digital scope connected and I cannot reproduce your issue with either example code.:

  • The first code outputs as expected, with enable inputs being operated on a regular pattern. The scope screenshot, you have provided, is not regular.
  • The second code yields result as expected

FastAccelStepper uses mcpwm/pcnt module for the first six allocated steppers and then rmt module. The mcpwm/pcnt combo uses a feedback loop: mcpwm generates steps and pcnt counts those. The theory is, that the pcnt-module gets input from the actual pin. So any noise on the pin could lead to wrong counts. To verify this, please try:

  • Use rmt-module using engine.stepperConnectToPin(stepPinStepper,DRIVER_RMT);. rmt generates pulses without looking at the actual pin
  • Disconnect your hardware from the step pin, so induced noise should vanish

If this does not help, then it will get tricky.

@Samthecoolman
Copy link
Author

Using rmt module seems to fix it, I will do some more testing to verify stability.

Thanks for the help!

@gin66 gin66 closed this as completed Mar 27, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants