Skip to Content

Como controlar servomotores com Arduino

Como controlar servomotores com Arduino

Neste tutorial, vais aprender como funcionam os servomotores e como controlá-los com Arduino. Incluí diagramas de ligação e vários exemplos de código!

Os servomotores são frequentemente usados em projetos de robótica, mas também os podes encontrar em carros RC, aviões, etc. São muito úteis quando precisas de controlo preciso da posição e/ou de alto binário.

Na primeira parte deste artigo, vamos analisar o funcionamento interno de um servo e que tipo de sinal de controlo utiliza. Também explico as diferenças entre um servo standard e um servo contínuo. De seguida, vou mostrar como ligar um servomotor ao Arduino.

Com o primeiro exemplo de código, podes controlar tanto a posição como a velocidade do servomotor. Depois, vamos ver como controlar um servo com um potenciômetro e como modificar o código para controlar vários servos ao mesmo tempo. Por fim, no final deste artigo, encontras as especificações e dimensões de alguns dos servos mais populares no mercado.

Materiais

Componentes de hardware

SG90 micro servo× 1Amazon
MG996R high-torque servo× 1Amazon
Arduino Uno Rev3× 1Amazon
Jumper wires× 15Amazon
Breadboard× 1Amazon
10 kΩ potentiometer (tipo breadboard)× 1Amazon
USB cable type A/B× 1Amazon
5V power supply (opcional)× 1Amazon

Software

Arduino IDEArduino IDE

Makerguides is a participant in affiliate advertising programs designed to provide a means for sites to earn advertising fees by linking to Amazon, AliExpress, Elecrow, and other sites. As an Affiliate we may earn from qualifying purchases.

Como funciona um servomotor?

Um servo hobby standard tipicamente consiste num pequeno motor elétrico, um potenciômetro, eletrónica de controlo e uma caixa de engrenagens. A posição do eixo de saída é constantemente medida pelo potenciômetro interno e comparada com a posição alvo definida pelo controlador (ex. o Arduino).

De acordo com o erro, a eletrónica de controlo ajusta a posição real do eixo de saída para que corresponda à posição alvo. Isto é conhecido como um sistema de controlo em malha fechada.

Esquema de um servomotor RC (Hwang et al. 2018)

A caixa de engrenagens reduz a velocidade do motor, o que aumenta o binário no eixo de saída. A velocidade máxima do eixo de saída é geralmente cerca de 60 RPM.

Controlo do servo

Os servomotores são controlados enviando um sinal PWM (modulação por largura de pulso) para a linha de sinal do servo. A largura dos pulsos determina a posição do eixo de saída. Quando envias ao servo um sinal com largura de pulso de 1,5 milissegundos (ms), o servo move-se para a posição neutra (90 graus). As posições mínimas (0 graus) e máximas (180 graus) correspondem tipicamente a larguras de pulso de 1 ms e 2 ms, respetivamente. Nota que isto pode variar ligeiramente entre diferentes tipos e marcas de servos (ex. 0,5 e 2,5 ms). Muitos servos só giram cerca de 170 graus (ou até apenas 90), mas a posição intermédia está quase sempre nos 1,5 ms.

Para ajustar a posição mínima e máxima no código, vê a secção abaixo.

Pulsos para controlar o servo

Os servos geralmente esperam um pulso a cada 20 milissegundos ou 50 Hz, mas muitos servos RC funcionam bem numa gama de 40 a 200 Hz.

Servo de 360 graus (contínuo) vs servo de 180 graus (standard)

A maioria dos servos RC são do tipo 180 graus, o que significa que só podem girar numa faixa de 0 a 180 graus. No entanto, também existem servos de rotação contínua, conhecidos como servos de 360 graus.

Os servos de rotação contínua reagem de forma diferente ao sinal de controlo comparado com os servos standard de 180 graus. Com um servo de rotação contínua, não podes controlar a posição exata do eixo de saída, apenas a velocidade e a direção. Um pulso de 1 ms define a velocidade do servo para a máxima numa direção e um pulso de 2 ms para a máxima na direção oposta. Um valor perto de 1,5 ms faz o motor parar.

