Início
/
Projetos Arduino
/
Projetos Squids
/
Intermediário
/
I23a - Testando suporte pan tilt para Arduino - Código Otimizado por ChatGPT
I23a - Testando suporte pan tilt para Arduino - Código Otimizado por ChatGPT
Angelo Luis Ferreira | 04/01/2025
Acessos: 985
Intermediário - Projeto 23a
Testando suporte pan tilt para Arduino com código otimizado por ChatGPT
Objetivo
Neste artigo, vou apresentar o teste de um suporte pan tilt para Arduino, utilizando dois micro-servos motores. Essa é uma continuidade do artigo anterior, I23 - Testando suporte pan tilt para Arduino, porém, desta vez, com o código de programação otimizado com a ajuda do ChatGPT.
A otimização do código resultou em um controle mais eficiente dos servos, simplificando a implementação e tornando o código mais legível. Ficou tão interessante que decidi compartilhar neste tutorial junto com toda a explicação.
O projeto ilustra como um sistema de suporte plástico "pan tilt" pode ser controlado automaticamente pelo Arduino. A base realizará movimentos de rotação de 180º e, em seguida, retornará para 90º, iniciando o movimento de inclinação em até 120º. Para isso, utilizaremos tanto o código original quanto a versão otimizada com o auxílio da inteligência artificial via ChatGPT.
Definições
1. ChatGPT é um modelo avançado de inteligência artificial desenvolvido pela OpenAI, projetado para interagir de forma natural e responder a perguntas, auxiliar na resolução de problemas, criar conteúdos e muito mais. Ideal para quem busca suporte criativo, técnico ou informativo, o ChatGPT é uma ferramenta poderosa para diversos usos. Experimente agora mesmo: Acesse o ChatGPT.

2. Suporte plástico "pan tilt" para Arduino é um acessório mecânico amplamente utilizado em projetos de eletrônica e robótica para movimentação precisa de componentes, como sensores, câmeras ou LEDs. Ele é composto por uma estrutura articulada que permite o movimento em dois eixos principais:
Pan (giro horizontal): Permite a rotação no eixo horizontal, movimentando o componente de um lado para o outro (esquerda e direita).
Tilt (giro vertical): Permite a rotação no eixo vertical, movimentando o componente para cima e para baixo.

2. Micro servo motor 9g: É um micro atuador eletromecânico que apresenta rotação do seu eixo proporcional ao comando emitido por um sinal digital, que pode ser por um microcontrolador, como pela placa Arduino, por exemplo. Portanto, com um micro servo motor é possível controlar a posição e a velocidade de rotação do seu eixo com precisão. Por estas características, os servos motores são muito utilizados em projetos de robótica e mecatrônica.

Referências
Aplicação
O suporte Pan-Tilt é essencial em projetos didáticos e práticos que exigem mobilidade em dois eixos, sendo uma peça fundamental para explorar conceitos de mecânica, eletrônica e automação.
Componentes necessários
Referência
|
Componente
|
Quantidade
|
Imagem
|
Observação
|
Protoboard |
Protoboard 830 pontos |
1 |
 |
No mínimo utilizar protoboard com 400 pontos
|
Jumpers |
Kit cabos ligação macho / macho |
1 |
 |
|
Micro Servo Motor |
Micro Servo 9g SG90
|
2 |

|
Voltagem de Operação 3,0 - 7,2V Ângulo de rotação 180 graus Velocidade 0,12 seg/60Graus (4,8V) sem carga Torque 1,2 kg.cm (4,8V) e 1,6 kg.cm (6,0V) Temperatura de Operação -30C ~ +60C Tipo de Engrenagem Nylon Tamanho cabo 245mm Dimensões 32 x 30 x 12mm Peso 9g
(datasheet)
|
Suporte Pan Tilt |
Suporte Pan Tilt plástico
|
1 |
 |
Suporte plástico para sistema Pan Tilt Deverão ser utilizados 2 micros servos motores 9G como atuadores
S1 - Montagem Suporte Pan Tilt
|
Arduino UNO |
Arduino UNO R3 |
1 |
 |
