No post de hoje, nós iremos fazer um carrinho de controle remoto controlado por quatro push buttons!
O projeto consiste em duas partes: o Emissor e o Receptor. Para o emissor, nós iremos utilizar apenas um ESP8266 e quatro push buttons. Para o receptor, nós vamos usar um ESP32, que será conectado a um Arduino UNO para o controle dos motores.
Para fazer a transmissão dos dados sem fio entre os ESPs, nós iremos utilizar o protocolo ESP-NOW, desenvolvido pela Espressif.
No envio dos dados, o ESP8266 se conecta ao ESP32 por meio do endereço MAC do esp32, e envia os dados (Frente, Traz, Esquerda, Direita). Esses dados, quando recebidos pelo ESP32, serão transmitidos para o Arduino UNO por meio do protocolo de Master/Slave via I₂C.

O código que deve ser carregado no ESP8266 é o seguinte:
//inclui as bibliotecas
#include <espnow.h>
#include <ESP8266WiFi.h>
//define em quais portas os botões serão conectados
#define botaoesq D5
#define botaobaixo D6
#define botaocima D7
#define botaodir D2
bool esq = 0;
bool dir = 0;
bool cima = 0;
bool baixo = 0;
// é necessario mudar o endereço de acordo com o endereço do seu ESP32
uint8_t receiverMacAddress[] = {0xC0,0x49,0xEF,0xE4,0xD8,0xA8}; //C0:49:EF:E4:D8:A8
struct PacketData
{
byte esq;
byte dir;
byte cima;
byte baixo;
};
PacketData data;
// callback quando os dados são enviados
void OnDataSent(uint8_t *mac_addr, uint8_t sendStatus)
{
Serial.print("Status dos dados enviados: ");
if (sendStatus == 0) {
Serial.println("Envio ok!");
}
else {
Serial.println("Falha no envio!");
}
}
void setup()
{
Serial.begin(115200);
pinMode(botaoesq, INPUT_PULLUP);
pinMode(botaodir, INPUT_PULLUP);
pinMode(botaocima, INPUT_PULLUP);
pinMode(botaobaixo, INPUT_PULLUP);
WiFi.mode(WIFI_STA);
// Init ESP-NOW
if (esp_now_init() != 0) {
Serial.println("Erro ao inicializar o ESP-NOW");
return;
}
esp_now_set_self_role(ESP_NOW_ROLE_CONTROLLER);
esp_now_register_send_cb(OnDataSent);
esp_now_add_peer(receiverMacAddress, ESP_NOW_ROLE_SLAVE, 1, NULL, 0);
}
void loop()
{
if (digitalRead(botaoesq) == LOW) // Se o botão for pressionado
{
esq = 1; //define a variável para verdadeira
}
else{ //caso contrário
esq = 0; //define a variável para falsa
}
if (digitalRead(botaodir) == LOW) // Se o botão for pressionado
{
dir = 1; //define a variável para verdadeira
}
else{ //caso contrário
dir = 0; //define a variável para falsa
}
if (digitalRead(botaocima) == LOW) // Se o botão for pressionado
{
cima = 1; //define a variável para verdadeira
}
else{ //caso contrário
cima = 0; //define a variável para falsa
}
if (digitalRead(botaobaixo) == LOW) // Se o botão for pressionado
{
baixo = 1; //define a variável para verdadeira
}
else{ //caso contrário
baixo = 0; //define a variável para falsa
}
data.esq = esq;
data.dir = dir;
data.cima = cima;
data.baixo = baixo;
Serial.print("esq: ");
Serial.println(esq);
Serial.print("dir: ");
Serial.println(dir);
Serial.print("cima: ");
Serial.println(cima);
Serial.print("baixo: ");
Serial.println(baixo);
uint8_t result = esp_now_send(receiverMacAddress, (uint8_t *) &data, sizeof(data));
delay(50);
}O código que deve ser carregado no ESP32 é o seguinte:
//inclui as bibliotecas
#include <esp_now.h>
#include <WiFi.h>
#include <Wire.h>
const int slaveAdress = 0x08; // endereço da placa UNO na relação master/slave
#define SIGNAL_TIMEOUT 10000
unsigned long lastRecvTime = 0;
struct PacketData
{
byte esq;
byte dir;
byte cima;
byte baixo;
};
PacketData receiverData;
// funçao callback quando os dados sao recebidos
void OnDataRecv(const uint8_t * mac, const uint8_t *incomingData, int len)
{
if (len == 0)
{
return;
}
memcpy(&receiverData, incomingData, sizeof(receiverData));
// envia os dados para o UNO pela comunicação master/slave
if(receiverData.cima == 1){
Wire.beginTransmission(slaveAdress);
Wire.write("1");
Wire.endTransmission();
}
if(receiverData.baixo == 1){
Wire.beginTransmission(slaveAdress);
Wire.write("2");
Wire.endTransmission();
}
if(receiverData.dir == 1){
Wire.beginTransmission(slaveAdress);
Wire.write("3");
Wire.endTransmission();
}
if(receiverData.esq == 1){
Wire.beginTransmission(slaveAdress);
Wire.write("4");
Wire.endTransmission();
}
lastRecvTime = millis();
}
void setup()
{
Wire.begin();
Serial.begin(115200);
WiFi.mode(WIFI_STA);
// Init ESP-NOW
if (esp_now_init() != ESP_OK)
{
Serial.println("Erro inicializando ESP-NOW");
return;
}
esp_now_register_recv_cb(OnDataRecv);
}
void loop()
{
//Checa a perda de sinal
unsigned long now = millis();
if ( now - lastRecvTime > SIGNAL_TIMEOUT )
{
Serial.println("sinal perdido");
}
}O código que deve ser carregado no Arduino UNO é o seguinte:
//inclui a biblioteca
#include "Wire.h"
//define o endereço para o Master/Slave
const int myAdress = 0x08;
//define onde os pinos da ponte H estão conectados no arduino
int pino1 = 4;
int pino2 = 5;
int pino3 = 6;
int pino4 = 7;
//variaveis para o controle dos dados recebidos
int dados = 0;
bool frente = false;
bool tras = false;
bool esquerda = false;
bool direita = false;
void setup(){
Serial.begin(9600);
Wire.begin(myAdress); //inicia o protocolo master/slave
Wire.onReceive(receiveEvent);
//define os pinos como saida
pinMode(pino1, OUTPUT);
pinMode(pino2, OUTPUT);
pinMode(pino3, OUTPUT);
pinMode(pino4, OUTPUT);
}
void loop(){
Serial.print("DADOS: ");
Serial.println(dados);
// condições para o controle do motor de acordo com os dados recebidos dos botões
if (dados == 51) {
Serial.println("RECEBIDO 1");
direita = true ; // se a placa receber que o botão de cima está pressionado, ele manda o robô ir para frente
}
if (dados == 49){
Serial.println("RECEBIDO 2");
tras = true; // se a placa receber que o botão de baixo está pressionado, ele manda o robô ir para trás
}
if (dados == 52){
Serial.println("RECEBIDO 3");
esquerda = true; // se a placa receber que o botão da direita está pressionado, ele manda o robô ir para direita
}
if(dados == 50){
Serial.println("RECEBIDO 4");
frente = true ; // se a placa receber que o botão da esquerda está pressionado, ele manda o robô ir para esquerda
}
if(tras == true){
vaitras();
tras = !tras;
dados = 0;
}
else if(frente == true){
vaifrente();
frente = !frente ;
dados = 0;
}
else if(esquerda == true){
vaiesquerda();
esquerda = !esquerda ;
dados = 0;
}
else if(direita == true){
vaidireita();
direita = !direita;
dados = 0;
}
}
void receiveEvent(int howMany) {
// verifica se existem dados para serem lidos no barramento I2C
if (Wire.available()) {
char received = Wire.read();
Serial.println(received);
dados = received;
}
int dados = Wire.read();
}
void vaifrente(){ //responsável por mandar o robo para frente
digitalWrite(pino1, HIGH);
digitalWrite(pino2, LOW);
digitalWrite(pino3, HIGH);
digitalWrite(pino4, LOW);
delay(200);
digitalWrite(pino1, HIGH);
digitalWrite(pino2, HIGH);
digitalWrite(pino3, HIGH);
digitalWrite(pino4, HIGH);
}
void vaitras(){ //responsável por mandar o robo para trás
digitalWrite(pino1, LOW);
digitalWrite(pino2, HIGH);
digitalWrite(pino3, LOW);
digitalWrite(pino4, HIGH);
delay(200);
digitalWrite(pino1, HIGH);
digitalWrite(pino2, HIGH);
digitalWrite(pino3, HIGH);
digitalWrite(pino4, HIGH);
}
void vaidireita(){ //responsável por mandar o robo para esquerda
digitalWrite(pino3, LOW);
digitalWrite(pino4, LOW);
digitalWrite(pino1, LOW);
digitalWrite(pino2, HIGH);
delay(200);
digitalWrite(pino1, HIGH);
digitalWrite(pino2, HIGH);
digitalWrite(pino3, HIGH);
digitalWrite(pino4, HIGH);
}
void vaiesquerda(){ //responsável por mandar o robo para direita
digitalWrite(pino3, LOW);
digitalWrite(pino4, HIGH);
digitalWrite(pino1, HIGH);
digitalWrite(pino2, HIGH);
delay(200);
digitalWrite(pino1, HIGH);
digitalWrite(pino2, HIGH);
digitalWrite(pino3, HIGH);
digitalWrite(pino4, HIGH);
}Caso queira entender mais sobre o protocolo ESP-NOW, acesse o post abaixo:
https://blog.eletrogate.com/esp-now-comunicacao-sem-fio-entre-esp32s/
É necessário mudar o endereço Mac no código do emissor de acordo com o endereço MAC do seu esp32.

