With this project we will manage a Servo Motor TowerPro SG90, using the FTDI FT232H development board (of which there is a dedicated page on this site) and the NXP PCA9685 development board (of which there is a dedicated page on this site).
This Servo Motor must be connected to the NXP PCA9685 development board. The connection connectors are listed below:
Image | Board FT232H | Board PCA9685 | Servo Motor |
---|---|---|---|
AD0 | SCL | ------ | |
AD1 + AD2 | SDA | ------ | |
+5V | VCC | ------ | |
GND | GND | ------ | |
------ | Canale 0 - PWM | PWM | |
+5V | ------ | VCC | |
------ | Canale 0 - GND | GND |
To manage this Servo Motor, the presence of the "PCA9685_FTDI" library is required.
The following Python code example rotates the Servo Motor using a "Throttle" command and then an "Angle" command to rotate the motor:
# Simple demo of of the PCA9685 PWM servo/LED controller library. import time # Import the PCA9685 module. import pca9685_ftdi # Initialise the PCA9685 using the default address (0x40). pwm = pca9685_ftdi.PCA9685_FTDI() SERVO_FREQ = 50 # Analog servos run at ~50 Hz updates pwm.setPWMFreq(SERVO_FREQ) # Analog servos run at ~50 Hz updates # our servo # counter servonum = 0 actuation_range = 180 min_pulse = 750 max_pulse = 2250 _min_duty = int((min_pulse * SERVO_FREQ) / 1000000 * 0xFFFF) max_duty = (max_pulse * SERVO_FREQ) / 1000000 * 0xFFFF _duty_range = int(max_duty - _min_duty) def set_duty_cycle(value): if not 0 <= value <= 0xFFFF: raise ValueError("Out of range") if value == 0xFFFF: #print("set_duty_cycle", value) pwm.set_pwm(servonum, 0x1000, 0) else: value = (value + 1) >> 4 #print("set_duty_cycle", value) pwm.set_pwm(servonum, 0, value) def set_fraction(value): if value is None: set_duty_cycle(0) return if not 0.0 <= value <= 1.0: raise ValueError("Must be 0.0 to 1.0") duty_cycle = _min_duty + int(value * _duty_range) #print("duty_cycle", duty_cycle) set_duty_cycle(duty_cycle) def angle(new_angle): if new_angle < 0 or new_angle > actuation_range: raise ValueError("Angle out of range") set_fraction(new_angle / actuation_range) def throttle(value): if value > 1.0 or value < -1.0: raise ValueError("Throttle must be between -1.0 and 1.0") fraction = (value + 1) / 2 set_fraction(fraction) try: print("Throttle 1") throttle(1) time.sleep(2) print("Throttle -1") throttle(-1) time.sleep(2) print("Throttle 0\n") throttle(0) time.sleep(2) print("Angle 0") angle(0) time.sleep(2) print("Angle 90") angle(90) time.sleep(2) print("Angle 180") angle(180) time.sleep(2) print("Angle 0") angle(0) except KeyboardInterrupt: # Capture keyboard ^C to exit the program print('\nYou terminated the program. The program ends!') angle(0) pwm.set_all_pwm(0, 0) pwm.close()