Se o teu servo se comportar de forma inesperada, podes estar a usar um servo contínuo em vez de um standard.

Para mais informações, vê o nosso tutorial Positional versus Continuous Servos.

Como ligar um servomotor ao Arduino?

Ligar um servomotor é muito fácil porque só precisas de ligar três fios: alimentação, terra e sinal. O fio de alimentação é tipicamente vermelho e deve ser ligado a 5 V.

Um micro servo como o SG90 consome cerca de 10 mA em repouso e 100 – 250 mA em rotação, por isso podes alimentá-lo diretamente com a saída de 5 V do Arduino. No entanto, tens de ter cuidado ao usar vários servos ou servos maiores. Se o(s) teu(s) motor(es) consumirem mais de 300 mA, deves usar uma fonte de alimentação externa para evitar danificar o Arduino! Vê o esquema abaixo para usar fontes de alimentação externas.

O fio de terra é tipicamente preto ou castanho e deve ser ligado ao pino de terra do Arduino. Quando usares uma fonte de alimentação separada, liga o fio de terra tanto ao Arduino como à fonte de alimentação.

O fio de sinal é tipicamente amarelo, laranja ou branco e pode ser ligado a qualquer pino digital do Arduino. Neste caso, liguei-o ao pino digital 9.

Servo motor with Arduino Uno wiring diagram.
Diagrama de ligação do servomotor com Arduino Uno

As ligações estão também indicadas na tabela abaixo.

Ligações do servomotor

ServomotorArduino
Alimentação (vermelho)5 V
Terra (preto ou castanho)GND
Sinal (amarelo, laranja ou branco)Pino 9

Como mencionei antes, se estiveres a usar servos grandes ou múltiplos, deves usar uma fonte de alimentação externa. Basta ligar a fonte conforme mostrado no diagrama de ligação abaixo. Certifica-te de ligar o pino GND do Arduino e da fonte de alimentação em comum.

Também podes usar esta configuração se o teu servomotor precisar de uma voltagem diferente da que o Arduino pode fornecer, ex. 6 V ou mais. A imagem seguinte mostra como usar uma fonte de alimentação externa para alimentar o servo:

servo-motor-with-arduino-uno-and-external-power-supply-wiring-diagram-schematic-circuit-tutorial
Ligação do servo com Arduino Uno e fonte de alimentação

Ligações para servomotor com fonte de alimentação externa

ServomotorLigação
Alimentação (vermelho)Fonte de alimentação 5 V
Terra (preto ou castanho)Terra da fonte de alimentação e GND do Arduino
Sinal (amarelo, laranja ou branco)Pino 9 do Arduino

Exemplo de código Arduino

Para controlar o servomotor vamos usar a Servo.h biblioteca que já vem pré-instalada no Arduino IDE. Com o código de exemplo abaixo, podes controlar a posição exata do servomotor e inclui também código para mover o braço do servo automaticamente para a frente e para trás.

Podes carregar o código de exemplo para o teu Arduino via Arduino IDE. A seguir, vou explicar como o código funciona.

/* Servo motor with Arduino example code. Position and sweep. More info: https://www.makerguides.com/ */

// Include the servo library:
#include "Servo.h"

// Create a new servo object:
Servo myservo;

// Define the servo pin:
#define servoPin 9

void setup() {
  // Attach the Servo variable to a pin:
  myservo.attach(servoPin);
}

void loop() {
  // Tell the servo to go to a particular angle:
  myservo.write(90);
  delay(1000);
  myservo.write(180);
  delay(1000);
  myservo.write(0);
  delay(1000);

  // Sweep from 0 to 180 degrees:
  for (int angle = 0; angle <= 180; angle += 1) {
    myservo.write(angle);
    delay(15);
  }

  // And back from 180 to 0 degrees:
  for (int angle = 180; angle >= 0; angle -= 1) {
    myservo.write(angle);
    delay(15);
  }
  delay(1000);
}