No meu caso, o endereço MAC do meu ESP32 é C0:49:EF:E4:D8:A8
Para descobrir o seu endereço MAC, basta carregar o seguinte código no seu esp32:
/******************************************************************************
ESP-NOW: Comunicação entre ESP32s
Sketch Obtendo endereço MAC do ESP32
Criado em 08 de Dezembro de 2022
por Michel Galvão
Eletrogate - Loja de Arduino \\ Robótica \\ Automação \\ Apostilas \\ Kits
https://www.eletrogate.com/
******************************************************************************/
// Inclusão das bibliotecas
#include <WiFi.h>
void setup() {
Serial.begin(115200); // configurada a taxa de transferência em 115200 bits por segundo para a transmissão serial
WiFi.mode(WIFI_MODE_STA); // configura o WIFi para o Modo de estação WiFi
Serial.print("Endereço MAC: ");
Serial.println(WiFi.macAddress()); // retorna o endereço MAC do dispositivo
while(1); // loop infinito
}
void loop() {}Esse código foi feito pelo Michel Galvão lá no post sobre ESP-NOW.
Diagrama do Emissor:

Diagrama do Receptor:

*É necessário remover o jumper da alimentação do circuito lógico da ponte H
Caso tenha interesse em mudar a alimentação do seu projeto da forma adequada, acesse o post abaixo:
|
A Eletrogate é uma loja virtual de componentes eletrônicos do Brasil e possui diversos produtos relacionados à Arduino, Automação, Robótica e Eletrônica em geral.
Tenha a Metodologia Eletrogate dentro da sua Escola! Conheça nosso Programa de Robótica nas Escolas!