Micropython: Conectar con una red Wifi

Micropython puede utilizarse en una variedad de microcontroladores, entre ellos algunos que incorporan conectividad Wifi para conectarse a Internet, lo que los hace particularmente útiles para desarrollar aplicaciones de IoT (Internet de las cosas). En este artículo veremos específicamente como conectarnos a Internet con un ESP8266 y un ESP32.

ESP8266 y ESP32

Si bien existen diferencias a nivel de hardware entre el ESP8266 y el ESP32, el módulo que utilizaremos para realizar la conexión con la red Wifi funciona por igual en ambos, así que a menos que haga una aclaración puntual, lo que sigue es totalmente aplicable a los dos.

El módulo en cuestión se llama network y es una de las librerías integradas a Micropython, también llamadas librerías standard. Esto significa que la misma está almacenada en la memoria del microcontrolador, junto con el intérprete de Micropython y que no es necesario agregarla para poder utilizarla. Si quieren saber cuales son las librerías standard, desde Thonny (u otro entorno) en el Shell o consola, deben escribir:

Módulos standard en Micropython 1.12

Volviendo al módulo network, éste nos permite establecer una conexión Wifi de dos maneras:

Access Point (AP): En este modo, el dispositivo (ESP8266 o ESP32) genera una red Wifi que es capaz de aceptar conexiones de otros equipos (teléfonos, notebooks, etc).

Station: En esta configuración, el dispositivo se conecta a una red Wifi existente, por ejemplo la generada por un router.

En esta oportunidad analizaremos como usar el segundo modo, para conectarnos a una red ya existente y así poder enviar y recibir información a través de Internet. Veremos en otro artículo como configurar y utilizar el modo Access Point.

Lo primero que debemos hacer es importar el módulo network:

import network

Como ya dije este módulo nos permite realizar conexiones de dos tipos, que son llamadas interfaces: la interface tipo AP y la interface tipo STATION. Para crear una interface tipo STATION debemos instanciar un objeto de la clase WLAN, que es una clase incluida en el módulo, empleando un constructor que tiene el siguiente formato:

identificador network.WLAN (interface_id)

Donde:

identificador: Es el nombre que le daremos al objeto de la clase WLAN

interface_id: Indica el tipo de interface que queremos crear, y puede tomar los valores network.STA_IF (interface tipo STATION) y network.AP_IF (interface tipo AP).

El siguiente ejemplo crea un objeto de tipo WLAN para una interface STATION:

miRed = network.WLAN (network.STA_IF)

A continuación debemos activar la interface, empleando el método active, que tiene el siguiente formato:

active ([activo])

activo: Valor booleano que indica si se activa (True) o desactiva (False) la interface. Si no se provee un parámetro, el método devuelve el estado de la interface.

Ejemplo:

import network

miRed = network.WLAN(network.STA_IF)

miRed.active (True)  #Activa la interface
print (miRed.active()) #Imprime el estado de la interface

miRed.active (False) #Desactiva la interface
print (miRed.active()) #Imprime el estado de la interface

Finalmente, debemos conectarnos a la red, empleando el método connect:

connect (ssidpassword)

ssid: Nombre o identificador de la red a la que queremos conectar

password: Contraseña de la red. Si la red es pública, dejar en blanco.

Ejemplo:

import network

miRed = network.WLAN(network.STA_IF)

miRed.active (True)  #Activa la interface
miRed.connect ("nombre", "contraseña") #Conecta a la red

Un inconveniente del método connect es que no nos devuelve información sobre el éxito (o no) de la conexión. Para saber si nos pudimos conectar sin inconvenientes, podemos utilizar el método isconnected , que nos devuelve True si se completó la conexión a la red y se obtuvo una IP válida.

Estos son los pasos mínimos necesarios para conectarnos a una red, pero debemos tener en cuenta que la red puede demorar en establecer la conexión, así que debemos incluir una espera a que la conexión se complete. Una función con estas características nos quedaría como la que se ve a continuación, que he llamado conectaWifi

