23 agosto 2015

Controle vários servo motores com o Servo Motor Shield 16 canais da Adafruit

Uma dúvida frequente entre os leitores do blog é o controle de vários servo motores com o Arduino, não só pela limitação do número de portas, como também pelo consumo desses motores, que podem sobrecarregar o Arduino. Se o seu projeto precisa de vários deles, uma boa opção é o Servo Motor Shield 16 Canais, da Adafruit.

Adafruit Servo Motor Shield 16 channel 12 bit PWM

Com esse shield, todo o controle dos servos (16 por shield) fica por conta do controlador PWM embutido na placa, liberando o Arduino dessa carga de processamento. Além disso, o shield tem a sua própria entrada de força (5 à 6VDC) para alimentação dos motores.

A comunicação entre o Arduino e o servo shield é feita pela interface I2C, utilizando apenas os pinos A4 (SDA) e A5 (SCL), liberando os outros pinos para utilização de acordo com as necessidades do seu projeto. A placa permite ainda que que você encaixe outros shields iguais, podendo controlar até 992 servos ! (16 servos por shield x 62 shields = 992 servos).

Montagem do shield

Antes de começar a utilizar o shield, você precisa soldar os conectores que acompanham a placa. Você pode optar por soldar os conectores que já vem com o shield (pinos macho/macho), como na imagem acima, ou adquirir um Kit Barra de pinos empilhável, com conectores macho/fêmea, se desejar empilhar vários shields:
Servo Shield conectores macho/fêmea

Servo Motor Shield conexões e endereçamento

Na imagem abaixo, temos as principais conexões da placa. No lado esquerdo, os pinos de alimentação dos servos e os leds indicadores de tensão de entrada (verde/inferior) e alimentação do shield pelo Arduino (vermelho/superior), além do botão de reset. 

Adafruit Servo Shield - Conexões


Próximo ao conector de alimentação, temos um espaço (C2) para colocar um capacitor eletrolítico, caso seja necessário para evitar oscilações/ruídos. A Adafruit recomenda um capacitor de aproximadamente 100µF para cada servo, assim, se você tiver 4 servos, por exemplo, use um capacitor de 470µF. Este capacitor não é fornecido junto com o shield.

O endereçamento de cada shield é feito por meio dos pontos A0 à A5 do shield (não confunda com as portas analógicas do Arduino). O endereço padrão é 0x40, e você pode alterar esse endereço soldando os pontos correspondentes como na imagem abaixo:

Endereçamento Servo Shield


Assim, se você quiser o endereço 0x41, solde os pontos correspondentes ao A0 (1000001 em binário = 0x41 em hexadecimal), se quiser o endereço 0x42 , solde o terminal A1 (1000010 = 0x42), e assim por diante.

Conexão do Adafruit Servo Shield ao Arduino

Agora que já temos informações sobre a montagem e conexões do servo shield, chegou a hora de montar um circuito de testes, onde vamos movimentar cada servo de maneira independente. 

Monte o circuito abaixo, composto por:
  • 3 leds
  • 3 resistores de 330 ohms para os leds
  • 1 push button
  • 1 resistor de 10K para o push-button
  • 1 potenciômetro
  • 3 servo motores

Circuito Arduino Uno - Adafruit Servo Shield

Observe que é obrigatória a utilização de uma fonte de 5 à 6V para alimentação do shield. Sem ela, os servo motores não funcionam. Ao alimentar o shield com a fonte externa, o led verde irá acender.

Siga o esquema de ligação do servo motor mostrado acima: fio marrom = GND, vermelho = VCC e laranja = Sinal.

Programa e biblioteca Adafruit Servo Shield

O programa usa a biblioteca Adafruit-PWM-Servo-Driver, disponível neste link. Descompacte o arquivo e renomeie a pasta para Adafruit_PWMServoDriver. Depois copie essa pasta para dentro da pasta LIBRARIES da IDE do Arduino.

O controle dos motores dentro do programa, apesar de ser feito pela biblioteca, pode exigir a configuração de parâmetros relativos ao PWM. Consulte os programas de exemplo da biblioteca para maiores informações sobre esses parâmetros.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
//Programa: Adafruit Servo Shield 16 Canais
//Autor: Arduino e Cia

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

//Seleciona o shield com endereço 0x40
Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver(0x40);

//Configuração PWM para o servo motor. Ajuste o pulso de acordo com
//o servo motor que você vai utilizar
#define SERVOMIN  150 //Comprimento de pulso minimo
#define SERVOMAX  600 //Comprimento de pulso maximo

#define pino_botao A0
#define pino_pot A2

int motor_selecionado = 0;
int pino_led = 5;

void setup() {
  Serial.begin(9600);
  pinMode(pino_botao, INPUT);
  pinMode(pino_pot, INPUT);
  pinMode(5, OUTPUT);
  pinMode(6, OUTPUT);
  pinMode(7, OUTPUT);
  digitalWrite(5, HIGH);
  Serial.println("Pressione o botao para selecionar o servo\n");
  Serial.println("Motor selecionado: 0");

  pwm.begin();
  //Frequencia servo analogico
  pwm.setPWMFreq(60);
}

