Utilizzare la classe PWM per controllare un servo 0-180 gradi

Il servo meccanismo è un dispositivo capace di eseguire dei movimenti meccanici in funzione del segnale applicato al suo ingresso. Viene utilizzato spesso per eseguire lavori continui, ovvero per controllare meccanismi che non possono essere azionati continuamente da personale umano.  In campo hobbystico viene impegnato per azionamenti a distanza tipici del radio modellismo.

Servo meccanismo TowerPro sg-5010

Le caratteristiche comuni tra i servo sono principalmente, l’angolo di rotazione, la velocità di rotazione e la coppia motrice.
Il modello SG-5010 che ho acquistato viene prodotto dalla TowerPro e le sue caratteristiche tecniche sono elencate nella tabella seguente:

Segnale di pilotaggioPWM
Tensione Alimentazioneda 4.8Vdc a 6.0 Vdc
Velocitàa 4.8Vdc 0.2  S/60°
a 6.0Vdc 0.16 S/60°
Coppiaa 4.8Vdc 5.5 Kg/cm
a 6.0Vdc 6.5 Kg/cm
Intervallo di rotazione0 – 180 gradi
Peso38g
Dimensioni40x20x40 mm
CostoCirca 10 €

Il suo funzionamento è veramente elementare, tutto si riduce nell’utilizzo del segnale PWM variando il valore di duty cycle tra 1% e 50% .
Per convenienza possiamo alimentare il servo tramite il pin 5Vdc del Netduino, anche se per applicazioni operative consiglio vivamente di alimentare il servo con una tensione esterna, evitando in questo modo di sovraccaricare il Netduino rendendolo instabile.
Il TowerPro Sg-5010 dispone di tre fili con colori che possono essere ambigui infatti il filo marrone deve essere collegato a massa, il filo rosso deve essere collegato alla +5Vdc e il filo arancione va collegato ad un pin PWM del Netduino (Pin 5-6-9-10).

In via generale il segnale PWM tipico deve avere una frequenza di 50Hz (Periodo di 20mS), mentre l’impulso positivo del segnale deve avere una larghezza compresa tra 1ms e 2ms, infatti per portare l’asse del servo nella posizione centrale la larghezza dovrà essere di 1.5ms (zero gradi) per portare l’asse a +90° l’impulso deve essere largo 2ms mentre per portare l’asse a -90° l’impulso dovrà essere largo 1ms.

L’illustrazione seguente aiuta a capire meglio il funzionamento

Impostazione periodo pwm servo meccanismo

Il codice che andremmo a scrivere dovrà generare un segnale pwm con una frequenza di 50Hz e con un impulso la cui larghezza dovrà variare da 1ms sino a 2ms, questo è possibile utilizzando la classe PWM e il metodo SetPulse(), per maggiori informazioni riguardo questa classe vi consiglio di leggere questo articolo

// Istanzio un oggetto pwm
// Setto il pin 9 come uscita pwm
PWM servo = new PWM(Pins.GPIO_PIN_D9);

while (true)
{
  //imposto una frequenza di circa 50Hz
  //con un impulso di 1.5ms
  //l'asse del servo viene posizionato a 0°
  servo.SetPulse(20000, 1500);
  //attendo 2 secondi
  Thread.Sleep(2000);

  //imposto la frequenza sempre a 50Hz
  //con un impulso di 1ms
  //l'asse del servo si posiziona a -90°
  servo.SetPulse(20000, 1000);
  Thread.Sleep(2000);

  //imposto la frequenza sempre a 50Hz
  //con un impulso di 2ms
  //l'asse del servo si posiziona a +90°
  servo.SetPulse(20000, 2000);
  Thread.Sleep(2000);
}

 

Il codice esegue continuamente, ogni due secondi, la rotazione dell’asse del servo. Sicuramente i valori di larghezza generati non portano alla rotazione completa dell’asse del servo, questo perché anche se si ha una certa standardizzazione ci possono essere delle differenze tra i vari modelli.

Quindi sarà necessaria una calibrazione per capire quali sono i valori limite che portano alla rotazione di 180° dell’asse. Eseguendo il codice precedente potremo vedere se l’asse compie una manovra di 180° se per esempio non raggiunge i limiti di -90° e +90° possiamo aumentare e diminuire della stessa quantità la larghezza degli impulsi relativa a questi limiti ad esempio portando il valore di 1000 (1ms) a 800 (0.8ms) e il valore di 2000 (2ms) a 2200 (2.2ms).

Tabella riepilogativa

Gradi Asse ServoLarghezza impulsoValore duration da passare alla SetPulse()
0 Gradi1.5ms1500
-90 Gradi1ms1000
+90 Gradi2ms2000

Col servo in mio possesso ho dovuto cambiare i valori della larghezza dell’impulso in questo modo

Valori per il mio servo
Gradi Asse ServoLarghezza impulsoValore duration da passare alla SetPulse()
0 Gradi1.5ms1500
-90 Gradi0.6ms600
+90 Gradi2.4ms2400

In questo modo abbiamo capito quali sono i valori limite per il nostro servo, questo è fondamentale per impostare la larghezza dell’impulso per spostare l’asse anche nei valori intermedi.