Eletrônica Por Equipe DevBras

Capa do artigo: Servo motor no Arduino: ligação, calibração e código

Servo motor no Arduino: ligação, calibração e código

Servo motor no Arduino sem reset nem zumbido: ligue a fonte com GND comum, calibre os pulsos do seu servo e mova suave com millis(), com código testado.

Para ligar um servo motor no Arduino sem reset nem zumbido, três coisas resolvem quase tudo: alimentar o servo por uma fonte própria com o GND unido ao da placa, descobrir os pulsos mínimo e máximo que o seu exemplar aceita e mover em passos pequenos, sem delay(). Este guia faz as três com sketches que compilam para o Arduino Uno (testados com arduino-cli 1.5.1, núcleo AVR 1.8.8 e biblioteca Servo 1.3.0) e explica o que a biblioteca faz por baixo.

Se o servo já está ligado certo e mesmo assim esquenta ou não aguenta a carga, o assunto é torque e dimensionamento de fonte, tratado em torque do servo: calcule a carga e a fonte certa.

Como o servo entende o ângulo

O fio de sinal recebe um pulso a cada 20 ms. A largura do pulso diz a posição: perto de 1.000 µs num extremo, 1.500 µs no centro e perto de 2.000 µs no outro, mas cada modelo tem a sua faixa. A figura mostra três pulsos de um servo calibrado e, em laranja, a faixa que a biblioteca usa por padrão.

No código da biblioteca Servo, write(0) vira 544 µs e write(180) vira 2.400 µs (MIN_PULSE_WIDTH e MAX_PULSE_WIDTH). Um detalhe do código-fonte para AVR: write() trata qualquer valor abaixo de 544 como ângulo e qualquer valor a partir de 544 como microssegundos. write(90) é ângulo; write(1500) é pulso.

Se o seu servo bate no limite mecânico antes de 544 ou 2.400 µs, pedir 0° ou 180° faz o motor empurrar o batente sem parar. Daí vêm o zumbido, o calor e, com o tempo, a engrenagem espanada.

Ligação: sinal num pino, energia fora da placa

O servo tem três fios: alimentação (geralmente vermelho), terra (preto ou marrom) e sinal (amarelo, laranja ou branco). O próprio repositório da biblioteca avisa que servos puxam bastante energia e que, para mais de um ou dois, o certo é usar fonte separada, com os terras unidos.

  • Sinal num pino digital do Arduino (pino 6 nos exemplos).
  • Alimentação e terra do servo na fonte externa, dentro da faixa de tensão da folha do servo.
  • GND da fonte ligado ao GND do Arduino. Sem isso, o pulso não tem referência e o servo treme ou vai para um canto.
  • Capacitor eletrolítico de algumas centenas de microfarads entre positivo e negativo, perto do servo, respeitando a polaridade.

Alimentar o servo pelo pino de 5 V até funciona com um micro servo sem carga, mas na primeira partida forte a tensão cai e a placa reinicia. Os limites de cada entrada de energia estão em como alimentar o Arduino.

Calibre o seu servo pelo monitor serial

Este sketch recebe a largura do pulso digitada no monitor serial. Com o braço do servo solto, sem carga, comece em 1500 e desça de 50 em 50 até ouvir o motor forçar; volte um pouco e anote. Repita subindo. A leitura de números pela serial é explicada em Arduino pela porta serial.

#include <Servo.h>

const uint8_t PINO_SERVO = 6;
Servo servo;

void setup() {
  Serial.begin(9600);
  servo.attach(PINO_SERVO);        // limites padrão: 544 a 2400 µs
  servo.writeMicroseconds(1500);   // centro
  Serial.println(F("Digite o pulso em microssegundos (544 a 2400):"));
}

void loop() {
  if (Serial.available() > 0) {
    long us = Serial.parseInt();
    if (us >= 544 && us <= 2400) {
      servo.writeMicroseconds((int)us);
      Serial.print(F("pulso: "));
      Serial.println(us);
    }
  }
}

No servo do exemplo, os limites seguros ficaram em 600 e 2.350 µs. Servos do mesmo modelo variam um pouco entre si, então calibre cada exemplar que vai para o projeto. O sketch ocupa 3.276 bytes de programa (10% do Uno).

