firmata / protocol

Documentation of the Firmata protocol.
995 stars 151 forks source link

Is it possible to control multiple stepper motors using pymata or any python libraries ? pls give some example #116

Open panchalmanish2208 opened 4 years ago

panchalmanish2208 commented 4 years ago

Is it possible to control multiple stepper motors using pymata or any python libraries ? pls give some example

Originally posted by @Manish2208 in https://github.com/firmata/protocol/issues/42#issuecomment-605647156

dtex commented 4 years ago

No hablo Python, but I see Pymata supports Firmata's legacy stepper motor code which I believe allows you to use multiple steppers. Have you tried editing the Pymata example and just adding another stepper instance?

Pymata does not yet support Firmata's new and improved accelStepper code. AccelStepper adds lots of options and commands. It even allows for coordinated movement of multiple stepper motors which is great for plotters, printers and things of that nature.

Maybe @MrYsLab has thoughts on what it might take to get support for the new stepper features in Pymata? I bet they accept pull requests.

MrYsLab commented 4 years ago

@dtex I don't own this repository, but since I have been "pulled into" ;-) this conversation, I will add my 2 cents. To run a stepper motor, the stepper motor library activates the coils in sequence, using a time delay between activations. StandardFirmata, in its loop method, checks for input data changes about every 19ms or so (for analog inputs - digital inputs are checked at a higher rate). Arduino's do not support concurrency, and therefore adding a stepper library into the mix will upset this timing.

On top of that, running a Python (or any other client) in a non-realtime operating system (such as Windows, Linux or macOS) adds even more uncertainty as to when events will occur.

Why do the pymata libraries support a single stepper? It was provided so that an instructor could demonstrate a stepper motor to their students. For this purpose, it works well.

So the real question is what is the application? Typically, a stepper motor is used to control something in finite precise steps and in a predictable fashion. One may use a sensor to determine when to start or stop the motor, again in a precise fashion. The better solution, IMHO is to create an Arduino sketch that actually does the bulk of the processing. If remote operation is absolutely necessary, one may add a simple serial interface to the sketch.

Don't get me wrong, I use Firmata quite a lot, and for many applications it simplifies life but I don't think this is a valid application of its use.

dtex commented 4 years ago

Sorry to rope you in like that, I figured it was really a Python question and to the best of my knowledge, you're the most expert of all the experts when it comes to Firmata + Python.

Everything you said is true, but I do need to clarify one thing. accelStepper (and the legacy stepper library) in Configurable Firmata already handle all the stepper movements in the Arduino sketch, not remotely. We simply send one command to "move n steps, at x speed" and everything else is handled on the microcontroller. Firmata does not send one command per step (or worse, one command per pin per step). You can achieve pretty high step speeds, with acceleration and multiple stepper control (it gets sketchy around 800 steps per second on an Uno).

I have a video that demonstrates. Disregard the JS stickers, all the magic is happening in Firmata running on an Arduino Uno.

https://youtu.be/015PZOXdqiE

MrYsLab commented 4 years ago

@dtex Thanks for your comment. Hopefully, I will not sound like a jerk for this, but I will not use accelStepper because of the following statement on the author's web page: "Do not contact the author directly, unless it is to discuss commercial licensing. " This does not inspire confidence should I or any of my users run into an issue. In addition, the library license was not GPL'ed until this month.

To be clear, the stepping being performed within FirmataExpress (my adaptation of StandardFirmata) is also done within the sketch and not in Python. The standard Arduino stepper library was integrated into FirmataExpress. The pymata4 API has 2 calls to deal with the stepper:

set_pin_mode_stepper(self, steps_per_revolution, stepper_pins)

The set of pins is stored in the sketch

stepper_write(self, motor_speed, number_of_steps)

The number of steps parameter incorporates direction.

One last point, and perhaps I am missing something here, but both the accelStepper and Jeff's stepper library do not appear to be non-blocking. If the application only needs to run multiple motors, as your very nice video shows, this, of course, will work. But let's say you wish to run the motor for 30 seconds and if it should trigger some type of fail-safe sensor during that time, how would the Firmata sketch know that that happened while waiting for the motor command to finish? You could break that 30 seconds down into smaller chunks of time or steps, and check the sensor along the way, this might make the turning motion of the motor choppy.

So to make a short story longer, I will not be changing my Firmata sketch code at this time.

panchalmanish2208 commented 4 years ago

Sorry for closing the issue ,it is done by mistake. Is there is any other python libraries or other way to use firmata to running multiple stepper motors

panchalmanish2208 commented 4 years ago

No hablo Python, but I see Pymata supports Firmata's legacy stepper motor code which I believe allows you to use multiple steppers. Have you tried editing the Pymata example and just adding another stepper instance?

Pymata does not yet support Firmata's new and improved accelStepper code. AccelStepper adds lots of options and commands. It even allows for coordinated movement of multiple stepper motors which is great for plotters, printers and things of that nature.

Maybe @MrYsLab has thoughts on what it might take to get support for the new stepper features in Pymata? I bet they accept pull requests.

As you said it is possible to run multiple stepper by creating different instances but its not working. If you have another example of it then please post it.

panchalmanish2208 commented 4 years ago

Sorry to rope you in like that, I figured it was really a Python question and to the best of my knowledge, you're the most expert of all the experts when it comes to Firmata + Python.

