Manufaturação industrial
Internet das coisas industrial | Materiais industriais | Manutenção e reparo de equipamentos | Programação industrial |
home  MfgRobots >> Manufaturação industrial >  >> Manufacturing Technology >> Processo de manufatura

WiDC: Robô FPV Wi‑Fi – Controle Remoto com Vídeo ao Vivo

Componentes e Materiais

Arduino UNO 1
Espressif ESP8266 ESP-01 1
Arduino Proto Shield 1
Motor DC com roda 1
Ponte H (H-bridge) 1

Aplicativos e Serviços Online

Sobre o Projeto

Que tal usar um robô controlado remotamente para explorar o ambiente, alcançar lugares inacessíveis, vigiar, tirar fotos, filmar ou transmitir vídeo? Este tutorial mostra como construir um robô acessível para todos esses propósitos.

Este tutorial é uma melhoria do meu projeto anterior (robô FPV controlado por Wi‑Fi), apresentando um robô caseiro mais rápido. Ensina como projetar e construir um robô de duas rodas controlado remotamente via rede Wi‑Fi, usando dois motores DC, um Arduino Uno e um módulo Wi‑Fi ESP8266.

O robô pode ser controlado a partir de um navegador comum, usando uma interface HTML. Um smartphone Android pode ser usado para transmitir vídeo e áudio do robô para a interface de controle.

Como no tutorial anterior, mostro como projetar e construir uma estrutura de baixo custo para um projeto robótico, usando apenas ferramentas comuns (sem necessidade de impressora 3D, cortadora a laser ou roteador CNC).

Note que os componentes usados aqui podem não ser os ideais para o propósito. Um NodeMCU poderia substituir a combinação Arduino + ESP8266, por exemplo. Um Raspberry Pi com câmera substituiria o smartphone e também controlaria os motores. Até mesmo um smartphone Android poderia servir como "cérebro" do robô.

Este tutorial deriva de outro projeto do qual participo: Joy Robot (Hackaday ou Hackster). O mesmo hardware foi usado aqui por simplicidade. O Arduino Uno foi escolhido por ser muito acessível e fácil de usar, e queríamos projetar um shield simples para ele. No projeto original, também controlamos servos e matrizes de LED, e fazemos interface com o ESP. O smartphone é na verdade substituído por um tablet, que roda outros aplicativos. Você pode encontrar outros tutoriais relacionados a esse robô nos links abaixo:

Este guia pode ser adaptado e ter seu formato ou interface de controle alterados para atender às suas necessidades.

Neste outro tutorial, apresento uma forma de controlar um robô a partir de um smartphone usando o app Blynk! Confira:

Hackster

Passo 1: Ferramentas

As seguintes ferramentas foram usadas na construção deste protótipo:

Essas ferramentas foram usadas na produção da estrutura mecânica, montagem do robô e conexão dos componentes eletrônicos. Algumas não são necessárias se você optar por comprar a estrutura em vez de construir a sua própria.

Você pode até usar outros equipamentos (impressora 3D ou cortadora a laser, por exemplo), dependendo das ferramentas disponíveis no seu makerspace.

Passo 2: Estrutura Mecânica e Materiais

Os seguintes materiais foram usados na estrutura mecânica:

Passo 3: Componentes Eletrônicos

Os seguintes componentes eletrônicos foram usados neste robô:

Todos os componentes podem ser encontrados facilmente em lojas online. A escolha dos componentes foi derivada de outro projeto que projetei e pode ser otimizada usando um microcontrolador diferente, por exemplo.

Passo 4: Projetando a Estrutura

Primeiro, projetei a estrutura mecânica do robô. Você também pode comprar a estrutura completa online se não quiser construir a sua própria (existem muitos kits robóticos disponíveis). Neste caso, pule para o Passo 6.

