fbpx
Novidade

Como controlar servomotores com o Shield PWM PCA9685

O Shield PWM PCA9685 é uma placa de expansão utilizada para controlar múltiplos servos ou LEDs PWM com precisão via protocolo I2C. Ela é frequentemente usada com Arduino e outros microcontroladores para projetos de robótica.

Shield PWM PCA9685.
Figura 1- Shield PWM PCA9685.

O Shield PWM PCA9685 conta com os 16 canais com saídas PWM independentes, podendo controlar até 16 servos. Este componente se destaca pela sua funcionalidade de endereçamento I2C flexível, que permite o uso de até 62 dispositivos no mesmo barramento, facilitando a expansão dos sistemas. Além disso, o PCA9685 é um driver PWM versátil que se adapta a uma ampla gama de aplicações de controle, marcando presença significativa em projetos de tecnologia avançada e inovação em sistemas de controle automatizado.

Apesar de ter sido projetado para se acoplar diretamente à placa UNO, o PCA9685 permite a alimentação separada para o controle dos motores, independente da alimentação do microcontrolador, o que é crucial para prevenir sobrecarga.

Os 16 pinos PWM do Shield PWM PCA9685 são enumerados do 0 ao 15. Cada um destes pinos pode ser utilizado para controlar servomotores, LEDs ou outros dispositivos PWM. A interface I2C, através dos pinos SDA e SCL, simplifica a comunicação entre o Arduino e o PCA9685, utilizando apenas dois pinos de controle e liberando os demais pinos do Arduino para outras funcionalidades.

Além disso, o Shield replica os pinos digitais e analógicos do Arduino e inclui o botão Reset e os conectores de alimentação. A Figura 2 indica os pinos do Shield PWM PCA9685, que serão detalhados em seguida.

Conexões da Shield PWM PCA9685
Figura 2-Conexões da Shield PWM PCA9685.

A Shield PWM PCA9685 conta com:

– Conector de alimentação externa, usado para garantir a tensão necessária para o circuito.
-Botão reset, que replica o botão reset do Arduino.
-Pinos PWM, 16 pinos de saída PWM usados para controlar servos ou LEDs.
-Conectores de alimentação que são replicados do Arduino.
-Entradas analógicas e digitais replicadas do Arduino.

Agora que já conhecemos as especificações e forma de funcionamento do Shield PWM PCA9685, vamos aprender como utilizá-la na prática. Neste tutorial, vamos usar o Shield para controlar 16 servo motores.

MATERIAIS NESCESSÁRIOS

1 x Shield PWM PCA9685;
1 x Placa UNO SMD R3 Atmega328 compatível com Arduino UNO;
1 x Cabo USB Tipo A-B compatível com Arduino UNO;
16 x Micro Servo Motor 9G SG90;
1x Fonte de alimentação 5V de no mínimo 2A.

ESQUEMÁTICO DE LIGAÇÃO

Certifique-se que o circuito esteja desenergizado e, em seguida, monte o circuito seguindo as orientações abaixo.

Esquemático de ligação
Figura 3- Esquemático de ligação.

Ao montar o circuito, observe os seguintes pontos:

  • Encaixe o Shield PWM PCA9685 à placa UNO. Certifique-se de que os pinos do Shield PCA9685 estejam alinhados corretamente com os pinos correspondentes na placa UNO;
  • Cada servomotor possui três fios. O fio marrom deve ser conectado ao terminal GND do Shield, o fio vermelho deve ser ligado ao V+ e o fio amarelo deve ser conectado ao pino PWM;
  • Conecte os servomotores nas entradas PWM do Shield PCA9685 em sequência.

ATENÇÃO: Conectar a fonte de alimentação ao Shield antes de conectar o Arduino ao computador é crucial para prevenir sobrecarga e possíveis danos aos componentes.

ELABORANDO O CÓDIGO

Com o circuito montado, vamos à programação. A proposta desse projeto é controlar 16 servos utilizando o Shield PWM PCA9685. Para tal, vamos fazer uso da biblioteca Adafruit PWM Servo Driver Library. Para instalá-la abra o Gerenciador de Bibliotecas do Arduino IDE pelo caminho: Rascunho > Incluir biblioteca > Gerenciar bibliotecas, ou pelo atalho Ctrl+Shift+I.

Caminho para instalar a biblioteca.
Figura 4- Caminho para instalar a biblioteca.

Ao adicionar, caso tenha dúvidas, veja nosso tutorial de Como adicionar biblioteca na Arduino IDE.

Nossa intenção é que todos os servos se movam igualmente. Para isso, precisamos nos certificar de que todos comecem na mesma posição e que todas as hélices sejam colocadas corretamente. Portanto, vamos sincronizar os servos antes de encaixar as hélices. Para isso, criamos um código que faz com que todos os servos girem para a posição 0. Logo após, podemos encaixar as hélices na mesma posição em todos os servos.

CÓDIGO PARA SINCRONIZAR OS SERVOS

Primeiro, incluímos as bibliotecas Wire.h, que permite usar o I2C, e Adafruit_PWMServoDriver.h, que é responsável pelo funcionamento do Shield. Logo após, criamos o objeto que usa o endereço padrão 0x40.

