Facebook
From Szymon , 4 Years ago, written in Python.
Embed
Download Paste or View Raw
Hits: 281
  1. #!/usr/bin/python
  2.  
  3. import time
  4. import math
  5. import smbus
  6.  
  7. # ============================================================================
  8. # Raspi PCA9685 16-Channel PWM Servo Driver
  9. # ============================================================================
  10.  
  11. class PCA9685:
  12.  
  13.   # Registers/etc.
  14.   __SUBADR1            = 0x02
  15.   __SUBADR2            = 0x03
  16.   __SUBADR3            = 0x04
  17.   __MODE1              = 0x00
  18.   __PRESCALE           = 0xFE
  19.   __LED0_ON_L          = 0x06
  20.   __LED0_ON_H          = 0x07
  21.   __LED0_OFF_L         = 0x08
  22.   __LED0_OFF_H         = 0x09
  23.   __ALLLED_ON_L        = 0xFA
  24.   __ALLLED_ON_H        = 0xFB
  25.   __ALLLED_OFF_L       = 0xFC
  26.   __ALLLED_OFF_H       = 0xFD
  27.  
  28.  
  29.   def __init__(self, address, debug=False):
  30.     self.bus = smbus.SMBus(1)
  31.     self.address = address
  32.     self.debug = debug
  33.     if (self.debug):
  34.       print("Reseting PCA9685")
  35.     self.write(self.__MODE1, 0x00)
  36.     self.PWMA = 0
  37.     self.AIN1 = 1
  38.     self.AIN2 = 2
  39.     self.PWMB = 5
  40.     self.BIN1 = 3
  41.     self.BIN2 = 4
  42.  
  43.   def write(self, reg, value):
  44.     "Writes an 8-bit value to the specified register/address"
  45.     self.bus.write_byte_data(self.address, reg, value)
  46.     if (self.debug):
  47.       print("I2C: Write 0x%02X to register 0x%02X" % (value, reg))
  48.  
  49.   def read(self, reg):
  50.     "Read an unsigned byte from the I2C device"
  51.     result = self.bus.read_byte_data(self.address, reg)
  52.     if (self.debug):
  53.       print("I2C: Device 0x%02X returned 0x%02X from reg 0x%02X" % (self.address, result & 0xFF, reg))
  54.     return result
  55.  
  56.   def setPWMFreq(self, freq):
  57.     "Sets the PWM frequency"
  58.     prescaleval = 25000000.0    # 25MHz
  59.     prescaleval /= 4096.0       # 12-bit
  60.     prescaleval /= float(freq)
  61.     prescaleval -= 1.0
  62.     if (self.debug):
  63.       print("Setting PWM frequency to %d Hz" % freq)
  64.       print("Estimated pre-scale: %d" % prescaleval)
  65.     prescale = math.floor(prescaleval + 0.5)
  66.     if (self.debug):
  67.       print("Final pre-scale: %d" % prescale)
  68.  
  69.     oldmode = self.read(self.__MODE1);
  70.     newmode = (oldmode & 0x7F) | 0x10        # sleep
  71.     self.write(self.__MODE1, newmode)        # go to sleep
  72.     self.write(self.__PRESCALE, int(math.floor(prescale)))
  73.     self.write(self.__MODE1, oldmode)
  74.     time.sleep(0.005)
  75.     self.write(self.__MODE1, oldmode | 0x80)
  76.  
  77.   def setPWM(self, channel, on, off):
  78.     "Sets a single PWM channel"
  79.     self.write(self.__LED0_ON_L + 4*channel, on & 0xFF)
  80.     self.write(self.__LED0_ON_H + 4*channel, on >> 8)
  81.     self.write(self.__LED0_OFF_L + 4*channel, off & 0xFF)
  82.     self.write(self.__LED0_OFF_H + 4*channel, off >> 8)
  83.     if (self.debug):
  84.       print("channel: %d  LED_ON: %d LED_OFF: %d" % (channel,on,off))
  85.  
  86.   def setDutycycle(self, channel, pulse):
  87.     self.setPWM(channel, 0, int(pulse * (4096 / 100)))
  88.  
  89.   def setLevel(self, channel, value):
  90.     if (value == 1):
  91.       self.setPWM(channel, 0, 4095)
  92.     else:
  93.       self.setPWM(channel, 0, 0)
  94.  
  95.  
  96.   def MotorRun(self, m1, m2):
  97.         self.MotorRunL(m1)
  98.         self.MotorRunR(m2)
  99.  
  100.   def MotorRunL(self,m1):
  101.         if m1 > 101:
  102.             return
  103.         if m1 < -101:
  104.             return
  105.         if m1 > 0:
  106.                 self.setLevel(self.AIN1, 0)
  107.                 self.setLevel(self.AIN2, 1)
  108.         elif m1 < 0:
  109.                 self.setLevel(self.AIN1, 1)
  110.                 self.setLevel(self.AIN2, 0)
  111.                 m1 = -m1
  112.         #elif m1 = 0:
  113.  
  114.         self.setDutycycle(self.PWMA, m1)
  115.  
  116.   def MotorRunR(self,m2):
  117.         if m2 > 101:
  118.             return
  119.         if m2 < -101:
  120.             return
  121.         if m2 > 0:
  122.                 self.setLevel(self.BIN1, 0)
  123.                 self.setLevel(self.BIN2, 1)
  124.         elif m2 < 0:
  125.                 self.setLevel(self.BIN1, 1)
  126.                 self.setLevel(self.BIN2, 0)
  127.                 m2 = -m2
  128.         #elif m2 = 0:
  129.  
  130.         self.setDutycycle(self.PWMB, m2)
  131. # pwm = PCA9685(0x5f, debug=False)
  132. # pwm.setPWMFreq(50)
  133. # pwm.setDutycycle(0,100)
  134. # pwm.setLevel(1,0)
  135. # pwm.setLevel(2,1)
  136.