Para este tutorial, uma estrutura de acrílico de baixo custo foi projetada para fixação dos motores e outros componentes. A estrutura foi modelada em 3D usando o software CAD Fusion 360 e construída com ferramentas comuns (sem impressora 3D, cortadora a laser ou roteador CNC). Você pode usar os mesmos princípios descritos abaixo para projetar uma estrutura personalizada que atenda às suas necessidades.

Primeiro, criei modelos 3D dos componentes principais para decidir o arranjo da estrutura. Alguns foram baixados da Biblioteca da Comunidade GrabCAD:

Os componentes eletrônicos foram arranjados em um plano para determinar a área necessária. Depois, escolhi a posição dos motores e rodas para criar uma estrutura estável. Baseado nessas posições, a estrutura principal foi projetada, composta por três placas (uma base e duas laterais) conectadas por braquetes.

Arquivos de corte: base.pdf, base.svg

Passo 5: Construindo e Montando a Estrutura

A construção da base é dividida nas seguintes etapas:

1. Corte a base de acrílico conforme as dimensões do desenho 2D: Pode ser feito com cortadora a laser (se tiver acesso) ou, como no meu caso, com ferramentas comuns. Transfira as dimensões do modelo para a chapa de acrílico: imprima o desenho 2D em papel adesivo, recorte e aplique na superfície do acrílico. Com estilete e régua, risque o acrílico em linhas retas. Não precisa cortar totalmente, apenas marcar para depois quebrar. Coloque o acrílico sobre superfície plana, prenda com grampos e aplique pressão até a chapa se partir. Repita até concluir todos os cortes. Use lixa para suavizar bordas. Também pode usar serra manual.

2. Fure os furos nas posições indicadas no desenho 2D: Fure com furadeira nas posições indicadas (marcadas na máscara). O acrílico é relativamente fácil de furar. Se não tiver furadeira, pode furar manualmente com ferramenta pontiaguda, como estilete. Use também para alargar furos pequenos para caber os parafusos. Remova a máscara e a base estará pronta.

3. Monte os componentes com parafusos e porcas conforme o desenho 3D: Monte conforme o vídeo, e sua estrutura estará pronta. Parafusos M3 para instalação dos braquetes e motores DC. Parafusos M2 para componentes eletrônicos. Parafusos 5/32" para roda dianteira e clipe do smartphone.

Arquivo: base.pdf

Passo 6: Montando a Eletrônica

O circuito proposto usa um Arduino Uno como controlador principal, que interfaceia com um ESP8266 para comunicação Wi‑Fi. O Arduino controla os motores DC usando um circuito driver de ponte H, capaz de controlar até dois motores, girando-os independentemente em ambas as direções.

Um power bank foi usado para alimentar a eletrônica, conectado diretamente à porta USB do Arduino. É uma forma fácil de alimentar o Arduino: fácil de recarregar, pode ser trocado facilmente e fornece 5V seguros.

Conecte todos os componentes conforme o esquema. Você precisará de fios jumpers para conectar o módulo ESP8266 (que não é compatível com protoboard), a ponte H e os motores DC. Pode usar um proto shield (para circuito mais compacto), uma protoboard comum, ou projetar seu próprio shield para Arduino.

O ESP8266-01 não é compatível com protoboard. Será conectado com fios jumpers, mas não ficará fixado à estrutura.

Conecte um cabo USB ao Arduino e prossiga para o próximo passo.

Arquivos: wiDC_Esquemático.pdf, wiDC.fzz, wiDC_bb.pdf

Passo 7: Código do Arduino

Instale a versão mais recente da Arduino IDE. Nenhuma biblioteca foi necessária para comunicação com o módulo ESP8266 ou controle dos motores. Verifique o baud rate do seu ESP8266 e configure corretamente no código. Baixe o código do Arduino (WiDC.ino) e substitua XXXXX pelo SSID do seu roteador Wi‑Fi e YYYYY pela senha. Conecte o Arduino ao computador via USB e carregue o código.

// Inclui bibliotecas
#include <SoftwareSerial.h>
SoftwareSerial esp8266(3, 2); // RX = 3, TX = 2

