Hoy os traigo un tutorial básico acerca de cómo usar la conexión WLAN en nuestro ESP32. Esto nos permitirá añadir conectividad en nuestro ESP32 que va desde configurarlo como un servidor web, enviar datos por Wifi, y hasta descargar datos desde internet. Con el WLAN en ESP32 podrás incluso hacer las dos cosas al mismo tiempo, lo cual ter permitirá crear un ESP32 maestro con conexión a internet.

WLAN es ESP32: Modo Punto de Acceso (host)

El primer modo del que hablaré es del modo punto de acceso. Este modo nos permitirá configurar el WLAN en ESP32 como host para que otros clientes se conecten a él. Esto es muy útil para entornos donde no dispones de router y necesitas conectarte al ESP32, o simplemente si quieres prescindir de él y crear una red propia.

En este modo se le conoce como Soft-AP, debido a que no dispone de conexión con un router o similar. Al no disponer de esta conexión, no es posible utilizar ningún servicio que necesite de internet, como la descarga de librerías, conexiones HTTP, servicios en la nube como envío de emails,…

Un código de ejemplo para crear un punto de acceso sería el siguiente.

/*
  WiFi AP simple example by Daniel Carrasco in https://www.electrosoftcloud.com
*/

#include <WiFi.h>

// Set these to your desired credentials.
static const char *SSID = "yourAP";
static const char *PASSWORD = "yourPassword";

void setup() {
  Serial.begin(115200);
  Serial.println();
  Serial.println("Configuring access point...");

  // You can remove the password parameter if you want the AP to be open.
  WiFi.softAP(SSID, PASSWORD);
  IPAddress myIP = WiFi.softAPIP();
  Serial.print("AP SSID: ");
  Serial.println(SSID);
  Serial.print("AP IP address: ");
  Serial.println(myIP);
}

void loop() {
}

En este ejemplo simplemente crearemos un AP con el SSID y el Password indicados arriba. Hecho esto, si con tu móvil buscas redes Wifi cercanas verás que aparece el ESP32.

Explicación del código

El código es bastante simple y se compone básicamente de 5 líneas:

#include <WiFi.h>

En esta línea incluimos la librería WiFi para poder hacer uso del mismo.

// Set these to your desired credentials.
static const char *SSID = "yourAP";
static const char *PASSWORD = "yourPassword";

En estas líneas simplemente almacenaremos los datos del SSID y el Password del Punto de Acceso que queremos crear.

  WiFi.softAP(SSID, PASSWORD);
  IPAddress myIP = WiFi.softAPIP();

Y por último en estas dos líneas generamos el Punto de Acceso y recuperamos la IP que tiene nuestro ESP32.

Configurar una IP estática

Algo muy útil e importante, es configurar la IP fija en nuestros dispositivos. Esto nos permitirá tenerlos localizados en todo momento. En nuestro ESP32 podemos configurar la IP estática simplemente con la siguiente función:

WiFi.softAPConfig(local_IP, gateway, subnet);

Los argumentos que recibe son variables del tipo IPAddress, las cuales se inicializan de la siguiente manera:

IPAddress local_IP(192,168,4,22);
IPAddress gateway(192,168,4,22);
IPAddress subnet(255,255,255,0);

Con esto ya tendrías tu punto de acceso con una IP fija.

Funciones callback para el modo Punto de Acceso

Una vez que hayamos configurado el AP en el ESP32, dispondremos de las siguientes funciones callback que nos permitirá reaccionar a ciertos eventos como la conexión de un cliente. Las funciones de las que disponemos son las siguientes:

  • SYSTEM_EVENT_AP_START: El punto de acceso se ha iniciado
  • SYSTEM_EVENT_AP_STOP: El punto de acceso se ha parado
  • SYSTEM_EVENT_AP_STACONNECTED: Un cliente se ha conectado al punto de acceso
  • SYSTEM_EVENT_AP_STADISCONNECTED: Un cliente se ha desconectado del punto de acceso
  • SYSTEM_EVENT_AP_PROBEREQRECVED: Se ha recibido un paquete de petición de sondeo