Você poderá utilizar uma placa Arduino UNO original ou similar
|
Montagem do Circuito
Conecte os componentes no Protoboard como mostra a figura abaixo. Verifique cuidadosamente os cabos de ligação antes de ligar seu Arduino. Lembre-se que o Arduino deve estar totalmente desconectado da energia elétrica enquanto você monta o circuito.

Atenção
1. Faça a montagem do suporte "pan tilt" conforme o tutorial: S1 - Montagem Suporte Pan Tilt controlado com Arduino e Micro Servos Motores.

2. A montagem dos módulos micro servo motor 9g SG90 deve seguir a configuração abaixo:
- Cabo marrom (ou preto em algumas marcas) - Deve ser conectado ao pino GND do Arduino ou ao polo negativo de uma fonte de alimentação externa
- Cabo vermelho - Deve ser conectado a um pino 5V do Arduino ou ao polo positivo de uma fonte de alimentação externa
- Cabo laranja - Deve ser conectado a um pino digital do Arduino configurado como saída. No projeto, utilizamos o pino 9 do Arduino para o motor 1 (motor pan - horizontal) e o pino 10 para o motor 2 (motor tilt - vertical).

2.1. Utilize "jumpers" macho-macho para fazer as conexões com o Arduino.
2.2. No projeto usamos as seguintes conexões:
Micro Servo Motor |
Pino Digital Arduino |
(Servo 1) base (pan) |
9 |
(Servo 2) inclinação (tilt) |
10 |
3. A montagem do nosso projeto foi realizada em um protoboard 400 pontos:

