Vídeo: Controle de Servo Motor sem biblioteca 7

O servo motor certamente já é um dispositivo muito conhecido para todos que trabalham com projetos envolvendo Arduino. Pode ser utilizado em robôs, sistemas de controle e automação em geral, e existem vários tipos de servo motores e acessórios disponíveis para o seu projeto.

Os Servo Motores

Os servo motores são extremamente úteis em robótica e automação, por apresentar em um só conjunto motor, caixa de redução, eixo, acessórios, circuito driver/controle e sensor linear (Figura 2).

controle de servo motor
Figura 2 – Principais partes de um servo motor

Um ponto importante para projetistas é o domínio sobre o hardware que estão controlando e também sobre o sistema de controle. O servo motor é controlado facilmente através de um único terminal onde, conforme a largura de pulso enviada, há o posicionamento do eixo em determinado ângulo.

O que a maioria dos projetistas que trabalham com Arduino faz é utilizar a já famosa biblioteca Servo.h, onde apenas é necessário instanciar o objeto servo ao pino em que o mesmo está conectado, e após chamar funções informando o ângulo de movimento.

Neste artigo veremos que não é sempre necessário ficarmos presos a esta biblioteca, conhecendo o fato de que a maioria dos servos obedecem ao diagrama de tempos apresentado na Figura 3.

Diagrama de tempos
Figura 3 – Diagrama de tempos típico de um servo motor

Pode-se observar claramente que, para um ângulo de 0°, a largura do pulso deve ser de 0,6ms; para um ângulo de 90°, deve ser 1,5ms e; para um ângulo de 180°, deverá ser de 2,4ms. Alguns modelos de servo ainda utilizam a largura mínima de 1ms e máxima de 2ms. Uma consulta ao datasheet do modelo controlado sempre é aconselhável.

Outro ponto observável é que o período se mantém nos 3 casos, 20ms. Com isso conclui-se que a frequência se mantém. Logo, atua-se apenas no ciclo ativo do sinal, caracterizam-se claramente por um sinal PWM (pulse width modulation) ou Modulação por Largura de Pulso.

Também fica claro que a posição angular do eixo é diretamente proporcional à largura do pulso aplicado, dentro dos limites mínimo e máximo. Utilizando a função de delay do Arduino pode-se desenvolver funções para criar estes sinais para o servo, evitando-se assim o uso da biblioteca. É claro que existem outras formas mais elegantes de se controlar os servo motores, que abordaremos em outra oportunidade. Mas para projetos em que se deseja posicionar o servo em pontos específicos, esta técnica se mostra satisfatória.

Programa de controle de Servo Motor

No Box 1 pode-se conferir o código fonte completo, já com as funções de controle.

/*
   Aula 67 - Funções para Controle de Servo Motor sem utilização da biblioteca servo.h
   
   Autor: Eng. Wagner Rambo  Data: Maio de 2016
*/

// --- Mapeamento de Hardware ---
#define servo1 33 //servo1 ligado no pino digital 33


// --- Protótipo das Funções Auxialiares ---
void servo0graus();
void servo90graus();
void servo180graus();


// --- Configurações Iniciais ---
void setup()
{
   pinMode(servo1, OUTPUT); //saída para o servo1
} //end setup

// --- Loop Infinito ---
void loop()
{
  for(char i=0;i<100;i++) servo0graus();    //move o servo para a posição 0º por 2 segundos
  
  for(char i=0;i<100;i++) servo90graus();    //move o servo para a posição 90º por 2 segundos

  for(char i=0;i<100;i++) servo180graus();    //move o servo para a posição 180º por 2 segundos
  
  for(char i=0;i<100;i++) servo90graus();    //move o servo para a posição 90º por 2 segundos
} //end loop

// --- Desenvolvimento das Funções Auxialiares ---

void servo0graus()              //Posiciona o servo em 0 graus
{
   digitalWrite(servo1, HIGH);  //pulso do servo
   delayMicroseconds(600);      //0.6ms
   digitalWrite(servo1, LOW);   //completa periodo do servo
   for(int i=0;i<32;i++)delayMicroseconds(600);
                               // 20ms = 20000us
                               // 20000us - 600us = 19400us
                               // 19400/600 = ~~32
} //end servo0graus

void servo90graus()             //Posiciona o servo em 90 graus
{
   digitalWrite(servo1, HIGH);  //pulso do servo
   delayMicroseconds(1500);     //1.5ms
   digitalWrite(servo1, LOW);   //completa periodo do servo
   for(int i=0;i<12;i++)delayMicroseconds(1500);
                               // 20ms = 20000us
                               // 20000us - 1500us = 18500us
                               // 18500/1500 = ~~12 
} //end servo0graus

void servo180graus()             //Posiciona o servo em 180 graus
{
   digitalWrite(servo1, HIGH);  //pulso do servo
   delayMicroseconds(2400);     //2.4ms
   digitalWrite(servo1, LOW);   //completa periodo do servo
   for(int i=0;i<7;i++)delayMicroseconds(2400);
                               // 20ms = 20000us
                               // 20000us - 2400us = 17600us
                               // 17600/2400 = ~~7
} //end servo0graus

O código está ricamente comentado para eventuais dúvidas.

Para mais informações com explicação do código e funções propostas, assista o vídeo disponível no início deste post e para baixar os arquivos pertinentes ao projeto acesse este link.

 Gostou? Deixe seu comentário logo abaixo.

Faça seu comentário

Acesse sua conta e participe

7 Comentários

  1. Olá Wagner Rambo,

    A mina dúvida é a seguinte: Estou utilizando duas boards UNO no meu projeto (cancela acionada por módulo RF 433MHz), a abertura dessa cancela seriam no ângulo de 180° para 90° e vice-versa. Utilizo também as bibliotecas VirtualWire.h e Servo.h, porém, quando compilo o programa, acaba gerando um erro entre as bibliotecas. Gostaria de saber se é possível acionar o servo motor através de comando RF, sem a necessidade da biblioteca Servo.h no receptor?

    1. Respondendo a minha própria dúvida: Sim, é possível! Acabei de finalizar meu projeto para faculdade utilizando essa programação acima para o acionamento de cancela por RF, sem a necessidade de declarar a biblioteca Servo.h. Quebrei um pouco a cabeça analisando as duas programações mas deu certo.

      Abraço.

  2. Estou iniciando em Arduino agora, pois ganhei uma UNO de um amigo, e desejo me desenvolver nisso.
    A principio eu necessito controlar 10 servos motor 9g com a placa UNO via Android. Preciso de ajuda de como posso implementar … é para uma maquete de ferreomodelismo para acionar desvios..
    Desde já agradeço a todos

    Demarques Ribeiro da Silva
  3. Porque temos que colocar um for para completar o período do Servo ? Exemplo: no “Void servo0graus()” foi colocado “for(int i=0;i<32;i++)delayMicroseconds(600)" porque não podemos substituir por "delayMicroseconds(19400)" ?

  4. ola amigo!!
    estou iniciando com arduino achei bem interessante sua explicação,estou querendo fazer um projeto para meu curso de eletrônica mas nao sei quase nada de arduino, sera que da para fazer um robo controlado por controle do ps2 sem fio usando um arduino uno e uma placa de relé para comandar 5 motores cc?

    1. Cara, eu acho que para controlar sem fio precisaria de 2 arduinos. Um para emitir e outro para receber

Trackbacks and Pingbacks

  1. […] nosso último tutorial demonstramos como efetuar o controle de um servo motor sem a utilização da clássica biblioteca servo.h. No projeto, utilizamos as funções de delay disponíveis na IDE do Arduino. Também mencionamos […]