Para usarlas tendremos que crear una función callback que será llamada cuando ocurra alguno de los eventos. Dicha función recibirá el evento como argumento, por lo que podremos crear varias funciones y vincularlas a los distintos eventos, o crear una sola función y actuar dependiendo del evento que reciba. Os dejo un ejemplo de cómo se usan los callbacks, y veréis que es muy fácil:

/*
  WiFi AP simple example by Daniel Carrasco in https://www.electrosoftcloud.com
*/

#include <WiFi.h>

// Set these to your desired credentials.
static const char *SSID = "yourAP";
static const char *PASSWORD = "yourPassword";


void WiFiAPEvent(WiFiEvent_t event, WiFiEventInfo_t info)
{
  // Handling function code

  if (event == SYSTEM_EVENT_AP_START) {
    Serial.println("AP Started");
  }
  else if (event == SYSTEM_EVENT_AP_STACONNECTED) {
    Serial.println("Client connected");
  }
  else if (event == SYSTEM_EVENT_AP_STADISCONNECTED) {
    Serial.println("Client disconnected");
  }
}


void setup() {
  Serial.begin(115200);
  Serial.println();
  Serial.println("Configuring access point...");

  // Attach WiFi events to callback function
  WiFi.onEvent(WiFiAPEvent, SYSTEM_EVENT_AP_START);
  WiFi.onEvent(WiFiAPEvent, SYSTEM_EVENT_AP_STACONNECTED);
  WiFi.onEvent(WiFiAPEvent, SYSTEM_EVENT_AP_STADISCONNECTED);

  // You can remove the password parameter if you want the AP to be open.
  WiFi.softAP(SSID, PASSWORD);
  IPAddress myIP = WiFi.softAPIP();
  Serial.print("AP SSID: ");
  Serial.println(SSID);
  Serial.print("AP IP address: ");
  Serial.println(myIP);
}

void loop() {
}

Como puedes observar, en la función setup adjuntamos el callback a cada uno de los eventos que queremos utilizar, y por ello podemos usar funciones separadas. Yo he usado una sola, pero eso va a gusto del consumidor.

También como puedes observar, hay un argumento en dichas funciones del tipo WiFiEventInfo_t. Este argumento nos devolverá un objeto de ese tipo el cual incluye datos como por ejemplo la dirección IP.

WLAN en ESP32: Modo cliente

Como has podido observar, utilizar la WLAN en ESP32 es muy fácil a la hora de crear un punto de acceso. Por supuesto teniendo en cuenta que esa es la parte difícil, conectarse a un punto de acceso será igual de fácil o más si cabe. En este apartado os enseñaré cómo conectaros a un host para poder hacer uso de internet, o simplemente estar en la misma red que el resto de equipos.

El código de ejemplo que usaremos será el siguiente:

/*
  WiFi AP simple example by Daniel Carrasco in https://www.electrosoftcloud.com
*/

#include <WiFi.h>

// Set these to your desired credentials.
static const char *SSID = "RouterSSID";
static const char *PASSWORD = "RouterPassword";

void setup() {
  Serial.begin(115200);
  Serial.println();
  Serial.println("Connecting to access point...");

  // Connectingo to access point using SSID and PASSWORD
  WiFi.begin(SSID, PASSWORD);

  // Waiting to be connected
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  // Returning the IP Address
  IPAddress myIP = WiFi.localIP();
  Serial.print("Client IP address: ");
  Serial.println(myIP);
}

void loop() {
}

Tal y como prometí, es bastante fácil conectarse a un punto de acceso usando la WLAN en ESP32, y el funcionamiento del código es el siguiente.

Explicación del código

Al igual que el punto de acceso, el código es bastante simple:

#include <WiFi.h>

En esta línea incluimos la librería WiFi para poder hacer uso del mismo.

// Set these to your desired credentials.
static const char *SSID = "yourAP";
static const char *PASSWORD = "yourPassword";

