ESP8266 - Controle de Carro via Web

Este tutorial ensina você a usar o ESP8266 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 web gráfica que usa algo chamado WebSocket, permitindo um controle suave e dinâmico do carro.

ESP8266 NodeMCU controla carro robô via Web

Sobre o Carro RC 2WD e o WebSocket

Mas por que usar WebSocket? Veja o motivo:

  • Sem WebSocket, mudar a direção do carro exigiria recarregar a página a cada vez. Nada ideal!
  • Porém, com o WebSocket, estabelecemos uma conexão especial entre a página web e o ESP8266. Isso permite enviar comandos ao ESP8266 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ão é?

Resumindo, a conexão WebSocket permite o controle suave 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 ao ESP8266, o código do ESP8266... Saiba mais nos links a seguir:

Como Funciona

O código do ESP8266 cria um servidor web e um servidor WebSocket. Veja como funciona:

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

A tabela abaixo mostra a lista de comandos que a página web envia ao ESP8266 com base nas ações do usuário:

Ação do Usuário Botão Comando Ação do Carro
PRESSIONAR UP 1 ANDAR PARA FRENTE
PRESSIONAR DOWN 2 ANDAR PARA TRÁS
PRESSIONAR LEFT 4 VIRAR À ESQUERDA
PRESSIONAR RIGHT 8 VIRAR À DIREITA
PRESSIONAR STOP 0 PARAR
SOLTAR UP 0 PARAR
SOLTAR DOWN 0 PARAR
SOLTAR LEFT 0 PARAR
SOLTAR RIGHT 0 PARAR
SOLTAR STOP 0 PARAR

Diagrama de Ligação entre o Carro RC 2WD e o ESP8266

Diagrama de Ligação do Carro RC 2WD com ESP8266 NodeMCU

This image is created using Fritzing. Click to enlarge image

Para mais informações, veja Pinagem do ESP8266 e como alimentar o ESP8266 e outros componentes.