Código do Projeto (ORIGINAL)
1) Faça o download e abra o arquivo projetoI23.ino no IDE do Arduino: DOWNLOAD - projetoI23.ino
Tutorial Completo: I23 - Testando suporte pan tilt para Arduino
Se preferir, copie e cole o código abaixo no IDE do Arduino:
/*******************************************************************************
*
* I23: Testando um suporte pan tilt usando 2 micro-servos motores - Arduino
* Autor: Angelo Luis Ferreira
* Data: 31/12/2025
*
* http://squids.com.br/arduino
*
*******************************************************************************/
#include <Servo.h> //biblioteca para controle do servo motor
// instâncias para os servos
Servo servo1; // Cria um objeto servo1 para controle do servo motor 1
Servo servo2; // Cria um objeto servo2 para controle do servo motor 2
// variáveis e constantes globais
int pos = 0; // variável para armazenar a posição do servo
byte stopPos; // variável para amazenar posições de parada do servo
const byte stepPos = 15; // define a incremento para parar o servo (a cada 15 graus)
const byte servo1Pin = 9; // Pino digital 9 conectado no servo1 (base - pan)
const byte servo2Pin = 10; // Pino digital 10 conectado no servo2 (inclinação - tilt)
void setup() {
// inicialização dos servos
servo1.attach(servo1Pin); // Inicializa servo1 pino 9 (horizontal - base)
servo2.attach(servo2Pin); // Inicializa servo2 pino 10 (vertical - inclinação)
// define as posições iniciais dos servos
servo1.write(0); // Inicia o servo1 em 0 graus
servo2.write(0); // Inicia o servo2 em 0 graus
}
void loop() {
// movimento horizontal do servo1 (pan)
runServo1H(0,180); // servidor 1 vai da posição 0 até 180º (pan)
runServo1A(180,0); // servidor 1 volta para a posição 0º
runServo1H(0,90); // servidor 1 vai da posição 0 até 90º (pan)
delay(1000); // espera 1 segundo
// movimento vertical do servo2 (tilt)
stopPos = 0; // posição de parada em 0º (para o servidor 2)
runServo2(0,120); // servidor 2 vai da posição 0 até 120º (tilt)
delay(1000); // espera 1 segundo
// retorno do servo1 para posição inicial
stopPos = 90; // posição de parada em 90º (para o servidor 1)
runServo1A(90,0); // servidor 1 volta para a posição 0º
delay(1000); // espera 1 segundo
}
void runServo1H(int x, int y) {
// vai de zero a 180º e para por 500ms a cada 15º
for (pos = x; pos <= y; pos += 1) { // vai de zero a 180 graus, girando o eixo a cada 1º
if (pos == stopPos) { // para o servo durante 500ms a cada 15 graus
delay(500); // espera 500ms
stopPos += stepPos; // acrescenta mais 15 graus (para a próxima parada)
}
servo1.write(pos); // diz ao servo para ir para a posição da variável 'pos'
delay(15); // espera 15ms para o servo alcançar a posição
}
stopPos = 180; // posição de parada em 180º
}
// volta para 0º e a cada 15º
void runServo1A(int x, int y) {
// vai de 180º a 0º e para por 500ms a cada 15º
for (pos = x; pos >= y; pos -= 1) { // vai de 180º para a posição inicial, girando o eixo a cada 1º
if (pos == stopPos) { // para o servo durante 500ms a cada 15 graus
delay(500); // espera 500ms
stopPos -= stepPos; // acrescenta mais 15 graus (para a próxima parada)
}
servo1.write(pos); // diz ao servo para ir para a posição da variável 'pos'
delay(15); // espera 15ms para o servo alcançar a posição
}
stopPos = 0; // posição de parada em 0º
}
void runServo2(int x, int y) {
// vai de zero a 180º e para por 500ms a cada 15º
for (pos = x; pos <= y; pos += 1) { // vai de zero a 180 graus, girando o eixo a cada 1º
if (pos == stopPos) { // para o servo durante 500ms a cada 15 graus
delay(500); // espera 500ms
stopPos += stepPos; // acrescenta mais 15 graus (para a próxima parada)
}
servo2.write(pos); // diz ao servo para ir para a posição da variável 'pos'
delay(15); // espera 15ms para o servo alcançar a posição
}
stopPos = 120;
// vai de 180º a 0º e para por 500ms a cada 15º
for (pos = 120; pos >= 0; pos -= 1) { // vai de 180º para a posição inicial, girando o eixo a cada 1º
if (pos == stopPos) { // para o servo durante 500ms a cada 15 graus
delay(500); // espera 500ms
stopPos -= stepPos; // acrescenta mais 15 graus (para a próxima parada)
}
servo2.write(pos); // diz ao servo para ir para a posição da variável 'pos'
delay(15); // espera 15ms para o servo alcançar a posição
}
stopPos = stepPos; // define a primeira parada de cada ciclo em 15 graus
}
Código do Projeto Otimizado (POR CHATGPT)
1) Faça o download e abra o arquivo projetoI23a.ino no IDE do Arduino: DOWNLOAD - projetoI23a.ino
Se preferir, copie e cole o código abaixo no IDE do Arduino:
/*******************************************************************************
*
* I23: Testando um suporte pan tilt usando 2 micro-servos motores - Arduino
* Autor: Angelo Luis Ferreira otimizado por ChatGPT
* Data: 31/12/2025
*
* http://squids.com.br/arduino
*
*******************************************************************************/
#include <Servo.h> // Biblioteca para controle do servo motor
// Instâncias para os servos
Servo servo1; // Objeto para controle do servo motor 1 (pan - horizontal)
Servo servo2; // Objeto para controle do servo motor 2 (tilt - vertical)
// Variáveis e constantes globais
const byte stepPos = 15; // Incremento para parar os servos (a cada 15 graus)
const byte servo1Pin = 9; // Pino digital 9 conectado ao servo1
const byte servo2Pin = 10; // Pino digital 10 conectado ao servo2
int stopPos = 0; // Posição de parada do servo (usada em loops)
void setup() {
// Inicialização dos servos
servo1.attach(servo1Pin);
servo2.attach(servo2Pin);
// Define as posições iniciais dos servos
servo1.write(0); // Servo 1 inicia em 0º
servo2.write(0); // Servo 2 inicia em 0º
}
void loop() {
// Movimento horizontal do servo1 (pan)
runServo(servo1, 0, 180, stepPos, 15); // Servo 1 vai de 0º a 180º
runServo(servo1, 180, 0, stepPos, -15); // Servo 1 volta de 180º a 0º
runServo(servo1, 0, 90, stepPos, 15); // Servo 1 vai de 0º a 90º
delay(1000); // Pausa de 1 segundo
// Movimento vertical do servo2 (tilt)
runServo(servo2, 0, 120, stepPos, 15); // Servo 2 vai de 0º a 120º
runServo(servo2, 120, 0, stepPos, -15); // Servo 2 volta de 120º a 0º
delay(1000); // Pausa de 1 segundo
// Retorno do servo1 para posição inicial
runServo(servo1, 90, 0, stepPos, -15);
delay(1000); // Pausa de 1 segundo
}
/**
* Função para controlar o movimento de um servo motor
* @param servo - Objeto do servo motor a ser controlado
* @param start - Posição inicial do movimento
* @param end - Posição final do movimento
* @param step - Incremento para parar o servo
* @param increment - Incremento por ciclo (+1 ou -1)
*/
void runServo(Servo &servo, int start, int end, int step, int increment) {
int nextStopPos = start + (increment > 0 ? step : -step); // Define a primeira posição de parada
for (int pos = start; (increment > 0) ? (pos <= end) : (pos >= end); pos += increment) {
servo.write(pos); // Move o servo para a posição 'pos'
delay(15); // Aguarda 15ms para o movimento
// Verifica se atingiu uma posição de parada
if (pos == nextStopPos || ((increment > 0) && pos >= end) || ((increment < 0) && pos <= end)) {
delay(500); // Pausa de 500ms na posição de parada
nextStopPos += (increment > 0 ? step : -step); // Atualiza a próxima posição de parada
}
}
}
O que foi otimizado:
-
Eliminação de Redundâncias:
- As funções específicas para cada servo (runServo1H, runServo1A e runServo2) foram substituídas por uma única função genérica, chamada runServo. Isso eliminou a duplicação de código, facilitando a manutenção e deixando o programa mais enxuto.
- A lógica de movimentos foi centralizada, proporcionando um código mais modular e organizado.
-
Controle Genérico para Servos:
- A função runServo agora aceita como parâmetro um objeto do tipo
Servo
, permitindo que a mesma lógica seja usada para controlar qualquer servo motor do projeto.
-
Clareza e Organização:
- Variáveis e constantes foram ajustadas para nomes mais intuitivos, melhorando a legibilidade do código.
- Comentários foram revisados e detalhados, tornando o entendimento do programa mais claro.
-
Configuração do Passo de Movimento:
- O passo dos movimentos (incremento) agora pode ser configurado diretamente na função, proporcionando maior flexibilidade para ajustes futuros.
Explicando a função runServo(Servo &servo, int start, int end, int step, int increment)
A função runServo(Servo &servo, int start, int end, int step, int increment) é uma implementação genérica e modular que controla o movimento de um servo motor. Ela foi criada para otimizar o controle dos servos no projeto, eliminando redundâncias e centralizando a lógica de movimentação. Vamos entender cada parte dessa função:
Parâmetros da função
1. Servo &servo
Este parâmetro recebe uma referência a um objeto da classe Servo (ou seja, o próprio servo que será controlado). Isso permite que a função manipule diretamente o servo sem duplicar dados.
Em C++ (linguagem do Arduino), uma referência é como um "apelido" para um objeto já existente. Isso significa que, quando passamos um objeto como referência para uma função, qualquer modificação ou comando dentro da função afeta diretamente o objeto original.
No caso do código acima, a função runServo foi projetada para ser genérica e controlar qualquer servo. A referência Servo &servo permite que a mesma função seja usada para diferentes servos (como servo1 e servo2) sem criar cópias desnecessárias ou duplicar o código.
Por que usar referência no lugar de passar o objeto diretamente?
Se você passar o objeto diretamente (ou seja, sem usar referência), o C++ criará uma cópia do objeto Servo. Isso consome mais memória e pode causar problemas de desempenho, especialmente no Arduino, que tem recursos limitados.
Com a referência Servo &servo, estamos trabalhando diretamente com o objeto original, economizando memória e garantindo que as alterações feitas dentro da função sejam refletidas no objeto passado.
A função genérica runServo foi definida assim:
void runServo(Servo &servo, int start, int end, int step, int increment) {
// Código que controla o movimento do servo
}
Nesse caso, ao chamar runServo(servo1, ...), o Arduino criaria uma cópia do objeto servo1. Isso é desnecessário e consome mais memória, especialmente em microcontroladores com recursos limitados como o Arduino.
Portanto, o uso de Servo &servo foi uma escolha consciente para:
- Economizar memória no microcontrolador.
- Evitar duplicação de código, já que a mesma função pode ser usada para qualquer servo.
- Garantir que a função altere diretamente o objeto servo original.
2. int start
Posição inicial do movimento do servo (em graus). Define o ângulo a partir do qual o movimento começa.
3. int end
Posição final do movimento do servo (em graus). Define o ângulo no qual o movimento termina.
4. int step
Incremento de parada intermediária (em graus). A cada intervalo definido por este valor, o servo irá "parar" por um curto período para simular paradas em posições específicas.
5. int increment
Determina se o movimento será crescente (+1) ou decrescente (-1).
- Se
increment > 0
, o servo se moverá do menor ângulo (start) para o maior (end).
- Se
increment < 0
, o movimento será no sentido contrário, do maior ângulo (start) para o menor (end).
Como a função funciona
void runServo(Servo &servo, int start, int end, int step, int increment) {
stopPos = (increment > 0) ? step : (180 - step); // Define a posição de parada inicial
for (int pos = start; pos != end; pos += increment) { // Laço para mover o servo de start até end
servo.write(pos); // Move o servo para a posição atual 'pos'
delay(15); // Aguarda 15ms para o servo alcançar a posição
if (pos == stopPos) { // Verifica se o servo está na posição de parada
delay(500); // Pausa de 500ms simulando uma "parada"
stopPos += (increment > 0) ? step : -step; // Atualiza a próxima posição de parada
}
}
}
Definindo a posição de parada inicial
stopPos = (increment > 0) ? step : (180 - step);
Aqui, a variável stopPos é definida dependendo do sentido do movimento:
- Para um movimento crescente (
increment > 0
), a primeira parada ocorre em step
graus.
- Para um movimento decrescente (
increment < 0
), a primeira parada ocorre em (180 - step)
graus.
Laço for
para movimentar o servo
for (int pos = start; pos != end; pos += increment) {
O servo é movido de start
até end
, ajustando o ângulo em cada iteração com base no valor de increment
(+1 ou -1). O laço continua enquanto a posição atual (pos
) não alcançar o valor final (end
).
Movimento do servo
servo.write(pos);
delay(15);
O comando servo.write(pos)
move o servo para a posição atual especificada pela variável pos
.
A função delay(15)
pausa por 15ms, permitindo ao servo alcançar a posição antes de prosseguir para o próximo movimento.
Pausas em posições específicas
if (pos == stopPos) {
delay(500);
stopPos += (increment > 0) ? step : -step;
}
Quando a posição atual (pos
) coincide com a posição de parada (stopPos
), o código pausa por 500ms. Isso simula uma "parada" no movimento.
Após isso, stopPos
é atualizado para a próxima posição de parada:
- Se crescente: Soma o valor de
step
(stopPos += step
).
- Se decrescente: Subtrai o valor de
step
(stopPos -= step
).
Porque usar o ChatGPT para melhorar os seus projetos
Se você deseja otimizar seus códigos, resolver problemas de programação ou até mesmo aprender novas técnicas, o ChatGPT é uma ferramenta incrível. Com ele, você pode:
- Identificar e corrigir erros no código.
- Simplificar e organizar funções para maior eficiência.
- Aprender boas práticas de programação através de exemplos otimizados.
- Tirar dúvidas e explorar novos conceitos de forma prática e didática.
Ao usar o ChatGPT, você não só melhora seus projetos, mas também evolui como programador, entendendo o porquê das otimizações. Experimente, teste e aprenda enquanto aprimora seus códigos.
???? Acesse agora e descubra o potencial do ChatGPT para seus projetos!
Experiências
Teste o projeto usando os dois códigos, o original e o otimizado pelo ChatGPT, e comente quais a diferenças você verificou e qula tem a melhor performance funcional.
O anúncio abaixo ajuda a manter o Squids Arduino funcionando
Comentários