Controlando Micro Servo 9g usando Joystick 27

Quem começa a mexer com servo motores no Arduino geralmente tem, como um dos primeiros projetos, controlar o ângulo de rotação do motor usando um potenciômetro, ou utilizar botões para girar o eixo para a direita ou para a esquerda. Hoje mostraremos uma outra alternativa, que é o uso de um Módulo Joystick para controle de Micro Servos 9g, itens disponíveis para compra na loja MakerHero:

O módulo joystick trabalha com potenciômetros para definir o deslocamento dos eixos X e Y, e um push button para o eixo Z. Cada um deles se comunica com o Arduino por meio de um pino específico (VRx para o eixo X, VRy para o eixo Y e SW para o botão), e a alimentação do circuito é de 5V.

O servo que vamos utilizar, o micro servo 9g, é muito utilizado em aeromodelismo e projetos de robótica por seu tamanho e peso reduzidos, que não comprometem o torque e o desempenho do motor:

Micro Servo 9G

Ligação do Joystick ao Arduino

No nosso circuito, vamos ligar dois servo motores ao Arduino, controlando um deles pelo movimento do eixo X do joystick, e outro pelo movimento do eixo Y. Esse tipo de ligação pode ser utilizado com um Suporte Pan/Tilt (abaixo), muito usado em câmeras de monitoração. Nesse tipo de dispositivo, é utilizado um servo motor para controlar a rotação da base, e outro para alterar a inclinação da câmera :

Suporte Pan Tilt

A ligação do joystick ao Arduino e também aos dois servo motores pode ser feita dessa maneira:

Circuito Joystick - Servo - Pan/Tilt

Programa controle Pan/Tilt

Como o joystick é formado basicamente por dois potenciômetros e um push button, não há necessidade de utilizar bibliotecas específicas para o módulo. Já para o servo, vamos utilizar a biblioteca VarSpeedServo, disponível neste link.

A biblioteca VarSpeedServo permite controlar a velocidade de movimentação do servo motor, o que não é possível com a biblioteca Servo original embutida na IDE do Arduino. Na VarSpeedServo, utilizamos o comando abaixo para definição da porta e das velocidades minima e máxima (entre 0 e 255) de cada servo:

nome_servo.attach( porta, velocidade minima, velocidade maxima)

Para movimentação do motor, simplesmente definimos a posição e a velocidade:

nome_servo.slowmove( posição, velocidade)

Criamos então dois objetos servo dentro do programa. Um é o servo_base, utilizando a porta 7 do Arduino, e o outro o servo_inclinacao, utilizando a porta 8. Dentro do loop, são lidos os valores recebidos dos potenciômetros (eixo X, porta analógica 4 e eixo Y, porta analógica 5), que são usados para movimentar o servo correspondente dentro do limite de 180 graus.

//Programa : Controle servo motor com joystick
//Autor : MakerHero

#include <VarSpeedServo.h>

//Cria objeto para controlar o servo base
VarSpeedServo servo_base;
//Cria objeto para controlar o servo inclinacao
VarSpeedServo servo_inclinacao;

int pino_x = A4; //Pino ligado ao X do joystick
int pino_y = A5; //Pino ligado ao Y do joystick
int val_x;   //Armazena o valor do eixo X
int val_y;   //Armazena o valor do eixo Y

void setup()
{
  //Define a porta a ser ligada ao servo base
  servo_base.attach(7, 1, 180);
  //Define a porta a ser ligada ao servo inclinacao
  servo_inclinacao.attach(8, 1, 180);
}

void loop()
{
  //Recebe o valor do joystick, eixo X
  val_x = analogRead(pino_x);
  //Converte o valor lido para um valor entre 1 e 180 graus
  val_x = map(val_x, 0, 1023, 1, 180);
  //Move o servo base para a posicao definida pelo joystick
  servo_base.slowmove(val_x, 60);
  //Recebe o valor do joystick, eixo Y
  val_y = analogRead(pino_y);
  //Converte o valor lido para um valor entre 1 e 180 graus
  val_y = map(val_y, 0, 1023, 1, 180);
  //Move o servo inclinacao para a posicao definida pelo joystick
  servo_inclinacao.slowmove(val_y, 60);
  //Aguarda a movimentacao do servo e reinicia a leitura
  delay(30);
}