Como o código funciona

O primeiro passo é incluir a biblioteca Arduino necessária. Também podes encontrar esta biblioteca em Sketch > Include Library > Servo.

// Include the servo library:
#include "Servo.h"

De seguida, precisas criar um novo objeto da classe Servo. Neste caso, chamei o servo de ‘myservo’, mas podes usar outros nomes. Nota que terás de alterar o nome do servo no resto do código.

// Create a new servo object:
Servo myservo;

Depois, defini a que pino do Arduino o servomotor está ligado.

// Define the servo pin:
#define servoPin 9

A instrução #define é usada para dar um nome a um valor constante. O compilador vai substituir todas as referências a esta constante pelo valor definido quando o programa for compilado. Assim, em todo o lado onde mencionares servoPin, o compilador vai substituir pelo valor 9 quando o programa for compilado.

Na secção setup do código, ligamos o objeto servo que criámos ao pino que vai controlar o servo. A função attach() também tem dois parâmetros opcionais, que discuto na secção abaixo.

void setup() {
  // Attach the Servo variable to a pin:
  myservo.attach(servoPin);
}

Controlar ângulo/posição:

Na primeira parte do loop, simplesmente dizemos ao servomotor para se mover para um ângulo específico com a função write(). Nota que precisas de um delay entre os comandos para dar tempo ao servo para se mover para a posição definida.

  // Tell the servo to go to a particular angle:
  myservo.write(90);
  delay(1000);
  myservo.write(180);
  delay(1000);
  myservo.write(0);
  delay(1000);

Controlar velocidade:

Na última parte do código, usei dois ciclos for para mover o servo para a frente e para trás. Este pedaço de código também pode ser útil se quiseres controlar a velocidade do servomotor. Alterando o valor do delay no final do ciclo for, podes ajustar a velocidade do braço do servo.

  // Sweep from 0 to 180 degrees:
  for (int angle = 0; angle <= 180; angle += 1) {
    myservo.write(angle);
    delay(15);
  }
  // And back from 180 to 0 degrees:
  for (int angle = 180; angle >= 0; angle -= 1) {
    myservo.write(angle);
    delay(15);
  }

Porque é que o meu servo não roda os 0 – 180 graus completos?

Como expliquei na introdução, o ângulo do eixo de saída do servomotor é determinado pela largura do pulso elétrico aplicado ao fio de controlo. Geralmente, uma largura de pulso de cerca de 1 ms (milissegundo) corresponde à posição mínima, 2 ms à posição máxima, e 1,5 ms a 90° (posição neutra). No entanto, isto pode variar ligeiramente entre marcas e até entre servos diferentes da mesma marca. Isto significa que terás de ajustar os valores mínimos e máximos no código para corresponder ao servo que estás a usar.

A biblioteca Servo do Arduino torna muito fácil ajustar o ângulo mínimo e máximo do servomotor especificando dois parâmetros opcionais na função attach(). Nesta função, o primeiro parâmetro é o número do pino ao qual o servo está ligado. O segundo parâmetro é a largura do pulso, em microssegundos (μs), correspondente ao ângulo mínimo (0 graus) do servomotor. O terceiro parâmetro é a largura do pulso, em microssegundos, correspondente ao ângulo máximo (180 graus) do servomotor.

Por defeito, a largura mínima e máxima do pulso está definida para 544 e 2400 microssegundos. Estes valores funcionam para a maioria dos servos comuns, mas por vezes tens de ajustar ligeiramente os valores.

Recomendo ajustar os valores mínimo e máximo em pequenos incrementos (10-20 microssegundos) para evitar danificar o servo. Se o braço do servo bater nos limites físicos do motor, aumenta o valor mínimo e diminui o valor máximo.

#define servoPin 9
int min = 480;
int max = 2500;
Servo myservo;

void setup() {
  myservo.attach(servoPin, min, max);
}

Controlar um servomotor com um potenciômetro e Arduino

