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:
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 :
A ligação do joystick ao Arduino e também aos dois servo motores pode ser feita dessa maneira:
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.
Esse é meu primeiro contato com Arduíno. É possível comandar esse conjunto a partir de um controle remoto de aeromodelo?
obrigado
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();
}
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
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?
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
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;
}
}
}
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
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á!
Para este servo eu não preciso da ponte H então?
Olá sou seguidor do site gosto muito de seus projetos parabens !
Uma duvida como alterar o sketch para os servos movimentarem mas rapido ?
servo_inclinacao.attach(x, 1, 180);. Altere o valor “x”, pois ele indica tempo.
Excelente. Tem como adicionar um transmissor para comandar a distância?
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
Podia ter um tutorial só de como montar esse suporte pan-tilt, sofri aqui! D=
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?
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?
como colocar um motor dc junto no programa ?? podia me dar um exemplo ?? obrigado !!
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!!!!!
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!
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
como se faz isso por favor.
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
}
Damn…
* como ajuste FINO
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
Ó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
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
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