// Definição de variáveis
#define DEBUG true
int state = 5; // estado inicial (5 = standby)

// Pinos dos motores
const int motor1Pin1 = 5;
const int motor1Pin2 = 6;
const int motor2Pin1 = 9;
const int motor2Pin2 = 10;

// Velocidade dos motores (PWM)
int motorSpeed = 150;

void setup() {
  pinMode(motor1Pin1, OUTPUT);
  pinMode(motor1Pin2, OUTPUT);
  pinMode(motor2Pin1, OUTPUT);
  pinMode(motor2Pin2, OUTPUT);

  Serial.begin(9600);
  esp8266.begin(9600);

  sendData("AT+RST\r\n", 2000, DEBUG); // reset módulo
  sendData("AT+CWMODE=1\r\n", 1000, DEBUG); // modo station
  sendData("AT+CWJAP=\"XXXXX\",\"YYYYY\"\r\n", 2000, DEBUG); // conecta Wi‑Fi
  delay(5000); // aguarda conexão
  sendData("AT+CIFSR\r\n", 1000, DEBUG); // mostra IP
  sendData("AT+CIPMUX=1\r\n", 1000, DEBUG); // múltiplas conexões
  sendData("AT+CIPSERVER=1,80\r\n", 1000, DEBUG); // servidor web na porta 80
}

void loop() {
  if (esp8266.available()) {
    if (esp8266.find("+IPD,")) {
      String msg;
      esp8266.find("?");
      msg = esp8266.readStringUntil(' ');
      String command = msg.substring(0, 3);
      Serial.println(command);

      if (command == "cm1") state = 1; // frente
      else if (command == "cm2") state = 2; // trás
      else if (command == "cm3") state = 3; // direita
      else if (command == "cm4") state = 4; // esquerda
      else if (command == "cm5") state = 5; // parar
    }
  }

  // Estado 1: frente
  if (state == 1) {
    analogWrite(motor1Pin1, motorSpeed); digitalWrite(motor1Pin2, LOW);
    analogWrite(motor2Pin1, motorSpeed); digitalWrite(motor2Pin2, LOW);
  }
  // Estado 2: trás
  else if (state == 2) {
    digitalWrite(motor1Pin1, LOW); analogWrite(motor1Pin2, motorSpeed);
    digitalWrite(motor2Pin1, LOW); analogWrite(motor2Pin2, motorSpeed);
  }
  // Estado 3: direita
  else if (state == 3) {
    analogWrite(motor1Pin1, motorSpeed); digitalWrite(motor1Pin2, LOW);
    digitalWrite(motor2Pin1, LOW); analogWrite(motor2Pin2, motorSpeed);
  }
  // Estado 4: esquerda
  else if (state == 4) {
    digitalWrite(motor1Pin1, LOW); analogWrite(motor1Pin2, motorSpeed);
    analogWrite(motor2Pin1, motorSpeed); digitalWrite(motor2Pin2, LOW);
  }
  // Estado 5: parar
  else if (state == 5) {
    digitalWrite(motor1Pin1, LOW); digitalWrite(motor1Pin2, LOW);
    digitalWrite(motor2Pin1, LOW); digitalWrite(motor2Pin2, LOW);
  }
}

String sendData(String command, const int timeout, boolean debug) {
  String response = "";
  esp8266.print(command);
  long int time = millis();
  while ((time + timeout) > millis()) {
    while (esp8266.available()) {
      char c = esp8266.read();
      response += c;
    }
  }
  if (debug) Serial.print(response);
  return response;
}

Explicação do código:

O código usa uma porta serial para comunicação entre Arduino e ESP8266, e outra para comunicação com o computador. Como o Arduino Uno tem apenas uma porta serial hardware, a biblioteca SoftwareSerial cria uma porta secundária nos pinos digitais 2 e 3.

