diff options
Diffstat (limited to 'Adafruit_Python_GPIO/Adafruit_GPIO/PWM.py')
-rw-r--r-- | Adafruit_Python_GPIO/Adafruit_GPIO/PWM.py | 128 |
1 files changed, 128 insertions, 0 deletions
diff --git a/Adafruit_Python_GPIO/Adafruit_GPIO/PWM.py b/Adafruit_Python_GPIO/Adafruit_GPIO/PWM.py new file mode 100644 index 0000000..1e1717a --- /dev/null +++ b/Adafruit_Python_GPIO/Adafruit_GPIO/PWM.py @@ -0,0 +1,128 @@ +# Copyright (c) 2014 Adafruit Industries +# Author: Tony DiCola +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. +import Adafruit_GPIO.Platform as Platform + + +class RPi_PWM_Adapter(object): + """PWM implementation for the Raspberry Pi using the RPi.GPIO PWM library.""" + + def __init__(self, rpi_gpio, mode=None): + self.rpi_gpio = rpi_gpio + # Suppress warnings about GPIO in use. + rpi_gpio.setwarnings(False) + # Set board or BCM pin numbering. + if mode == rpi_gpio.BOARD or mode == rpi_gpio.BCM: + rpi_gpio.setmode(mode) + elif mode is not None: + raise ValueError('Unexpected value for mode. Must be BOARD or BCM.') + else: + # Default to BCM numbering if not told otherwise. + rpi_gpio.setmode(rpi_gpio.BCM) + # Store reference to each created PWM instance. + self.pwm = {} + + def start(self, pin, dutycycle, frequency_hz=2000): + """Enable PWM output on specified pin. Set to intiial percent duty cycle + value (0.0 to 100.0) and frequency (in Hz). + """ + if dutycycle < 0.0 or dutycycle > 100.0: + raise ValueError('Invalid duty cycle value, must be between 0.0 to 100.0 (inclusive).') + # Make pin an output. + self.rpi_gpio.setup(pin, self.rpi_gpio.OUT) + # Create PWM instance and save a reference for later access. + self.pwm[pin] = self.rpi_gpio.PWM(pin, frequency_hz) + # Start the PWM at the specified duty cycle. + self.pwm[pin].start(dutycycle) + + def set_duty_cycle(self, pin, dutycycle): + """Set percent duty cycle of PWM output on specified pin. Duty cycle must + be a value 0.0 to 100.0 (inclusive). + """ + if dutycycle < 0.0 or dutycycle > 100.0: + raise ValueError('Invalid duty cycle value, must be between 0.0 to 100.0 (inclusive).') + if pin not in self.pwm: + raise ValueError('Pin {0} is not configured as a PWM. Make sure to first call start for the pin.'.format(pin)) + self.pwm[pin].ChangeDutyCycle(dutycycle) + + def set_frequency(self, pin, frequency_hz): + """Set frequency (in Hz) of PWM output on specified pin.""" + if pin not in self.pwm: + raise ValueError('Pin {0} is not configured as a PWM. Make sure to first call start for the pin.'.format(pin)) + self.pwm[pin].ChangeFrequency(frequency_hz) + + def stop(self, pin): + """Stop PWM output on specified pin.""" + if pin not in self.pwm: + raise ValueError('Pin {0} is not configured as a PWM. Make sure to first call start for the pin.'.format(pin)) + self.pwm[pin].stop() + del self.pwm[pin] + + +class BBIO_PWM_Adapter(object): + """PWM implementation for the BeagleBone Black using the Adafruit_BBIO.PWM + library. + """ + + def __init__(self, bbio_pwm): + self.bbio_pwm = bbio_pwm + + def start(self, pin, dutycycle, frequency_hz=2000): + """Enable PWM output on specified pin. Set to intiial percent duty cycle + value (0.0 to 100.0) and frequency (in Hz). + """ + if dutycycle < 0.0 or dutycycle > 100.0: + raise ValueError('Invalid duty cycle value, must be between 0.0 to 100.0 (inclusive).') + self.bbio_pwm.start(pin, dutycycle, frequency_hz) + + def set_duty_cycle(self, pin, dutycycle): + """Set percent duty cycle of PWM output on specified pin. Duty cycle must + be a value 0.0 to 100.0 (inclusive). + """ + if dutycycle < 0.0 or dutycycle > 100.0: + raise ValueError('Invalid duty cycle value, must be between 0.0 to 100.0 (inclusive).') + self.bbio_pwm.set_duty_cycle(pin, dutycycle) + + def set_frequency(self, pin, frequency_hz): + """Set frequency (in Hz) of PWM output on specified pin.""" + self.bbio_pwm.set_frequency(pin, frequency_hz) + + def stop(self, pin): + """Stop PWM output on specified pin.""" + self.bbio_pwm.stop(pin) + + +def get_platform_pwm(**keywords): + """Attempt to return a PWM instance for the platform which the code is being + executed on. Currently supports only the Raspberry Pi using the RPi.GPIO + library and Beaglebone Black using the Adafruit_BBIO library. Will throw an + exception if a PWM instance can't be created for the current platform. The + returned PWM object has the same interface as the RPi_PWM_Adapter and + BBIO_PWM_Adapter classes. + """ + plat = Platform.platform_detect() + if plat == Platform.RASPBERRY_PI: + import RPi.GPIO + return RPi_PWM_Adapter(RPi.GPIO, **keywords) + elif plat == Platform.BEAGLEBONE_BLACK: + import Adafruit_BBIO.PWM + return BBIO_PWM_Adapter(Adafruit_BBIO.PWM, **keywords) + elif plat == Platform.UNKNOWN: + raise RuntimeError('Could not determine platform.') |