Definimos os parâmetros servomin, configurando o pulso por milissegundo do servo e a quantidade de servos, que no nosso caso é 16.

Na função setup(), iniciamos o PCA9685 usando a função pwm.begin() para e definimos a frequência em 60 Hz com a função pwm.setPWMFreq(60) PWM.
Um breve delay de 10ms deve ser adicionado ao final do setup para que o hardware estabilize após ser configurado.

Ainda na função setup, criamos um for para definir a posição do servo para posição 0.

Na função loop, não é necessário colocar nada. No final, o código ficará da seguinte maneira:

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

// Cria o objeto PCA9685 usando o endereço I2C padrão 0x40
Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver();

// Definições dos parâmetros do servo
#define SERVOMIN  150 // Este é o 'pulso mínimo' em milissegundos, que geralmente corresponde à posição 0
#define NUM_SERVOS  16 // Número de servos conectados ao PCA9685

void setup() 
  pwm.begin(); // Inicia o PCA9685
  pwm.setPWMFreq(60); // Ajusta a frequência do PWM para 60 Hz (típico para servos)

  delay(10);
  
  // Define a posição 0 para todos os servos
  for (int i = 0; i < NUM_SERVOS; i++) {
    pwm.setPWM(i, 0, SERVOMIN);
  }
}

void loop() {

}


Após transferir o código, os motores serão colocados na posição 0. Coloque as hélices em todos os servos da mesma maneira, garantindo que fiquem alinhadas para possibilitar um movimento síncrono ao final do projeto.

Imagem dos servomotores  alinhados.
Figura 5- Imagem dos servomotores alinhados.

Agora, vamos ao código final do projeto.

Código final

Vamos iniciar incluindo as bibliotecas Wire.h e Adafruit_PWMServoDriver.h como no código anterior.

Em seguida, criamos o objeto PWM que utiliza por padrão o endereço I2C 0x40, que é usado para a comunicação com a shield.

Definimos os parâmetros importantes: SERVOMIN e SERVOMAX, que determinam os pulsos mínimo e máximo em milissegundos para os servos, ajustáveis conforme necessário.

Também definimos o número de servos, NUM_SERVOS, que neste caso é 16, indicando quantos servos estão conectados a shield.

Na função setup(), iniciamos o PCA9685 usando a função pwm.begin() para e definimos a frequência em 60 Hz com a função pwm.setPWMFreq(60) PWM.
Um breve delay de 10ms deve ser adicionado ao final do setup para que o hardware estabilize após ser configurado.

Na função loop(), adicionamos um laço de repetição para mover todos os servos. todos os servos são movidos para a posição máxima de forma acelerada, aumentando o pulso de SERVOMIN para SERVOMAX.

Após atingir a posição máxima, outro laço de repetição é utilizado para mover todos os servos de volta para a posição mínima, também de forma acelerada.

O pulso é reduzido de SERVOMAX para SERVOMIN. Entre laços de repetição do efeito foram criados delays de 5ms para garantir a estabilidade.

No final, o código ficará da seguinte maneira:

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

// Cria o objeto PCA9685 usando o endereço I2C padrão 0x40
Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver();

// Definições dos parâmetros do servo
#define SERVOMIN  150 // Pulso mínimo (ajuste conforme necessário para seu servo)
#define SERVOMAX  600 // Pulso máximo (ajuste conforme necessário para seu servo)
#define NUM_SERVOS  16 // Número de servos conectados ao PCA9685

void setup() {
  
  pwm.begin(); // Inicia o PCA9685
  pwm.setPWMFreq(60); // Ajusta a frequência do PWM para 60 Hz (típico para servos)

  delay(10);
}

void loop() {
  // Move todos os servos para a posição máxima mais rapidamente
  for (uint16_t pulselen = SERVOMIN; pulselen < SERVOMAX; pulselen++) {
    for (int i = 0; i < NUM_SERVOS; i++) {
      pwm.setPWM(i, 0, pulselen);
    }
    delay(5); // Reduzido para tornar o movimento mais rápido
  }

  // Move todos os servos de volta para a posição mínima mais rapidamente
  for (uint16_t pulselen = SERVOMAX; pulselen > SERVOMIN; pulselen--) {
    for (int i = 0; i < NUM_SERVOS; i++) {
      pwm.setPWM(i, 0, pulselen);
    }
    delay(5); // Reduzido para tornar o movimento mais rápido
  }
}

Veja o vídeo de como ficou nosso projeto:

Vídeo 1- Shield controlando 16 servomotores.

Espero ter ajudado, qualquer dúvida, deixe um comentário abaixo!

Até a próxima.

Estagiário no setor de desenvolvimento na Casa da Robótica

Graduando em Engenharia da Computação pela Faculdade Independente do Nordeste. Estagiário do setor de desenvolvimento da Casa da Robótica.

Raphael Christian

Graduando em Engenharia da Computação pela Faculdade Independente do Nordeste. Estagiário do setor de desenvolvimento da Casa da Robótica.