No setup(), ambas as comunicações seriais são iniciadas com baud rate 9600. Meu ESP8266 estava configurado para 9600 kbps; por padrão a maioria vem em 115200 kbps, mas SoftwareSerial não funciona nessa velocidade, então é necessário alterar o baud rate do módulo.

Não usei biblioteca específica para o módulo Wi‑Fi; apenas comandos AT padrão do firmware do ESP8266:

A função auxiliar sendData envia comandos ao ESP8266, lê e exibe a resposta no Monitor Serial.

No loop(), o Arduino verifica dados recebidos. Quando recebe um comando (cm1 a cm5), entra em um dos cinco estados (frente, trás, direita, esquerda, standby) e mantém esse estado até receber outro comando.

Cada estado define os sinais nos pinos dos motores. Usei digitalWrite(pino, LOW) para 0V e analogWrite(pino, motorSpeed) para PWM, permitindo controle de velocidade.

Os motores operam entre 3 e 6V. Com fonte de 5V, é possível modular a tensão média (PWM) entre 3 e 5V, alterando a velocidade. Não permite controle fino da velocidade.

Arquivo: WiDC.ino

Passo 8: Interface de Controle Baseada na Web

Uma interface HTML foi projetada para controle do robô. Baixe interface.rar e extraia todos os arquivos em uma pasta. Abra no Firefox. Um formulário com caixa de texto permite inserir os endereços IP do módulo ESP e do servidor de vídeo/áudio (app IP Webcam no Android). Há um botão de teste que faz o robô girar até receber outro comando. As setas do teclado controlam o movimento.

Um smartphone Android transmite vídeo e áudio do robô para a interface. Encontre o app na Google Play Store: IP Webcam.

HTML explicado:

A interface tem duas divisões: uma para áudio/vídeo (servidor IP Webcam) e outra para comandos.

Divisão de vídeo/áudio: formulário com textbox e botão para especificar IP do servidor e carregá-lo. Vem com IP padrão (192.168.0.5), mas o usuário pode alterar. Vídeo e áudio são carregados em objetos <object> abaixo.

<div id="video_and_audio" style="position: absolute; top: 50px; width:25%">
  <form name="myform" action="" method="GET">
    IP Webcam (IP): <input type="text" name="inputbox" value="192.168.0.5">
    <input type="button" name="button1" value="Load" onClick="readUrlAV(this.form)">
  </form>
  <object id="video" type="text/html" data="https://192.168.0.5:8080/video" style="position: absolute; width:100%; height:480px;"></object>
  <object id="audio" type="text/html" data="https://192.168.0.5:8080/audio.opus" style="position: absolute; width:388px; height:30px; left:8px; top:425px;"></object>
</div>

Divisão de comandos: formulário com textbox para informar IP do ESP8266.

<div id="commands" style="position: absolute; top: 50px; left:35%; width:65%">
  <form name="myform2" action="" method="GET">
    Arduino IP Address: <input type="text" name="inputbox" Value="192.168.0.5">
    <input type="button" name="button3" Value="Test" onClick="testarArduino(this.form)">
  </form>
  <img src="images/keyboard.png" style="margin-left:100px; margin-top:50px;">
  <h4> Pressione e segure as setas do teclado para mover o robô </h4>
</div>

JavaScript gerencia a interface e envia dados ao Arduino. Scripts em arquivos separados, incluídos no <head>:

<head>
  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
  <meta name="author" content="Igor Fonseca Albuquerque">
  <title>Control interface</title>
  <script src="jquery.js"></script>
  <script src="myscript.js"></script>
</head>

JavaScript explicado:

Função readUrlAV lê o IP do formulário e carrega nos objetos "video" e "audio".

function readUrlAV(form) {
  TextVar = form.inputbox.value;
  VideoVar = "https://" + TextVar + ":8080/video";
  AudioVar = "https://" + TextVar + ":8080/audio.opus";
  document.getElementById("video").setAttribute('data', VideoVar);
  document.getElementById("audio").setAttribute('data', AudioVar);
}