import network

def conectaWifi (red, password):
     miRed = network.WLAN(network.STA_IF)     
     if not miRed.isconnected():           #Si no está conectado…
         miRed.active(True)                     #activa la interface
         miRed.connect(red, password)         #Intenta conectar con la red
         print('Conectando a la red', red +"…")
         while not miRed.isconnected():           #Mientras no se conecte..
             pass                                  #hace "nada"
     print('Datos de la red (IP/netmask/gw/DNS):', miRed.ifconfig())

conectaWifi ("nombre", "contraseña")

Como podemos ver, luego de crear el objeto miRed en modo STATION, comprueba que no haya una conexión previa y si no la hay activa la interfase e intenta una conexión a la red de nombre “red” y contraseña “password”, saliendo recién cuando la conexión fue exitosa y mostrando los datos de la conexión con el método ifconfig.

Un problema evidente de esta función es que si la conexión no se logra, por la causa que sea, la función se queda intentándolo indefinidamente. En esta nueva versión se le agrega un timeout de 10 segundos (que se pueden modificar) luego de los cuales la función sale con error.

import network, time

def conectaWifi (red, password):
     global miRed
     miRed = network.WLAN(network.STA_IF)     
     if not miRed.isconnected():              #Si no está conectado…
         miRed.active(True)                   #activa la interface
         miRed.connect(red, password)         #Intenta conectar con la red
         print('Conectando a la red', red +"…")
         timeout = time.time ()
         while not miRed.isconnected():           #Mientras no se conecte..
             if (time.ticks_diff (time.time (), timeout) > 10):
                 return False
     return True

if conectaWifi ("--red--", "--contraseña--"):
     print ("Conexión exitosa!")
     print('Datos de la red (IP/netmask/gw/DNS):', miRed.ifconfig())
else:
     print ("Imposible conectar")

Dentro de la función conectaWifi se declara miRed como global, para que pueda ser usada fuera de la función. El timeout se logra combinando los métodos time y ticks_diff que analizamos en otro artículo. Ahora se devuelve un valor tipo boolean: Si se logró la conexión, la función retorna True y si pasan los 10 segundos sin lograrlo sale con un valor False.

Una vez que se logró la conexión, ya podemos acceder a Internet para transferir información o acceder a cualquier sitio, para lo cual existen distintos protocolos. Solo a modo de ejemplo accederemos al sitio www.example.com usando el protocolo HTTP, para lo cual agregaremos el módulo urequests y usaremos algunos de sus métodos:

import network, time, urequests

def conectaWifi (red, password):
     global miRed
     miRed = network.WLAN(network.STA_IF)     
     if not miRed.isconnected():              #Si no está conectado…
         miRed.active(True)                   #activa la interface
         miRed.connect(red, password)         #Intenta conectar con la red
         print('Conectando a la red', red +"…")
         timeout = time.time ()
         while not miRed.isconnected():           #Mientras no se conecte..
             if (time.ticks_diff (time.time (), timeout) > 10):
                 return False
     return True
 
if conectaWifi ("Los Tolo network", "performance"):
     print ("Conexión exitosa!")
     print('Datos de la red (IP/netmask/gw/DNS):', miRed.ifconfig())
else:
     print ("Imposible conectar")

#Prueba acceder a una página con el método GET del protocolo HTTP
respuesta = urequests.get("http://www.example.com")
print(respuesta.text)

Cuando funciona, nos trae el contenido del sitio www.example.com, que es una página en HTML:

En próximos artículos iremos profundizando en el uso de estos protocolos y cómo acceder a distintos servicios de Internet desde nuestro dispositivo usando Micropython. También analizaremos otros métodos incluidos en el módulo network. Cualquier duda o sugerencia pueden dejarla en la sección de comentarios.

Deja un comentario

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

A %d blogueros les gusta esto: