Arduino Nano ESP32 - Controla Carro via Web

Este guia mostra como usar o Arduino Nano ESP32 para controlar sem fio um carro robô a partir de um navegador web no seu celular ou PC, usando WiFi. O controle é feito por meio de uma interface de usuário web gráfica usando algo chamado WebSocket, permitindo um controle fluido e dinâmico do carro.

Arduino Nano ESP32 controls robot car via Web

Sobre o Carro RC 2WD e o WebSocket

Agora, por que escolher o WebSocket? Veja só:

  • Sem o WebSocket, mudar a direção do carro exigiria recarregar a página toda vez. Nada ideal!
  • Porém, com o WebSocket, estabelecemos uma conexão especial entre a página web e o Arduino Nano ESP32. Isso permite enviar comandos para o Arduino Nano ESP32 em segundo plano, sem precisar recarregar a página. O resultado? O carro robô se move de forma contínua e em tempo real. Bem legal, né?

Resumindo, a conexão WebSocket permite o controle fluido e em tempo real do robô.

Temos tutoriais específicos sobre o Carro RC 2WD e o WebSocket. Cada tutorial contém informações detalhadas e instruções passo a passo sobre a pinagem do hardware, o princípio de funcionamento, a ligação com o ESP32, o código do Arduino Nano ESP32... Saiba mais sobre eles nos links a seguir:

Como Funciona

O código do Arduino Nano ESP32 cria tanto um servidor web quanto um servidor WebSocket. Veja como funciona:

  • Quando você digita o endereço IP do ESP32 em um navegador web, ele solicita a página web (Interface do Usuário) ao Arduino Nano ESP32.
  • O servidor web do ESP32 responde enviando o conteúdo da página web (HTML, CSS, JavaScript).
  • Seu navegador web então exibe a página web.
  • O código JavaScript dentro da página web estabelece uma conexão WebSocket com o servidor WebSocket no Arduino Nano ESP32.
  • Depois que essa conexão WebSocket é estabelecida, se você pressionar/soltar os botões na página web, o código JavaScript envia discretamente os comandos para o Arduino Nano ESP32 por meio dessa conexão WebSocket, em segundo plano.
  • O servidor WebSocket no ESP32, ao receber os comandos, controla o carro robô de acordo.

A tabela abaixo mostra a lista de comandos que a página web envia para o Arduino Nano ESP32 com base nas ações do usuário:

Ação do Usuário Botão Comando Ação do Carro
PRESSIONAR CIMA 1 MOVER PARA FRENTE
PRESSIONAR BAIXO 2 MOVER PARA TRÁS
PRESSIONAR ESQUERDA 4 VIRAR À ESQUERDA
PRESSIONAR DIREITA 8 VIRAR À DIREITA
PRESSIONAR PARAR 0 PARAR
SOLTAR CIMA 0 PARAR
SOLTAR BAIXO 0 PARAR
SOLTAR ESQUERDA 0 PARAR
SOLTAR DIREITA 0 PARAR
SOLTAR PARAR 0 PARAR

Diagrama de Ligação entre o Carro RC 2WD e o Arduino Nano ESP32

The wiring diagram between Arduino Nano ESP32 and 2WD RC Car

This image is created using Fritzing. Click to enlarge image

O módulo L9110S (que serve como driver de motor) alimenta os motores diretamente pelos pinos VCC e GND e não tem regulador de 5V embutido. Isso permite alimentar tudo a partir de uma única fonte – quatro pilhas de 1,5V para totalizar 6V. Veja como fazer:

  • Conecte a bateria de 6V aos pinos VCC e GND do módulo L9110S para alimentar os motores.
  • Conecte a mesma bateria de 6V aos pinos Vin e GND do Arduino Nano ESP32 para alimentar a placa Arduino Nano ESP32.
  • Certifique-se de que o módulo L9110S e o Arduino Nano ESP32 compartilhem um GND comum.

Diferentemente do L298N, o L9110S não tem jumpers de habilitação ENA/ENB nem bornes de parafuso de 12V, então a ligação é mais simples.

Como o carro RC 2WD tem uma chave liga/desliga, você pode opcionalmente conectar a bateria por meio da chave para poder ligar/desligar a energia do carro. Se você quiser simplificar, é só ignorar a chave.

Código Arduino Nano ESP32

O conteúdo da página web (HTML, CSS, JavaScript) é armazenado separadamente em um arquivo index.h. Portanto, teremos dois arquivos de código na Arduino IDE:

  • Um arquivo .ino que é o código do Arduino Nano ESP32, que cria um servidor web e um servidor WebSocket, e controla o carro
  • Um arquivo .h, que contém o conteúdo da página web.

Passos Rápidos

