wifi-conexion-redes-nanoframework

Conexión Wi-Fi en nanoFramework: escaneo y DHCP

  • 5 min

La conectividad Wi-Fi en nanoFramework es la forma de unir nuestro microcontrolador a una red IP para comunicarse con otros sistemas.

Hasta ahora, nuestro ESP32 podía leer sensores y mover servos, pero no podía intercambiar esos datos con otros sistemas.

En este bloque vamos a conectarlo a una red local y, desde ella, a Internet.

Conectar un microcontrolador a una red Wi-Fi puede parecer trivial (“pones la contraseña y listo”), pero en sistemas embebidos hay que gestionar timeouts, direcciones IP, reconexiones automáticas y ahorro de energía.

Afortunadamente, nanoFramework nos ofrece herramientas de alto nivel para no tener que lidiar con los registros de la radio Wi-Fi manualmente.

Para este tutorial necesitas instalar los siguientes paquetes NuGet:

  • nanoFramework.System.Device.Wifi (Para gestionar el adaptador y escanear).
  • nanoFramework.System.Net (Para la gestión de red).

Escanear redes Wi-Fi

Antes de intentar conectarnos, vamos a verificar que la antena funciona y ver qué hay en el aire. Vamos a crear un Escáner de Wi-Fi.

Utilizaremos la clase WifiAdapter.

using System;
using System.Device.Wifi;
using System.Diagnostics;
using System.Threading;

namespace WifiScanner
{
    public class Program
    {
        public static void Main()
        {
            Debug.WriteLine("Iniciando escaneo Wi-Fi...");

            // 1. Obtener el adaptador Wi-Fi del hardware
            // En el ESP32 suele ser el primero disponible
            WifiAdapter wifi = WifiAdapter.FindAllAdapters()[0];

            // 2. Iniciar escaneo
            wifi.ScanAsync();

            // Esperar un poco a que termine el escaneo...
            Thread.Sleep(5000);

            // 3. Obtener resultados
            foreach (var network in wifi.NetworkReport.AvailableNetworks)
            {
                Debug.WriteLine($"SSID: {network.Ssid}  |  RSSI: {network.SignalBars} ({network.Rssi}dBm)");
            }

            Thread.Sleep(Timeout.Infinite);
        }
    }
}
Copied!

Si ejecutas esto, verás en la consola de Visual Studio una lista de todas las redes Wi-Fi de tu vecindario con su potencia de señal (RSSI). ¡Nuestra radio funciona!

Conectar con WifiNetworkHelper

Gestionar la conexión “a mano” implica lidiar con eventos de cambio de estado, DHCP, asignación de IP… es tedioso.

Para simplificarnos la vida, nanoFramework incluye la clase estática WifiNetworkHelper. Es una utilidad que gestiona todo el proceso de conexión y espera hasta que la red está realmente lista (es decir, cuando ya tenemos fecha y dirección IP válida).

Conexión mediante DHCP

La mayoría de las veces querremos que el Router nos asigne una IP automáticamente.

using System.Device.Wifi;
using System.Diagnostics;
using System.Net.NetworkInformation;
using System.Threading;

// ... dentro del Main

Debug.WriteLine("Conectando al Wi-Fi...");

// Credenciales (¡Ojo! No las subas a GitHub)
string ssid = "MiFibra_5G";
string password = "MiSuperPassword";

// Esta función bloquea la ejecución hasta que conecta o se agota el tiempo
bool exito = WifiNetworkHelper.ConnectDhcp(ssid, password, requiresDateTime: true, token: new CancellationTokenSource(60000).Token);

if (exito)
{
    Debug.WriteLine("¡Conectado con éxito!");
    Debug.WriteLine($"IP: {NetworkInterface.GetAllNetworkInterfaces()[0].IPv4Address}");
}
else
{
    Debug.WriteLine("Error: No se pudo conectar tras 60 segundos.");
}
Copied!

Fíjate en el parámetro requiresDateTime: true. Esto hace que el Helper no devuelva true hasta que el dispositivo haya sincronizado la hora por NTP (Network Time Protocol). Es muy importante si vas a conectar con servicios seguros (HTTPS/Azure), ya que sin la hora correcta los certificados SSL fallan.

Conexión con IP fija

A veces necesitamos que nuestro dispositivo tenga siempre la misma IP (por ejemplo, si vamos a montar un servidor web en él).

En este caso usamos ConnectFixAddress.

IPConfiguration ipConfig = new IPConfiguration(
    "192.168.1.200",   // IP deseada
    "255.255.255.0",   // Máscara de subred
    "192.168.1.1",     // Puerta de enlace (Router)
    new[] { "8.8.8.8" } // DNS (Google)
);

bool exito = WifiNetworkHelper.ConnectFixAddress(
    ssid,
    password,
    ipConfig,
    requiresDateTime: true,
    token: new CancellationTokenSource(60000).Token);
Copied!

Gestionar la reconexión

En un dispositivo que debe funcionar durante horas o días, la conexión Wi-Fi puede caer por un reinicio del router o por interferencias.

Si tu código solo conecta al principio del Main y la red se cae a las 3 horas, tu dispositivo se quedará “sordo” para siempre.

WifiNetworkHelper también nos ayuda a reconectar automáticamente si le decimos que guarde el perfil.

// Conectar y guardar el perfil para poder reconectar después
WifiNetworkHelper.ConnectDhcp(
    ssid,
    password,
    WifiReconnectionKind.Automatic,
    requiresDateTime: true);
Copied!

Sin embargo, para una robustez total, a menudo implementamos un patrón de Monitorización de Red:

// Evento que salta cuando cambia el estado de la red (IP obtenida, cable desconectado...)
NetworkChange.NetworkAddressChanged += NetworkChange_NetworkAddressChanged;

// ...

private static void NetworkChange_NetworkAddressChanged(object sender, EventArgs e)
{
    var ipProperties = NetworkInterface.GetAllNetworkInterfaces()[0].IPv4Address;
    
    if (ipProperties != null && ipProperties.Length > 0 && ipProperties != "0.0.0.0")
    {
        Debug.WriteLine($"Estado de Red: CONECTADO - IP: {ipProperties}");
    }
    else
    {
        Debug.WriteLine("Estado de Red: DESCONECTADO. Intentando reconectar...");
        // Aquí podríamos forzar un reinicio o reintentar conexión
    }
}
Copied!

Proteger las credenciales

Poner el usuario y contraseña en el código fuente (string password = "...") es cómodo para aprender, pero una pésima práctica de seguridad.

Recuerda que en la entrada sobre nanoff vimos que podíamos inyectar las credenciales al flashear:

nanoff --target ESP32_REV0 --update --ssid "MiRed" --password "1234"
Copied!

Si haces esto, nanoFramework guarda los datos en su configuración no volátil. En tu código puedes llamar a WifiNetworkHelper.Reconnect(requiresDateTime: true) para reutilizar el perfil automático. Esto evita incluir la clave en el repositorio, pero no implica que quede cifrada frente a un atacante con acceso físico.