Manual
do
Maker
.
com
No artigo "Socket server com Python" vimos como implementar a ferramenta de teste para desenvolvimento. Não só o server, mas implementamos também o client, que nos auxiliará nos artigos sobre socket server com ESP32 e ESP8266. Nesse artigo veremos como fazer um socket client com ESP32, utilizando uma quantidade ínfima de linhas de código, e tendo rapidamente um bom resultado para uma comunicação leve.
Esse código é para a prova de conceito, então use-o como base para a implementação, mas continue a leitura para ver um outro exemplo.
#include <WiFi.h>
#define SSID "suaRede"
#define PASSWD "suaSenha"
unsigned long int last_time = millis();
const uint16_t port = 8888;
const char * host = "192.168.10.100";
void setup(){
Serial.begin(9600);
WiFi.begin(SSID,PASSWD);
while (WiFi.status() != WL_CONNECTED){delay(100);}
Serial.print("IP: ");
Serial.println(WiFi.localIP());
}
void loop(){
WiFiClient client;
if (!client.connect(host, port)) {
Serial.println("Falha de conexao");
delay(1000);
return;
}
Serial.println("Conectado!");
client.print("Hell low word");
Serial.println("Desconectando...");
client.stop();
Serial.print("Aguardando 15 segundos para proximo envio:");
while ((millis()-last_time) < 15000){delay(100);}
last_time = millis();
}
Nesse exemplo forçamos uma rotina padrão que prende o fluxo em um loop. Nada mal para prova de conceito, mas tratando-se de um ESP32, podemos criar uma task para ser executada somente quando houver a necessidade da comunicação socket. Com isso, não precisamos temporizar e mandar periodicamente, servindo então como um processo de alarme.
Para tal, basta criar uma função antes de setup():
void vSocket(void *pvParameters){
WiFiClient client;
if (!client.connect(host, port)){
Serial.println("Falha de conexao");
delay(1000);
vTaskDelete(NULL);
}
Serial.println("Conectado!");
client.print("Hell low word");
Serial.println("Desconectando...");
client.stop();
vTaskDelete(NULL);
}
Essa tarefa faz o envio e se encerra. Para executá-la, instancie-a no momento em que for necessário. Para exemplo, ela será executada apenas uma vez ao iniciar, sendo chamada dentro da função setup():
void setup(){
//...tudo o que for em setup, então a última linha...
xTaskCreatePinnedToCore(vSocket,"vSocket",10000,NULL,0,NULL,0);
}
Mas podemos iniciar a task em qualquer lugar, dentro da função loop() ou a partir de outra task.
Para testar esse código, podemos abrir um socket server com python utilizando esse código:
import socket
HOST = '192.168.1.200'
PORT = 1234
tcp = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
orig = (HOST, PORT)
tcp.bind(orig)
tcp.listen(1)
while True:
con, client = tcp.accept()
print( 'Client: ', client)
while True:
msg = con.recv(6)
if not msg: break
#print( client, msg)
for i in range(len(msg)):
print(chr(msg[i]),end=' ')
print(" ")
print( 'Closing connection to: ', client)
con.close()
Troque o IP pelo IP do computador que estiver rodando o script.
Uma dica nesse código é em relação à função print(). Repare que como é lido e impresso byte a byte, é necessário manter tudo na mesma linha no output. Para não ter um line feed a cada byte, passamos o parâmetro end=' ' ao final da função.
Essa tarefa pode ler o valor de uma variável global ou o valor pode ser passado via parâmetro. Se gostaria de saber como passar parâmetros em tasks com ESP32, recomendo a leitura desse artigo.
Os artigos em torno desse devem todos ser relacionados a comunicação socket server e client com ESP32, ESP8266 e Python, para fazer a comunicação de teste a partir do computador. Dê uma verificada nos artigos anteriores e posteriores para mais conteúdo sobre o tema!
Para ver o exemplo dessa comunicação e a utilização de parâmetros na task, acompanhe em nosso canal DobitaobyteBrasil no Youtube - agora com bem mais qualidade. Se não é inscrito e puder fazê-lo, será de imensa alegria tê-lo conosco.
Clique aqui para ir diretamente ao vídeo desse artigo.
Caso ainda tenha dúvidas de como iniciar a task, eis um exemplo simples, usando a função loop para fazer a repetição da chamada. Claro que se for pra fazer assim é mais simples criar uma função e executá-la, mas é só pra exemplificar:
#include <Arduino.h>
#include <WiFi.h>
#include "heltec.h"
#define OLED_UPDATE_INTERVAL 500
const char* ssid = "SuhankoFamily";
const char* password = "fsjmr112";
const char* host = "192.168.1.200";
const uint16_t port = 1234;
//Opção 2: task
void vSocket(void *pvParameters){
WiFiClient client;
if (client.connect(host, port) > -1) {
Serial.println("Conectado!");
client.print("Hell low word");
Serial.println("Desconectando...");
client.stop();
vTaskDelete(NULL);
}
else{
client.stop();
vTaskDelay(pdMS_TO_TICKS(2000));
}
}
void setupWIFI(){
Heltec.display->clear();
Heltec.display->drawString(0, 0, "Connecting...");
Heltec.display->drawString(0, 10, String(ssid));
Heltec.display->display();
WiFi.disconnect(true);
delay(1000);
WiFi.mode(WIFI_STA);
//WiFi.onEvent(WiFiEvent);
WiFi.setAutoConnect(true);
WiFi.setAutoReconnect(true);
//WiFi.setHostname(HOSTNAME);
WiFi.begin(ssid, password);
byte count = 0;
while(WiFi.status() != WL_CONNECTED && count < 10)
{
count ++;
delay(500);
Serial.print(".");
}
Heltec.display->clear();
if(WiFi.status() == WL_CONNECTED){
Heltec.display->drawString(0, 0, "Conectado");
Heltec.display->drawString(0, 10, "Ate logo");
Heltec.display->display();
delay(5000);
Heltec.display->clear();
Heltec.display->display();
}
else{
Heltec.display->drawString(0, 0, "Connect False");
Heltec.display->display();
}
Heltec.display->clear();
}
void setup(){
pinMode(0,INPUT_PULLDOWN);
Heltec.begin(true /*DisplayEnable Enable*/, false /*LoRa Disable*/, true /*Serial Enable*/);
pinMode(25, OUTPUT);
while (!Serial) {
vTaskDelay(pdMS_TO_TICKS(10));
}
setupWIFI();
//se escolhida a opção 2, a primeira chamada pode ser no setup:
//
}
void loop() {
xTaskCreatePinnedToCore(vSocket,"vSocket",10000,NULL,0,NULL,0);
vTaskDelay(pdMS_TO_TICKS(4000));
}
Até o próximo artigo!
Revisão: Ricardo Amaral de Andrade
Inscreva-se no nosso canal Manual do Maker no YouTube.
Também estamos no Instagram.
Autor do blog "Do bit Ao Byte / Manual do Maker".
Viciado em embarcados desde 2006.
LinuxUser 158.760, desde 1997.