O módulo L9110S alimenta os motores diretamente a partir dos pinos VCC e GND e não tem regulador de 5V embutido. Isso significa que você pode alimentar tudo com uma única fonte de energia — quatro pilhas AA de 1,5V (totalizando 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 ESP8266 para alimentar a placa ESP8266.
  • Certifique-se de que o módulo L9110S e o ESP8266 compartilhem um GND comum.

Ao contrário do L298N, o L9110S não tem jumpers de habilitação ENA/ENB nem borne 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 quiser simplificar, é só ignorar a chave.

Código ESP8266

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

  • Um arquivo .ino com o código do ESP8266, 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 ESP8266 no Arduino IDE, siga estes passos:

  • Confira o tutorial como configurar o ambiente para o ESP8266 no Arduino IDE se for a primeira vez que você usa o ESP8266.
  • Faça a ligação dos componentes conforme mostrado no diagrama.
  • Conecte a placa ESP8266 ao seu computador usando um cabo USB.
  • Abra o Arduino IDE no seu computador.
  • Escolha a placa ESP8266 correta, como (por exemplo, NodeMCU 1.0 (ESP-12E Module)), e a respectiva porta COM.
  • Abra o Library Manager clicando no ícone Library Manager na barra de navegação à esquerda do Arduino IDE.
  • Pesquise “WebSockets” e encontre a biblioteca WebSockets criada por Markus Sattler.
  • Clique no botão Install para instalar a biblioteca WebSockets.
Biblioteca WebSockets do ESP8266 NodeMCU
  • No Arduino IDE, crie um novo sketch e dê um nome a ele, por exemplo, newbiely.com.ino
  • Copie o código abaixo e abra com o Arduino IDE
/* * Este código de ESP8266 NodeMCU foi desenvolvido por pt.newbiely.com * Este código de ESP8266 NodeMCU é disponibilizado ao público sem nenhuma restrição. * Para tutoriais completos e diagramas de ligação, visite: * https://pt.newbiely.com/tutorials/esp8266/esp8266-controls-car-via-web */ #include <ESP8266WiFi.h> #include <ESP8266WebServer.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 D2 // The ESP8266 pin connected to the A-IA pin of the L9110S (Motor A) #define MOTOR_A_IB_PIN D5 // The ESP8266 pin connected to the A-IB pin of the L9110S (Motor A) #define MOTOR_B_IA_PIN D6 // The ESP8266 pin connected to the B-IA pin of the L9110S (Motor B) #define MOTOR_B_IB_PIN D7 // The ESP8266 pin connected to the B-IB pin of the L9110S (Motor B) const char* ssid = "YOUR_WIFI_SSID"; // CHANGE IT const char* password = "YOUR_WIFI_PASSWORD"; // CHANGE IT ESP8266WebServer server(80); // Web server on port 80 DIYables_ESP32_WebSocket* webSocket; void webSocketEvent(uint8_t num, WStype_t type, uint8_t* payload, size_t length) { switch (type) { case WStype_DISCONNECTED: Serial.printf("[%u] Disconnected!\n", num); break; case WStype_CONNECTED: { IPAddress ip = webSocket.remoteIP(num); Serial.printf("[%u] Connected from %d.%d.%d.%d\n", num, ip[0], ip[1], ip[2], ip[3]); } break; case WStype_TEXT: //Serial.printf("[%u] Received text: %s\n", num, payload); String angle = String((char*)payload); 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"); } break; } } void setup() { Serial.begin(9600); pinMode(MOTOR_A_IA_PIN, OUTPUT); pinMode(MOTOR_A_IB_PIN, OUTPUT); pinMode(MOTOR_B_IA_PIN, OUTPUT); pinMode(MOTOR_B_IB_PIN, OUTPUT); // Connect to Wi-Fi WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(1000); Serial.println("Connecting to WiFi..."); } Serial.println("Connected to WiFi"); // Initialize WebSocket server webSocket.begin(); webSocket.onEvent(webSocketEvent); // Serve a basic HTML page with JavaScript to create the WebSocket connection server.on("/", HTTP_GET, []() { Serial.println("Web Server: received a web page request"); String html = HTML_CONTENT; // Use the HTML content from the servo_html.h file server.send(200, "text/html", html); }); server.begin(); Serial.print("ESP8266 Web Server's IP address: "); Serial.println(WiFi.localIP()); } void loop() { // Handle client requests server.handleClient(); // Handle WebSocket events webSocket.loop(); // TO DO: Your code here } 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 no Arduino IDE:
    • 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 adiciona arquivo
    • Dê ao arquivo o nome index.h e clique no botão OK
    Arduino IDE 2 adiciona arquivo index.h
    • Copie o código abaixo e cole no index.h.
    /* * Este código de ESP8266 NodeMCU foi desenvolvido por pt.newbiely.com * Este código de ESP8266 NodeMCU é disponibilizado ao público sem nenhuma restrição. * Para tutoriais completos e diagramas de ligação, visite: * https://pt.newbiely.com/tutorials/esp8266/esp8266-controls-car-via-web */ const char *HTML_CONTENT = R"=====( <!DOCTYPE html> <html> <head> <title>ESP8266 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://newbiely.com/images/tutorial/up_inactive.png') no-repeat; background-size: contain; left: 200px; top: 0px; transform: translateX(-50%); } .button_down { background: url('https://newbiely.com/images/tutorial/down_inactive.png') no-repeat; background-size: contain; left:200px; bottom: 0px; transform: translateX(-50%); } .button_right { background: url('https://newbiely.com/images/tutorial/right_inactive.png') no-repeat; background-size: contain; right: 0px; top: 200px; transform: translateY(-50%); } .button_left { background: url('https://newbiely.com/images/tutorial/left_inactive.png') no-repeat; background-size: contain; left:0px; top: 200px; transform: translateY(-50%); } .button_stop { background: url('https://newbiely.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://newbiely.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://newbiely.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>ESP8266 - 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 no Arduino IDE para fazer o upload do código para o ESP8266
    • Abra o Serial Monitor
    • Veja o resultado no Serial Monitor.
    ∞
    Newbiely | Arduino IDE 2.3.8
    ──
    ☐
    ✕
    File
    Edit
    Sketch
    Tools
    Help
    Nodemcu 1.0 (ESP-12E Module)
    Newbiely.ino
    ···
    8 Serial.println("Hello World!");
    Output
    Serial Monitor
    Message (Enter to send message to 'Nodemcu 1.0 (ESP-12E Module)' on 'COM15')
    New Line
    9600 baud
    Connecting to WiFi... Connected to WiFi ESP8266 Web Server's IP address IP address: 192.168.0.5
    Ln 11, Col 1
    Nodemcu 1.0 (ESP-12E Module) 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:
    ESP8266 NodeMCU controla carro via navegador web
    • O código JavaScript da página web cria automaticamente a conexão WebSocket com o ESP8266.
    • 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 ESP8266, as imagens dos botões de controle NÃO são armazenadas no ESP8266. 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 de controle web.

    ※ 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 ESP8266, o Arduino IDE não atualizará o conteúdo HTML.
    • Para fazer o 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 ESP8266 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!