IurkivTech

EletronicaLogo

Troca de dados por WIFI entre ESP32 e um software em C#

Neste projeto realizo a comunicação e troca de informações via WIFI entre ESP32 e um software em um computador em uma rede local.

Clique AQUI para fazer download dos arquivos.

ESP32

Configuro o ESP32 como o servidor com IP local fixo. O endereço escolho um qualquer que seja válido no range do roteador.
O ESP32 aguarda um cliente (software) se conectar. Após conectado ele apenas retorna a string que recebe do cliente com uma mensagem de confirmação.

/*
  Comunicação e controle WIFI entre software e ESP32-WROOM
  Feito como exemplo para treinar e ter como base para comunicação e controle WIFI.
  ESP32 está no modo servidor e programa se conecta como cliente.
  ESP32 tem IP fixo

  Compilador: Arduino IDE 2.2.1
  Autor: Anderson Iurkiv
  Janeiro 2024
*/

// Bibliotecas
#include <WiFi.h>

// Definições para a configuração do IP
IPAddress ip(192,xxx,xxx,xxx);        // IP do ESP. Tem de colocar um IP válido na faixa do roteador.
IPAddress gateway(xxx,xxx,xxx,xxx);   // IP do servidor.
IPAddress subnet(xxx,xxx,xxx,xxx);    // Mascara de rede. Colocar a mesma do roteador.

// Variáveis
const char *ssid = "NomeDaRede";       // Inserir aqui o nome da rede WIFI.
const char *password = "SenhaDaRede";  // Inserir aqui a senha da rede WIFI.
int baudRate = 115200;                  // Velocidade da comunicação.

// Objetos e variáveis
WiFiServer server(80);                  // Declaração do servidor. Parâmetro é o número da porta.
WiFiClient client;                      // Declaração do cliente para aceitar a conexão.
String strRead = "";                    // String de leitura
String strWrite = "";                   // String de escrita

// Declaração de funções
void servidor_escuta_responde();        // Função que controla o recebimento e envio de mensagens.
                                
void setup() 
{
  Serial.begin(baudRate);               // Inicia a serial
}

// Loop infinito
void loop() 
{
  if(WiFi.status() != WL_CONNECTED)     // Aguarda conexão
  {
    Serial.println("\nWiFi desconectado");
    Serial.print("Conectando-se em ");
    Serial.println(ssid);
    WiFi.config(ip, gateway, subnet);   // Configurando o WIFI.
    WiFi.begin(ssid, password);         // Conectando a rede

    while(WiFi.status() != WL_CONNECTED)  // Aguarda conexão.
    {
      delay(1000);                      // Verifica conexão a cada 1s
      Serial.print(".");
    }

    Serial.println("\nWiFi conectado");
    Serial.print("IP: ");
    Serial.println(WiFi.localIP());     // Mostra o endereço IP
    server.begin();                     // Inicializa modo servidor
  }
  servidor_escuta_responde();           // Chama a função de controle das mensagens.
}


/*  Função servidor_escuta_responde()
    Aceita a conexão somente de 1 cliente.
    Recebe uma mensagem, trata e retorna.
*/
void servidor_escuta_responde()
{
  int posRead = 0;
  char aux;
  client = server.available();                        // Aguarda cliente conectar.
  
  if(client)                                          // Se cliente conectado, faça
  {
    Serial.println("Cliente conectado.");
    while(client.connected())                         // Permanece em loop enquanto conectado.
    {
      if(client.available())                          // Se existir dados para ler, faça
      {
        strRead = client.readString();                // Lê uma string de bytes
        strWrite = "Mensagem recebida: " + strRead;   // Monta a string de retorno.
        client.print(strWrite);                       // Retorna a string por WIFI
        Serial.println(strWrite);                     // Retorna a string por Serial
        strRead = "";                                 // Limpa buffer
        strWrite = "";
      }
    }
    client.stop();                                    // Finaliza conexão.
    Serial.println("Cliente desconectado.");
  }
}

Software em C#

Configuro o software como cliente.
Criei uma interface simples para digitar as informações de conexão (IP e Porta), um campo para digitar a string de envio e um campo que mostra a string recebida.

Abaixo o código do software que criei em C#.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

/*
 *   Comunicação e controle WIFI entre software e ESP32-WROOM
 *   Feito como exemplo para treinar e ter como base para comunicação e controle WIFI.
 *   Software é configurado como cliente.
 *   
 *   Compilador: Visual Studio Community 2022 - 17.6.5
 *   Autor: Anderson Iurkiv
 *   Janeiro 2024
 */
namespace WifiClient
{
    public partial class Form1 : Form
    {
        // Objetos e variáveis
        private TcpClient client;
        private NetworkStream stream;
        private bool conectado = false;

        public Form1()
        {
            InitializeComponent();

            // Iniciando variáveis globais.
            textBoxIP.Text = "192.168.15.101:80";
            textBoxTempo.Text = "5000";
            textBoxRecebido.Enabled = false;
            client = null;
            stream = null;
        }

        /*  Evento buttonConectar_Click()
         *  Controla a ação de clicar no botão conectar. 
         */
        private void buttonConectar_Click(object sender, EventArgs e)
        {
            // Se não estiver conectado, conecta.
            if (!conectado)
            {
                // Só tenta conectar se o campo com o IP de conexão não for nulo.
                if (!string.IsNullOrEmpty(textBoxIP.Text))
                {
                    // Configura botões, campos ...
                    client = new TcpClient();
                    textBoxIP.Enabled = false;
                    textBoxTempo.Enabled = false;
                    buttonConectar.Enabled = false;
                    buttonConectar.Text = "Conectando";
                    string[] strCon = textBoxIP.Text.Split(':');            // Separa a string em IP e porta
                    client.Connect(strCon[0], Convert.ToInt32(strCon[1]));  // Conecta
                    // Se conectar
                    if (client.Connected)
                    {
                        stream = client.GetStream();
                        buttonConectar.Enabled = true;
                        buttonConectar.Text = "Desconectar";
                        conectado = true;
                    }
                    // Se não conectar, avisa e reconfigura botões e campos.
                    else
                    {
                        buttonConectar.Enabled = true;
                        buttonConectar.Text = "Conectar";
                        textBoxTempo.Enabled = true;
                        textBoxRecebido.Text = "Erro ao conectar.";
                        client.Close();
                        client = null;
                    }   
                }
            }
            // Se não, desconecta
            else
            {
                buttonConectar.Enabled = false;
                buttonConectar.Text = "Desconectando";
                client.Close();
                stream.Close();
                client = null;
                stream = null;
                textBoxIP.Enabled = true;
                buttonConectar.Enabled = true;
                textBoxTempo.Enabled = true;
                buttonConectar.Text = "Conectar";
                conectado = false;
            }
        }

        /*  Evento buttonEnviar_Click()
         *  Controla a ação de enviar dados. 
         */
        private void buttonEnviar_Click(object sender, EventArgs e)
        {
            // Só envia se estiver conectado
            if (conectado)
            {
                byte[] dados = Encoding.ASCII.GetBytes(textBoxEnviar.Text);
                stream.Write(dados, 0, dados.Length);
                textBoxEnviar.Clear();
                textBoxRecebido.Clear();

                // Abre a função que aguarda o recebimento da mensagem em outra thread.
                Task.Run(() => aguarda_receber_dados(Convert.ToInt64(textBoxTempo.Text)));
            }
        }

        /*  Função aguarda_receber_dados()
         *  Aguarda é retorno da mensagem até o tempo configurado no textBoxTempo 
         */
        private void aguarda_receber_dados(long tempo)
        {
            bool recebido = false;
            Stopwatch stopWatch = new Stopwatch();
            stopWatch.Start();
            while(stopWatch.ElapsedMilliseconds < tempo)
            {
                if (stream.DataAvailable)
                {
                    stopWatch.Stop();
                    // Como abro a função em uma thread, tenho de usar delegate para alterar o conteúdo do textBox
                    Invoke(new Action (() => atualiza_textBoxRecebido(stopWatch.ElapsedMilliseconds)));
                    recebido = true;
                    break;
                }
                Thread.Sleep(100);
            }
            if(!recebido)
            {
                stopWatch.Stop();
                Invoke(new Action(() => textBoxRecebido.Text = "Tempo expirou"));
            }
        }

        /*  Função atualiza_textBoxRecebido()
         *  Altera o conteúdo do textBoxRecebido.
         *  Recebe como parâmentro o tempo de retorno em ms
         */
        private void atualiza_textBoxRecebido(long tempo)
        {
            byte[] dados = new byte[100];
            int tam = stream.Read(dados, 0, 100);
            string str = "Tempo: " + tempo.ToString() + " ms - " + Encoding.ASCII.GetString(dados, 0, tam);
            textBoxRecebido.Text = str;
        }

        /*  Função Form1_FormClosing()
         *  Garante que desconecta antes de fechar o programa.
         */
        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (client != null)
                if (client.Connected)
                    client.Close();
        }

        /*  Função buttonLimpar_Click()
         *  Limpa o textBoxRecebido
         */
        private void buttonLimpar_Click(object sender, EventArgs e)
        {
            textBoxRecebido.Clear();
        }
    }
}
Demonstração do funcionamento do sistema

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *

Rolar para cima