Con questo progetto andremo a gestire un servomotore TowerPro SG90, usando la scheda di sviluppo FTDI FT232H (di cui esiste una pagina dedicata su questo sito) e la scheda di sviluppo NXP PCA9685 (di cui esiste una pagina dedicata su questo sito).
Il servomotore deve essere collegato alla scheda di sviluppo NXP PCA9685. I connettori di collegamento sono elencati qui di seguito:
Immagine | Scheda FT232H | Scheda PCA9685 | Servomotore |
---|---|---|---|
AD0 | SCL | ------ | |
AD1 + AD2 | SDA | ------ | |
+5V | VCC | ------ | |
GND | GND | ------ | |
------ | Canale 0 - PWM | PWM | |
+5V | ------ | VCC | |
------ | Canale 0 - GND | GND |
Per gestire il servomotore, è richiesta la presenza della libreria "PCA9685_FTDI".
Il seguente esempio di codice Python fa ruotare il servomotore usando un comando "throttle" e in seguito un comando "Angle" per ruotare il motore:
# 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()