Everything you said is true, but I do need to clarify one thing. accelStepper (and the legacy stepper library) in Configurable Firmata already handle all the stepper movements in the Arduino sketch, not remotely. We simply send one command to "move n steps, at x speed" and everything else is handled on the microcontroller. Firmata does not send one command per step (or worse, one command per pin per step). You can achieve pretty high step speeds, with acceleration and multiple stepper control (it gets sketchy around 800 steps per second on an Uno).

I have a video that demonstrates. Disregard the JS stickers, all the magic is happening in Firmata running on an Arduino Uno.

https://youtu.be/015PZOXdqiE

Pls send code of it if you have. I have no idea of syntax in python so upload code of it.

dtex commented 4 years ago

As you said it is possible to run multiple stepper by creating different instances but its not working.

I did not realize that Pymata did not use Firmata's legacy stepper code until it was explained above so just adding another instance will not work. I'm sorry, I don't know of any other options for Python. It would be quite a lot of work for you to make that happen.

One possibility would be to use JavaScript instead of Python, but rarely is switching languages an attractive option. I feel like a jerk for even suggesting it, but that's all I've got.

One more clarification though, accelStepper does not block. You can have a limit switch or something like that send it's updated state back to your host code which can, in turn, stop a stepper mid-move. There's a round trip involved so it may take a bit to stop, but it totally works.

MrYsLab commented 4 years ago

Since Mainsh2208 states that he doesn't know Python syntax, dtex's suggestion of JS at this point in time is probably the best. Without knowing the actual application requirements it is difficult to help. This issue should really be closed since it has nothing to do with the Firmata protocol. I have no idea where it should be moved since for me it would entail changing the client, FirmataExpress sketch and the purchase of additional steppers, none of which I am willing to do at this point in time.

dtex commented 4 years ago

@Manish2208

Here's a JavaScript example:

https://github.com/firmata/firmata.js/blob/master/packages/firmata.js/examples/stepper-multi.js

panchalmanish2208 commented 4 years ago

Sorry to rope you in like that, I figured it was really a Python question and to the best of my knowledge, you're the most expert of all the experts when it comes to Firmata + Python. Everything you said is true, but I do need to clarify one thing. accelStepper (and the legacy stepper library) in Configurable Firmata already handle all the stepper movements in the Arduino sketch, not remotely. We simply send one command to "move n steps, at x speed" and everything else is handled on the microcontroller. Firmata does not send one command per step (or worse, one command per pin per step). You can achieve pretty high step speeds, with acceleration and multiple stepper control (it gets sketchy around 800 steps per second on an Uno). I have a video that demonstrates. Disregard the JS stickers, all the magic is happening in Firmata running on an Arduino Uno. https://youtu.be/015PZOXdqiE

Pls send code of it if you have. I have no idea of syntax in python so upload code of it.

Let me correct it first I want to say that I don't know how to use Configurable Firmata in python only for handling stepper movement as you mention in the video . And I want example for the same. Using a JavaScript for running stepper it might be difficult for me. As my whole project is using python programming only .

MrYsLab commented 4 years ago

@Manish2208 I have a solution for you, but it is going to take some effort on your part. I have written a framework called python-banyan that will allow you to create an application using both your existing Python code (with some refactoring) and being able to easily communicate with a portion of the application written in JavaScript, Ruby or Java. Since @dtex has already supplied some JS code so that would be the way I would go.

In the banyan documentation, I have an example of an echo server written in JS and the client written in Python and both communicating and interacting with one another easily and seamlessly.

What I would suggest is that you read the docs through tutorial 4. The Python client and the JS server are discussed in those sections.

You would need to refactor your design so that all the interaction with the Arduino would be done on the JS side. It need not do any fancy processing other than the very basic Firmata interactions. The data processing would still be done on the Python side.

Although I am not willing to write code for you, I would be more than willing to provide any explanations about Banyan and if you should run into issues, I would be willing to look at your code. On the JS and configurable-firmata side, I am less likely to be able to help because my experience is limited in these areas.

If you decide to take me up on this offer, I would ask that:

  1. You close this issue.
  2. If you wish to contact me directly you may. My email address is on my GitHub homepage.
LinuksGuru commented 4 years ago

Hi, Manish2208! Can you please publish your Python code which sends commands to Arduino / AccelStepperFirmata? I have some problems with that combo described here: https://github.com/firmata/protocol/issues/120 Thanks in advance !

MrYsLab commented 4 years ago

I have documented, in great detail, how to create SysEx message in this article. It is several years old and is specific to my original Python client. I will be publishing a similar article for pymata4 in the very near future.

raprakashvi commented 1 year ago

I know I am quite late to the discussion but I came across a need to run two stepper motors using pymata and one of my solution worked. Mentioning here in case it helps.

We can only create a single instance of board (Arduino) and this is okay. I bypassed the issue by creating a motor class which took board and motor ID as instance, and I initialized my motors by using the pin numbers rather than the stepper motor function. Now that I have two objects of motors , I can alternately call them to do what I want, though I can only use one at a given time.

This does have issues which I cannot solve or explain, such as, the motors stop reacting to commands at times. Happens less but does happen.

MrYsLab commented 1 year ago

@raprakashvi The Arduino side uses the Arduino Servo library. It was designed to control servos individually, so Pymata is under that constraint. You may wish to explore using a PCA9685 controller to run simultaneous servos. It uses i2c. I have a pca9685 library for Telemetrix