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

Add StepperMotor #757

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open

Add StepperMotor #757

wants to merge 5 commits into from

Conversation

alcarazzam
Copy link

Hello:
This is a suggestion to add a StepperMotor class to the library. It is based on this code with some improvements and tested using this motor.

Some examples:

from time import sleep
from gpiozero import StepperMotor

motor = StepperMotor(pins=(18,22,17,27), sequence=((1, 0, 1, 0),(0, 1, 1, 0),(0, 1, 0, 1),(1, 0, 0, 1)), 
delay=4/1000)
motor.forward(100) # Move 100 steps
motor.backward() # Move unlimited time
sleep(3)
motor.cleanup() # Stop motor and shut down pins

with StepperMotor(pins=(18,22,17,27), sequence=((1, 0, 1, 0),(0, 1, 1, 0),(0, 1, 0, 1),(1, 0, 0, 1)), delay=4/1000) as mt:
    mt.forward()
    sleep(1)
    mt.backward()
    sleep(1)

@codecov-io
Copy link

codecov-io commented Mar 17, 2019

Codecov Report

Merging #757 into master will decrease coverage by 1.28%.
The diff coverage is 20.2%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master     #757      +/-   ##
==========================================
- Coverage   79.46%   78.17%   -1.29%     
==========================================
  Files          23       23              
  Lines        4470     4568      +98     
  Branches      650      669      +19     
==========================================
+ Hits         3552     3571      +19     
- Misses        863      942      +79     
  Partials       55       55
Impacted Files Coverage Δ
gpiozero/__init__.py 100% <ø> (ø) ⬆️
gpiozero/output_devices.py 82.95% <20.2%> (-12.03%) ⬇️
gpiozero/pins/pigpio.py 1.34% <0%> (ø) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 9cba4aa...528ce41. Read the comment docs.

@lurch
Copy link
Contributor

lurch commented Mar 20, 2019

Thanks. Just some quick feedback (without having looked at the underlying code, which I'll try to do later...)

IMHO having an __init__ method that requires the user to specify the pins as a list and the sequence as a list-of-lists isn't very user-friendly and doesn't feel like the same level of abstraction as the rest of GpioZero. I don't know much about stepper motors but when/why would the user need to provide a different sequence? Would it make sense to also provide e.g. a HMISoftwareStepperDriver class as a wrapper around this StepperMotor class, which has e.g. pinX1_0, pinX1_1, pinX1_2, pinX1_3 as init-params? (if you're feeling adventurous you could implement this as a CompositeDevice of two StepperMotors)

I'm not sure about a .forward(steps) method as it conflicts with the .forward(speed) method of the existing Motor class. Would it be possible (or make sense) to implement a .forward(speed) method for compatibility, and add a separate method for specifying the number of steps? 🤷‍♂️

@alcarazzam
Copy link
Author

Hello

I've rename the forward and backward functions so you can set the speed of the motor relative to its initial velocity. Now, if you want to move a certain number of steps, you need to call the forward_steps function.

For a user-friendly __init__ method, I've added the BasicStepperMotor class with predefined attributes. You can create another classes for others motors that uses another configurations.

Now it is the example code:

from time import sleep
from gpiozero import BasicStepperMotor

motor = BasicStepperMotor() # Set pins=() if you are using another.
motor.forward_steps(100) # Move 100 steps
motor.backward(2) # Move unlimited time at x2 speed
sleep(3)
motor.cleanup() # Stop motor and shut down pins.

@lurch
Copy link
Contributor

lurch commented Mar 21, 2019

Thanks.

motor.backward(2)

If you look at the docs for the existing Motor class you'll see that the speed ranges from 0 (stopped) to 1 (full speed), with values inbetween indicating different speeds (e.g. 0.5 for half maximum speed). Would it be possible for you to tweak your code to match that "API" too?
And I don't think you need an explicit cleanup() method, IIRC GpioZero automatically calls any close() method on your class when it garbage-collects the object.

@alcarazzam
Copy link
Author

Hello
I was thinking about the speed value when I wrote the code. To control de speed of the motor, you change the delay attribute. But if you want to move the motor at its half maximum speed, you need to know the maximum delay the motor can have. If you use a huge delay, the motor won't move. I can add a new attribute to the StepperMotor class to define its min and max delay time. Is it a good option? What do you think? Thanks.

@alcarazzam
Copy link
Author

Hello
StepperMotor class now match "API". That's the code:

from time import sleep
from gpiozero import StepperMotor, BasicStepperMotor

motor = BasicStepperMotor()
motor.forward(speed=0.1)
sleep(2)
motor.backward()
sleep(2)
motor.stop() # Stop motor

And I don't think you need an explicit cleanup() method

Sorry, it's for the first example I wrote, which uses later the same pins for other test.

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

Successfully merging this pull request may close these issues.

None yet

3 participants