
Controlar um Servo Motor SG90 com Arduino: Tutorial Detalhado
Bem-vindo a este guia completo e detalhado sobre como controlar o popular servo motor SG90 utilizando uma placa Arduino. Se está a dar os primeiros passos no mundo da eletrónica e robótica, ou se procura aprofundar os seus conhecimentos sobre o controlo de movimento preciso, este tutorial é para si. Cobriremos desde os conceitos fundamentais até exemplos práticos de código, passando pelas ligações de hardware e dicas de otimização.
Introdução: O que é um Servo Motor e Porquê o SG90?
Antes de mergulharmos nas ligações e no código, é fundamental perceber o que é um servo motor e porque o SG90 é tão popular entre entusiastas e educadores.
O que é um Servo Motor?
Ao contrário dos motores DC comuns, que rodam continuamente quando alimentados, um servo motor (ou simplesmente "servo") é um atuador rotativo ou linear que permite um controlo preciso da posição angular ou linear, velocidade e aceleração. É um dispositivo que contém um motor (normalmente DC), um conjunto de engrenagens para redução de velocidade e aumento de binário (torque), um sensor de posição (geralmente um potenciómetro) e um circuito de controlo.
A magia do servo motor reside na sua capacidade de se mover para uma posição específica e mantê-la. O circuito de controlo interno recebe um sinal de comando (normalmente um sinal de Modulação por Largura de Pulso - PWM), compara a posição atual (lida pelo potenciómetro) com a posição desejada (determinada pelo sinal PWM) e aciona o motor para corrigir qualquer diferença. Este sistema de ciclo fechado (closed-loop) é o que garante a precisão do servo.
Tipos de Servo Motores:
Existem diversos tipos de servos, variando em tamanho, binário, velocidade, tipo de motor (com ou sem escovas - brushed/brushless), tipo de engrenagens (plástico ou metal) e ângulo de rotação (os mais comuns são de 90°, 180°, 270°, ou de rotação contínua, que funcionam mais como motores DC com controlo de velocidade e direção).
O Servo Motor Micro SG90:
O Tower Pro SG90 é um dos servo motores mais conhecidos e utilizados em projetos de pequena escala. As suas principais vantagens são:
Baixo Custo: É extremamente acessível, tornando-o ideal para projetos com orçamento limitado, educação e prototipagem rápida.
Pequeno Tamanho e Peso Leve: As suas dimensões reduzidas (aproximadamente 23 x 12.2 x 29 mm) e peso (cerca de 9 gramas) permitem integrá-lo facilmente em projetos compactos e leves, como pequenos robôs, braços robóticos simples, mecanismos de pan/tilt para câmaras, aeromodelismo leve, etc.
Facilidade de Uso: É relativamente simples de controlar com microcontroladores como o Arduino, graças a bibliotecas bem estabelecidas.
Alimentação Simples: Opera tipicamente com tensões entre 4.8V e 6V, compatíveis com a saída de 5V da maioria das placas Arduino (embora com ressalvas, como veremos).
No entanto, o SG90 também tem limitações:
Baixo Binário: Devido ao seu tamanho e construção (engrenagens de nylon/plástico), o binário (força de rotação) é limitado (tipicamente 1.8 kgf·cm a 4.8V). Não é adequado para aplicações que exijam mover cargas pesadas.
Engrenagens de Plástico: As engrenagens de plástico são menos duráveis que as de metal e podem desgastar-se ou partir sob stress excessivo.
Precisão Limitada: Sendo um servo de baixo custo, a sua precisão e repetibilidade podem não ser tão elevadas como as de servos mais caros. Pode apresentar alguma "zona morta" (dead band) e um ligeiro "jitter" (vibração) em algumas posições.
Ângulo de Rotação: Embora frequentemente anunciado como de 180°, na prática, o seu alcance útil costuma ser ligeiramente menor, dependendo do sinal PWM aplicado (algo entre 160°-170° é mais realista em muitos casos).
Apesar das limitações, o SG90 é um ponto de partida fantástico para aprender sobre o controlo de servos.
O Papel do Arduino:
O Arduino é uma plataforma de prototipagem eletrónica de código aberto (open-source) baseada em hardware e software fáceis de usar. As placas Arduino (como o popular Arduino UNO, Nano, ou Mega) são microcontroladores capazes de ler entradas (luz num sensor, um dedo num botão, ou uma mensagem do Twitter) e transformá-las numa saída (ativar um motor, ligar um LED, publicar algo online).
O Arduino é perfeito para controlar servos como o SG90 porque:
Possui Pinos PWM: As placas Arduino têm pinos específicos capazes de gerar os sinais PWM necessários para controlar a posição do servo.
Biblioteca Servo Dedicada: O Arduino IDE (Ambiente de Desenvolvimento Integrado) vem com uma biblioteca (Servo.h) que simplifica enormemente o processo de geração dos sinais PWM corretos e o controlo do servo.
Comunidade e Documentação: Existe uma vasta comunidade online e documentação extensa, facilitando a resolução de problemas e a aprendizagem.
Flexibilidade: Permite integrar o controlo do servo com outros sensores e atuadores, criando projetos interativos complexos.
Neste tutorial, vamos focar-nos em como usar o Arduino para enviar os comandos corretos ao SG90 e fazê-lo mover-se para as posições desejadas.
Materiais Necessários
Para seguir este tutorial e controlar o seu servo motor SG90 com um Arduino, precisará dos seguintes componentes:
Placa Arduino: Qualquer placa Arduino compatível servirá. As mais comuns são o Arduino UNO, Arduino Nano ou Arduino Mega. Usaremos o Arduino UNO como referência, mas os princípios aplicam-se a outras placas.
Servo Motor SG90: O protagonista do nosso tutorial. Geralmente vem com um conjunto de "horns" ou braços de plástico que podem ser acoplados ao eixo de saída.
Fios de Ligação (Jumper Wires): Precisará de pelo menos 3 fios macho-macho ou macho-fêmea, dependendo se está a usar uma breadboard. Recomenda-se ter um conjunto variado. Usaremos fios macho-macho para ligação direta ou macho-fêmea se ligar diretamente aos pinos da placa.
Cabo USB: Para ligar o Arduino ao seu computador (programação e alimentação inicial).
Computador com Arduino IDE: Necessário para escrever, compilar e carregar o código para a placa Arduino. Pode descarregar o IDE gratuitamente do site oficial do Arduino (arduino.cc).
(Opcional, mas Recomendado) Breadboard (Placa de Ensaio): Facilita a organização das ligações, especialmente se planeia adicionar mais componentes (como potenciómetros ou outros servos).
(Opcional, Altamente Recomendado para Múltiplos Servos ou Carga Elevada) Fonte de Alimentação Externa: Uma fonte de 5V (ou ajustável entre 4.8V e 6V) com corrente suficiente (pelo menos 1A por servo, como regra geral) para alimentar o(s) servo(s) diretamente, em vez de depender da saída de 5V do Arduino, que pode ser insuficiente e causar problemas.
Certifique-se de que tem o Arduino IDE instalado e configurado no seu computador antes de prosseguir.
Compreender o Servo Motor SG90 em Detalhe
Para controlar eficazmente o SG90, é útil conhecer as suas especificações e como funciona internamente.
Especificações Típicas do SG90:
Tensão de Operação: 4.8V a 6.0V (algumas folhas de dados indicam 4.8V a 5V como ideal)
Velocidade de Operação (sem carga):0.12 seg/60° (a 4.8V)
0.10 seg/60° (a 6.0V)
Binário (Torque):1.8 kgf·cm (quilograma-força por centímetro) a 4.8V
2.2 kgf·cm a 6.0V
Ângulo de Rotação Máximo: Nominalmente 180° (na prática, muitas vezes limitado a cerca de 160°-170° com sinais PWM padrão).
Largura da Banda Morta (Dead Band Width): ~10 µs (microssegundos) - A quantidade mínima de alteração no sinal PWM necessária para que o servo comece a mover-se.
Tipo de Engrenagens: Nylon / Plástico
Tipo de Conector: Universal tipo "JR" / "Futaba" com 3 pinos.
Dimensões: ~23 x 12.2 x 29 mm
Peso: ~9 g
Pinout do SG90:
O SG90 possui um cabo com 3 fios, geralmente com as seguintes cores (embora possa variar ligeiramente entre fabricantes, a ordem costuma ser a mesma):
Fio Castanho (ou Preto): Terra (Ground - GND)
Fio Vermelho: Alimentação Positiva (VCC) - Ligar a 4.8V - 6V (tipicamente 5V do Arduino para testes simples).
Fio Laranja (ou Amarelo): Sinal PWM (Signal) - Ligar a um pino digital com capacidade PWM do Arduino.
Importante: Verifique sempre a documentação específica do seu servo se as cores forem diferentes, mas a ordem GND-VCC-Signal é a mais comum. Ligar incorretamente pode danificar o servo ou o Arduino.
Como o SG90 Interpreta o Sinal PWM:
O coração do controlo de um servo é o sinal de Modulação por Largura de Pulso (PWM). O circuito de controlo do SG90 espera receber um pulso elétrico numa frequência específica (geralmente 50 Hz, o que corresponde a um período de 20 milissegundos - ms). A posição angular do eixo do servo é determinada pela duração (ou largura) desse pulso elétrico, dentro de cada ciclo de 20 ms.
Pulso de ~1 ms (1000 µs): Corresponde tipicamente à posição de 0 graus (extremo esquerdo).
Pulso de ~1.5 ms (1500 µs): Corresponde tipicamente à posição central de 90 graus.
Pulso de ~2 ms (2000 µs): Corresponde tipicamente à posição de 180 graus (extremo direito).
Valores de largura de pulso intermédios resultarão em posições angulares intermédias. Por exemplo, um pulso de 1.25 ms moveria o servo para aproximadamente 45 graus.
É crucial entender que não é a voltagem do pulso (que é tipicamente 5V ou 3.3V, dependendo do microcontrolador) nem a frequência (que deve ser constante em ~50 Hz) que definem a posição, mas sim a duração do pulso positivo dentro de cada ciclo de 20 ms. A biblioteca Servo.h do Arduino abstrai grande parte desta complexidade, permitindo-nos especificar a posição em graus (0-180) ou diretamente em microssegundos (usando writeMicroseconds()).
Mecanismo Interno (Simplificado):
O pino de sinal recebe o pulso PWM do Arduino.
O circuito de controlo interno mede a largura deste pulso. Este valor representa a posição desejada.
O circuito lê a posição atual do eixo através do potenciómetro interno, que está mecanicamente ligado ao eixo de saída através das engrenagens.
O circuito compara a posição desejada com a posição atual.
Se houver diferença, o circuito envia energia ao motor DC interno na direção apropriada para reduzir essa diferença.
As engrenagens reduzem a alta velocidade e baixo binário do motor DC para uma baixa velocidade e alto binário no eixo de saída, movendo o braço do servo.
À medida que o eixo roda, o potenciómetro também roda, alterando a leitura da posição atual.
O processo repete-se continuamente (muitas vezes por segundo) até que a posição atual coincida com a posição desejada. Nesse ponto, o motor para (ou aplica uma pequena força para manter a posição se houver carga).
Ligação do Hardware: Conectar o SG90 ao Arduino
Agora que entendemos os componentes, vamos proceder à ligação física. Para um único servo SG90 e testes iniciais, podemos alimentar o servo diretamente a partir da saída de 5V do Arduino UNO.
Esquema de Ligação Simples:
GND (Terra): Ligue o fio Castanho (ou Preto) do SG90 a um dos pinos GND do Arduino. É fundamental que ambos os dispositivos partilhem uma referência de terra comum.
VCC (Alimentação): Ligue o fio Vermelho do SG90 ao pino 5V do Arduino.
Signal (Sinal PWM): Ligue o fio Laranja (ou Amarelo) do SG90 a um dos pinos digitais com capacidade PWM do Arduino. No Arduino UNO, estes pinos estão marcados com um til (~), como os pinos 3, 5, 6, 9, 10 e 11. Vamos usar o pino 9 neste exemplo.
Descrição Visual (Imagine esta ligação):
Tem a sua placa Arduino UNO.
Tem o seu servo SG90 com os três fios (Castanho, Vermelho, Laranja).
Usando fios de ligação:Um fio liga o pino Castanho do servo a um pino GND do Arduino.
Um fio liga o pino Vermelho do servo ao pino 5V do Arduino.
Um fio liga o pino Laranja do servo ao pino digital ~9 do Arduino.
Diagrama de Ligações (Texto):
Servo SG90 Arduino UNO
----------- ------------
Fio Castanho (GND) ----> GND
Fio Vermelho (VCC) ----> 5V
Fio Laranja (Signal) --> Pino Digital ~9
Considerações Importantes sobre a Alimentação:
Alimentação via USB: Quando o Arduino está alimentado apenas pela porta USB do computador, a corrente disponível no pino 5V é limitada (geralmente < 500mA). Um servo SG90 pode consumir picos de corrente significativos ao arrancar ou sob carga (várias centenas de mA). Alimentar um único SG90 diretamente do pino 5V do Arduino geralmente funciona para testes simples e sem carga, mas pode levar a comportamentos erráticos (jitter, reset do Arduino) se o servo exigir mais corrente do que a porta USB ou o regulador do Arduino podem fornecer.
Alimentação Externa (Recomendado): Se planeia usar múltiplos servos, ou se o seu servo SG90 vai operar sob carga, ou se notar comportamento instável, é altamente recomendável usar uma fonte de alimentação externa dedicada para os servos.
Como ligar com fonte externa:A fonte externa (5V, 1A ou mais por servo) deve ter o seu terminal positivo (+) ligado ao fio Vermelho (VCC) de todos os servos.
O terminal negativo (-) da fonte externa deve ser ligado ao fio Castanho (GND) de todos os servos E TAMBÉM a um pino GND do Arduino. Esta ligação de terra comum é essencial!
O fio Laranja (Signal) de cada servo continua ligado a um pino PWM distinto do Arduino.
O pino 5V do Arduino não é usado para alimentar os servos neste caso. O Arduino continua a ser alimentado separadamente (via USB ou pelo seu próprio jack de alimentação).
Servo SG90 Arduino UNO Fonte Externa 5V
----------- ------------ ----------------
Fio Castanho (GND) ----> GND <---------- Negativo (-)
Fio Vermelho (VCC) --------------------> Positivo (+)
Fio Laranja (Signal) --> Pino Digital ~9
Para os exemplos básicos seguintes, assumiremos a ligação simples (alimentação pelo pino 5V do Arduino), mas tenha em mente a opção da fonte externa para projetos mais robustos.
Programação Básica: Usando a Biblioteca Servo.h
O Arduino IDE vem com a biblioteca Servo.h, que torna o controlo de servos incrivelmente fácil. Não precisa de se preocupar em gerar manualmente os sinais PWM de 50 Hz com as larguras de pulso corretas; a biblioteca trata disso.
Passos Fundamentais no Código:
Incluir a Biblioteca: No início do seu sketch (programa Arduino), precisa de incluir a biblioteca Servo:
C++
#include <Servo.h>
Criar um Objeto Servo: Declare uma variável do tipo Servo para cada servo que pretende controlar. Dê-lhe um nome descritivo:
C++
Servo meuServo; // Cria um objeto servo chamado meuServo
Anexar o Servo a um Pino (no setup()): Na função setup(), que corre uma vez quando o Arduino liga ou é reiniciado, use a função attach() para associar o seu objeto servo a um pino PWM específico do Arduino.
C++
void setup() {
meuServo.attach(9); // Associa meuServo ao pino digital 9
}
A função attach() pode ter argumentos opcionais para definir os limites mínimo e máximo da largura de pulso em microssegundos (µs), caso precise de ajustar o alcance do servo: meuServo.attach(pin, min_us, max_us);. Os valores padrão costumam ser 544 µs e 2400 µs, mas os valores efetivos que correspondem a 0-180 graus para o SG90 estão mais perto de 1000-2000 µs ou, por vezes, um intervalo ligeiramente diferente. Para começar, a forma simples attach(pin) é suficiente.
Comandar a Posição (no loop() ou noutras funções): Para mover o servo, use a função write(). Esta função aceita um valor entre 0 e 180, representando o ângulo desejado em graus.
C++
void loop() {
meuServo.write(0); // Move o servo para a posição 0 graus
delay(1000); // Espera 1 segundo
meuServo.write(90); // Move o servo para a posição 90 graus (centro)
delay(1000); // Espera 1 segundo
meuServo.write(180); // Move o servo para a posição 180 graus
delay(1000); // Espera 1 segundo
}
A função write() mapeia o valor de 0-180 para a largura de pulso apropriada (usando os limites definidos no attach() ou os padrões da biblioteca).
Exemplo 1: Varrer o Servo (Sweep)
Este é o exemplo clássico "Olá, Mundo!" para servos. Faz o servo mover-se suavemente de uma extremidade à outra e vice-versa.
C++
#include <Servo.h> // Inclui a biblioteca Servo
Servo meuServo; // Cria um objeto servo para controlar um servo
int pos = 0; // Variável para armazenar a posição do servo (ângulo)
void setup() {
meuServo.attach(9); // Anexa o servo ao pino 9
Serial.begin(9600); // Inicia a comunicação serial (opcional, para depuração)
Serial.println("Teste de Sweep do Servo SG90");
}
void loop() {
// Varrer de 0 graus para 180 graus
Serial.println("Varrendo de 0 para 180 graus...");
for (pos = 0; pos <= 180; pos += 1) { // Incrementa a posição de 1 em 1 grau
meuServo.write(pos); // Define a posição do servo
delay(15); // Espera 15ms para o servo atingir a posição
}
Serial.println("Varredura 0->180 concluída.");
delay(500); // Pausa no final
// Varrer de 180 graus para 0 graus
Serial.println("Varrendo de 180 para 0 graus...");
for (pos = 180; pos >= 0; pos -= 1) { // Decrementa a posição de 1 em 1 grau
meuServo.write(pos); // Define a posição do servo
delay(15); // Espera 15ms
}
Serial.println("Varredura 180->0 concluída.");
delay(500); // Pausa no final
}
Explicação do Código "Sweep":
#include <Servo.h>: Importa as funcionalidades necessárias para controlar servos.
Servo meuServo;: Declara um objeto chamado meuServo que representará o nosso SG90.
int pos = 0;: Declara uma variável inteira pos para guardar o ângulo atual do servo, inicializada em 0.
setup():meuServo.attach(9);: Informa a biblioteca que o nosso meuServo está ligado ao pino 9 e inicia a geração do sinal PWM nesse pino.
Serial.begin(9600);: Inicializa a comunicação serial para que possamos ver mensagens no Monitor Serial do Arduino IDE (útil para depuração).
Serial.println(...): Envia uma mensagem inicial para o Monitor Serial.
loop(): Esta função repete-se continuamente.Primeiro for loop:for (pos = 0; pos <= 180; pos += 1): Inicia um ciclo que começa com pos = 0, continua enquanto pos for menor ou igual a 180, e incrementa pos em 1 a cada iteração.
meuServo.write(pos);: Envia o comando para o servo se mover para o ângulo atual de pos.
delay(15);: Introduz uma pequena pausa. Isto é importante para dar tempo ao servo para se mover fisicamente para a nova posição antes de receber o próximo comando. Um valor mais pequeno resulta num movimento mais rápido (mas potencialmente menos suave ou que sobrecarrega o servo), um valor maior torna o movimento mais lento. O valor de 15ms é um bom ponto de partida.
delay(500);: Pausa de meio segundo quando o servo atinge os 180 graus.
Segundo for loop:for (pos = 180; pos >= 0; pos -= 1): Semelhante ao primeiro, mas agora decrementa pos de 180 até 0.
meuServo.write(pos);: Move o servo para a nova posição.
delay(15);: Pausa para o movimento.
delay(500);: Pausa de meio segundo quando o servo retorna a 0 graus.
O loop() recomeça, repetindo o movimento de varredura.
Como Carregar e Executar:
Abra o Arduino IDE.
Copie e cole o código acima num novo sketch.
Certifique-se de que as ligações de hardware entre o Arduino e o SG90 estão corretas (GND->GND, VCC->5V, Signal->Pino 9).
Ligue o Arduino ao computador com o cabo USB.
No Arduino IDE, vá a Ferramentas > Placa e selecione o modelo da sua placa (e.g., "Arduino UNO").
Vá a Ferramentas > Porta e selecione a porta COM à qual o Arduino está ligado.
Clique no botão "Verificar" (ícone de visto) para compilar o sketch e verificar se há erros.
Clique no botão "Carregar" (ícone de seta para a direita) para enviar o código para o Arduino.
Se tudo correr bem, o servo SG90 deverá começar a mover-se lentamente de uma extremidade à outra.
Pode abrir o Monitor Serial (Ferramentas > Monitor Serial ou Ctrl+Shift+M), certificar-se que a taxa de transmissão (baud rate) está definida para 9600, e verá as mensagens indicando o progresso da varredura.
Técnicas de Controlo Avançadas
Além do movimento básico de varredura, podemos controlar o servo de formas mais interativas.
Exemplo 2: Controlar o Servo com um Potenciómetro
Um potenciómetro é um resistor variável que pode ser usado para fornecer uma entrada analógica ao Arduino. Podemos ler o valor do potenciómetro e mapeá-lo para o ângulo do servo, permitindo controlar manualmente a posição do servo rodando o eixo do potenciómetro.
Materiais Adicionais:
Potenciómetro (qualquer valor comum, como 10kΩ, funcionará)
Mais 3 fios de ligação
Ligações Adicionais:
Ligue os dois pinos externos do potenciómetro ao 5V e GND do Arduino.
Ligue o pino central (wiper/cursor) do potenciómetro a um pino de entrada analógica do Arduino (e.g., A0).
Diagrama de Ligações (Texto):
Potenciómetro Arduino UNO
------------- ------------
Pino Externo 1 ----> 5V
Pino Central ----> Pino Analógico A0
Pino Externo 2 ----> GND
Servo SG90 Arduino UNO
----------- ------------
Fio Castanho (GND) ----> GND
Fio Vermelho (VCC) ----> 5V
Fio Laranja (Signal) --> Pino Digital ~9
Código:
C++
#include <Servo.h>
Servo meuServo;
int pinoPot = A0; // Pino analógico onde o potenciómetro está ligado
int valorPot; // Variável para armazenar o valor lido do potenciómetro
int anguloServo; // Variável para armazenar o ângulo calculado para o servo
void setup() {
meuServo.attach(9); // Anexa o servo ao pino 9
Serial.begin(9600); // Inicia a comunicação serial
Serial.println("Controlador de Servo com Potenciómetro");
}
void loop() {
// Ler o valor do potenciómetro (varia de 0 a 1023)
valorPot = analogRead(pinoPot);
Serial.print("Valor Potenciómetro: ");
Serial.print(valorPot);
// Mapear o valor do potenciómetro (0-1023) para o ângulo do servo (0-180)
// A função map() faz uma regra de três simples:
// map(valor, fromLow, fromHigh, toLow, toHigh)
anguloServo = map(valorPot, 0, 1023, 0, 180);
Serial.print(" | Ângulo Servo: ");
Serial.println(anguloServo);
// Comandar o servo para a posição calculada
meuServo.write(anguloServo);
delay(15); // Pequena pausa para estabilidade e dar tempo ao servo
}
Explicação:
pinoPot = A0;: Define que o potenciómetro está ligado ao pino analógico A0.
analogRead(pinoPot);: Lê a tensão no pino A0, que varia conforme roda o potenciómetro. O Arduino converte esta tensão num valor inteiro entre 0 (para 0V) e 1023 (para 5V).
map(valorPot, 0, 1023, 0, 180);: Esta função é crucial. Ela pega no valorPot (que está na faixa de 0 a 1023) e converte-o proporcionalmente para um valor na faixa de 0 a 180 (a faixa de ângulos do nosso servo).
meuServo.write(anguloServo);: Envia o ângulo calculado para o servo.
Ao rodar o potenciómetro, o valor lido (valorPot) muda, o map() calcula um novo anguloServo, e o servo move-se para essa nova posição.
Exemplo 3: Controlo Preciso com writeMicroseconds()
A função write(angle) é conveniente, mas mapeia ângulos para larguras de pulso usando os padrões da biblioteca ou os definidos no attach(). Se precisar de um controlo mais fino ou se o seu servo não responde bem à faixa 0-180 graus padrão, pode usar writeMicroseconds(us). Esta função permite especificar diretamente a largura do pulso em microssegundos (µs).
Para o SG90, a faixa útil de microssegundos costuma ser aproximadamente entre 500 µs e 2500 µs, mas a faixa que corresponde aos limites mecânicos (próximo de 0-180 graus) é frequentemente mais estreita, talvez 1000 µs a 2000 µs, ou 700 µs a 2300 µs. Terá de experimentar para encontrar os valores exatos para o seu servo específico.
Código (Exemplo de varredura usando microssegundos):
C++
#include <Servo.h>
Servo meuServo;
// Defina aqui os limites de pulso (em microssegundos) que correspondem
// aos limites físicos do seu servo SG90 (0 e 180 graus).
// Estes valores podem necessitar de ajuste experimental!
int minPulse = 1000; // Valor típico para 0 graus
int maxPulse = 2000; // Valor típico para 180 graus
void setup() {
// Podemos especificar os limites min/max no attach,
// mas para usar writeMicroseconds diretamente, apenas o pino é necessário.
meuServo.attach(9);
Serial.begin(9600);
Serial.println("Teste de Sweep com writeMicroseconds()");
Serial.print("Usando faixa de pulso: ");
Serial.print(minPulse);
Serial.print("us a ");
Serial.print(maxPulse);
Serial.println("us");
}
void loop() {
Serial.println("Movendo para pulso mínimo...");
meuServo.writeMicroseconds(minPulse);
delay(1500);
Serial.println("Movendo para pulso central...");
int centerPulse = (minPulse + maxPulse) / 2; // Calcula o pulso central
meuServo.writeMicroseconds(centerPulse);
delay(1500);
Serial.println("Movendo para pulso máximo...");
meuServo.writeMicroseconds(maxPulse);
delay(1500);
// Exemplo de varredura suave usando microssegundos
Serial.println("Varrendo com microssegundos...");
for (int pulse = minPulse; pulse <= maxPulse; pulse += 5) { // Incremento de 5us
meuServo.writeMicroseconds(pulse);
delay(10);
}
delay(500);
for (int pulse = maxPulse; pulse >= minPulse; pulse -= 5) { // Decremento de 5us
meuServo.writeMicroseconds(pulse);
delay(10);
}
delay(500);
}
Explicação:
minPulse e maxPulse: Definimos variáveis para os limites de largura de pulso que queremos usar. É crucial experimentar para encontrar os valores que levam o seu SG90 aos limites de 0 e 180 graus sem forçar o mecanismo. Comece com 1000 e 2000 e ajuste se necessário.
meuServo.writeMicroseconds(pulse);: Em vez de write(angle), usamos esta função para enviar diretamente o valor da largura do pulso em microssegundos.
O código demonstra como mover para os limites mínimo, central e máximo, e depois como fazer uma varredura incrementando/decrementando diretamente o valor do pulso. Isto oferece um controlo potencialmente mais fino sobre a posição e velocidade do servo.
Exemplo 4: Controlar Múltiplos Servos SG90
Controlar vários servos é simples em termos de código, mas exige atenção redobrada à alimentação.
Materiais Adicionais:
Mais servos SG90
Mais fios de ligação
(Altamente Recomendado) Fonte de alimentação externa (5V, >1A por servo)
Ligações (com fonte externa):
GND: Ligue os fios Castanhos de TODOS os servos ao terminal negativo (-) da fonte externa E a um pino GND do Arduino.
VCC: Ligue os fios Vermelhos de TODOS os servos ao terminal positivo (+) da fonte externa. NÃO ligue ao 5V do Arduino.
Signal: Ligue o fio Laranja de cada servo a um pino PWM diferente do Arduino (e.g., Servo 1 no pino 9, Servo 2 no pino 10).
Código:
C++
#include <Servo.h>
Servo servo1; // Objeto para o primeiro servo
Servo servo2; // Objeto para o segundo servo
int angulo1 = 90; // Posição inicial servo 1
int angulo2 = 90; // Posição inicial servo 2
void setup() {
servo1.attach(9); // Anexa servo 1 ao pino 9
servo2.attach(10); // Anexa servo 2 ao pino 10
// Mover para posições iniciais
servo1.write(angulo1);
servo2.write(angulo2);
delay(500); // Dar tempo para chegar à posição inicial
Serial.begin(9600);
Serial.println("Controlo de múltiplos servos");
}
void loop() {
// Exemplo: Mover servo 1 para 0 graus e servo 2 para 180 graus
Serial.println("Movendo Servo 1 para 0, Servo 2 para 180");
servo1.write(0);
servo2.write(180);
delay(2000); // Espera 2 segundos
// Exemplo: Mover servo 1 para 180 graus e servo 2 para 0 graus
Serial.println("Movendo Servo 1 para 180, Servo 2 para 0");
servo1.write(180);
servo2.write(0);
delay(2000); // Espera 2 segundos
// Exemplo: Varredura sincronizada (ou dessincronizada)
Serial.println("Varredura...");
for (int i = 0; i <= 180; i++) {
servo1.write(i); // Servo 1 varre de 0 a 180
servo2.write(180 - i); // Servo 2 varre de 180 a 0 (movimento oposto)
delay(15);
}
delay(1000);
}
Explicação:
Criamos dois objetos Servo: servo1 e servo2.
No setup(), anexamos cada servo a um pino PWM diferente (attach(9) e attach(10)).
No loop(), podemos comandar cada servo independentemente usando servo1.write() e servo2.write().
Lembrete Crítico: Ao usar múltiplos servos, a probabilidade de sobrecarregar a saída 5V do Arduino é muito alta. Use uma fonte de alimentação externa adequada, partilhando apenas o GND com o Arduino.
Resolução de Problemas Comuns (Troubleshooting)
Ao trabalhar com servos SG90 e Arduino, pode encontrar alguns problemas. Aqui estão os mais comuns e as suas possíveis soluções:
Servo Faz Ruído/Vibra (Jitter) mas Não se Move ou Move-se Erraticamente:
Causa Provável: Alimentação insuficiente ou instável. O servo tenta mover-se, consome um pico de corrente que a fonte (pino 5V do Arduino ou fonte externa fraca) não consegue fornecer, causando queda de tensão e comportamento errático. Pode até reiniciar o Arduino.
Solução: Use uma fonte de alimentação externa de 5V com corrente suficiente (pelo menos 1A por servo, idealmente mais). Certifique-se que o GND da fonte externa está ligado ao GND do Arduino. Verifique a qualidade das ligações (maus contactos em breadboards ou fios).
Outra Causa: Sinal PWM ruidoso ou interferência. Tente usar fios mais curtos para o sinal. Mantenha os fios de sinal afastados de fios de alta corrente ou motores.
Outra Causa: Servo de baixa qualidade ou danificado. Experimente com outro servo.
Outra Causa (Código): Comandos write() muito rápidos sem delay() suficiente entre eles. O servo pode não conseguir acompanhar. Adicione pequenos delay() após cada write().
Servo Não se Move de Todo:
Causa Provável: Ligações incorretas. Verifique triplamente: GND do servo -> GND do Arduino (e da fonte externa, se usada); VCC do servo -> 5V (Arduino ou fonte externa); Signal do servo -> Pino PWM correto definido no attach().
Causa Provável: Pino errado no código. Certifique-se que o número do pino em meuServo.attach(PINO) corresponde ao pino físico onde ligou o fio de sinal.
Causa Provável: Pino não é PWM. Certifique-se que está a usar um pino com ~ (no UNO: 3, 5, 6, 9, 10, 11).
Causa Provável: Falta de alimentação. Verifique se o Arduino e a fonte externa (se usada) estão ligados e a fornecer tensão.
Causa Provável: Código não foi carregado ou não está a correr. Verifique se o carregamento para o Arduino foi bem-sucedido e se não há erros lógicos no setup() ou loop() que impeçam a execução do write().
Causa Provável: Servo danificado.
Servo Move-se, mas Não Atinge os 0 ou 180 Graus (Alcance Limitado):
Causa Provável: Limites físicos do SG90. Como mencionado, muitos SG90 não têm um alcance real de 180 graus. O seu limite pode ser 5-175 graus, por exemplo.
Solução (Ajuste por Código): Use writeMicroseconds() e experimente encontrar os valores de pulso (µs) que correspondem aos limites físicos reais do seu servo. Em vez de map(..., 0, 180), mapeie para o seu alcance real (e.g., map(..., 5, 175)). Ou, ao usar writeMicroseconds(), use os valores min/max µs que encontrou experimentalmente.
Solução (Biblioteca): Pode tentar especificar os limites no attach(): meuServo.attach(9, min_us, max_us);. Encontre os valores min_us e max_us experimentando com writeMicroseconds() primeiro. Por exemplo, se descobrir que 700µs corresponde a 0° e 2300µs a 180°, use meuServo.attach(9, 700, 2300);. Depois, meuServo.write(0) e meuServo.write(180) deverão usar estes limites.
Servo Aquece Demasiado:
Causa Provável: Servo está constantemente sob carga ou a tentar manter uma posição contra uma força externa (stall condition).
Solução: Reduza a carga no servo. Use um servo com maior binário se necessário. Certifique-se que o mecanismo ligado ao servo se move livremente.
Solução (Código): Se o servo não precisar de estar ativo constantemente, use a função detach(). Quando chama meuServo.detach(), o Arduino para de enviar o sinal PWM para aquele pino. O servo deixa de tentar ativamente manter a posição e consome menos energia (mas também não resistirá a forças externas). Pode reanexá-lo mais tarde com attach() quando precisar de o mover novamente.C++
meuServo.write(90); // Move para 90 graus
delay(1000); // Espera
meuServo.detach(); // Desliga o sinal PWM, servo fica "solto"
// ... fazer outras coisas ...
// Mais tarde, para mover novamente:
// meuServo.attach(9); // Reanexa ao pino (necessário antes do próximo write)
// meuServo.write(45);
Movimento do Servo não é Suave:
Causa Provável: delay() entre os passos de movimento muito pequeno ou inexistente.
Solução: Aumente o valor no delay() após cada write() num loop de varredura.
Causa Provável: Alimentação instável (ver problema 1).
Causa Provável: Servo de baixa qualidade ou engrenagens danificadas.
Otimizações e Melhores Práticas
Alimentação: Reforçando: para qualquer projeto sério ou com múltiplos servos, use uma fonte de alimentação externa robusta e partilhe o GND com o Arduino.
Pinos PWM: Use sempre os pinos PWM dedicados do Arduino para o sinal do servo.
detach() para Poupar Energia e Desgaste: Se um servo não precisa de manter a sua posição ativamente por longos períodos, use detach() para desligar o sinal PWM. Isto reduz o consumo, o ruído e o aquecimento. Lembre-se de usar attach() novamente antes de enviar um novo comando write() ou writeMicroseconds().
Não Use delay() Excessivamente em Projetos Complexos: A função delay() bloqueia toda a execução do Arduino. Se precisar de ler sensores ou controlar outros atuadores enquanto o servo se move ou espera, delay() é problemático. Investigue a técnica de programação "Blink Without Delay" usando a função millis(). Isto permite criar movimentos de servo não-bloqueantes, onde o Arduino pode continuar a fazer outras tarefas enquanto o servo se move gradualmente ou espera por um intervalo de tempo.
Calibração: Cada servo SG90 pode ser ligeiramente diferente. Dedique algum tempo a encontrar os valores exatos de writeMicroseconds() (ou os ângulos em write()) que correspondem aos limites físicos e à posição central do seu servo específico para obter a máxima precisão.
Estrutura do Código: Organize o seu código com comentários claros, nomes de variáveis descritivos e funções, se necessário, para tornar o seu projeto mais fácil de entender e manter.
Ideias de Projetos com Servo Motor SG90 e Arduino
Agora que sabe como controlar um SG90, as possibilidades são vastas (dentro das limitações de binário do servo):
Mini Braço Robótico: Use 2 ou 3 servos SG90 para criar um pequeno braço robótico que pode ser controlado por potenciómetros ou comandos via Serial Monitor.
Mecanismo Pan/Tilt para Câmara ou Sensor: Use dois SG90 montados perpendicularmente para criar uma base que pode mover uma pequena câmara (como a do ESP32-CAM) ou um sensor (como um ultrassónico HC-SR04) em duas direções (horizontal - pan, e vertical - tilt).
Fechadura Inteligente Simples: Um SG90 pode ser usado para rodar um pequeno trinco ou ferrolho.
Caixa Automática: Crie uma caixa cuja tampa abre e fecha automaticamente (controlada por um sensor de proximidade, por exemplo) usando um SG90.
Ponteiro Laser Automático (para Gatos?): Monte um pequeno módulo laser num mecanismo pan/tilt e programe movimentos aleatórios ou controlados. (Tenha cuidado com a segurança dos olhos!).
Animatrónica Simples: Faça os olhos ou boca de um boneco moverem-se.
Indicador Físico: Use um servo para mover um ponteiro num mostrador analógico que indica algum dado (e.g., temperatura lida por um sensor).
Weathervane (Cata-vento) Eletrónico: Use um sensor de direção do vento e um servo para apontar uma seta na direção correspondente.
Conclusão
O servo motor SG90, apesar da sua simplicidade e baixo custo, é uma ferramenta incrivelmente poderosa e versátil quando combinado com a plataforma Arduino. Neste tutorial detalhado, explorámos os fundamentos dos servo motores, as especificidades do SG90, as ligações de hardware essenciais (incluindo a importância da alimentação externa), e diversas formas de o controlar usando a biblioteca Servo.h do Arduino – desde movimentos básicos e varreduras até ao controlo interativo com potenciómetros e o ajuste fino com writeMicroseconds(). Abordámos também a resolução de problemas comuns e as melhores práticas para garantir que os seus projetos funcionem de forma fiável.
Dominar o controlo do servo SG90 abre portas para inúmeros projetos criativos e funcionais no campo da robótica, automação e sistemas interativos. Esperamos que este guia completo sirva como um recurso valioso na sua jornada de aprendizagem com Arduino e eletrónica. Agora, é tempo de experimentar, construir e dar vida às suas ideias! Lembre-se que a prática e a experimentação são fundamentais para solidificar estes conhecimentos. Boa programação e construção!