Índice:
2025 Autor: John Day | [email protected]. Última modificação: 2025-01-13 06:58
Hoje apresentarei o PAN TILT, que é um dispositivo que possibilita a movimentação de uma câmera para os sentidos de cima, baixo e para os lados. Eu mesmo produzi este dispositivo através de peças impressas em 3D, utilizando dois servos e o ESP32, o que permite controlar este mecanismo através de wi-fi. Vamos então fazer leituras usando os canais AD do ESP32, bem como uma operação analógica usando o controlador LED_PWM. Além disso, aplicamos o controle sobre uma conexão TCP / IP.
No vídeo, você pode ver que tenho um ESP32 lendo os valores dos dois potenciômetros, que são enviados (via WiFi) para outro ESP32. Ele está conectado aos dois servo motores. A câmera se move (e é acoplada ao PAN TILT) nas direções para cima, para baixo ou lateralmente, dependendo do controle que você faz através dos potenciômetros.
O link para o design de impressão 3D PAN TILT pode ser encontrado aqui:
Etapa 1: Recursos usados
• Múltiplos jumpers para conexão
• Dois Nó MCU ESP32s
• Dois cabos USB para o ESP32
• Uma WebCam para controle
• Dois potes de controle
• Um protoboard
• Uma fonte para os servos
Etapa 2: NodeMCU ESP32S - Pinagem
Etapa 3: periféricos ESP32
Periféricos PWM O ESP32 tem dois periféricos capazes de gerar sinais PWM. Isso inclui o motor Pulse Width Modulator (MCPWM) projetado para potência e controle do motor, e o LED_PWM, desenvolvido para controle de intensidade de LED. Mas também podem ser usados de forma genérica.
Usaremos o LED_PWM, que pode gerar 16 canais PWM independentes com períodos e ciclos de trabalho configuráveis. Possui resolução de até 16 bits.
Etapa 4: Controle do servo motor PWM
O controle do servo motor é realizado ajustando a modulação da largura de pulso de um quadrado com frequência específica.
Para o servo usado (assim como para a maioria), a frequência é de 50Hz. Além disso, uma largura de 1 a 2 ms de comprimento de pulso determina a posição angular do servo.
Iremos rotear o canal 0 do LED_PWM para o GPIO13, e o canal 1 para o GPIO12, usando essas informações para realizar o controle.
Etapa 5: captura analógica
Periférico de conversão analógico para digital
O ESP32 possui conversores analógico para digital que podem ser aplicados em até 18 canais, mas apenas em GPIOs habilitados para analógico.
A tensão aplicada não deve exceder a faixa de 0 a 3V.
A conversão realizada não mantém um erro constante para todas as tensões amostradas, e tudo isso depende da faixa configurada. Para uma faixa de 150mV a 2, 450V, uma verificação de comportamento é necessária para aplicações mais críticas.
Para a captura, usaremos um potenciômetro de 10k como divisor de tensão. A captura será feita no canal ADC0 e ADC3, acessível por GPIO36 e GPIO39.
Etapa 6: Circuito - Servidor e Cliente
Etapa 7: Código Fonte do Ponto de Acesso e Servidor
Afirmações
Incluo a biblioteca WiFi e defino algumas variáveis.
#include // inclusão da biblioteca WiFi const int freq = 50; // frequência do PWM const int canal_A = 0; // primeiro canal do controlador LED_PWM const int canal_B = 1; // segundo canal do controlador LED_PWM const int resolucao = 12; // Resolução usado sem controlador LED_PWM const int pin_Atuacao_A = 13; // Pino para onde o canal 0 será redirecionado const int pin_Atuacao_B = 12; // Pino para onde o canal 1 será redirecionado const char * ssid = "ESP32ap"; // constante com o SSID do WiFi do ponto de acesso ESP32 const char * password = "12345678"; // senha para conexão de conexão sem ponto de acesso const int port = 2; // porta na qual o servidor receberá como viciado int ciclo_A = 0; // variável que receberá o ciclo de atuação do canal A int ciclo_B = 0; // variável que receberá o ciclo de atuação do canal A servidor WiFiServer (porta); // declaração do objeto servidor IPAddress myIP; // declaração da variável de IP
Configurar ()
Aqui, definimos os pinos de saída. Definimos os canais com a frequência desejada e definimos o valor PWM.
void setup () {pinMode (pin_Atuacao_A, OUTPUT); // definindo o pino de atuação A como saída pinMode (pin_Atuacao_B, OUTPUT); // definindo o pino de atuação B como saída ledcSetup (canal_A, freq, resolucao); // Ajustando o canal 0 para frequência de 50 Hz e resolução de 12bits ledcSetup (canal_B, freq, resolucao); // Ajustando o canal 1 para frequência de 50 Hz e resolução de 12bits ledcAttachPin (pin_Atuacao_A, canal_A); // redirecionando o canal 0 para o pino 13 ledcAttachPin (pin_Atuacao_B, canal_B); // redirecionando o canal 1 para o pino 12 ledcWrite (canal_A, ciclo_A); // definindo o valor do PWM para 0 ledcWrite (canal_B, ciclo_B); // definindo o valor do PWM para 0
Iniciamos o serial, o ponto de acesso com SSID ESP32ap e a senha. Em seguida, obtemos o IP do servidor e o iniciamos.
Serial.begin (115200); // iniciando um Serial Serial.println ("Iniciando ponto de acesso:" + String (ssid)); // mensagem WiFi.softAP (ssid, senha); // iniciando o ponto de acesso com SSID ESP32ap e senha 12345678 Serial.println ("Obtendo IP"); // mensagem myIP = WiFi.softAPIP (); // obtendo o IP do servidor (como não foi configurado deve ser o padrão de fábrica) Serial.println ("IP:" + WiFi.localIP ()); // mensagem Serial.println ("Iniciando servidor em:" + String (porta)); // mensagem server.begin (); // iniciando o servidor}
Ciclo ()
No Loop, a primeira coisa que faremos é instanciar o cliente, conectando e vinculando à variável do cliente. Verifique se o cliente está conectado. Nesse caso, iniciamos a variável que receberá os dados. Contanto que a conexão seja estabelecida, e se dados forem recebidos, lemos os caracteres para a variável c. Finalmente, concatenamos c na variável de dados.
loop vazio () {WiFiClient cliente = server.available (); // se um cliente conectado, associe a variável cliente if (cliente.connected ()) {// se um cliente conectado String dados = ""; // inicia uma variável que receberá os dados Serial.println ("Cliente conectado."); // mensagem while (cliente.connected ()) {// enquanto a conexão conectar if (cliente.available ()) {// e se houver dados a receber char c = cliente.read (); // leia os caracteres para a variável c dados = dados + c; // concatena dados variáveis
Se um caractere de nova linha for recebido, procuramos o índice do caractere ',' na string nos dados. Pegamos as substrings até logo antes da vírgula e depois as convertemos em inteiros. Definimos o PWM dos canais A e B. Limpamos a variável.
if (c == '\ n') {// se um caractere de nova linha para envio int virgula = dados.indexOf (','); // adquirir pelo índice do caracter ',' na string em dados ciclo_A = (dados.substring (0, virgula)). toInt (); // baixe uma substring até antes da vírgula e converta para todo o ciclo_B = dados.substring (virgula + 1, dados.length ()). toInt (); // baixe uma substring após a vírgula e converta para todo ledcWrite (canal_A, ciclo_A); // Ajusta o PWM do canal A ledcWrite (canal_B, ciclo_B); // Ajusta o PWM do canal B dados = ""; // Limpa a variável}}}}
Se o cliente se desconectar, confirmamos o fim da conexão. Aguardamos um momento e imprimimos "Nenhum cliente conectado". Em seguida, esperamos mais um segundo antes de reiniciar.
// caso o cliente se desconecte, confirme o fim da conexão delay (50); // aguarda um momento cliente.stop (); Serial.println ("Nenhum cliente conectado."); // atraso de mensagem (1000); // aguarda um segundo antes de reiniciar}
Etapa 8: Código-fonte do cliente
Afirmações
Incluímos a biblioteca WiFi novamente, desta vez no cliente. Além disso, definimos as variáveis.
#include const char * ssid = "ESP32ap"; // SSID do ponto de acesso ESP32 const char * password = "12345678"; // Senha de acesso ao ponto de acesso const uint16_t port = 2; // Porta de escuta do servidor const char * host = "192.168.4.1"; // endereço IP do servidor const int pin_Leitura_A = 36; // GPIO de leitura do ADC0 const int pin_Leitura_B = 39; // GPIO de leitura do ADC3 int ciclo_A = 0; // variável que receberá o valor do ciclo do PWM A int ciclo_B = 0; // Variável que receberá o valor do ciclo do PWM B WiFiClient cliente; // declaração do objeto cliente
Configurar ()
Definimos os GPIOs como entrada, iniciamos o serial e conectamos ao ponto de acesso.
void setup () {pinMode (pin_Leitura_A, INPUT); // define o GPIO como entrada pinMode (pin_Leitura_B, INPUT); // define o GPIO como entrada Serial.begin (115200); // inicia a comunicação serial WiFi.begin (ssid, senha); // conexão ao ponto de acesso}
Ciclo ()
Neste Loop, vamos nos conectar ao servidor, ou seja, ao outro ESP.
void loop () {// não está conectado ao ponto de acesso, tenta conectar while (WiFi.status ()! = WL_CONNECTED) {Serial.println (String (millis ()) + "- Conectando no WiFi" + ssid + "…"); // mensagem WiFi.begin (ssid, senha); atraso (2000); } Serial.println (String (millis ()) + "- Conectado…"); // mensagem // se não conectado ao servidor, tenta se conectar while (! cliente.connect (host, porta)) {Serial.println (String (millis ()) + "- Conectando no Servidor" + host + ":" + porta + "…"); // atraso de mensagem (1000); }
Nesta etapa, enquanto conectado ao servidor, executamos as variáveis para armazenar a leitura de ADC0 e ADC3. Além disso, realizamos a leitura de 500 amostras e calculamos a média das leituras. Mapeamos a leitura para criar a duração correta para o controle dos servos, concatenar e enviar para o servidor.
// enquanto estiver conectado ao servidor enquanto (cliente.connected ()) {int leitura_A = 0; // variável para armazenar a leitura do ADC0 int leitura_B = 0; // variável para armazenar a leitura do ADC3 int. = 500; // número do proprietário int contador = 0; // contador de controlador enquanto (contador <contador) {// acumua várias leituras leitura_A = leitura_A + analogRead (pin_Leitura_A); leitura_B = leitura_B + analogRead (pin_Leitura_B); contador ++; } leitura_A = leitura_A / conta; // média das leituras leitura_B = leitura_B / sed; ciclo_A = mapa (leitura_A, 0, 4095, 140, 490); // mapeia a leitura para criar a duração correta para controle do servo ciclo_B = map (leitura_B, 0, 4095, 140, 490); // mapeia a leitura para criar a duração correta para controle do servo // concatena e envia para o servidor cliente.println (String (ciclo_A) + "," + String (ciclo_B)); }
Finalmente, se não estiver conectado, garantimos que a conexão foi encerrada exibindo a mensagem equivalente.
// se não coonectado, garante que a conexão foi finalizada cliente.stop (); Serial.println (String (millis ()) + "- cliente desconectado…"); // mensagem}
Etapa 9: Arquivos
Baixe os arquivos:
EU NÃO