Para começar com o Arduino Nano ESP32, siga estes passos:

  • Se você é novo no Arduino Nano ESP32, consulte o tutorial sobre como configurar o ambiente para o Arduino Nano ESP32 na Arduino IDE.
  • Faça a ligação dos componentes de acordo com o diagrama fornecido.
  • Conecte a placa Arduino Nano ESP32 ao seu computador usando um cabo USB.
  • Abra a Arduino IDE no seu computador.
  • Selecione a placa Arduino Nano ESP32 e a porta COM correspondente.
  • Abra o Library Manager clicando no ícone Library Manager na barra de navegação à esquerda da Arduino IDE.
  • Pesquise por “DIYables ESP32 WebServer” e encontre a biblioteca Web Server criada pela DIYables.
  • Clique no botão Install para instalar a biblioteca Web Server.
Arduino Nano ESP32 Web Server library
  • Na Arduino IDE, crie um novo sketch e dê um nome a ele, por exemplo, newbiely.com.ino
  • Copie o código abaixo e abra-o na Arduino IDE
/* * Este código de Arduino Nano ESP32 foi desenvolvido por pt.newbiely.com * Este código de Arduino Nano ESP32 é disponibilizado ao público sem nenhuma restrição. * Para tutoriais completos e diagramas de ligação, visite: * https://pt.newbiely.com/tutorials/arduino-nano-esp32/arduino-nano-esp32-controls-car-via-web */ #include <DIYables_ESP32_WebServer.h> #include "index.h" #define CMD_STOP 0 #define CMD_FORWARD 1 #define CMD_BACKWARD 2 #define CMD_LEFT 4 #define CMD_RIGHT 8 #define MOTOR_A_IA_PIN D5 // The Arduino Nano ESP32 pin connected to the A-IA pin of the L9110S (Motor A) #define MOTOR_A_IB_PIN D6 // The Arduino Nano ESP32 pin connected to the A-IB pin of the L9110S (Motor A) #define MOTOR_B_IA_PIN D9 // The Arduino Nano ESP32 pin connected to the B-IA pin of the L9110S (Motor B) #define MOTOR_B_IB_PIN D10 // The Arduino Nano ESP32 pin connected to the B-IB pin of the L9110S (Motor B) // WiFi credentials const char WIFI_SSID[] = "YOUR_WIFI_SSID"; const char WIFI_PASSWORD[] = "YOUR_WIFI_PASSWORD"; // Create web server instance DIYables_ESP32_WebServer server; DIYables_ESP32_WebSocket* webSocket; // Web Page handlers void handleHome(WiFiClient& client, const String& method, const String& request, const QueryParams& params, const String& jsonData) { server.sendResponse(client, HTML_CONTENT); // HTML_CONTENT is from index.h } // WebSocket event handlers void onWebSocketOpen(net::WebSocket& ws) { Serial.println("New WebSocket connection"); // Send welcome message const char welcome[] = "Connected to ESP32 WebSocket Server!"; } void onWebSocketMessage(net::WebSocket& ws, const net::WebSocket::DataType dataType, const char* message, uint16_t length) { String angle = String(message); int command = angle.toInt(); Serial.print("command: "); Serial.println(command); switch (command) { case CMD_STOP: Serial.println("Stop"); CAR_stop(); break; case CMD_FORWARD: Serial.println("Move Forward"); CAR_moveForward(); break; case CMD_BACKWARD: Serial.println("Move Backward"); CAR_moveBackward(); break; case CMD_LEFT: Serial.println("Turn Left"); CAR_turnLeft(); break; case CMD_RIGHT: Serial.println("Turn Right"); CAR_turnRight(); break; default: Serial.println("Unknown command"); } } void onWebSocketClose(net::WebSocket& ws, const net::WebSocket::CloseCode code, const char* reason, uint16_t length) { Serial.println("WebSocket client disconnected"); } void setup() { Serial.begin(9600); delay(1000); pinMode(MOTOR_A_IA_PIN, OUTPUT); pinMode(MOTOR_A_IB_PIN, OUTPUT); pinMode(MOTOR_B_IA_PIN, OUTPUT); pinMode(MOTOR_B_IB_PIN, OUTPUT); Serial.println("Arduino Nano ESP32 Web Server and WebSocket Server"); // Configure web server routes server.addRoute("/", handleHome); // Start web server with WiFi connection server.begin(WIFI_SSID, WIFI_PASSWORD); // Enable WebSocket functionality webSocket = server.enableWebSocket(81); if (webSocket != nullptr) { // Set up WebSocket event handlers webSocket->onOpen(onWebSocketOpen); webSocket->onMessage(onWebSocketMessage); webSocket->onClose(onWebSocketClose); } else { Serial.println("Failed to start WebSocket server"); } } void loop() { // Then handle HTTP requests server.handleClient(); // Handle WebSocket server.handleWebSocket(); } void CAR_moveForward() { digitalWrite(MOTOR_A_IA_PIN, HIGH); digitalWrite(MOTOR_A_IB_PIN, LOW); digitalWrite(MOTOR_B_IA_PIN, HIGH); digitalWrite(MOTOR_B_IB_PIN, LOW); } void CAR_moveBackward() { digitalWrite(MOTOR_A_IA_PIN, LOW); digitalWrite(MOTOR_A_IB_PIN, HIGH); digitalWrite(MOTOR_B_IA_PIN, LOW); digitalWrite(MOTOR_B_IB_PIN, HIGH); } void CAR_turnLeft() { digitalWrite(MOTOR_A_IA_PIN, HIGH); digitalWrite(MOTOR_A_IB_PIN, LOW); digitalWrite(MOTOR_B_IA_PIN, LOW); digitalWrite(MOTOR_B_IB_PIN, LOW); } void CAR_turnRight() { digitalWrite(MOTOR_A_IA_PIN, LOW); digitalWrite(MOTOR_A_IB_PIN, LOW); digitalWrite(MOTOR_B_IA_PIN, HIGH); digitalWrite(MOTOR_B_IB_PIN, LOW); } void CAR_stop() { digitalWrite(MOTOR_A_IA_PIN, LOW); digitalWrite(MOTOR_A_IB_PIN, LOW); digitalWrite(MOTOR_B_IA_PIN, LOW); digitalWrite(MOTOR_B_IB_PIN, LOW); }
  • Crie o arquivo index.h na Arduino IDE da seguinte forma:
    • Clique no botão logo abaixo do ícone do Serial Monitor e escolha New Tab, ou use as teclas Ctrl+Shift+N.
    Arduino IDE 2 adds file
    • Dê ao arquivo o nome index.h e clique no botão OK
    Arduino IDE 2 adds file index.h
    • Copie o código abaixo e cole-o no index.h.
    /* * Este código de Arduino Nano ESP32 foi desenvolvido por pt.newbiely.com * Este código de Arduino Nano ESP32 é disponibilizado ao público sem nenhuma restrição. * Para tutoriais completos e diagramas de ligação, visite: * https://pt.newbiely.com/tutorials/arduino-nano-esp32/arduino-nano-esp32-controls-car-via-web */ const char *HTML_CONTENT = R"=====( <!DOCTYPE html> <html> <head> <title>Arduino Nano ESP32 Control Car via Web</title> <meta name="viewport" content="width=device-width, initial-scale=0.7, maximum-scale=1, user-scalable=no"> <style type="text/css"> body { text-align: center; font-size: 24px;} button { text-align: center; font-size: 24px;} #container { margin-right: auto; margin-left: auto; width: 400px; height: 400px; position: relative; margin-bottom: 10px; } div[class^='button'] { position: absolute; } .button_up, .button_down { width:214px; height:104px;} .button_left, .button_right { width:104px; height:214px;} .button_stop { width:178px; height:178px;} .button_up { background: url('https://esp32io.com/images/tutorial/up_inactive.png') no-repeat; background-size: contain; left: 200px; top: 0px; transform: translateX(-50%); } .button_down { background: url('https://esp32io.com/images/tutorial/down_inactive.png') no-repeat; background-size: contain; left:200px; bottom: 0px; transform: translateX(-50%); } .button_right { background: url('https://esp32io.com/images/tutorial/right_inactive.png') no-repeat; background-size: contain; right: 0px; top: 200px; transform: translateY(-50%); } .button_left { background: url('https://esp32io.com/images/tutorial/left_inactive.png') no-repeat; background-size: contain; left:0px; top: 200px; transform: translateY(-50%); } .button_stop { background: url('https://esp32io.com/images/tutorial/stop_inactive.png') no-repeat; background-size: contain; left:200px; top: 200px; transform: translate(-50%, -50%); } </style> <script> var CMD_STOP = 0; var CMD_FORWARD = 1; var CMD_BACKWARD = 2; var CMD_LEFT = 4; var CMD_RIGHT = 8; var img_name_lookup = { [CMD_STOP]: "stop", [CMD_FORWARD]: "up", [CMD_BACKWARD]: "down", [CMD_LEFT]: "left", [CMD_RIGHT]: "right" } var ws = null; function init() { var container = document.querySelector("#container"); container.addEventListener("touchstart", mouse_down); container.addEventListener("touchend", mouse_up); container.addEventListener("touchcancel", mouse_up); container.addEventListener("mousedown", mouse_down); container.addEventListener("mouseup", mouse_up); container.addEventListener("mouseout", mouse_up); } function ws_onmessage(e_msg) { e_msg = e_msg || window.event; // MessageEvent //alert("msg : " + e_msg.data); } function ws_onopen() { document.getElementById("ws_state").innerHTML = "OPEN"; document.getElementById("wc_conn").innerHTML = "Disconnect"; } function ws_onclose() { document.getElementById("ws_state").innerHTML = "CLOSED"; document.getElementById("wc_conn").innerHTML = "Connect"; console.log("socket was closed"); ws.onopen = null; ws.onclose = null; ws.onmessage = null; ws = null; } function wc_onclick() { if(ws == null) { ws = new WebSocket("ws://" + window.location.host + ":81"); document.getElementById("ws_state").innerHTML = "CONNECTING"; ws.onopen = ws_onopen; ws.onclose = ws_onclose; ws.onmessage = ws_onmessage; } else ws.close(); } function mouse_down(event) { if (event.target !== event.currentTarget) { var id = event.target.id; send_command(id); event.target.style.backgroundImage = "url('https://esp32io.com/images/tutorial/" + img_name_lookup[id] + "_active.png')"; } event.stopPropagation(); event.preventDefault(); } function mouse_up(event) { if (event.target !== event.currentTarget) { var id = event.target.id; send_command(CMD_STOP); event.target.style.backgroundImage = "url('https://esp32io.com/images/tutorial/" + img_name_lookup[id] + "_inactive.png')"; } event.stopPropagation(); event.preventDefault(); } function send_command(cmd) { if(ws != null) if(ws.readyState == 1) ws.send(cmd + "\r\n"); } window.onload = init; </script> </head> <body> <h2>Arduino Nano ESP32 - RC Car via Web</h2> <div id="container"> <div id="0" class="button_stop"></div> <div id="1" class="button_up"></div> <div id="2" class="button_down"></div> <div id="8" class="button_right"></div> <div id="4" class="button_left"></div> </div> <p> WebSocket : <span id="ws_state" style="color:blue">closed</span><br> </p> <button id="wc_conn" type="button" onclick="wc_onclick();">Connect</button> <br> <br> <div class="sponsor">Sponsored by <a href="https://amazon.com/diyables">DIYables</a></div> </body> </html> )=====";
    • Agora você tem o código em dois arquivos: newbiely.com.ino e index.h
    • Clique no botão Upload na Arduino IDE para fazer o upload do código para o Arduino Nano ESP32
    • Abra o Serial Monitor
    • Veja o resultado no Serial Monitor.
    ∞
    Newbiely | Arduino IDE 2.3.8
    ──
    ☐
    ✕
    File
    Edit
    Sketch
    Tools
    Help
    Arduino Nano ESP32
    Newbiely.ino
    ···
    8 Serial.println("Hello World!");
    Output
    Serial Monitor
    Message (Enter to send message to 'Arduino Nano ESP32' on 'COM15')
    New Line
    9600 baud
    Connecting to WiFi... Connected to WiFi Arduino Nano ESP32 Web Server's IP address IP address: 192.168.0.2
    Ln 11, Col 1
    Arduino Nano ESP32 on COM15
    2
    • Anote o endereço IP exibido e digite esse endereço na barra de endereços de um navegador web no seu celular ou PC.
    • Você verá a página web como abaixo:
    Arduino Nano ESP32 controls car via web browser
    • O código JavaScript da página web cria automaticamente a conexão WebSocket com o Arduino Nano ESP32.
    • Agora você pode controlar o carro para virar à esquerda/direita e andar para frente/para trás pela interface web.

    Para economizar a memória do ESP32, as imagens dos botões de controle NÃO são armazenadas no Arduino Nano ESP32. Em vez disso, elas ficam armazenadas na internet, então seu celular ou PC precisa ter conexão com a internet para carregar as imagens da página web de controle.

    ※ Nota:

    • Se você modificar o conteúdo HTML no index.h e não mexer em nada no arquivo newbiely.com.ino, quando você compilar e fizer o upload do código para o ESP32, a Arduino IDE não atualizará o conteúdo HTML.
    • Para fazer a Arduino IDE atualizar o conteúdo HTML nesse caso, faça uma alteração no arquivo newbiely.com.ino (por exemplo, adicionar uma linha vazia, adicionar um comentário....)

    Explicação do Código Linha por Linha

    O código do Arduino Nano ESP32 acima contém uma explicação linha por linha. Por favor, leia os comentários no código!

※ NOSSAS MENSAGENS

  • Fique à vontade para compartilhar o link deste tutorial. Porém, por favor, não use nosso conteúdo em outros sites. Investimos muito esforço e tempo para criar este conteúdo, por favor respeite nosso trabalho!