Controlador de servos

Descrición:

O controlador de servos (ou de saídas PWM) PCA9685 permite xerar ata 16 saídas PWM ou controlar a ta 16 servos empregando só 2 pins de sinal, pois a comunicación realízase a través do bus I2C.

Conexión:

A conexión realízase como vén na seguinte imaxe. No arduino UNO: SDA (pin A4) e SCL (pin A5)

A alimentación dos servos realízase mediante unha fonte externa, non desde a placa arduino, xa que o consumo é moi elevado, sobre todo cando se conectan moitos. Ao utilizar alimentación externa, lembra poñer GND común.

Programa:

1. Un mesmo tipo de servos

Neste exemplo imos controlar dous servos SG90. O primeiro vai tomar un ángulo 90º e o segundo 0º e un tempo despois ao revés, o primeiro un ángulo de 0º e o segundo de 90º.

Necesitamos dúas librerías: Wire para a comunicación I2C, e Adafruit PWMServoDriver para o controlador de servos.

// Controlador de servos 

#include <Wire.h>
#include <Adafruit_PWMServoDriver.h>

Adafruit_PWMServoDriver controladorServo = Adafruit_PWMServoDriver(0x40); // enderezo I2C do controlador

// Valores para controlar un microservo SG90 (comentados os valores para un MG996R ou KS-3518)

int MIN_PULSE_WIDTH = 650 ;     // 500
int MAX_PULSE_WIDTH = 2600 ;    // 2400
int FREQUENCY =       60 ;      // 50

// Variables

uint8_t n_servos = 4; //Indicamos cantos servos están conectados
int tempo= 300;   

// configuración

void setup() {
  
  controladorServo.begin();               
  controladorServo.setPWMFreq(FREQUENCY);  

  for (uint8_t n = 0; n<n_servos; n++){       // poñemos todos os servos ao ángulo 0
    controladorServo.setPWM(n, 0, angulo(0));
  }
  
}

// para pasar a ángulo

int angulo(int angle){
  int pulse_wide, analog_value;
  pulse_wide   = map(angle, 0, 180, MIN_PULSE_WIDTH, MAX_PULSE_WIDTH);
  analog_value = int(float(pulse_wide) / 1000000 * FREQUENCY * 4096);
  return analog_value;
}

// bucle

void loop() {      
  
  controladorServo.setPWM(0, 0, angulo(90)); 
  controladorServo.setPWM(1, 0, angulo(0));
  delay(tempo);
  controladorServo.setPWM(0, 0, angulo(0)); 
  controladorServo.setPWM(1, 0, angulo(90));
  delay(tempo);
 
}

2. Varios tipos de servos


Se queremos controlar varios servos de diferentes tipos imos ter valores máximos e mínimos diferentes.
Por exemplo, neste caso, os 5 primeiros servos son SG90 e os 2 último son servos MG996R

Os valores dos pulsos definímolos mediante arrays:

int servoPin[7]={0,1,2,3,4,9,8};
int minPulse[]={650,650,650,650,650,500,500};
int maxPulse[]={2600,2600,2600,2600,2600,2400,2400};
int FREQUENCY=60;

A función para calcular o ángulo establecémola cos datos anteriores:

int angulo(int angle, int servo){
  
  int pulse_wide, analog_value;
  pulse_wide   = map(angle, 0, 180, minPulse[servo], maxPulse[servo]);
  analog_value = int(float(pulse_wide) / 1000000 * FREQUENCY * 4096);
  return analog_value;
  
}

Para mover un dos servos a un ángulo determinado poderiamos usar esta función:

 controladorServo.setPWM(servoPin[servo], 0, angulo(sinal[servo], servo));

Adapta así o teu programa se vas usar diferentes tipos de servos.

Propostas:

Conecta 4 servos e realiza as seguintes prácticas:

  • Random: Establece unha variable que teme un valor random entre 0 e 3 (son 4 servos) e fai que cada certo tempo se mova o servo elixido ao chou. Fai que se visualice na consola que servo se está a mover.
  • Secuencia: Fai que os catro servos se movan secuencialmente (desde o a 3) ata 90º e despois se movan secuencialmente (de 3 a 0) ata os 0º.
  • Pouco a pouco: No programa anterior, fai que o movemento dos servos se realice pouco a pouco, adaptando ao controlador o que vimos no control directo.