Guardamos los credenciales de nuestro punto de acceso como variables para poder conectarnos.

  // Connectingo to access point using SSID and PASSWORD
  WiFi.begin(SSID, PASSWORD);

  // Waiting to be connected
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

Nos conectamos al punto de acceso y esperamos a que el cliente esté conectado antes de continuar.

  // Returning the IP Address
  IPAddress myIP = WiFi.localIP();
  Serial.print("Client IP address: ");
  Serial.println(myIP);

Recuperamos la dirección IP del cliente y la mandamos por el puerto serial.

Configurar una IP estática

Al igual que con el punto de acceso, podemos configurar una IP estática en el cliente para saber en todo momento cual es en lugar de que nos dé una aleatoria. También es útil cuando el punto de acceso no tiene DHCP y no proporciona IP a los clientes.

WiFi.config(local_IP, gateway, subnet, primaryDNS, secondaryDNS);

Y al igual que con el AP, los argumentos que reciben son del tipo IPAddress como los del siguiente ejemplo.

// Set your Static IP address
IPAddress local_IP(192, 168, 1, 60);
// Set your Gateway IP address
IPAddress gateway(192, 168, 1, 1);

IPAddress subnet(255, 255, 255, 0);
IPAddress primaryDNS(8, 8, 8, 8);   //optional
IPAddress secondaryDNS(8, 8, 4, 4); //optional

Y así de fácil podemos configurar una IP estática en nuestro ESP32.

Funciones callback para el modo Cliente

El modo cliente al igual que el modo punto de acceso, dispone de sus propias llamadas callback a funciones. Estas llamadas se generan con los siguientes eventos:

  • SYSTEM_EVENT_STA_START: El cliente se ha inicializado
  • SYSTEM_EVENT_STA_STOP: El cliente se ha parado
  • SYSTEM_EVENT_STA_CONNECTED: El cliente se ha conectado a un punto de acceso. No se dispara si se configura la IP es estática en el cliente.
  • SYSTEM_EVENT_STA_DISCONNECTED: El cliente se ha desconectado de un punto de acceso
  • SYSTEM_EVENT_STA_AUTHMODE_CHANGE: Cambio de modo de authenticación
  • SYSTEM_EVENT_STA_WPS_ER_SUCCESS: Conexión a través de WPS correcta
  • SYSTEM_EVENT_STA_WPS_ER_FAILED: Error de conexión WPS
  • SYSTEM_EVENT_STA_WPS_ER_TIMEOUT: La conexión WPS ha dado timeout
  • SYSTEM_EVENT_STA_WPS_ER_PIN: El pin de la conexión WPS es incorrecto

Su uso es igual que el del punto de acceso, por lo que podremos vincular cada uno de los eventos a una función separada, o juntarlos en una sola función (a gusto del consumidor :P).

Aunque parezca que no, estos eventos son muy útiles. Yo por ejemplo en un proyecto que estoy trabajando de un reloj RTC sincronizado con NTP, mantengo la función de sincronización desactivada hasta que recibo un evento del tipo SYSTEM_EVENT_STA_CONNECTED. Con esto no tengo que estar comprobando en el loop principal si hay conexión WiFi, sino que el propio callback se encarga de notificármelo.

Un ejemplo sería el siguiente:

/*
  WiFi AP simple example by Daniel Carrasco in https://www.electrosoftcloud.com
*/

#include <WiFi.h>

// Set these to your desired credentials.
static const char *SSID = "yourAP";
static const char *PASSWORD = "yourPassword";

// Set your Static IP address
IPAddress local_IP(192, 168, 1, 60);
// Set your Gateway IP address
IPAddress gateway(192, 168, 1, 1);

IPAddress subnet(255, 255, 255, 0);
IPAddress primaryDNS(8, 8, 8, 8);   //optional
IPAddress secondaryDNS(8, 8, 4, 4); //optional