void loop()
{
  int valor = digitalRead(A0);
  //Verifica se o botao foi pressionado
  if (valor == 0)
  {
    //Altera o motor selecionado
    motor_selecionado++;
    pino_led++;
    if (motor_selecionado > 2)
    {
      motor_selecionado = 0;
      pino_led = 5;
    }
    //Mostra o motor selecionado no serial monitor
    Serial.print("Motor selecionado: ");
    Serial.println(motor_selecionado);
    //Aciona o led correspondente
    digitalWrite(5, LOW);
    digitalWrite(6, LOW);
    digitalWrite(7, LOW);
    digitalWrite(pino_led, HIGH);
    while (digitalRead(A0) == 0) {}
  }
  //Leitura do valor do potenciometro
  int valor_pot = analogRead(pino_pot);
  //Converte o valor lido do potenciometro para um valor
  //entre SERVOMIN e SERVOMAX
  int valor_pulso = map(valor_pot, 0, 1024, SERVOMIN, SERVOMAX);
  //Movimenta o servo
  pwm.setPWM(motor_selecionado, 0, valor_pulso);
  delay(50);
}

O programa começa selecionando o Motor 1, e você pode movimentá-lo utilizando o potenciômetro. Pressione o push-button para também controlar o Motor 2 ou o Motor 3. A cada toque no botão, o led correspondente ao motor será aceso, e a indicação do motor selecionado também é enviada para o serial monitor.

Adafruit Servo Motor Shield

18 comentários:

  1. existe possibilidades de eu uisar esse shield para enviar sinal de tensão de 1 a 5 para controlar uma valvula insdustrial de 4 a 20 miliampres? Obrigado..

    ResponderExcluir
    Respostas
    1. Bom dia,

      Não sei qual o esquema de ligação dessa válvula, mas neste caso você nem precisa do shield. A própria porta do Arduino pode fornecer a tensão e a corrente que você precisa.

      Abraço!

      Excluir
  2. Busquei essa placa no site da Adafruit (https://www.adafruit.com) e não encontrei. Há uma placa com funcionalidade similar de código PCA9685 que me parece menor que essa. Qual a diferença entre elas e onde encontro mais informações acerca dela?

    ResponderExcluir
    Respostas
    1. Bom dia Ronaldo,

      O link que você está procurando é esse:

      https://www.adafruit.com/products/1411

      A diferença entre a placa desse post e a PCA9685 é que a do post é em formato Shield, e possui uma área de prototipagem. No restante, as características são as mesmas.

      Abraço!

      Excluir
  3. Amigo, ao invés de servos posso usar um motor de passo?

    ResponderExcluir
    Respostas
    1. Bom dia Felipe,

      Esse shield e a biblioteca são indicados apenas para utilização com servo motores.

      Abraço!

      Excluir
  4. Tenho um projeto com 1024 motores de passo, posso usar um Shield desse para controlar um módulo com 16?

    ResponderExcluir
  5. Olá boa noite
    Estou querendo controlar 4 servos com esses módulo gostaria de saber qual a programação que devo usar para direcionar cada servo com ângulos diferentes

    ResponderExcluir
  6. Boa tarde, preciso utilizar 5 servos, porem necessito que cada um tenha um range diferente, a biblioteca permite apenas de 0 a 180, gostaria de outras possibilidades como de -90 a 90, -45 a 135, tem algum comando para alterar esses valores.?

    ResponderExcluir
    Respostas
    1. Bom dia Pedro,

      Talvez você consiga usar o comando map():

      map(variavel_angulo, 0, 180, -90, 90)

      referencia: https://www.arduino.cc/en/Reference/Map

      Abraço!

      Excluir
    2. Deu certo amigo,
      Muito Obrigado pela ajuda.

      Excluir
  7. funciona no arduino mega 2560? nao ta rodando o motor mas o resto do script ta funcionando normal com as leds e o potenciômetro, eu conectei do mesmo jeito exceto pelo sda e scl depois do ARef, eu tentei conectar esses dois com jumper wires no digital 20 e 21 do arduino mega (marcados como sda e scl) mas isso fazia parar de funcionar o script todo.

    ResponderExcluir
    Respostas
    1. Boa tarde,

      Funciona, mas vc precisa cortar algumas trilhas da placa, veja as instruções neste link, por favor:

      https://learn.adafruit.com/adafruit-16-channel-pwm-slash-servo-shield/shield-connections

      Abraço!

      Excluir
  8. bom dia não consigo controlar os servos mg 996r so os mg90 qual sera o defeito

    ResponderExcluir
    Respostas
    1. Bom dia,

      Estranho. O que acontece quando vc liga o MG996 ?

      Abraço!

      Excluir
  9. Boa tarde!
    Aonde posso conseguir a "biblioteca" deste componente para o fritzing?
    Grato

    ResponderExcluir
  10. Olá, boa noite! Estou fazendo um projeto em que preciso controlar a intensidade de 51 LEDs no arduino. Minha idéia é utilizar dois módulos desse e tentar controlar a intensidade dos LEDs pelo PWM do módulo. Será que seria possivel? Tem idéia de como?

    Desde já agradeço a ajuda!

    ResponderExcluir
  11. Olá estou montando um braço robotico, mas preciso gravar as posições dos servos para movimentos autonomos. Você teria um codigo que possa me ajudar a desenrolar o projeto ?

    Grato !

    ResponderExcluir