Movimento suave sem travar o loop

O exemplo final aponta o servo conforme um potenciômetro em A0, lido como em potenciômetro no Arduino, e acende um LED com brilho proporcional. O servo anda 10 µs a cada 15 ms, controlado por millis(), então o loop continua livre para ler sensores:

#include <Servo.h>

const uint8_t PINO_SERVO = 6;
const uint8_t PINO_POT = A0;
const uint8_t PINO_LED = 5;          // PWM fora dos pinos 9 e 10
const int PULSO_MIN = 600;           // medido neste servo
const int PULSO_MAX = 2350;
const int PASSO_US = 10;
const unsigned long INTERVALO_MS = 15;

Servo ponteiro;
int pulsoAtual = 1500;
unsigned long ultimoPasso = 0;

void setup() {
  pinMode(PINO_LED, OUTPUT);
  ponteiro.writeMicroseconds(pulsoAtual);  // posição antes do primeiro pulso
  ponteiro.attach(PINO_SERVO, PULSO_MIN, PULSO_MAX);
}

void loop() {
  int leitura = analogRead(PINO_POT);
  int alvo = map(leitura, 0, 1023, PULSO_MIN, PULSO_MAX);
  analogWrite(PINO_LED, leitura / 4);    // brilho segue o potenciômetro

  if (millis() - ultimoPasso >= INTERVALO_MS) {
    ultimoPasso = millis();
    int diferenca = alvo - pulsoAtual;
    if (abs(diferenca) > PASSO_US) {
      pulsoAtual += (diferenca > 0) ? PASSO_US : -PASSO_US;
      ponteiro.writeMicroseconds(pulsoAtual);
    }
  }
}

Três detalhes desse código vêm direto do funcionamento da biblioteca:

  • Limites no attach. Com attach(pino, 600, 2350), qualquer write ou writeMicroseconds fora da faixa é cortado para o limite. Nenhuma leitura ruidosa manda o eixo contra o batente. A biblioteca guarda esses limites como desvio de 544 e 2.400 µs em passos de 4 µs, num inteiro de 8 bits; por isso o mínimo precisa ficar entre cerca de 36 e 1.056 µs e o máximo entre cerca de 1.892 e 2.912 µs.
  • Posição antes do attach. No AVR, o construtor já grava 1.500 µs como posição inicial, e writeMicroseconds antes do attach troca esse valor. Assim o primeiro pulso já sai na posição certa, sem um pulo ao ligar.
  • LED no pino 5. Fora do Arduino Mega, usar a biblioteca desativa o analogWrite() nos pinos 9 e 10, haja servo neles ou não (está no README oficial). Motor DC, LED com brilho e buzzer com PWM vão para outros pinos.

Quantos servos cabem e quando usar detach()

A biblioteca controla até 12 servos na maioria das placas e até 48 no Mega, segundo a documentação da biblioteca Servo. No Mega, de 12 a 23 servos desativam o PWM nos pinos 11 e 12. Cada servo novo usa um pino de sinal; a fonte é que precisa crescer junto.

detach() para de mandar pulsos naquele pino. Muitos servos analógicos relaxam o eixo sem pulso, o que poupa corrente numa junta que não segura peso, mas a junta deixa de resistir. Teste no seu modelo antes de contar com isso, porque servos digitais podem segurar a última posição.

Se mesmo assim der errado

  • Reinicia ao mover: a corrente está saindo da placa. Confira se o positivo do servo vem da fonte externa.
  • Treme parado: falta GND comum, o capacitor ou um fio de sinal mais curto. Ruído no potenciômetro também faz o alvo oscilar; um passo mínimo maior que o ruído resolve.
  • Zune num extremo: o limite do attach está além do batente. Refaça a calibração.
  • Esquenta com carga: o servo está fraco para a junta. A conta de torque está no post sobre torque do servo.


Avalie este artigo

Referência: http://www.seucurso.com.br/index.php?option=com_content&view=article&id=218:controlando-um-servo-motor-com-arduino