MrYsLab / PyMata

A Python client class library for Interaction with Standard Firmata
GNU Affero General Public License v3.0
95 stars 40 forks source link

Stepper Motor Library Support #1

Closed FineLineAutomation closed 10 years ago

FineLineAutomation commented 10 years ago

Do you support the stepper motor library of configurable firmata? If not, what would it take to implement it?

MrYsLab commented 10 years ago

The stepper motor is currently not supported. I think adding support would be rather straight forward. Basically here is what would need to be done:

  1. A new method would need to be added to the PyMata class that would accept the parameters for a stepper motor command from the user.
  2. A new method would also be added to the PyMataCommandHandler class to process the stepper data sent from the method of step 1 above. This method would format an appropriate sysex command message and send it out the serial port. This command would need to be placed in the command dispatch table as well.

Currently, I do not own any stepper motors or I would give it a try.

What is your time frame to have this available? I have a few things in the fire currently, and am not sure how soon I could get to this. If you want to try and implement it yourself, I would be happy to provide some guidance.

Also, are you looking for support for a specific motor?

FineLineAutomation commented 10 years ago

I don't need it right away. It's a hobby project at the moment.

I can try to implement it myself. The configurable firmata protocol supports 3 types of configurations: 2 wire drive, 4 wire drive, and a driver type (step and direction inputs). The motors I am going to be using have a driver type configuration. I think that if the protocol is going to be implemented, you do all 3 types. I just need some background on what sysex command I am supposed to send. It's not very apparent to me even after looking at the firmata library code. Also, will I need to modify your custom firmata implementation to support stepper motors or can I use the configurable firmata library? I think that library has stepper motor support.

MrYsLab commented 10 years ago

This is going to be a long explanation. If this become way too confusing, we can always schedule a google video hangout and it may be easier to understand. If you want to do that, just email me at MisterYsLab@gmail.com

Let me answer your last question first. I might be missing your point, but I just want to clarify something. If I am misunderstanding, just let me know. Firmata support, consists of 2 pieces. One, the server portion, resides on the Arduino. That could be StandardFirmata, or configurable. The other piece is the client piece that normally resides on a PC. PyMata is a Firmata client.

So to implement this, assuming that the configurable code for steppers has been tested and has no problems, you would need to implement things on the PyMata end only.

OK, so to understand what PyMata needs to do, you need to look at the StepperFirmata class This class interfaces with PyMata through a data stream called sysex messaging. The other class, FirmataStepper, is where the Arduino talks to the motor(s) and is directed by StepperFirmata through method calls. The protocol needed for a sysex command is specified implicitly within the Arduino code (in this case StepperFirmata).

So to summarize, PyMata sends a sysex command and accompanying data stream to StepperFirmata. StepperFirmata interprets these messages, calls the correct FirmataStepper method which then controls the motor.

OK, back to PyMata and sysex. What you need to look at is StepperFirmata in detail. I will get to that in a minute, but just a little info on what a sysex data stream consists of. Hold on to your hat - this isn't very pretty, but once you understand this, everything else is a piece of cake. The sysex data consists of a stream of 7 bit values (each 7 bit value fits within an 8 bit byte - you would mask the value with 0x7f). If you need to pass a parameter that is larger than 7 bits, you need to break the large value into 7 bit pieces and the receiver would then piece them back together.

OK, so let me take some example code from StepperFirmata so you can see what you need to do. I will comment the code beginning with //MrY so can identify my comments

boolean StepperFirmata::handleSysex(byte command, byte argc, byte *argv) { //MrY all of the data in a sysex stream is constructed by PyMata and sent to configurable serially. Since the stepper interface is a one way interface, no sysex streams will be going back to PyMata (makes life easier)

//MrY the "command" is the sysex command that Arduino Firmata uses to dispatch which method handles the sysex stream. In this case the method is double checking to make sure it is the correct command for it to handle and if not, it just returns. if (command == STEPPER_DATA) {]

byte stepCommand, deviceNum, directionPin, stepPin, stepDirection, interface;
byte motorPin3, motorPin4;
unsigned int stepsPerRev;
long numSteps;
int stepSpeed;
int accel;
int decel;

// MrY PyMata is responsible for placing the bytes of the sysex stream in the correct order. It knows how to do this by the developer looking at the code on the Arduino side to see what the protocol is for the "command" and then implements that protocol. The rest of the comments will describe what is going on.

// MrY The first byte of the sysex stream - argv[0] contains the step command and argv[1] contains the device number, in case you are using more than one motor.
stepCommand = argv[0];
deviceNum = argv[1];

if (deviceNum<MAX_STEPPERS) {
  if (stepCommand == STEPPER_CONFIG) {

//MrY the interface specifies 2 wire, 4 wire, or driver interface = argv[2]; // MrY now the interesting part. StepsPerRev is defined above as a uint. So it takes two 7 bit values to construct the uint. argv[3] is the lower order value and argv[4] is the high order value. We know that because of the shifting. On the PyMata side, it would have shifted and AND'ed to construct the value stepsPerRev = (argv[3] + (argv[4] << 7)); //MrY and the rest of the method is left out.

So, this class reconstructs parameter values from the sysex stream by looking at the position of the data, and then calls the appropriate method in FirmataStepper to get the motor to move using the reconstructed values.

That is it in a nutshell. It sounds worse than it is (or at least how I described it). I can guide you through the process when you need help.

Sorry to be so long winded.

Alan

MrYsLab commented 10 years ago

I am closing this issue since there have been no further comments.

FineLineAutomation commented 10 years ago

Alan,

I actually couldn't get your library to work with Configurable Firmata. It looks like it needed all of the module installed to probe the input capabilities. I ended up switching to the pyfirmata library. Doing some final implementation testing on the stepper code I wrote. I'll let you know when it's done in case you want to port it here. Thanks for all the help.

MrYsLab commented 10 years ago

Thanks for the feedback. I have not tested configurable as of yet, but it looks as if you add the analogInput and analogOutput features in the .ino, probing should work.

:

MrYsLab commented 10 years ago

Please read: http://www.instructables.com/id/Going-Beyond-StandardFirmata-Adding-New-Device-Sup/

jrr1984 commented 4 years ago

any updates here?

MrYsLab commented 4 years ago

Hi, I am not sure what you are asking. Are you asking if there are any updates with PyMata and Configurable Firmata? If that is your question, then the answer is no. I could never get Configurable Firmata to build and work, so I will not be supporting Configurable Firmata. If this is not your question, please explain.

panchalmanish2208 commented 4 years ago

How to control or connect 2 or 3 stepper motors using pymata with arduino? Pls give some examples

MrYsLab commented 4 years ago

@Manish2208 Thanks for your question. The simple answer is that pymata can only support a single stepper motor. The reason for this is that the stepper motor library blocks when it is moving a motor. This then blocks the Firmata sketch. What this means, is that if you need to start a second motor while the first is running, you will not be able to until the stepper library is finished with the first motor. In addition, if you need to have real-time monitoring of a sensor while the stepper library is executing, because of the blocking, the sensor data update is blocked as well.

Also, I have not found an Arduino stepper motor board that can control more than a single stepper. One solution is to use i2c based motor controllers, such as the one from Pololu. This is a very expensive solution, and you would be responsible to create the i2c code. This may or may not work with PyMata.

Please let me know if you have any other questions.