void WiFiStationEvent(WiFiEvent_t event, WiFiEventInfo_t info)
{
  // Handling function code

  if (event == SYSTEM_EVENT_STA_START) {
    Serial.println("Client Started");
  }
  else if (event == SYSTEM_EVENT_STA_CONNECTED) {
    Serial.println("Connected to access point");
  }
  else if (event == SYSTEM_EVENT_STA_DISCONNECTED) {
    Serial.println("Disconnected from access point");
  }
}

void setup() {
  Serial.begin(115200);
  Serial.println();
  Serial.println("Connecting to access point...");

  // Attach WiFi events to callback function
  WiFi.onEvent(WiFiStationEvent, SYSTEM_EVENT_STA_START);
  WiFi.onEvent(WiFiStationEvent, SYSTEM_EVENT_STA_CONNECTED);
  WiFi.onEvent(WiFiStationEvent, SYSTEM_EVENT_STA_DISCONNECTED);

  // Connectingo to access point using SSID and PASSWORD
  WiFi.begin(SSID, PASSWORD);
}

void loop() {
}

En la función setup añadiremos los callbacks a los que queremos reaccionar al igual que hicimos con el access point. Es importante hacerlo antes de iniciar el WiFi o es probable que el primer callback de conexión no se ejecute.

WLAN en ESP32: Modo Mixto

Nuestro ESP32 nos permite además del modo Host y el modo Cliente, un modo mixto en el que nuestro ESP32 actuará como ambos. Esto nos puede ser muy útil si queremos por ejemplo tener un ESP32 que se conecte a internet o a la red local, y una serie de ESP32 que sólo se conectarán a este ESP32 y por lo tanto estarán aislados de la red. Nos servirá para no sobrecargar nuestro punto de acceso y a la vez por seguridad.

Para utilizar este modo tendremos que configurar el ESP32 para ello, y luego configurar ambos modos. El código de ejemplo sería el siguiente:

/*
  WiFi AP simple example by Daniel Carrasco in https://www.electrosoftcloud.com
*/

#include <WiFi.h>

// Set these to your desired credentials.
static const char *stationSSID = "MOVISTAR_F611";
static const char *stationPASSWORD = "C89qlqMifsjDMWhbdsJQ";

// Set these to your desired credentials.
static const char *apSSID = "yourAP";
static const char *apPASSWORD = "yourPassword";

void WiFiStationEvent(WiFiEvent_t event, WiFiEventInfo_t info)
{
  // Handling function code

  if (event == SYSTEM_EVENT_STA_CONNECTED) {
    Serial.println("Connected to access point");
  }
  else if (event == SYSTEM_EVENT_STA_DISCONNECTED) {
    Serial.println("Disconnected from access point");
  }
}

void setup() {
  Serial.begin(115200);
  Serial.println();
  Serial.println("Configuring access point...");

  // Connecting to Wifi
  WiFi.onEvent(WiFiStationEvent, SYSTEM_EVENT_STA_CONNECTED);
  WiFi.onEvent(WiFiStationEvent, SYSTEM_EVENT_STA_DISCONNECTED);

  // You can remove the password parameter if you want the AP to be open.
  WiFi.softAP(apSSID, apPASSWORD);
  IPAddress myIP = WiFi.softAPIP();
  Serial.print("AP SSID: ");
  Serial.println(apSSID);
  Serial.print("AP IP address: ");
  Serial.println(myIP);

  // Connectingo to access point using SSID and PASSWORD
  WiFi.begin(stationSSID, stationPASSWORD);
}

void loop() {
}

Como puedes observar, la configuración es la misma que hemos visto anteriormente sólo que se ponen ambas al mismo tiempo. Es por ello que no os daré la turra repitiendo lo mismo de arriba 😛

Espero que os haya gustado y si os gustó, no dudéis en compartir o dejar vuestro comentario. ¡Un saludo!

Daniel Carrasco

DevOps con varios años de experiencia, y arquitecto cloud con experiencia en Google Cloud Platform y Amazon Web Services. En sus ratos libres experimenta con Arduino y electrónica.

Deja un comentario

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.