O script monitora o teclado periodicamente. Se o usuário pressiona uma seta (cima=38, baixo=40, esquerda=37, direita=39), envia comando ("cm1" a "cm4") para o IP informado. Uma função latch evita repetição do comando. Dados são enviados apenas quando a tecla é pressionada.

var latch = false;
document.onkeydown = checkKeyDown;
function checkKeyDown(e) {
  e = e || window.event;
  if (e.keyCode == '38') { // cima
    if (!latch) { sendCommand("cm1"); latch = true; }
  } else if (e.keyCode == '40') { // baixo
    if (!latch) { sendCommand("cm2"); latch = true; }
  } else if (e.keyCode == '37') { // esquerda
    if (!latch) { sendCommand("cm3"); latch = true; }
  } else if (e.keyCode == '39') { // direita
    if (!latch) { sendCommand("cm4"); latch = true; }
  }
}

Quando a tecla é solta, doNothing envia "cm5" (para motores) e reseta o latch.

document.onkeyup = checkKeyUp;
function checkKeyUp(e) {
  e = e || window.event;
  if (e.keyCode=='38'||e.keyCode=='40'||e.keyCode=='37'||e.keyCode=='39') {
    setTimeout(doNothing, 200);
  }
}
function doNothing(){
  sendCommand("cm5");
  latch = false;
}

Arquivo: interface.rar

Passo 9: Uso

Ao reiniciar, o Arduino tentará conectar à sua rede Wi‑Fi automaticamente. Use o Monitor Serial para verificar se a conexão foi bem-sucedida e obter o IP atribuído ao ESP8266 pelo roteador. Abra o arquivo HTML no navegador (Firefox) e informe este IP na caixa de texto.

Você também pode usar outros meios para descobrir o IP atribuído. Desconecte o Arduino do computador e conecte ao power bank. Aguarde reconectar. Inicie o app IP Webcam no smartphone acoplado ao robô. Digite o IP de vídeo/áudio na interface de controle, conecte ao servidor e pronto. Pode ser necessário reduzir a resolução do vídeo no app para diminuir o atraso na transmissão. Clique e segure as setas do teclado para girar ou mover o robô e divirta-se explorando.

Note que o robô opera em malha aberta. Diferenças entre motores, alinhamento, etc., causam desvios cumulativos, dificultando movimento em linha reta.

O robô inicia o movimento ao receber comando ("cm1" a "cm4") e mantém esse estado até receber outro comando ("cm1" a "cm5"). Às vezes o ESP8266 perde mensagens, o que pode causar problemas. Se, por exemplo, um comando "cm5" for perdido, o robô continuará movendo mesmo após soltar a tecla. Ainda estou lidando com isso. Sinta-se à vontade para alterar a forma como os comandos são interpretados para evitar esse problema.

Código

Código Arduino

// (código completo já apresentado no Passo 7)

Interface

Download only (interface.rar)

Peças Personalizadas e Caixas

base_7JLgOpcox6.svg

Esquemáticos

(Consulte os arquivos PDF/Fritzing no Passo 6)

Processo de manufatura

  1. Construa um Robô Raspberry Pi Controlado por Bluetooth com Feedback de Áudio
  2. Dados Digital com Arduino: Gere Números Aleatórios 1-6 em LCD 16x2
  3. Controle USB para Jogos DIY com Arduino – Construa Seu Próprio Gamepad de Alto Desempenho
  4. Criar Robô Seguidor de Linha Autônomo com Arduino UNO
  5. Construa um Robô Controlado por Voz com Arduino Nano
  6. MobBob: Construa Seu Próprio Robô Arduino, Controlado via Smartphone Android
  7. Pixel Chaser: Jogo LED Interativo de Um Toque com Arduino Nano
  8. Levitação Magnética Repulsiva com Arduino: Circuito Simples e Guia DIY
  9. PiBot: Robô Pianista Arduino para Performance Musical de Precisão
  10. Robô Assistente Doméstico Autônomo: Lista Completa de Peças e Guia de Configuração