Lembre-se de que você ainda tem disponível o botão do joystick (pino SW), para incluir novas funções no programa.

 Gostou? Deixe seu comentário logo abaixo.

Faça seu comentário

Acesse sua conta e participe

27 Comentários

  1. Esse é meu primeiro contato com Arduíno. É possível comandar esse conjunto a partir de um controle remoto de aeromodelo?
    obrigado

  2. Estou com um código qui para controlar um servo motor com 2 botoes, cada botão controla um ângulo diferente do servo…..como eu faria um código para eu usar dois servos nos mesmos botões.

    Segue código :

    // Projeto 8 – Acionando um Motor

    #include

    Servo meuServo;
    int botao = 7;

    void setup()
    {
    pinMode(botao, INPUT_PULLUP); // define o botão como saidas
    }

    void loop()
    {
    meuServo.attach(9);
    if(digitalRead(botao) == LOW)
    {
    for(int angulo=0; angulo=0; angulo–)// Diminui o angulo do servo
    {
    meuServo.write(angulo);
    delay(10);
    }
    }

    //botao 2

    if(digitalRead(botao2) == LOW)
    {
    for(int angulo=0; angulo=0; angulo–)// Diminui o angulo do servo
    {
    meuServo.write(angulo);
    delay(10);
    }
    }
    meuServo.detach();
    }

    1. Arthur,

      Você deseja acionar 1 servo com 1 botão, ou os dois botões acionarão os 2 servos? Para adicionar um novo servo no código, basta você instanciar da seguinte forma: Servo meuServo2. Em seguida, no void loop(), você deve colocar: meuServo2.attach(pino).

      Não esqueça de no final usar o meuServo.detach().

      Abraços!
      Diogo – Equipe MakerHero

  3. Lembre-se de que você ainda tem disponível o botão do joystick (pino SW), para incluir novas funções no programa
    E como faço isso?

    1. Olá Fabio!

      Você conecta o pino SW em uma porta digital da sua placa e a partir dela você acrescenta funcionalidades.

      Abraços!

      André – Equipe MakerHero

  4. Boa tarde. Excelente matéria, como sempre. Vcs são sensacionais!

    Fiz um experimento utilizando um app de joystick via bluetooth , coisa simples, para movimentar dois servos, e usei essa biblioteca pra reduzir um pouco a velocidade. Funcionou bem com relação a velocidade, porém notei que houve uma séria redução no range da excursão total de ambos os servos com relação ao uso da biblioteca original Servo.h . Tem alguma ideia do motivo pelo qual isso ocorreu? Obg, desde já.

    #include <VarSpeedServo.h>

    #include<SoftwareSerial.h>

    VarSpeedServo servo1; //inicializa o primeiro servo

    VarSpeedServo servo2; //inicializa o segundo servo

    SoftwareSerial BT(3,4);//atribui tx e rx pinos 3 e 4

     

    //—————————————- variaveis —————————————

    char msg;

    //——————————————setup———————————————

    void setup(){

    pinMode(13,OUTPUT);

    servo1.write(110);

    servo2.write(110);

    BT.begin(9600);//inicializa o bluetooth

    Serial.begin(9600);

    servo1.attach(8,1,180); //atriui ao pino 8 o servo 1

    servo2.attach(9,1,180); // atribui ao pino 9 o servo 2

    }

    void loop(){

    if (BT.available()>0){// checa se ha transmissao no bluetooth

    msg = BT.read();

    Serial.println(msg);

    //———————-MOVIMENTO PARA ESQUERDA————————————

    switch (msg){

    case ‘E’:

    servo1.slowmove(1,80);

    break;

    //—————————MOVIMENTO PARA DIREITA————————————-

    case ‘D’:

    servo1.slowmove(180,80);

    break;

    //————————-MOVIMENTO PARA CIMA—————————————-

    case ‘C’:

    servo2.slowmove(1,80);

    break;

    //——————————-MOVIMENTO PARA BAIXO————————————–
    case ‘B’:

    servo2.slowmove(180,80);

    break;

    //———————————–VERTICAL 90 ———————————————-

    case ‘Y’:

    servo2.slowmove(90,80);

    break;

    //————————————HORIZONTAL 90 ——————————————-

    case ‘X’:

    servo1.slowmove(90,80);

    break;

    }

    }

    }

    1. Olá Leandro!

      Ficamos felizes em saber que você gosta dos nossos posts!

      Existem muitos tipos de servos, e nem sempre todas as bibliotecas funcionam perfeitamente em todos os servos.
      Você já tentou colocar um angulo maior para o servo e ver o que acontece?

      Você poderia colocar sua dúvida no nosso fórum? Ali você pode descrever melhor todo o seu problema e mais pessoas podem te ajudar a resolver!

      Abraços!

      André – Equipe MakerHero

  5. Olá,
    No texto diz “utilizamos o comando abaixo para definição da porta e das velocidades minima e máxima (entre 0 e 255) de cada servo”. Porém nas linhas 19 e 21, foram utilizados 1-180 como minimo e maximo do motor ao invés de 0-255.

    19 servo_base.attach(7, 1, 180);
    21 servo_inclinacao.attach(8, 1, 180);

    Isso se deu apenas por uma escolha pessoal? Eu poderia realmente utilizar de 0-255?

    Grato desde já!

  6. Para este servo eu não preciso da ponte H então?

  7. Olá sou seguidor do site gosto muito de seus projetos parabens !
    Uma duvida como alterar o sketch para os servos movimentarem mas rapido ?

    1. servo_inclinacao.attach(x, 1, 180);. Altere o valor “x”, pois ele indica tempo.

  8. Excelente. Tem como adicionar um transmissor para comandar a distância?

  9. Como iniciante em arduíno e também em blog seguo o tutorial acima para acionar 2 servos

    com o Joystick mas eles não responderam aos comandos

    Parece que há necessidade de mesclar os sketchs antes individuais para que tenha êxito.

    Sendo o caso , como seria o novo*SKETCH ?
    oBRIGADO

  10. Podia ter um tutorial só de como montar esse suporte pan-tilt, sofri aqui! D=

  11. Boa noite!
    Gostei do texto.
    Montei e funcionou bem.
    Mas, os motores ficam funcionando mesmo quando não toco no joystick.
    Isso faz tremer o tilt.
    Alguém sabe resolver?

  12. Boa tarde
    Pessoal, sabem me informar se consigo posições intermediários de posicionamento de um servo motor ( mg 996r) preciso posiciona-lo em 100 graus… consigo essa posição ajustando a largura do pulso apenas?

  13. como colocar um motor dc junto no programa ?? podia me dar um exemplo ?? obrigado !!

  14. obrigado!desculpe a ignorância mas é que estou iniciando no arduino, como faço pra travar as variáveis conforme vc falou?ah e estou usando um sensor shield v4.0 para conectar os servos(arduino mega), poderia me enviar um exemplo de código?eu agradeço e muito desde já valew mesmo!!!!!

  15. Cara muito show! to precisando que na hora em que eu soltar o joystick o servo não retorne para posição
    inicial, mas permaneça na posição que está. tem como?desde já agradeço!!!Valew!

    1. Boa tarde Rael,

      O que você pode fazer é travar as variáveis do programa, para que quando ele volte á posição central do joystick ele não mexa no Servo.

      Abraço.

      Adilson – Equipe MakerHero

      1. como se faz isso por favor.

    2. Muito bom o tutorial. Alterei o seu código para permitir usar o joystick como ajuste final, sem o servo retornar junto com o joy.
      Caso alguém se interesse:

      //Programa : Controle servo motor com joystick
      //Autor : MakerHero modificado por SJS para nao retornar ao ponto medio em conjunto com o joy

      #include

      #define HORIZ_SERVO_PIN 10
      #define VERT_SERVO_PIN 9
      #define KEY_JOY_PIN A0 //CLICK DO JOYSTICK
      #define HORIZ_JOY_PIN A1
      #define VERT_JOY_PIN A2

      //544 = 0, 2400 = 180 graus
      //RESTRICOES FISICAS H: 700-2400 V: 750-1500
      #define MID_POINT_HORIZ 1600 //Middle point for LR Servo; only used if there is no existing calibration
      #define MID_POINT_VERT 1000 //Middle point for UD Servo; only used if there is no existing calibration
      #define INF_POINT_HORIZ 1925 //Left-Bottom point for LR Servo; only used if there is no existing calibration
      #define INF_POINT_VERT 800 //Left-Bottom point for UD Servo; only used if there is no existing calibration
      #define MIN_AMPL_SERVO_H 700
      #define MAX_AMPL_SERVO_H 2000
      #define MIN_AMPL_SERVO_V 750
      #define MAX_AMPL_SERVO_V 1500

      //range: 0-1023
      #define MID_POINT_JOY_H 500 //posicao de repouso do joy
      #define MID_POINT_JOY_V 493
      #define TOLERANCIA_JOY 3 //tolerancia entre as leituras do joy
      #define FATOR_JOY 0.1 //fator de sensibilidade do joy

      Servo servo_horiz;//Cria objeto para controlar o servo base
      Servo servo_vert;

      int val_x; //Armazena o valor do eixo X
      int val_y;
      int ult_val_x = MID_POINT_JOY_H;
      int ult_val_y = MID_POINT_JOY_V;

      void setup(){
      servo_horiz.attach(HORIZ_SERVO_PIN, MIN_AMPL_SERVO_H, MAX_AMPL_SERVO_H);//Define a porta a ser ligada ao servo base
      servo_vert.attach(VERT_SERVO_PIN, MIN_AMPL_SERVO_V, MAX_AMPL_SERVO_V);

      servo_horiz.write(MID_POINT_HORIZ);//Move o servo base para a posicao definida pelo joystick
      servo_vert.write(MID_POINT_VERT);
      }

      void loop() {
      val_x = analogRead(HORIZ_JOY_PIN);//Recebe o valor do joystick, eixo X
      val_y = analogRead(VERT_JOY_PIN);

      val_x -= MID_POINT_JOY_H; //diferenca a ser movida
      if(abs(val_x) > TOLERANCIA_JOY){ //se a diferenca e grande
      val_x = int(val_x * FATOR_JOY) + ult_val_x; //somando aa ultima posicao relativa
      // val_x = map(val_x, 0, 1023, 1, 180);//Converte o valor lido para um valor entre 1 e 180 graus
      ult_val_x = val_x;
      val_x = map(val_x, 0, 1023, MIN_AMPL_SERVO_H, MAX_AMPL_SERVO_H);
      servo_horiz.write(val_x);
      }
      val_y -= MID_POINT_JOY_V; //diferenca a ser movida
      if(abs(val_y) > TOLERANCIA_JOY){
      val_y = int(val_y * FATOR_JOY) + ult_val_y; //somando aa ultima posicao relativa
      ult_val_y = val_y;
      DEBUG_PRINTc(“Servo val_y: “, val_y, __LINE__);
      val_y = map(val_y, 0, 1023, MIN_AMPL_SERVO_V, MAX_AMPL_SERVO_V);
      servo_vert.write(val_y);
      }

      delay(250);//Aguarda a movimentacao do servo e reinicia a leitura
      }

      1. Damn…
        * como ajuste FINO

      2. Bom Dia SJS
        gostei da sua alteração no projeto.
        preciso justamente disto, de quando soltar o joystick o servo não retorne a posição Zero,
        Porém, não conseguii compilá-lo e gostaria que se possivel me enviasse novamente o cogido para colocar no software arduino

  16. Ótimo post, e também gostaria de saber se você conhece alguma loja onde posso adquirir um suporte para servo, semelhante ao da primeira figura, muito obrigado, site é 10

  17. Olá gostaria de agradecer este projeto, mas gostaria de saber como posso duplicar o mesmo código (2 joysticks controlando 4 servo motores). Se puder me ajudar eu agradeço

    1. Bom dia Phelippe,

      Obrigado. Você pode utilizar esse código como base e duplicá-lo para controle de 4 motores. Se forem motores DC, sugiro a leitura desse artigo :

      https://www.makerhero.com/blog/controle-motor-dc-12v-com-motor-shield/

      Lá explicamos como utilizar o motor shield, que aceita até 4 motores DC.

      Abraço.

      Adilson – Equipe MakerHero