Introdução
Conectar dispositivos ao roteador tornou-se uma prática tão comum e natural que muitas vezes não percebemos os processos envolvidos. Por exemplo, para colocar o smartphone, assistente pessoal ou impressora na rede, é necessário realizar uma busca, escolher a rede e inserir as credenciais (senha). A etapa de busca é conhecida como Scanner, onde o dispositivo recebe pequenos pacotes (beacon) a cada segundo e realiza saltos de buscas em diferentes canais que podem operar em frequências de 2.4GHz e 5GHz.
O driver WiFi da Franzininho WiFi permite realizar a busca por redes apenas na frequência de 2.4GHz, que corresponde à maioria dos dispositivos em uso doméstico e comercial. Além disso, este driver tem baixo consumo de energia e tornou-se a escolha perfeita para projetos de IoT, Wearable e smarthome.
Nesse artigo vamos aprender a fazer um WiFi Scanner para realizar a varredura das redes disponíveis e imprimir as informações delas no monitor serial.
API biblioteca WiFi
begin()
Inicializa o drive WiFi com as configurações padrões. Lembre-se que inicializado uma vez, não é necessário chamar esse método.
wl_status_t WiFi.begin();
Retorna o status do drive ao inicializar, os são:
WL_CONNECT_FAILED: Falha ao registrar o drive
WL_IDLE_STATUS: informa que o drive WiFi está inicializado e aguardando próximas ações
mode()
Habilita o drive WiFi para o operar num modo específico.
bool WiFi.mode(wifi_mode_t m);
- m : seleciona o modo
WIFI_MODE_MODE_STA: modo estação (Estação)
WIFI_MODE_AP: modo ponto de acesso (Access Point)
WIFI_MODE_APSTA: modo pode operar como ponto de acesso e estação
Retorna true, caso tenha configurado modo ou false, caso não foi habilitado o modo.
scanNetworks()
Busca as redes WiFi disponíveis, esse método é executado apenas uma vez. Devido a sobrecarga do método esse método aceita duas opções para parametrizar.
uint16_t WiFi.scanNetworks();
Nesse método realiza-se o scanner da rede de maneira assíncrona, ou seja, é executada uma rotina de busca e finalizada sem aguardar uma espera do resultado da busca.
uint16_t WiFi.scanNetworks(bool async, bool,bool show_hidden);
- async : habilita scanner assíncrona
- show_hidden : habilita para scannear rede com SSID “escondidos”
Retorna o número de redes descobertas.
scanComplete()
Verifica o resultado do scanner assíncrono. Durante o scanner esse método retorna o número de redes descobertas.
uint16_t WiFi.scanNetworks();
Retorna a quantidade de redes encontradas ou status do scanner que são:
WIFI_SCAN_FAILED (-2) – Scanner não foi inicializado
WIFI_SCAN_RUNNING (-1) – Scanner está em execução
scanDelete()
Deleta a memória da RAM a lista de redes encontradas no último scanner.
void WiFi.scanDelete();
SSID()
Busca na lista de redes escaneadas o nome público.
String WiFi.SSID(int item);
- item : índice da lista
Retorna o SSID da rede.
encryptionType()
Informa o tipo de criptografia da rede encontrada durante o scanner.
wifi_auth_mode_t WiFi.encryptionType(int item);
- item: índice da lista
Retorna o tipo de criptografia, alguns estão apresentados seguir:
WIFI_AUTH_OPEN (0): rede aberta, ou seja, entra na rede sem uso de senha
WIFI_AUTH_WEP (1): rede com criptográfica Wire Equivalent Privacy (WEP), está em desuso, mas ainda há roteadores com esse tipo de criptografia
WIFI_AUTH_WPA_PSK(2) : rede com criptográfica Wi- Fi Protected Access (WPA). Pre Shared Key (PSK) ou Modo Pessoal, mais comuns em ambientes domésticos.
BSSID()
Informa o BSSID (Basic Service Set Identification) da rede encontrada durante o scanner.
uint8_t* WiFi.BSSID(int item);
- item : índice da lista
Retorna o BSSI, também é um outro nome para o endereço MAC da rede descoberta
BSSIDstr()
Informa o BSSID (Basic Service Set Identification) da rede encontrada durante o scanner.
String WiFi.BSSIDstr(int item);
- item : indice da lista
Retorna o BSSI no formato de string.
RSSI()
Informa a potência do sinal da rede encontrada, esse valor é dado em dBm.
int32_t WiFi.RSSI(int item);
- item : indice da lista
Retorna um valor da potência do sinal.
channel()
Informa o canal da rede encontrada.
int32_t WiFi.channel(int item);
- item : indice da lista
Retorna um valor do canal.
Materiais necessários
Para desenvolver nossa aplicação os materiais utilizados foram:
- Placa Franzininho WiFi
- Arduino IDE
Circuito para o WiFi Scanner
Nesse artigo vamos utilizar apenas a placa Franzininho WiFi para desenvolvermos a aplicação proposta.
Código para o WiFi Scanner
No projeto proposto vamos realizar a busca por redes Wi-Fi e imprimir no Monitor Serial as informações relevantes durante o scanner da rede que são:
- SSID : nome da rede
- RSSI: potência do sinal em dBm
- BSSID: endereço MAC do dispositivo
- Encryption Type: tipo autenticação da rede (Aberta ou Fechada)
// Inclui biblioteca
#include <WiFi.h>
int num_network;
void setup()
{
//Inicializa e configura a comunicação Serial
Serial.begin(115200);
//Inicializa o drive do WiFi
WiFi.begin();
// Configura o drive WiFi para modo Station
WiFi.mode(WIFI_STA);
// Aguarda 1 segundo
delay(1000);
}
void loop()
{
Serial.println("Iniciando scanner ...");
// Inicia o scanner da rede
WiFi.scanNetworks();
// Verifica a quantidade de redes disponíveis
num_network =WiFi.scanComplete();
//Caso tenha encontrado alguma rede, então...
if(num_network >0)
{
Serial.println("*** Rede(s) Wi-Fi *** ");
Serial.println();
// Entra no laço de repetição, para imprimir as informações
// de cada rede encontrada
for(int j = 0; j < num_network; j++)
{
Serial.print(j+1);
Serial.print(") ");
Serial.print(" SSID: " + WiFi.SSID(j));
Serial.print(" | Canal: ");
Serial.print(WiFi.channel(j));
Serial.print(" | RSSI: ");
Serial.print(WiFi.RSSI(j));
Serial.print(" (dBm) ");
Serial.print(" | BSSID: "+ WiFi.BSSIDstr(j));
Serial.print(" | Wi-Fi Aberto: ");
Serial.print(WiFi.encryptionType(j) == WIFI_AUTH_OPEN ? "sim": "não");
Serial.println();
delay(10);
}
Serial.println();
}
// Caso não encontre a rede Wi-Fi, então ...
else
{
Serial.println("Sem rede Wi-Fi");
}
//Aguarde 3 segundos
delay(3000);
}
Simule esse projeto no Wokwi:https://wokwi.com/projects/364261611824889857
Explicação do Código
Nesta seção explicaremos cada trecho do código a fim de esclarecer os métodos utilizados pelo WiFi.
Primeiro incluímos a biblioteca WiFi.h, nela teremos acesso ao objeto WiFi e consequentemente os métodos.
// Inclui biblioteca
#include <WiFi.h>Na função void setup(), inicializamos a comunicação Serial e o drive WiFi. Após inicializar, põe o drive WiFi em modo Station e aguarda 1 segundo.
void setup()
{
//Inicializa e configura a comunicação Serial
Serial.begin(115200);
//Inicializa o drive do WiFi
WiFi.begin();
// Configura o drive WiFi para modo Station
WiFi.mode(WIFI_STA);
// Aguarda 1 segundo
delay(1000);
}
Na função void loop(), imprime a no Monitor Serial “Iniciando scanner …”, faz a chamada do método scanNetworks() para realizar a busca das redes visíveis e armazenar em uma lista de itens encontrados. Após finalizar essa etapa verifica-se quantas redes foram encontradas pelo método scanComplete().
void loop()
{
Serial.println("Iniciando scanner ...");
// Inicia o scanner da rede
WiFi.scanNetworks();
// Verifica a quantidade de redes disponíveis
num_network =WiFi.scanComplete();Verifica se o número de redes encontradas foi maior que zero, então imprimiremos as informações de cada item da lista por um laço de repetição for.
//Caso tenha encontrado alguma rede, então...
if(num_network >0)
{
Serial.println("*** Rede(s) Wi-Fi *** ");
Serial.println();
// Entra no laço de repetição, para imprimir as informações
// de cada rede encontrada
for(int j = 0; j < num_network; j++)
{
Serial.print(j+1);
Serial.print(") ");
Serial.print(" SSID: " + WiFi.SSID(j));
Serial.print(" | Canal: ");
Serial.print(WiFi.channel(j));
Serial.print(" | RSSI: ");
Serial.print(WiFi.RSSI(j));
Serial.print(" (dBm) ");
Serial.print(" | BSSID: "+ WiFi.BSSIDstr(j));
Serial.print(" | Wi-Fi Aberto: ");
Serial.print(WiFi.encryptionType(j) == WIFI_AUTH_OPEN ? "sim": "não");
Serial.println();
delay(10);
}
Serial.println();
}
Caso não seja encontrado nenhuma rede Wi-Fi imprime na Serial :“ Sem rede Wi-Fi” e aguarda 3 segundos para realizar o próximo scanner da rede.
// Caso não encontre a rede Wi-Fi, então ...
else
{
Serial.println("Sem rede Wi-Fi");
}
//Aguarde 3 segundos
delay(3000);
}
Conclusão
Neste artigo, abordamos o assunto do WiFi, um driver que oferece diversos recursos de conectividade juntamente com uma flexibilidade no modo de operação. Os métodos apresentados na seção de API WiFi são utilizados quando se deseja escanear a rede local para encontrar o melhor ponto de acesso e estabelecer uma conexão estável. No exemplo de projeto, mostramos como extrair informações de cada rede. Esse tipo de funcionalidade é comum em aplicações que envolvem a necessidade de trocar informações para configurar ou atualizar dispositivos, tais como impressoras, equipamentos inteligentes (como Sonoff, Lâmpadas Inteligentes, Alexa), smartphones, computadores e muitos outros.
Saiba mais
Franzininho WiFi: A placa versátil para iniciantes e desenvolvedores experientes
Programando a Franzininho WiFi com Zephyr RTOS
Como programar a Franzininho WiFi: 6 opções para você escolher!










