Vídeo: Controle de Servo Motor sem biblioteca
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).

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.

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 ? Ajude-nos a melhorar o blog atribuindo uma nota a este tutorial (estrelas no final do artigo), comente e visite nossa loja FILIPEFLOP!
Site: Blog FILIPEFLOP