def __init__(self, hdwr): # ---- Setup PWM Generator ---- self.pin = navio.gpio.Pin(27) #Enable OE pin output. self.pin.write( 0 ) #Drive the PCA9685BS model HVQFN28's OE pin #20 (27 RPI2) to "LOW" self.frequency = 45.05 #This frequency prioritizes use of the ESC and plays well with the servo. self.period = 1.0 / self.frequency """ Please use 45.05Hz to properly operate the ESC controller. Please use frequencies 50Hz OR 300Hz for this code to reliably operate the steering servo. Other intermittent frequencies like 60,90,100 may or may not work. There doesn't appear to be a pattern. """ self.PCA9685_DEFAULT_ADDRESS = 0x40 #Adresses the PCA9685BS register controlling LED14_OFF_L self.pwm = PWM( 0x40, debug=False ) #Send the PWM register address to be used by internal modules adafruit_pwm_servo_driver.py, adafruit_i2c.py, and ultimately smbus.py self.pwm.setPWMFreq( self.frequency) #Set output pulse frequency of the PCA9685. # ---- End PWM Generator Setup ---- # ---- Set Separate PWM Constants ---- if (hdwr == "servo"): self.servoInit() self.rest() elif (hdwr == "esc"): self.escInit() self.stop() else: sys.exit("Specify the hardware to use vehiclePWM")
def __init__(self,hdwr): # ---- Setup PWM Generator ---- self.pin = navio.gpio.Pin(27)#Enable OE pin output. self.pin.write(0)#Drive the PCA9685BS model HVQFN28's OE pin #20 (27 RPI2) to "LOW" self.frequency = 45.05 #This frequency prioritizes use of the ESC and plays well with the servo. self.period = 1.0/self.frequency """ Please use 45.05Hz to properly operate the ESC controller. Please use frequencies 50Hz OR 300Hz for this code to reliably operate the steering servo. Other intermittent frequencies like 60,90,100 may or may not work. There doesn't appear to be a pattern. """ self.PCA9685_DEFAULT_ADDRESS = 0x40#Adresses the PCA9685BS register controlling LED14_OFF_L self.pwm = PWM(0x40, debug=False)#Send the PWM register address to be used by internal modules adafruit_pwm_servo_driver.py, adafruit_i2c.py, and ultimately smbus.py self.pwm.setPWMFreq(self.frequency)#Set output pulse frequency of the PCA9685. # ---- End PWM Generator Setup ---- # ---- Set Separate PWM Constants ---- if (hdwr == "servo"): self.servoInit() self.rest() elif (hdwr == "esc"): self.escInit() self.stop() else: sys.exit("Specify the hardware to use vehiclePWM")
class motor(NAVIO_RCOUTPUT): navio.util.check_apm() NAVIO_RCOUTPUT += 2 #drive Output Enable in PCA low pin = navio.gpio.Pin(27) pin.write(0) PCA9685_DEFAULT_ADDRESS = 0x40 frequency = 50 #NAVIO_RCOUTPUT_1 = 3 SERVO_MIN_ms = 1.250 # mS SERVO_MAX_ms = 1.750 # mS #Convertir mS a rango 0-4096: SERVO_MIN = math.trunc((SERVO_MIN_ms * 4096.0) / (1000.0 / frequency) - 1) SERVO_MAX = math.trunc((SERVO_MAX_ms * 4096.0) / (1000.0 / frequency) - 1) pwm = PWM(0x40, debug=False) #Set frecuencia pwm.setPWMFreq(frequency) def MotorOn: pwm.setPWM(self.NAVIO_RCOUTPUT, 0, self.SERVO_MAX); def MotorOff: pwm.setPWM(self.NAVIO_RCOUTPUT, 0, self.SERVO_MIN);
class rele: def __init__(self, NAVIO_RCOUTPUT): self.NAVIO_RCOUTPUT = NAVIO_RCOUTPUT + 2 self.inicial = inicial navio.util.check_apm() #drive Output Enable in PCA low pin = navio.gpio.Pin(27) pin.write(0) PCA9685_DEFAULT_ADDRESS = 0x40 frequency = 50 #NAVIO_RCOUTPUT_1 = 3 SERVO_MIN_ms = 1.000 # mS SERVO_MAX_ms = 2.000 # mS #Convertir mS a rango 0-4096: SERVO_MIN = math.trunc((SERVO_MIN_ms * 4096.0) / (1000.0 / frequency) - 1) SERVO_MAX = math.trunc((SERVO_MAX_ms * 4096.0) / (1000.0 / frequency) - 1) pwm = PWM(0x40, debug=False) #Set frecuencia pwm.setPWMFreq(frequency) def ReleOn: pwm.setPWM(self.NAVIO_RCOUTPUT, 0, self.SERVO_MAX); def ReleOff: pwm.setPWM(self.NAVIO_RCOUTPUT, 0, self.SERVO_MIN);
class vehiclePWM: #Notice: these variables outside of a method are class attributes. Their values are shared by all object instances of this class. PreviousSpeed = 0 #Notice: the variables inside the __init__ method are created privately for each object. def __init__(self,hdwr): # ---- Setup PWM Generator ---- self.pin = navio.gpio.Pin(27)#Enable OE pin output. self.pin.write(0)#Drive the PCA9685BS model HVQFN28's OE pin #20 (27 RPI2) to "LOW" self.frequency = 45.05 #This frequency prioritizes use of the ESC and plays well with the servo. self.period = 1.0/self.frequency """ Please use 45.05Hz to properly operate the ESC controller. Please use frequencies 50Hz OR 300Hz for this code to reliably operate the steering servo. Other intermittent frequencies like 60,90,100 may or may not work. There doesn't appear to be a pattern. """ self.PCA9685_DEFAULT_ADDRESS = 0x40#Adresses the PCA9685BS register controlling LED14_OFF_L self.pwm = PWM(0x40, debug=False)#Send the PWM register address to be used by internal modules adafruit_pwm_servo_driver.py, adafruit_i2c.py, and ultimately smbus.py self.pwm.setPWMFreq(self.frequency)#Set output pulse frequency of the PCA9685. # ---- End PWM Generator Setup ---- # ---- Set Separate PWM Constants ---- if (hdwr == "servo"): self.servoInit() self.rest() elif (hdwr == "esc"): self.escInit() self.stop() else: sys.exit("Specify the hardware to use vehiclePWM") def servoInit(self): self.NAVIO_RCOUTPUT = 3 self.PWM_MinWidth = 0.000685 #S. This calculation was updated on April 30, 2016. It is made large enough to work at 300Hz self.PWM_MaxWidth = 0.002675 #S. This calculation was updated on April 30, 2016. It is made small enough to work at 50Hz self.PWM_Range = self.PWM_MaxWidth - self.PWM_MinWidth #0.00199 self.SERVO_Range = 180.0 #Define servo degrees of movement. Must be a float for correct calculations/operation def escInit(self): self.NAVIO_RCOUTPUT = 5 self.PWM_MinWidth = 0.001158 #S. This was measured on May 1, 2016. self.PWM_MaxWidth = 0.0021 #Changed this on May 2, 2016 to get about 1.91ms output self.PWM_Range = self.PWM_MaxWidth - self.PWM_MinWidth self.PWM_Stop = 0.001700 #T = 0.0017 is the neutral, corresponding to about 1.5ms self.Motor_Range = 100.0 #Define motor max speed # ---- End PWM Constants ---- """ A 12bit digital I2C signal controls the PCA9685 which then prepares an analog PWM wave for the Savox SC-1258TG servo. The PWM signal's absolute width directly controls the servo's angle. Emperical testing on April 4, 2016 shows that in order to maintain a constant signal width, the value of the 12 bits written must change with respect to the operating frequency. The specific relation: 12BitWritten = 12BitRange * (DesiredSignalWidth * OperatingFrequency) """ # ---- Servo Outputs ---- def steer(self, deg): """ steering range is 70 degrees the servo must move about 1/4 of the total range to move the wheels at all deg = 50 to turn full right deg = 120 to turn full left deg = 81 to center, even though it is not the median of the range """ deg = 85 + deg #Convert from +-35 to 50-120 PWM_Width = self.PWM_MinWidth + (self.PWM_Range * (deg/self.SERVO_Range))# Convert our 180 degree positions to PWM widths in seconds SERVO_move = math.trunc((4096.0 * PWM_Width * self.frequency) -1)#Convert PWM widths to 12 bits (a scale of 0-4095) to write to the PCA9685. try: self.pwm.setPWM(self.NAVIO_RCOUTPUT, 0, SERVO_move) except KeyboardInterrupt: self.rest() sys.exit() def center(self): PWM_Width = self.PWM_MinWidth + (self.PWM_Range * (81/self.SERVO_Range)) SERVO_move = math.trunc((4096.0 * PWM_Width * self.frequency) -1) try: self.pwm.setPWM(self.NAVIO_RCOUTPUT, 0, SERVO_move) except KeyboardInterrupt: self.rest() sys.exit() def rest(self): self.pwm.setPWM(self.NAVIO_RCOUTPUT, 0, 0)#0S. To rest servo so it doesn't hold a position, send an invalid PWM signal by sending an invalid 0-4096 bits. #---- End Servo Outputs ---- #---- ESC Outputs ---- def accel(self, speed): #print 'start: s%d, p%d' % (speed,vehiclePWM.PreviousSpeed) if (speed < 0): if (vehiclePWM.PreviousSpeed > 0): self.stop() time.sleep(0.5) #print 'firstReverse' self.reverse(speed) time.sleep(0.25) self.stop() time.sleep(0.25) self.reverse(speed) else: self.reverse(speed) else: if (vehiclePWM.PreviousSpeed <= 0): self.stop() time.sleep(0.5) self.forward(speed) else: self.forward(speed) vehiclePWM.PreviousSpeed = speed #print 'end: s%d, p%d' % (speed,vehiclePWM.PreviousSpeed) def forward(self,Motor_speed): """ PWM width 1.725ms minimum forward loaded PWM width 2.140ms maximum forward loaded """ PWM_Width = 0.001725 + (0.000415 * (Motor_speed/self.Motor_Range)) #print 'PWM_Width %f' %PWM_Width Motor_move = math.trunc((4096.0 * PWM_Width * self.frequency) -1) #print 'Motor_move %f' %Motor_move self.pwm.setPWM(self.NAVIO_RCOUTPUT,0,Motor_move) def reverse(self,Motor_speed): """ PWM width 1.590ms minimum reverse loaded PWM width 1.300ms maximum reverse loaded """ PWM_Width = 0.00159 + (0.000290 * (Motor_speed/self.Motor_Range)) #print 'PWM_Width %f' %PWM_Width Motor_move = math.trunc((4096.0 * PWM_Width * self.frequency) -1) #print 'Motor_move %f' %Motor_move self.pwm.setPWM(self.NAVIO_RCOUTPUT,0,Motor_move) def stop(self): stop = math.trunc((4096.0 * self.PWM_Stop * self.frequency) -1) self.pwm.setPWM(self.NAVIO_RCOUTPUT,0,stop)#To stop the motor send a constant stop pulse
#from Adafruit_PWM_Servo_Driver import PWM from navio.adafruit_pwm_servo_driver import PWM import time import sys import navio.gpio import navio.util navio.util.check_apm() #drive Output Enable in PCA low pin = navio.gpio.Pin(27) pin.write(0) pwm = PWM(0x40, debug=False) # Set frequency to 60 Hz pwm.setPWMFreq(60) step = 1 # light color changing step # set initial color R = 0 G = 0 B = 4095 pwm.setPWM(0, 0, B) print "LED is yellow" time.sleep(1) while (True):
navio.util.check_apm() #drive Output Enable in PCA low pcaPin = 27 GPIO.setmode(GPIO.BCM) GPIO.setup(pcaPin, GPIO.OUT) GPIO.output(pcaPin, GPIO.LOW) PCA9685_DEFAULT_ADDRESS = 0x40 frequency = 50 NAVIO_RCOUTPUT_1 = 3 SERVO_MIN_ms = 1.250 # mS SERVO_MAX_ms = 1.750 # mS #convert mS to 0-4096 scale: SERVO_MIN = math.trunc((SERVO_MIN_ms * 4096.0) / (1000.0 / frequency) - 1) SERVO_MAX = math.trunc((SERVO_MAX_ms * 4096.0) / (1000.0 / frequency) - 1) pwm = PWM(0x40, debug=False) # Set frequency to 60 Hz pwm.setPWMFreq(frequency) while (True): pwm.setPWM(NAVIO_RCOUTPUT_1, 0, SERVO_MIN) time.sleep(1) pwm.setPWM(NAVIO_RCOUTPUT_1, 0, SERVO_MAX) time.sleep(1)
class vehiclePWM: #Notice: these variables outside of a method are class attributes. Their values are shared by all object instances of this class. PreviousSpeed = 0 #Notice: the variables inside the __init__ method are created privately for each object. def __init__(self, hdwr): # ---- Setup PWM Generator ---- self.pin = navio.gpio.Pin(27) #Enable OE pin output. self.pin.write( 0 ) #Drive the PCA9685BS model HVQFN28's OE pin #20 (27 RPI2) to "LOW" self.frequency = 45.05 #This frequency prioritizes use of the ESC and plays well with the servo. self.period = 1.0 / self.frequency """ Please use 45.05Hz to properly operate the ESC controller. Please use frequencies 50Hz OR 300Hz for this code to reliably operate the steering servo. Other intermittent frequencies like 60,90,100 may or may not work. There doesn't appear to be a pattern. """ self.PCA9685_DEFAULT_ADDRESS = 0x40 #Adresses the PCA9685BS register controlling LED14_OFF_L self.pwm = PWM( 0x40, debug=False ) #Send the PWM register address to be used by internal modules adafruit_pwm_servo_driver.py, adafruit_i2c.py, and ultimately smbus.py self.pwm.setPWMFreq( self.frequency) #Set output pulse frequency of the PCA9685. # ---- End PWM Generator Setup ---- # ---- Set Separate PWM Constants ---- if (hdwr == "servo"): self.servoInit() self.rest() elif (hdwr == "esc"): self.escInit() self.stop() else: sys.exit("Specify the hardware to use vehiclePWM") def servoInit(self): self.NAVIO_RCOUTPUT = 3 self.PWM_MinWidth = 0.000685 #S. This calculation was updated on April 30, 2016. It is made large enough to work at 300Hz self.PWM_MaxWidth = 0.002675 #S. This calculation was updated on April 30, 2016. It is made small enough to work at 50Hz self.PWM_Range = self.PWM_MaxWidth - self.PWM_MinWidth #0.00199 self.SERVO_Range = 180.0 #Define servo degrees of movement. Must be a float for correct calculations/operation self.changer = 0 self.lastDeg = 0 def escInit(self): self.NAVIO_RCOUTPUT = 5 self.PWM_MinWidth = 0.001158 #S. This was measured on May 1, 2016. self.PWM_MaxWidth = 0.0021 #Changed this on May 2, 2016 to get about 1.91ms output self.PWM_Range = self.PWM_MaxWidth - self.PWM_MinWidth self.PWM_Stop = 0.001700 #T = 0.0017 is the neutral, corresponding to about 1.5ms self.Motor_Range = 100.0 #Define motor max speed # ---- End PWM Constants ---- """ A 12bit digital I2C signal controls the PCA9685 which then prepares an analog PWM wave for the Savox SC-1258TG servo. The PWM signal's absolute width directly controls the servo's angle. Emperical testing on April 4, 2016 shows that in order to maintain a constant signal width, the value of the 12 bits written must change with respect to the operating frequency. The specific relation: 12BitWritten = 12BitRange * (DesiredSignalWidth * OperatingFrequency) """ # ---- Servo Outputs ---- def steer(self, deg): """ steering range is 70 degrees the servo must move about 1/4 of the total range to move the wheels at all deg = 50 to turn full right deg = 120 to turn full left deg = 81 to center, even though it is not the median of the range """ #changer = 0 at the top direction = math.pow( -1, deg < 0) #returns 1 if deg is positive, -1 if deg is negative #So long as the deg is the same set a target 1/4 the max range and iteratively approach target targetDeg = deg + (15 * direction) #Same sign as deg and 15 more #If the deg is the same keep iterating closer if (abs(deg - self.lastDeg) > 5): self.changer = min((self.changer + 10), 20) #changer will iterate until it maxes at 15 else: self.changer = 0 self.lastDeg = deg iterateDeg = targetDeg - self.changer * direction #the offset will iteratively approach deg deg = 85 + iterateDeg ###deg = 85 + deg #Convert from +-35 to 50-120 PWM_Width = self.PWM_MinWidth + ( self.PWM_Range * (deg / self.SERVO_Range) ) # Convert our 180 degree positions to PWM widths in seconds SERVO_move = math.trunc( (4096.0 * PWM_Width * self.frequency) - 1 ) #Convert PWM widths to 12 bits (a scale of 0-4095) to write to the PCA9685. try: self.pwm.setPWM(self.NAVIO_RCOUTPUT, 0, SERVO_move) except KeyboardInterrupt: self.rest() sys.exit() def center(self): PWM_Width = self.PWM_MinWidth + (self.PWM_Range * (81 / self.SERVO_Range)) SERVO_move = math.trunc((4096.0 * PWM_Width * self.frequency) - 1) try: self.pwm.setPWM(self.NAVIO_RCOUTPUT, 0, SERVO_move) except KeyboardInterrupt: self.rest() sys.exit() def rest(self): self.pwm.setPWM( self.NAVIO_RCOUTPUT, 0, 0 ) #0S. To rest servo so it doesn't hold a position, send an invalid PWM signal by sending an invalid 0-4096 bits. #---- End Servo Outputs ---- #---- ESC Outputs ---- def accel(self, speed): #print 'start: s%d, p%d' % (speed,vehiclePWM.PreviousSpeed) if (speed < 0): if (vehiclePWM.PreviousSpeed > 0): self.stop() time.sleep(0.5) #print 'firstReverse' self.reverse(speed) time.sleep(0.25) self.stop() time.sleep(0.25) self.reverse(speed) else: self.reverse(speed) else: if (vehiclePWM.PreviousSpeed <= 0): self.stop() time.sleep(0.5) self.forward(speed) else: self.forward(speed) vehiclePWM.PreviousSpeed = speed #print 'end: s%d, p%d' % (speed,vehiclePWM.PreviousSpeed) def forward(self, Motor_speed): """ PWM width 1.725ms minimum forward loaded PWM width 2.140ms maximum forward loaded """ PWM_Width = 0.001725 + (0.000415 * (Motor_speed / self.Motor_Range)) #print 'PWM_Width %f' %PWM_Width Motor_move = math.trunc((4096.0 * PWM_Width * self.frequency) - 1) #print 'Motor_move %f' %Motor_move self.pwm.setPWM(self.NAVIO_RCOUTPUT, 0, Motor_move) def reverse(self, Motor_speed): """ PWM width 1.590ms minimum reverse loaded PWM width 1.300ms maximum reverse loaded """ PWM_Width = 0.00159 + (0.000290 * (Motor_speed / self.Motor_Range)) #print 'PWM_Width %f' %PWM_Width Motor_move = math.trunc((4096.0 * PWM_Width * self.frequency) - 1) #print 'Motor_move %f' %Motor_move self.pwm.setPWM(self.NAVIO_RCOUTPUT, 0, Motor_move) def stop(self): stop = math.trunc((4096.0 * self.PWM_Stop * self.frequency) - 1) self.pwm.setPWM(self.NAVIO_RCOUTPUT, 0, stop) #To stop the motor send a constant stop pulse
# The goal of this file is to test # the led mounted on the top of the navio # # setPWMFreq(channel, on , off) # channel: The channel that should be updated with the new values (0..15) # on: The tick (between 0..4095) when the signal # should transition from low to high # off:the tick (between 0..4095) when the signal # should transition from high to low from navio.adafruit_pwm_servo_driver import PWM # what's doing ?!? pwm = PWM(0x40, debug=False) # 0x40 is the address of the LED pwm.setPWMFreq(60) while true: R = 0 G = 0 B = 4095 pwm.setPWMFreq(R, G, B)
import navio.gpio import navio.util navio.util.check_apm() #drive Output Enable in PCA low pin = navio.gpio.Pin(27) pin.write(0) PCA9685_DEFAULT_ADDRESS = 0x40 frequency = 50 NAVIO_RCOUTPUT_1 = 3 SERVO_MIN_ms = 1.250 # mS SERVO_MAX_ms = 1.750 # mS #convert mS to 0-4096 scale: SERVO_MIN = math.trunc((SERVO_MIN_ms * 4096.0) / (1000.0 / frequency) - 1) SERVO_MAX = math.trunc((SERVO_MAX_ms * 4096.0) / (1000.0 / frequency) - 1) pwm = PWM(0x40, debug=False) # Set frequency to 60 Hz pwm.setPWMFreq(frequency) while(True): pwm.setPWM(NAVIO_RCOUTPUT_1, 0, SERVO_MIN); time.sleep(1); pwm.setPWM(NAVIO_RCOUTPUT_1, 0, SERVO_MAX); time.sleep(1);