.. note:: Ciao e benvenuto nella SunFounder Raspberry Pi & Arduino & ESP32 Enthusiasts Community su Facebook! Approfondisci le tue conoscenze su Raspberry Pi, Arduino ed ESP32 insieme ad altri appassionati. **Perché unirsi a noi?** - **Supporto Esperto**: Risolvi problemi post-vendita e sfide tecniche con l'aiuto della nostra community e del nostro team. - **Impara e Condividi**: Scambia consigli e tutorial per migliorare le tue abilità. - **Anteprime Esclusive**: Ottieni l'accesso anticipato a nuovi annunci di prodotto e anteprime. - **Sconti Speciali**: Approfitta di sconti esclusivi sui nostri prodotti più recenti. - **Promozioni Festive e Giveaways**: Partecipa a concorsi e promozioni festive. 👉 Pronto a esplorare e creare insieme a noi? Clicca [|link_sf_facebook|] e unisciti oggi stesso! 1.3.2 Servo ============== Introduzione --------------- In questa lezione, impareremo a far ruotare un servomotore. Componenti ------------ .. image:: img/list_1.3.2.png Principio --------- **Servo** Un servomotore è generalmente composto dalle seguenti parti: custodia, asse, sistema di ingranaggi, potenziometro, motore CC e scheda integrata. .. image:: img/image121.png Funziona nel seguente modo: il microcontrollore invia segnali PWM al servomotore, e la scheda integrata nel servo riceve i segnali tramite il pin di segnale e controlla il motore interno per girare. Di conseguenza, il motore aziona il sistema di ingranaggi, che a sua volta muove l’asse dopo la decelerazione. L'asse e il potenziometro del servomotore sono collegati tra loro. Quando l'asse ruota, muove il potenziometro, che a sua volta emette un segnale di tensione alla scheda integrata. La scheda determina quindi la direzione e la velocità della rotazione in base alla posizione corrente, in modo che possa fermarsi esattamente nella posizione desiderata e mantenerla. .. image:: img/image122.png L'angolo è determinato dalla durata di un impulso applicato al filo di controllo, un processo chiamato modulazione della larghezza di impulso (PWM). Il servomotore si aspetta di ricevere un impulso ogni 20 ms. La lunghezza dell'impulso determinerà quanto ruoterà il motore. Ad esempio, un impulso di 1,5 ms farà girare il motore alla posizione di 90 gradi (posizione neutrale). Quando al servo viene inviato un impulso inferiore a 1,5 ms, il servomotore ruota in senso antiorario rispetto al punto neutro e mantiene l'albero di uscita in una determinata posizione. Quando l'impulso è più lungo di 1,5 ms, si verifica il contrario. La larghezza minima e massima degli impulsi necessari per posizionare il servo in una posizione valida varia per ogni servo. In genere, l'impulso minimo è di circa 0,5 ms e quello massimo è di 2,5 ms. .. image:: img/image123.jpeg Schema Elettrico -------------------- .. image:: img/image337.png Procedura Sperimentale -------------------------- **Passo 1:** Costruire il circuito. .. image:: img/image125.png :width: 800 Per gli utenti C ^^^^^^^^^^^^^^^^^^^^^^^^ **Passo 2**: Accedi alla cartella del codice. .. raw:: html .. code-block:: cd ~/davinci-kit-for-raspberry-pi/c/1.3.2 **Passo 3**: Compila il codice. .. raw:: html .. code-block:: gcc 1.3.2_Servo.c -lwiringPi **Passo 4**: Esegui il file eseguibile. .. raw:: html .. code-block:: sudo ./a.out Dopo l'esecuzione del programma, il servomotore ruoterà da 0 gradi a 180 gradi, e poi da 180 gradi a 0 gradi, in modo ciclico. .. note:: Se non funziona dopo l'esecuzione o appare un errore del tipo: \"wiringPi.h: No such file or directory\", fare riferimento a :ref:`faq_c_nowork`. **Codice** .. code-block:: c #include #include #include #define ServoPin 1 // definisce il servo su GPIO1 long Map(long value, long fromLow, long fromHigh, long toLow, long toHigh) { return (toHigh-toLow)*(value-fromLow) / (fromHigh-fromLow) + toLow; } void setAngle(int pin, int angle){ // Crea una funzione per controllare l'angolo del servo. if (angle < 0) angle = 0; if(angle > 180) angle = 180; softPwmWrite(pin,Map(angle, 0, 180, 5, 25)); } int main(void) { int i; if (wiringPiSetup() == -1){ // in caso di errore nell'inizializzazione di wiringPi, stampa messaggio su schermo printf("setup wiringPi failed !"); return 1; } softPwmCreate(ServoPin, 0, 200); //initialize PMW pin of servo while(1){ for(i=0;i<181;i++){ // Let servo rotate from 0 to 180. setAngle(ServoPin,i); delay(2); } delay(1000); for(i=181;i>-1;i--){ // Let servo rotate from 180 to 0. setAngle(ServoPin,i); delay(2); } delay(1000); } return 0; } **Spiegazione del Codice** .. code-block:: c long Map(long value,long fromLow,long fromHigh,long toLow,long toHigh){ return (toHigh-toLow)*(value-fromLow) / (fromHigh-fromLow) + toLow; } Crea una funzione Map() per mappare il valore nel codice seguente. .. code-block:: c void setAngle(int pin, int angle){ // Crea una funzione per controllare l'angolo del servo. if (angle < 0) angle = 0; if(angle > 180) angle = 180; softPwmWrite(pin,Map(angle, 0, 180, 5, 25)); } Crea una funzione, setAngle(), per impostare l'angolo del servo. .. code-block:: c softPwmWrite(pin,Map(angle,0,180,5,25)); Questa funzione può modificare il ciclo di lavoro del PWM. Per fare in modo che il servo ruoti da 0 a 180°, la larghezza dell'impulso deve variare tra 0,5ms e 2,5ms con un periodo di 20ms; nella funzione softPwmCreate(), abbiamo impostato il periodo a 200x100us=20ms, quindi dobbiamo mappare 0 ~ 180 a 5x100us ~ 25x100us. Il prototipo di questa funzione è mostrato di seguito. .. code-block:: int softPwmCreate(int pin, int initialValue, int pwmRange); **Parametro pin:** Qualsiasi pin GPIO del Raspberry Pi può essere impostato come pin PWM. **Parametro initialValue:** La larghezza dell'impulso iniziale è il valore di initialValue moltiplicato per 100us. **Parametro pwmRange:** il periodo del PWM è pwmRange moltiplicato per 100us. Per gli utenti Python ^^^^^^^^^^^^^^^^^^^^^^^^^ **Passo 2**: Vai alla cartella del codice. .. raw:: html .. code-block:: cd ~/davinci-kit-for-raspberry-pi/python/ **Passo 3**: Esegui il file eseguibile. .. raw:: html .. code-block:: sudo python3 1.3.2_Servo.py Dopo l'esecuzione del programma, il servo ruoterà da 0 gradi a 180 gradi, e poi da 180 gradi a 0 gradi, in modo ciclico. **Codice** .. note:: Puoi **Modificare/Reimpostare/Copiare/Eseguire/Interrompere** il codice qui sotto. Prima di farlo, assicurati di accedere alla cartella del codice sorgente, come ad esempio ``davinci-kit-for-raspberry-pi/python``. .. raw:: html .. code-block:: python import RPi.GPIO as GPIO import time SERVO_MIN_PULSE = 500 SERVO_MAX_PULSE = 2500 ServoPin = 18 def map(value, inMin, inMax, outMin, outMax): return (outMax - outMin) * (value - inMin) / (inMax - inMin) + outMin def setup(): global p GPIO.setmode(GPIO.BCM) # Numerazione GPIO in BCM GPIO.setup(ServoPin, GPIO.OUT) # Imposta il pin del servo come output GPIO.output(ServoPin, GPIO.LOW) # Imposta il pin del servo su LOW p = GPIO.PWM(ServoPin, 50) # Imposta la frequenza a 50Hz p.start(0) # Ciclo di lavoro iniziale = 0 def setAngle(angle): # fa ruotare il servo ad un angolo specifico (0-180 gradi) angle = max(0, min(180, angle)) pulse_width = map(angle, 0, 180, SERVO_MIN_PULSE, SERVO_MAX_PULSE) pwm = map(pulse_width, 0, 20000, 0, 100) p.ChangeDutyCycle(pwm) # mappa l'angolo in un ciclo di lavoro e lo emette def loop(): while True: for i in range(0, 181, 5): # ruota il servo da 0 a 180 gradi setAngle(i) # Scrive l'angolo sul servo time.sleep(0.002) time.sleep(1) for i in range(180, -1, -5): # ruota il servo da 180 a 0 gradi setAngle(i) time.sleep(0.001) time.sleep(1) def destroy(): p.stop() GPIO.cleanup() if __name__ == '__main__': # Programma inizia da qui setup() try: loop() except KeyboardInterrupt: # Quando si preme 'Ctrl+C', il programma eseguirà destroy(). destroy() **Spiegazione del Codice** .. code-block:: python p = GPIO.PWM(ServoPin, 50) # imposta la frequenza a 50Hz p.start(0) # Ciclo di lavoro = 0 Imposta ServoPin come pin PWM, con frequenza di 50Hz e periodo di 20ms. p.start(0): Avvia la funzione PWM, con valore iniziale impostato a 0. .. code-block:: python def setAngle(angle): # fa ruotare il servo ad un angolo specifico (0-180 gradi) angle = max(0, min(180, angle)) pulse_width = map(angle, 0, 180, SERVO_MIN_PULSE, SERVO_MAX_PULSE) pwm = map(pulse_width, 0, 20000, 0, 100) p.ChangeDutyCycle(pwm) # mappa l'angolo in un ciclo di lavoro e lo emette Crea la funzione setAngle() per scrivere un angolo da 0 a 180 nel servo. .. code-block:: python angle = max(0, min(180, angle)) Questa riga limita l’angolo entro il range di 0-180°. La funzione min() restituisce il valore minimo tra quelli in ingresso. Se 180 < angle, restituisce 180, altrimenti restituisce angle. La funzione max() restituisce il valore massimo tra quelli in ingresso. Se 0 > angle, restituisce 0, altrimenti restituisce angle. .. code-block:: python pulse_width = map(angle, 0, 180, SERVO_MIN_PULSE, SERVO_MAX_PULSE) pwm = map(pulse_width, 0, 20000, 0, 100) p.ChangeDutyCycle(pwm) Per impostare una gamma di 0 ~ 180° per il servo, la larghezza dell’impulso è impostata tra 0,5ms (500us) e 2,5ms (2500us). Il periodo di PWM è 20ms (20000us), quindi il ciclo di lavoro del PWM varia da (500/20000)% a (2500/20000)% e la gamma 0 ~ 180 è mappata a 2.5 ~ 12.5. Immagine Dimostrativa ------------------------ .. image:: img/image126.jpeg