-
Notifications
You must be signed in to change notification settings - Fork 151
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
Update Stepper to better fit common use cases #42
Comments
The existing (old) protocol is here: https://github.com/firmata/protocol/blob/master/stepper.md |
Edited 9/22 to add Stepper zero and update command values So here's my stab at a new protocol... This adds support for enable pins, multiStepper and more stepper interface types. In addition to There was some talk in other threads about adding the ability to poll the current position. I don't want to add this, but I would like for firmata to reply with the current position when a What limited steppers to 6 initially? Was it just a guess as to what Firmata could handle updating? I've bumped it to 10, but that's an arbitrary number. Stepper MotorProvides support for full 2 wire, full 3 wire, full 4 wire, half 3 wire, and half 4 wire stepper motor drivers (H-bridge, darlington array, etc) as well as step + direction drivers such as the EasyDriver. Includes optional support for acceleration and deceleration of the motor. Also includes multiStepper support which allows groups of steppers to be simultaneously passed different Example files:
ProtocolStepper configuration Note:
Stepper zero
Stepper step
Stepper to
Stepper enable
Stepper disable
Stepper stop
Stepper stop reply
MultiStepper configuration
MultiStepper to Note: You must pass a value for every stepper in the group.
MultiStepper stop
MultiStepper stop reply
|
I think the step to function in AccelStepper is blocking for the duration of the sequence, which is the reason I never used that library in the first place. However it's been a while since I've looked over the code so perhaps the authors made it non-blocking in a more recent release. |
|
Finally had time to review your proposal. Here are a few comments:
|
No, it is not. I will give it its own byte.
I'm skeptical. The time between commands to the steppers would be very small and a little unpredictable. I think it's more likely that a user would want to move only some members of a MultiStepper group and indices would give us the ability to do that too so I think it's a good addition but for a different reason.
The stop reply command can cover that. I'll make sure to document that.
That seems like a good idea (and matches my use case) but we will need the ability to add two digital pins (limits at either end) or one analog pin (potentiometer) with a range passed in.
👍 I'll submit as a PR next. |
Done in Stepper 2.0: https://github.com/firmata/protocol/blob/master/stepper-2.0.md |
Reopening for comments. |
Here is the AccelStepper API for reference: http://www.airspayce.com/mikem/arduino/AccelStepper/classAccelStepper.html These are current limitations according to what the library provides:
|
My comments are numbered and in bold below to make them easier to identify/respond to.
1. EasyDriver is great, but I'd like to recommend that it also support the BigEasyDriver. I'd like to note that it only adds 1 more micro-step pin to the configuration, which allows 1/16 micro-stepping mode. The likelihood of ever needing smaller resolution than this is minimal, however.
2. Minor comment: I was always kind of concerned about what would happen if the device numbers weren't sent in the proper order. Is there a way (perhaps using linked lists or something) to allow the device numbers to be set up out of order if necessary?
3. Bit packing is nice. Can you save on bits by counting 00 = driver, 01 = two-wire, 10 = three wire, 11 = four wire? Might be useful to have an unused bit in case there is ever need to add more features in the future...
4. This seems odd to me. Micro-step seems to cover 1/4, 1/8, and 1/16 step. Is this intentional? Why not explicitly provide for each? If this is intentional, I would just use 2 bits to convey the information: 00 = whole step, 01 = half step, 10 = micro-step. If 3 bits are going to be used, then 000 = whole step, 001 = half step, 010 = quarter step, 011 = eighth step, and 100 = sixteenth step, etc...
5. Please note there is also a sleep pin. I think the enable is more useful, but if it were me, I'd include the sleep pin functionality just in case. If sleep were included (and the 6th bit were freed up), you could make the 6th bit be "has enable pin" and the 7th bit be "has sleep pin".
6. I might suggest 3 7-bit bytes here for max speed. See my comments lower down... What about max acceleration and deceleration?
7. Is this a typo? There is a "stop command" here and in the stepper stop function...
8. I'm excited to see the addition of this this stepper zero function and the fact that we are now tracking position on the arduino side. However, I would have this be stepper set position so you can set the position to anything you like. 9. Also, obviously someone will eventually run into some position overflow issues. I'd like to propose another function: stepper normalize. The idea is that this can be used to normalize the tracked position to remain within 0-steps/rev. If a stepper motor has 200 SPR, a position of 200 would become 0, 300 would be come 100, - 30 would become 170. I think the formula is something like (position % stepsPerRev + stepsPerRev) % stepsPerRev. Devices that turn over (such as a carousel) would benefit from this greatly. There could even be a configuration value sent to tell it when to turn over instead of having to call stepper normalize manually all the time.
10. Minor suggestion: this is commonly referred to by ME's as a "relative move".
11. What happened to the optional acceleration/deceleration bytes? I think it useful to allow them here as a temporary override to the configured default speed/acceleration/deceleration values. 12. Also, I was running into max speed/speed overflow issues with only 2 significant bytes. I think I calculated out that a 200 step/rev stepper motor connected to a 8 mm lead screw would max out at 4 cm/s or something like that. If you can, throw in a 3rd byte (for speed and acceleration/deceleration) and I doubt we'll ever hit those theoretical limits. Of course, we are probably limited by the AccelStepper class as to the actual max/min. I haven't looked.
13. Minor suggestion: this is commonly referred to by ME's as an "absolute move".
14. You probably want to go with 3 bytes here. You use 3 bytes in the stepper move relative command above. Why limit yourself here? You might even throw in a 4th byte to allow moving to positive or negative positions in case someone decides position 0 is at the center of their mechanical design...
15. Can we get 3 bytes here?
15. And 3 bytes here?
15. And 3 bytes here?
16. Just want to point out that if we include sleep pin, we would need a stepper sleep function as well.
17. Yes, yes, and yes! I'm so glad this is going to be a feature. Just something to think about though: will the default behavior be to halt, or to use acceleration to stop? Or we could offer both options: stepper halt and stepper brake, which immediately stop and use deceleration to stop respectively.
18. How about being able to report position at any point in time? We could have a stepper get status: it can return more than one piece of information: is it moving, current position, where in the move is it (accelerating, constant speed, or decelerating)?. etc.
19. This is a cool feature! I wouldn't say it is absolutely necessary. The design model my company has been using is to think of a stepper motor as a single class and a limit switch as a separate class. Then, we have an abstraction layer above that which uses a motor object and zero or more limit sensor objects to create a new class which has all the concepts of the stepper class as well as storing configured position IDs (such as the IDs on a carousel), allowing for homing functions, allowing user to think in inches/revolutions/mL/whatever, etc.
20. I presume this would be used if not supplied during a stepper to or stepper step command? I see an inconsistency between this and other areas where acceleration/deceleration is used: are we limiting it to a single value for acceleration and deceleration (as implied here)? Or are we allowing both to be set individually (as in the functions above)?
21. I don't have any comments for the below other than what is already commented above and that I'm excited to see how this will work!
|
|
AccelStepper has its short comings, but the advantage of using it for the Arduino implementation of Stepper 2.0 is it's actively supported and fairly well-featured (although falls short of Stepper 2.0 in some areas). I don't plan to continue supporting the simple FirmataStepper library I cobbled together as I don't use stepper motors very often and have enough to work on in the greater Firmata scheme as it is. |
I'll open a new PR for the edits, will be easier to add any additional comments in context. |
Hey wow! Lots of good comments here. I honestly won't be able to give them the attention they deserve until Monday night. I'm out of town, doing the Christmas thing. |
for acceleration/deceleration values we need to work out what the max value is:
We need to multiply by 1000 since we can't sent floats directly, so we multiply and cast to either a 16-bit int or a 32-bit long. Do we need a long here or is an int sufficient? |
Lets move this conversation over to this PR: https://github.com/firmata/protocol/pull/79/files |
I thought of one other idea that might be useful (though it probably can't be supported because AccelStepper probably doesn't support it): It would be neat if you could pause in the middle of a move and then choose either to resume or cancel the move entirely. It would probably require a wrapper around AccelStepper though. I wish I had more time to look into these things... I could probably write a good stepper wrapper that cements the abstract concept of a stepper and then uses whatever library is best to achieve those goals on the Arduino side. I'm probably speaking gibberish here. |
By pause in the middle of a move, do you mean in the middle of a step or in the middle of a series of steps. I'd think you could accomplish the later already sending the stop message, but the former would be nearly impossible to achieve due to latency. |
The stop message changes the target value. Perhaps you could just set the speed to 0 to make it pause? |
I do mean in the middle of a series of steps. If you can set the speed and it affects the current move, then yes, that will work sufficiently as a pause, I think. |
OMG !! Amazing ! There is all I need ! |
I've been looking at the maxuino tutorial video, I tried Max/msp+Maxuino+Easydriver+arduino+nema17, and run normal。 |
Ya, the TB6600 isn't supported. Can you link to the specific stepper motor you are using? Nema 23 is just the frame size. If the current draw is low enough you should still be able to use the Easy Driver. There is also the Big Easy Driver which can handle higher loads. |
thank you! |
Is it possible to control multiple stepper motors using pymata or any python libraries ? pls give some example |
The current version of Stepper has a number of limitations. It should be updated to better meet common uses cases. A separate command byte (TBD) can be used to safely deprecate the old version.
The text was updated successfully, but these errors were encountered: