aboutsummaryrefslogtreecommitdiffstats
path: root/System/pendulum/motor.py
blob: 427d393c49f61ed5ce9cfeb94cedf807dfc7ec17 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
#!/usr/bin/env python

# Import required modules
import RPi.GPIO as GPIO
from time import sleep

# Constants: parameters that the caller cannot modify
# Frequency: We have determined that the optimal frequency for our motor is 1kHz
pwm_frequency = 1000

# Motor Class
# This controls the motor at the given IO
class Motor:
    def __init__(self, speed_pin, forward_pin, reverse_pin):
        # Set the board IO (just in case it hasn't been done yet)
        GPIO.setmode(GPIO.BCM)
        # Set our variables for the directional pins
        self.forward_pin = forward_pin
        self.reverse_pin = reverse_pin
        # setup the IO
        GPIO.setup(speed_pin, GPIO.OUT)
        GPIO.setup(self.forward_pin, GPIO.OUT)
        GPIO.setup(self.reverse_pin, GPIO.OUT)
        # Set speed pin as a PWM output
        self.speed_pwm = GPIO.PWM(speed_pin, pwm_frequency)
        self.current_speed = 0.
    # END __init__
        
    # Move the motor at a given speed, given as a floating point percentage (-100 <= x <= 100)
    # If speed is less than 0, motor will run in reverse, otherwise it will run forward
    def move(self, speed):
        if speed == self.current_speed:
            # do not attempt to readjust speed; this can cause erratic behavior
            return
        if speed < -100.0 or speed > 100.0:
            return
        # Stop any previous movements
        self.speed_pwm.stop()
        # Set the duty cycle for the speed of the motor
        self.speed_pwm.ChangeDutyCycle(abs(speed))
        if speed < 0:
            # Set direction to reverse
            GPIO.output(self.forward_pin, GPIO.LOW)
            GPIO.output(self.reverse_pin, GPIO.HIGH)
        else:
            # Set the direction to forward
            GPIO.output(self.forward_pin, GPIO.HIGH)
            GPIO.output(self.reverse_pin, GPIO.LOW)
        # Start the PWM output to start moving the motor
        self.speed_pwm.start(abs(speed))
        self.current_speed = speed
        sleep((1./pwm_frequency) * 3)
    # END Move
    
    # Stop the motor from spinning.
    # To brake the motor, both direction outputs are set to HIGH
    def brake(self):
        # Stop any current PWM signals
        self.speed_pwm.stop()
        # Set the direction outputs to brake
        GPIO.output(self.forward_pin, GPIO.HIGH)
        GPIO.output(self.reverse_pin, GPIO.HIGH)
        self.current_speed = 0.
    # END Brake
        
    # Set the motor to coast (i.e. Do not provide power to the motor, but still allow it to spin)
    # To coast the motor, both direction outputs are set to LOW
    def coast(self):
        # Stop any current PWM signals
        self.speed_pwm.stop()
        # Set the direction outputs to coast
        GPIO.output(self.forward_pin, GPIO.LOW)
        GPIO.output(self.reverse_pin, GPIO.LOW)
        self.current_speed = 0.
    # END Coast