-
-
Save ochafik/7593078f632ac952585e27d8ab41af01 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/python | |
| import time | |
| import math | |
| import smbus | |
| # ============================================================================ | |
| # Raspi PCA9685 16-Channel PWM Servo Driver | |
| # ============================================================================ | |
| class PCA9685: | |
| # Registers/etc. | |
| __SUBADR1 = 0x02 | |
| __SUBADR2 = 0x03 | |
| __SUBADR3 = 0x04 | |
| __MODE1 = 0x00 | |
| __PRESCALE = 0xFE | |
| __LED0_ON_L = 0x06 | |
| __LED0_ON_H = 0x07 | |
| __LED0_OFF_L = 0x08 | |
| __LED0_OFF_H = 0x09 | |
| __ALLLED_ON_L = 0xFA | |
| __ALLLED_ON_H = 0xFB | |
| __ALLLED_OFF_L = 0xFC | |
| __ALLLED_OFF_H = 0xFD | |
| def __init__(self, address=0x40, debug=False): | |
| self.bus = smbus.SMBus(1) | |
| self.address = address | |
| self.debug = debug | |
| if (self.debug): | |
| print("Reseting PCA9685") | |
| self.write(self.__MODE1, 0x00) | |
| def write(self, reg, value): | |
| "Writes an 8-bit value to the specified register/address" | |
| self.bus.write_byte_data(self.address, reg, value) | |
| if (self.debug): | |
| print("I2C: Write 0x%02X to register 0x%02X" % (value, reg)) | |
| def read(self, reg): | |
| "Read an unsigned byte from the I2C device" | |
| result = self.bus.read_byte_data(self.address, reg) | |
| if (self.debug): | |
| print("I2C: Device 0x%02X returned 0x%02X from reg 0x%02X" % (self.address, result & 0xFF, reg)) | |
| return result | |
| def setPWMFreq(self, freq): | |
| "Sets the PWM frequency" | |
| prescaleval = 25000000.0 # 25MHz | |
| prescaleval /= 4096.0 # 12-bit | |
| prescaleval /= float(freq) | |
| prescaleval -= 1.0 | |
| if (self.debug): | |
| print("Setting PWM frequency to %d Hz" % freq) | |
| print("Estimated pre-scale: %d" % prescaleval) | |
| prescale = math.floor(prescaleval + 0.5) | |
| if (self.debug): | |
| print("Final pre-scale: %d" % prescale) | |
| oldmode = self.read(self.__MODE1); | |
| newmode = (oldmode & 0x7F) | 0x10 # sleep | |
| self.write(self.__MODE1, newmode) # go to sleep | |
| self.write(self.__PRESCALE, int(math.floor(prescale))) | |
| self.write(self.__MODE1, oldmode) | |
| time.sleep(0.005) | |
| self.write(self.__MODE1, oldmode | 0x80) | |
| def setPWM(self, channel, on, off): | |
| "Sets a single PWM channel" | |
| self.write(self.__LED0_ON_L+4*channel, on & 0xFF) | |
| self.write(self.__LED0_ON_H+4*channel, on >> 8) | |
| self.write(self.__LED0_OFF_L+4*channel, off & 0xFF) | |
| self.write(self.__LED0_OFF_H+4*channel, off >> 8) | |
| if (self.debug): | |
| print("channel: %d LED_ON: %d LED_OFF: %d" % (channel,on,off)) | |
| def setServoPulse(self, channel, pulse): | |
| "Sets the Servo Pulse,The PWM frequency must be 50HZ" | |
| pulse = pulse*4096/20000 #PWM frequency is 50HZ,the period is 20000us | |
| self.setPWM(channel, 0, int(pulse)) | |
| if __name__=='__main__': | |
| pwm = PCA9685(0x40, debug=False) | |
| pwm.setPWMFreq(50) | |
| while True: | |
| # setServoPulse(2,2500) | |
| for i in range(500,2500,10): | |
| pwm.setServoPulse(0,i) | |
| time.sleep(0.02) | |
| for i in range(2500,500,-10): | |
| pwm.setServoPulse(0,i) | |
| time.sleep(0.02) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment