Neste artigo vamos falar sobre
o ESP8266-201. Sei que pouca gente conhece essa versão, mas eu gosto bastante
por conta de sua possibilidade de conexão de antena. Fizemos, então, uma
montagem para medir a intensidade de sinal de WiFi. Para isso, tornamos o ESP201
um Access Point. Comunicamos remotamente um segundo ESP8266-201 client com
servidor e medimos a força de sinal entre eles (dbm).
Pegamos, portanto, dois ESP201
que possuem conector PigTail e ligamos a uma antena. Fizemos um programa usando
Socket TCP que envia um pacote e recebe a potência em dbm (decibel miliwatt).
Isso é bastante útil, por exemplo, quando você está automatizando sua
residência e não sabe se o ESP utilizado vai chegar até o ponto de distância
pretendido. Com a montagem de hoje será possível descobrir isso na prática.
Você ainda pode usar esse mesmo exemplo com o ESP01.
A utilização da comunicação
Socket também será abordada hoje, a qual possui o Station e o Client.
Recursos usados
2 ESP 8266-201;
2 Displays Oled;
2 Antenas para módulo WiFi do
ESP 2,4G;
2 botões;
2 porta pilhas;
4 pilhas 8800mA;
Jumpers.
ESP8266-201 Pinout
Aqui temos o Pinout do ESP201
que não é tão comum, mas fácil de ser encontrado na internet. Além do conector
PigTail, ele tem mais IO.
Ligação de pinos
Aqui temos o esquema da
montagem, o qual basta seguir, pois está bem simples.
Distância medida
Neste mapa marquei o ponto 0 e
sai caminhando em linha reta para
identificar a distância alcançada entre os dois ESPs. Chegamos a
aproximadamente 120 metros entre as duas antenas. Em um primeiro teste que
fizemos, no ano passado, chegamos a alcançar 242 metros. No entanto, nesta nova
tentativa chegamos a somente 120m. O motivo desta mudança? Não sei, mas tenho
uma teoria. Acho que o ar aqui onde fazemos os teste está mais sujo, com muita
conexão WiFi, o que deve estar atrapalhando. Mas, claro que pode ser outra
coisa que desconheço já que o WiFi é um terreno movediço. A minha dica aqui é
que vocês usem antena externa, pois faz muita diferença e você vai bem mais
longe.
O menor sinal que
identificamos é o -96dbm. Se chegar a -97dbm, então, cai a comunicação. Esse
número identificamos na prática, muito melhor que em contas.
Circuito
Na nossa montagem nós temos o
AP, que funciona como servidor, e o Station, que é o Client. O client envia
os dados ao server, que são exibidos nos displays de ambos. Nas duas partes, os
ESP201 estão ligados em antenas. No lado traseiro nós instalamos duas baterias
de lítio em cada parte. Quanto mais paralelas as antenas estiverem melhor será
a propagação do sinal. Por fim, no Client um led pisca a cada envio de pacote
ao AP.
Código Servidor (Access Point)
Código Server - Includes e
configurações
Aqui
tratamos do código do server e, o que o server faz? Primeira coisa: ele é o AP,
ou seja, o acesso. Ele inicia como Access Point e fica esperando o cliente
conectar nele. Ele fica em listen e quando ele chegar uma string ele vai e
imprime na tela do display Oled.
Nesta parte do código
incluímos as libs, criamos o objeto, definimos o IP local, porta, subnet e
criamos ainda o WiFiserver, que tem número do porte do Socket marcado em 5000.
#include <ESP8266WiFi.h> //lib para conectar o wifi do ESP201 #include <U8x8lib.h> //lib usada para comunicação com o display #include <SPI.h> //protocolo síncrono de dados serial //SCL (ou serial clock) indica o sinal do clock, que é enviado do servidor para todos os clientes. Todos os sinais SPI são síncronos com este sinal //SDA (ou serial data) é o pino que efetivamente transfere os dados //O 3º parameto deve ser um inteiro, ele nada mais é do que o pino do reset. 'U8X8_PIN_NONE' é usado por que este pino não está conectado U8X8_SSD1306_128X32_UNIVISION_SW_I2C u8x8(SCL, SDA, U8X8_PIN_NONE); //ip da rede local IPAddress local_IP(192, 168, 10, 11); //gateway da rede local IPAddress gateway(192, 168, 10, 10); //subnet é uma divisão lógica da rede local IPAddress subnet(255, 255, 255, 0); //define servidor na porta 5000 do protocolo TCP WiFiServer servidor(5000);
Código Server - Setup
Aqui configuramos o pino do
led, inicializamos o display, configuramos a fonte de texto e fazemos uma
função para escrever no display. Configuramos ainda o modo como Access Point.
void setup() { //seta o pino do led pinMode(13, OUTPUT); //inicializa display u8x8.begin(); //desativa o modo de economia de energia do display u8x8.setPowerSave(0); //configura a fonte do texto que será exibido u8x8.setFont(u8x8_font_chroma48medium8_r); //aguarda 5 segundos delay(5000); //escreve no display "Definindo modo" escreva("Definindo modo", true, 1000, false); //configura modo como access point WiFi.mode(WIFI_AP); //escreve no display "Pronto" escreva("Pronto!", false, 1000, true);
Na sequência, determinamos
que, enquanto a interface de rede do Access Point não for configurada será
exibido um ponto, ou seja, “.”. Também definimos o que será escrito no display
para outras situações e os parâmetros da rede, como nome e senha, sendo que
WiFi_Range é o nome da rede que o Client vai conectar.
//escreve no display "Definindo AP" escreva("Definindo AP", true, 1000, false); //enquanto a interface de rede do access point não for configurada, exibe "." while (!(WiFi.softAPConfig(local_IP, gateway, subnet))) escreva(".", false, 100, false); //escreve no display "Definindo AP" escreva("Pronto!", false, 1000, true); //escreve no display "Definindo rede" escreva("Definindo rede", true, 1000, false); //enquanto a rede não for definida, escreve "." //parametros: WiFi.softAP(nomeDoAccessPoint, senhaRede, canal, redeVisivel) //canal: canal usado pelo ESP, pode ser do 1 ao 11 //redeVisivel: a rede pode ou não aparecer para outros serviços while (!(WiFi.softAP("WiFi_Range", "12341234", 6, false))) escreva(".", false, 100, false); //escreve no display "Definindo AP" escreva("Pronto!", false, 1000, true);
Nesta parte tratamos no
display do endereço de IP, entre outros. Inicializamos o servidor sem delay na
comunicação TCP.
//escreve no display "Endereco IP" escreva("Endereco IP", true, 1000, false); //escreve no display o ip do servidor escreva(WiFi.softAPIP().toString(), false, 1000, true); //escreve no display "Iniciando" escreva("Iniciando", true, 10, false); //escreve no display "servidor" escreva("servidor...", true, 1000, false); //inicializa servidor servidor.begin(); //define servidor para trabalhar sem delay //caso seja setado como true, tem o intuito de reduzir o tráfego TCP / IP de pequenos pacotes servidor.setNoDelay(true); //escreve no display "Pronto!" escreva("Pronto!", false, 1000, true); //escreve no display "Aguardando STA" escreva("Aguardando STA", true, 1000, false); }
Código Server – Loop
O código trabalha nesta parte
sobre a conexão entre servidor e Client. Instanciando o WiFiClient temos o
objeto que vai guardar todas as propriedades do cliente.
void loop() { //enquanto a quantidade de estações conectadas no servidor for zero //ou seja, ninguém conectou ainda while (WiFi.softAPgetStationNum() == 0) { //aguarda 1 segundo delay(1000); //se alguém conectou if (WiFi.softAPgetStationNum() != 0) { //exibe mensagem escreva("STA conectada!", true, 1000, false); } } //obtém o cliente que está conectado ao servidor WiFiClient client = servidor.available();
Em seguida configuramos
suposições com o cliente e definimos uma string para exibição da força do sinal
da estação. Limpamos o buffer de chegada, fechamos a conexão e apagamos o led.
if (client) { //limpa tela do display u8x8.clear(); //acende o led digitalWrite(13, HIGH); //enquanto o cliente estiver conectado while (client.connected()) { //se houver dados, leia if (client.available()) { //recebe dados do cliente String dbmSTA = client.readStringUntil('\n'); //exibe a força do sinal da estação escreva("STA: " + dbmSTA, true, 1000, true); //espera até que todos os caracteres de saída no buffer tenham sido enviados client.flush(); } } //aguarda envio delay(1); // fecha conexão client.stop(); //apaga led digitalWrite(13, LOW); } }
Código Server - Função
“escreva”
Sobre a função “escreva”,
tenho sempre a string que vou escrever no display. Nela também tratamos do
intervalo e ainda tenho um comando para caso queira limpar a tela. Essa mesma
função uso no cliente também.
//escreve no display de acordo com os parametros //nl = pular linha //intervalo = tempo enviado para o delay //limpar = limpa a tela do display void escreva(String texto, boolean nl, int intervalo, boolean limpar) { //se deseja pular linha no display, então pula if (nl) u8x8.println(texto); else //se não, exibe texto sem pular linha u8x8.print(texto); //aguarda o intervalo passado por parametro delay(intervalo); //se deseja limpar o display, então limpa if (limpar) u8x8.clear(); }
Código Cliente (Estação)
Código Client- Includes e
configurações
Agora sobre o cliente temos
as inclusões das libs, definições do display e criação de uma instância da
classe ESP8266WiFiMulti. Também criamos uma instância da classe IPAddress e
definimos o IP do servidor.
#include <ESP8266WiFi.h> //lib para conectar o wifi do ESP201 #include <ESP8266WiFiMulti.h>//lib para as funções addAP e run #include <U8x8lib.h> //lib usada para comunicação com o display #include <SPI.h> //protocolo síncrono de dados serial //SCL (ou serial clock) indica o sinal do clock, que é enviado do servidor para todos os clientes. Todos os sinais SPI são síncronos com este sinal //SDA (ou serial data) é o pino que efetivamente transfere os dados //O 3º parameto deve ser um inteiro, ele nada mais é do que o pino do reset. 'U8X8_PIN_NONE' é usado por que este pino não está conectado U8X8_SSD1306_128X32_UNIVISION_SW_I2C u8x8(SCL, SDA, U8X8_PIN_NONE); //cria uma instância da classe ESP8266WiFiMulti ESP8266WiFiMulti WiFiMulti; //Criar uma instância da classe IPAddress e define o ip do servidor IPAddress local_IP(192, 168, 10, 110);
Código Client – Setup
No Setup do cliente também
definimos o pino do led, inicializamos o display e configuramos o modo como
“Estação”.
void setup() { //define pino Led pinMode(pinoLed,OUTPUT); //inicializa o display u8x8.begin(); //desativa o modo de economia de energia do display u8x8.setPowerSave(0); //configura a fonte do texto que será exibido u8x8.setFont(u8x8_font_chroma48medium8_r); //aguarda 1 segundo delay(1000); //escreve no display "Definindo modo" escreva("Definindo modo", true, 1000, false); //configura modo como estação WiFi.mode(WIFI_STA); //escreve no display "Pronto!" escreva("Pronto!", false, 1000, true);Seguimos configurando parâmetros e também definimos nome da rede e senha, entre outros comandos.
//escreve no display "Definindo rede" escreva("Definindo rede", true, 1000, false); //parametros: WiFi.softAP(nomeDoAccessPoint, senhaRede) //redeVisivel: a rede pode ou não aparecer para outros serviços WiFiMulti.addAP("WiFi_Range", "12341234"); //escreve no display "Pronto!" escreva("Pronto!", false, 1000, true); //escreve no display "Conectando" escreva("Conectando...", true, 1000, false); //enquanto o cliente não estiver conectado, escreve "." while (WiFiMulti.run() != WL_CONNECTED) escreva(".", false, 1000, false); //escreve no display "Pronto" escreva("Pronto!", false, 1000, true);
Prosseguindo com o Setup,
definimos os textos a serem exibidos no display conforme cada situação.
escreva("Endereco IP:", true, 1000, false); //escreve no display o ip local escreva(WiFi.localIP().toString(), false, 1000, true); //escreve no display "Conectando" escreva("Conectando",true,10,false); //escreve no display "com servidor..." escreva("com servidor...",true,10,false); }
Código Client - Loop
No Loop o porte é definido
como 5000. O IP deve ser o mesmo utilizado pelo servidor. Defino um cliente e
conecto no “host port”. Se não fizer isso vai dar erro.
void loop() { //porta 5000 do protocolo TCP, deve ser a mesma utilizada pelo servidor const uint16_t port = 5000; //endereço ip, deve ser o mesmo utilizado pelo servidor const char * host = "192.168.10.11"; //inicializa a lib do cliente WiFiClient client; //se o cliente não estiver conectado, exibe "Falha..." if (!client.connect(host, port)) { escreva("Falha...",true, 1000,true); return; }
Pego a força do sinal da
conexão entre os ESPs e jogo na string WiFi.RSSI. Acendemos o led, transmitimos
a medida em dBm e exibimos a força do sinal da estação no display do server.
//obtém a força do sinal da conexão entre os ESPs String _RSSI = String(WiFi.RSSI()); //acende led digitalWrite(pinoLed,HIGH); //transmite esta medida em dBm client.println(_RSSI +"dBm"); //exibe a força do sinal da estação escreva("STA: " + _RSSI+"dBm",true,1000,true); //apaga led digitalWrite(pinoLed,LOW); }
Tabela dBm
Exponho nesta tabela o quanto
equivale uma unidade dBm em miliwatt.
Faça download dos arquivos:
0 Comentários