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

Strange behavior when use together with external interrupts #304

Open
0i0i0i opened this issue Dec 30, 2024 · 6 comments
Open

Strange behavior when use together with external interrupts #304

0i0i0i opened this issue Dec 30, 2024 · 6 comments

Comments

@0i0i0i
Copy link

0i0i0i commented Dec 30, 2024

I try to build a motor with two limiters. I used two external interrupts for the two limiters. However, when it turns, there is a certain chance the motor accelerates to a higher speed than the one I set after one limiter is triggered. This trigger should stop the motor according to the code.

#include "FastAccelStepper.h" #define dirPinStepper 5 #define stepPinStepper 7 byte direction = 1; //1 forward, 0 backward byte fLimiter = 0; byte bLimiter = 0; long backwardCounter = 0; long forwardCounter = 0; FastAccelStepperEngine engine = FastAccelStepperEngine(); FastAccelStepper *stepper = NULL; void setup() { Serial.begin(9600); Serial.println("Begin"); pinMode(3, INPUT); pinMode(2, INPUT); pinMode(18, INPUT); pinMode(19, INPUT); attachInterrupt(digitalPinToInterrupt(2), stop1, FALLING); attachInterrupt(digitalPinToInterrupt(3), stop2, FALLING); engine.init(); stepper = engine.stepperConnectToPin(stepPinStepper); if (stepper) { stepper->setDirectionPin(dirPinStepper); stepper->setSpeedInHz(8000); stepper->setAcceleration(3000); } } void loop() { if ((digitalRead(18) == LOW) && (bLimiter == 0)) { direction = 0; if (direction == 0) { backwardCounter++; Serial.println(backwardCounter); } if (backwardCounter == 500) { backwardCounter = 0; fLimiter = 0; } stepper->runForward(); } else if ((digitalRead(19) == LOW) && (fLimiter == 0)) { direction = 1; if (direction == 1) { forwardCounter++; Serial.println(forwardCounter); } if (forwardCounter == 300) { forwardCounter = 0; bLimiter = 0; } stepper->runBackward(); } else { stepper->forceStopAndNewPosition(0); backwardCounter = 0; forwardCounter = 0; } } void stop1() { if (direction == 0) { //后lmiter stepper->forceStopAndNewPosition(0); bLimiter = 1; forwardCounter = 0; direction = 1; } } void stop2() { if (direction == 1) { stepper->forceStopAndNewPosition(0); fLimiter = 1; backwardCounter = 0; direction = 0; } }

page1
page2

@gin66
Copy link
Owner

gin66 commented Dec 30, 2024

unfortunately, the formatting of the code is garbled up.What shall the code do ? I see only one setting of speed/acceleration and both not related to the switches.

@gin66
Copy link
Owner

gin66 commented Dec 30, 2024

you are using the backward/forwardCounters. perhaps better to work with time as reference using e.g. millis()

@0i0i0i
Copy link
Author

0i0i0i commented Dec 31, 2024

unfortunately, the formatting of the code is garbled up.What shall the code do ? I see only one setting of speed/acceleration and both not related to the switches.

sorry. I uploaded the screenshot of the ide. The structure of my code is very simple.

@0i0i0i
Copy link
Author

0i0i0i commented Dec 31, 2024

you are using the backward/forwardCounters. perhaps better to work with time as reference using e.g. millis()

Thanks for reminding me. Yes. I used that to avoid millis() so that there is no potential interferene between this counter and timers.

@0i0i0i
Copy link
Author

0i0i0i commented Dec 31, 2024

you are using the backward/forwardCounters. perhaps better to work with time as reference using e.g. millis()

I think it might be due to some the hardware interference due to the emergency stop triggered in the isr.

@gin66
Copy link
Owner

gin66 commented Dec 31, 2024

Thanks for providing the readable screenshots. Now is much better.

The loop instructs the motor to either runForward, runBackward or forceStopAndNewPosition.

One issue is now with the stop interrupts being called asynchronously. Assume the stop switch is hit, while the loop is executing direction = 0. Then the interrupt will request the motor to stop and after returning from the interrupt, the loop continues execution and the runForward() is called. At this point the stepper is not stopped as expected and if the switch is not causing multiple pulses, the stop interrupt will not be able to stop the motor again.

Another issue is the asymmetry regarding bLimiter and fLimiter tests in the loop. bLimiter takes precedence over fLimiter. This means after backwardCounter hits 500, the fLimiter will be relevant only after bLimiter is unequal to 0. But if the forwardCounter hits 300, the bLimiter is immediately relevant on the next loop iteration - independent of fLimiter. Could this be a cause ?

Further processing depends on the polled inputs 18/19. What are those and what are they doing ?

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