servo-motor-with-arduino-uno-and-potentiometer-wiring-diagram-schematic-circuit
Diagrama de ligação para controlar um servomotor com um potenciômetro e Arduino.

Controlar a posição de um servomotor com um potenciômetro é muito fácil e pode ser muito útil se quiseres ajustar a posição do motor manualmente. Como podes ver no diagrama de ligação acima, o servomotor está ligado da mesma forma que antes. A única diferença é que usei uma breadboard para distribuir a alimentação do Arduino.

O potenciômetro tem três pinos, liga os pinos exteriores a 5 V e GND. O pino do meio do potenciômetro está ligado ao pino analógico A0 do Arduino.

Exemplo de código Arduino para servomotor com potenciômetro

O código de exemplo abaixo permite controlar um servomotor com um potenciômetro.

/* Servo motor with potentiometer and Arduino example code. More info: https://www.makerguides.com/ */

#include "Servo.h" // include the required Arduino library

#define servoPin 9 // Arduino pin for the servo
#define potPin A0 // Arduino pin for the potentiometer

int angle = 0; // variable to store the servo position in degrees
int reading = 0; // variable to store the reading from the analog input

Servo myservo; // create a new object of the servo class

void setup() {
  myservo.attach(servoPin);
}

void loop() {
  reading = analogRead(potPin); // read the analog input
  angle = map(reading, 0, 1023, 0, 180); // map the input to a value between 0 and 180 degrees
  myservo.write(angle); // tell the servo to go to the set position
  delay(15); // wait 15 ms for the servo to reach the position
}

Repara que antes da secção setup e loop do código é adicionada uma nova variável reading e é definido o pino de entrada do potenciômetro.

Na secção loop do código, lemos o valor do pino analógico A0 com a função analogRead().

reading = analogRead(potPin); // read the analog input

As placas Arduino contêm um conversor analógico-digital (ADC) de 10 bits, por isso isto dá-nos um valor entre 0 e 1023 dependendo da posição do potenciômetro.

Como o servomotor só pode girar entre 0 e 180 graus, precisamos de escalar os valores com a função map(). Esta função remapeia um número de um intervalo para outro.

angle = map(reading, 0, 1023, 0, 180); // map the input to a value between 0 and 180 degrees

Por fim, escrevemos o ângulo para o servomotor:

myservo.write(angle); // tell the servo to go to the set position
delay(15); // wait 15 ms for the servo to reach the position

Controlar múltiplos servomotores

Controlar múltiplos servos é tão fácil como controlar apenas um, mas recebo frequentemente perguntas sobre como modificar o código. Por isso, adicionei um exemplo simples abaixo.

how-to-control-multiple-servo-motors-with-arduino-wiring-diagram-schematic-circuit-tutorial-1
Múltiplos servomotores ligados ao Arduino Uno e a uma fonte de alimentação externa.

Repara que terás de usar uma fonte de alimentação externa para alimentar os servos porque o Arduino não consegue fornecer corrente suficiente para alimentar todos os motores.

Para este exemplo, usamos apenas mais pinos do Arduino para os servos adicionais. No entanto, isto significa que estás limitado a 12 servos quando usas um Arduino Uno, e podes não ter pinos suficientes para outros componentes.

Outra opção é usar um ou vários PCA9685 PWM/servo drivers. Este driver permite controlar 16 servos com apenas 2 pinos do Arduino usando I2C. A Adafruit também vende estes em forma de Arduino shield.

Como a configuração destes drivers de servo é um pouco mais complexa, vou abordar isso num tutorial separado.

Exemplo de código Arduino com múltiplos servos

Como podes ver no exemplo abaixo, só tens de criar mais objetos da classe Servo com nomes diferentes. Podes endereçar cada servo usando o nome correto na secção setup e loop do código.

/* Arduino with multiple servos example code. More info: https://www.makerguides.com/ */

#include "Servo.h"

Servo servo1;
Servo servo2;
Servo servo3;
Servo servo4;
Servo servo5;

void setup()
{
  servo1.attach(9);
  servo2.attach(10);
  servo3.attach(11);
  servo4.attach(12);
  servo5.attach(13);
}

void loop()
{
  servo1.write(0);
  servo2.write(0);
  servo3.write(0);
  servo4.write(0);
  servo5.write(0);
  delay(2000);
  servo1.write(90);
  servo2.write(90);
  servo3.write(90);
  servo4.write(90);
  servo5.write(90);
  delay(1000);
  servo1.write(180);
  servo2.write(180);
  servo3.write(180);
  servo4.write(180);
  servo5.write(180);
  delay(1000);
}

Especificações dos servomotores

Abaixo encontras as especificações de alguns dos servos mais populares no mercado. O fabricante original destes servos é Tower Pro Pte Ltd. mas modelos semelhantes podem ser comprados em muitos outros fornecedores também.

SG90 analog micro servo

tower-pro-sg90-analog-micro-servo-motor-9g-1
[Fonte: towerpro.com.tw]

Pinout

CastanhoGND
VermelhoVCC
AmareloSinal (PWM)

Especificações

Tensão de funcionamento4.8 V
Peso9 g
Binário de bloqueio1.8 kg/cm (4.8 V)
Tipo de engrenagemConjunto de engrenagens POM
Velocidade de funcionamento0.12 s/60° (4.8 V)
Temperatura de funcionamento0 – 55 °C
CustoCheck price

Dimensões

A34.5 mm
B22.8 mm
C26.7 mm
D12.6 mm
E32.5 mm
F16 mm
sg90-micro-servo-motor-dimensions-2
[Fonte: towerpro.com.tw]

MG90S digital micro servo

tower pro mg90s digital micro servo
[Fonte: towerpro.com.tw]

Pinout

CastanhoGND
VermelhoVCC
AmareloSinal (PWM)

Especificações

Tensão de funcionamento4.8 V
Peso13.4 g
Binário de bloqueio1.8 kg/cm (4.8 V), 2.2 kg/cm (6.6 V)
Tipo de engrenagemAlumínio 6061-T6
Velocidade de funcionamento0.10 s/60° (4.8 V), 0.08 s/60° (6.0 V)
Temperatura de funcionamento0 – 55 °C
CustoCheck price

Dimensões

A32.5 mm
B22.8 mm
C28.4 mm
D12.4 mm
E32.1 mm
F18.5 mm
sg90-micro-servo-motor-dimensions-2
[Fonte: towerpro.com.tw]

MG996R high torque digital servo

[Fonte: towerpro.com.tw]

Pinout

CastanhoGND
VermelhoVCC
AmareloSinal (PWM)

Especificações

Tensão de funcionamento4.8 – 6.6 V
Consumo de corrente em repouso10 mA
Consumo de corrente em funcionamento sem carga170 mA
Consumo de corrente em bloqueio1400 mA
Peso55 g
Binário de bloqueio9.4 kg/cm (4.8 V), 11 kg/cm (6.0 V)
Tipo de engrenagemEngrenagem metálica
Velocidade de funcionamento0.19 s/60° (4.8 V), 0.15 s/60° (6.0 V)
Temperatura de funcionamento0 – 55 °C
CustoCheck price

Dimensões

A42.7 mm
B40.9 mm
C37 mm
D20 mm
E54 mm
F26.8 mm
sg90-micro-servo-motor-dimensions-2
[Fonte: towerpro.com.tw]

Conclusão

Neste tutorial, mostrei-te como usar servomotores com Arduino. Vimos o básico do controlo da posição e velocidade dos servos, como controlar um servo com um potenciômetro e como controlar vários servos ao mesmo tempo.

Se quiseres aprender mais sobre outros tipos de motores, vê os artigos abaixo:

Também tenho um artigo sobre How To Control Servo Motors using ESP32 se quiseres trabalhar com um microcontrolador ESP32 em vez disso.

Se tiveres alguma pergunta, sugestão, ou se achares que falta algo neste tutorial, deixa um comentário abaixo.