Librería para la gestión de conexión WIFI vía serie personalizada para ESP32


Sin duda alguna que el atractivo de los módulos de espressif no radica ni en su ridículamente reducida y poco detallada documentación, ni en su entorno de desarrollo propio (por ello todos usamos el Arduino que tampoco es la panacea pero al menos es usable) ni tampoco por la calidad final de sus productos. Nomás ver el convertidor AD y su mal desempeño y sabremos que es un producto que cumple con el precepto de "baratija china". Pero es justamente ahí donde radica su ventaja, al ser una baratija china es económico y dentro de todo genéricamente útil. Sin dudas nadie va a encontrar en una multifunción doméstica o de oficina un ESP32 ni mucho menos en una ECU de vehículo! No está siquiera diseñado para cubrir esos segmentos pero sirve y mucho en aquellas aplicaciones donde emplear otra tecnología de sabida calidad y buena procedencia con excelente documentación y soporte de ingeniería se vuelve inaplicable ya sea por costes, tiempos o disponibilidad inmediata. Nunca debemos olvidar que estamos en el fondo del planeta, si quien lee esto lo está haciendo en un país cuyo idioma nativo es el de este sitio de seguro me entenderá. En su momento cuando queríamos dotar de conectividad ethernet o WIFI a un microcontrolador ya sea PIC o Atmega o el que fuera teníamos que pensar desde el vamos en el costoso e imposible de conseguir MagJack! Ah, ese dichoso conector RJ45 con las etapas de RF ethernet incorporadas dentro! Había que empeñar un riñón para comprarlo y eso si había stock. Luego comprar el ENC28J60 como interface entre el mundo exterior previo pasar por el MagJack y el microcontrolador y por último el microcontrolador. En su momento una inversión de no menos de cien dólares en tres items... Un disparate de dinero. Arduino ayudó muchísimo a bajar esos costes con el shield W5000 el cual costaba muchísimo menos que el magjack y el ENC aunque tuviera a ambos a bordo, gracias a la magia de los chinos para hacer barato lo que otros occidentales no logran. Y ahora el ESP8266 y el ESP32 ambos dotados con módulo WIFI incorporado en una plaqueta que en argentina cuesta 10 dólares comprándola caro. Entonces se vuelve interesante por demás aprender a utilizar estas baratijas chinas pero siempre a sabiendas de que se tiene entre manos, un producto de baja calidad con precio acorde pero muy interesantes prestaciones.  Por supuesto que todo esto repercutió en una baja de precios abrupta en los productos tradicionales aunque también son variantes chinas por lo que hoy en Argentina se consigue un módulo ENC28J60 con el MagJack incorporado por algo mas de 3 dólares a lo cual hay que sumarle el microcontrolador y la capa o stack TCP/IP pero ya nos alejamos bastante de aquellos cien dólares de hace diez años. Seguramente en un futuro haga alguna aplicación en CCS C para PIC con conexión Ethernet usando alguno de esos módulos.

Lo cierto es que la necesidad hace al ladrón dice el refrán y no se puede decir menos del porqué me decido a hacer esta librería propia para gestionar la conexión WIFI de un ESP32. Tengo en mi empresa de transportes por un lado un aparato comprado comercialmente que registra en memoria cuando se le aproxima una tarjeta o tag RFID y guarda en su memoria interna fecha, hora y número de tarjeta. Incluso tiene un pequeño pero bien logrado gestor de referencias entonces en la página WEB a la que uno accede vía cable de red (no es inalámbrico) en vez de decir "01/02/2020 14:55:26 1234567890" donde el último dato serían los diez dígitos de la tarjeta o tag apoyado dice "01/02/2020 14:55:26 DARIO" porque en una tabla o grilla de tag's registrados dice a quien pertenece cada uno. Esta muy bueno, la verdad me agrada en si pero por cuestiones de limitaciones si bien es abre puertas también preferí poner por separado otro aparato que cumpla con dicha función el cual se programa aproximando una tarjeta programadora y luego la tarjeta a programar, un engorro pero cumple su función sin problemas. Bien, hace rato que quiero hacer algo a medida nuestra porque siempre le falta una moneda para el peso a cada uno de los equipos y por ende quería usar un ESP32 y armarlo entorno a dicho componente. Para ello me tengo que conectar por WIFI para poder administrarlo y ahí es donde nace la necesidad de la librería que da letra a esta publicación.

Durante un curso de capacitación dictado por Andrés Raúl Bruno Saravia y la gente de Microelectrónica SH el año pasado sobre ESP32 vimos varias clases referidas al WIFI ya sea conectarnos a una red WIFI para tener acceso al módulo desde un celular y actuar sobre su electrónica, leer parámetros, acceder a datos en internet y hasta convertir al ESP32 en un punto de acceso inalámbrico, lo que se suele denominar HotSpot y conectarnos a él para realizar distintas actividades. Pero un punto siempre estaba en el factor denominador, los parámetros de red eran valores constantes compilados y subidos al programa en forma personalizada.

Es como si comprásemos un artefacto para nuestra casa que requiera usar WIFI y tuviéramos que indicarle al fabricante que nos lo deje configurado para funcionar con determinados parámetros. Mañana cambiamos de proveedor de internet o por seguridad cambiamos los datos de la red inalámbrica (algo muy recomendable que nadie hace!) y tendríamos que devolverle al fabricante el aparato para que lo vuelva a grabar con los nuevos datos para que luego nos lo envíe a casa nuevamente! Un delirio, pero es algo que en los nefastos video tutos de YouTube donde lamentables quinceañeros se la pasan histéricamente sombreando con el mouse y relatando con voz de nariz llena de mocos casi inentendible y dan a entender que "esto es así". No, así es la limitación humana, pero no debe ser así un artefacto bien logrado! Y es por ello que decidí hacer mis propias librerías de gestión de datos de conexión de WIFI.

Por cuestiones de corriente decidí emplear durante el desarrollo de esta librería la placa Wemos D1 R32 dado que tiene un jack de entrada de alimentación el cual he conectado a mi fuente de taller para no cargar con el consumo del WIFI al puerto USB de la PC. Si bien un dongle WIFI o un modem USB de GSM consumen mas corriente que un ESP32 usando el WIFI no me parece lógico correr con ese consumo en la PC si puedo cargárselo a la fuente! Así que en esta nota usaremos esta placa:

Está mas que claro que es una ESP32 estándar a tal punto que ni siquiera he cambiado seteos en el IDE mas que el puerto serie puesto que cada una tiene su propio conversor USB CDC Serie y a cada uno el Windows le ha asignado un puerto COM con número diferente. Pero saliendo de esa configuración no he tenido que cambiar mas nada. Un detalle curioso de esta placa con respecto a otras que usan el mismo ESP32 es que no se requiere presionar el botón de BOOT para que se suba el firmware, de echo esta placa no tiene botón BOOT! Dado que tiene formato Arduino Uno con tiras hembras en sus lados he empleado un cable macho / macho (cable trolo como me gusta decirle a mi!) para ponerlo a GND en uno de sus extremos y meterlo en los diferentes hembras para actuar sobre las entradas de pulsador con lo cual el armado de prototipo se reduce a sólo ese cable macho / macho.

Teniendo el ESP32 conectado y configurado en el IDE Arduino les recomiendo ya ir bajando el programa haciendo clic acá para luego ir viendo en pantalla las diferentes partes del soft conforme van leyendo esta publicación.

Al abrir el archivo con extensión INO nos carga en pantalla el sketch el cual como primer medida incluye la librería miWIFI.h la cual está en la misma carpeta del sketch y por ello esta comillada y no notada entre símbolos de menor y mayor como se suele ver. Estas comillas le indican que la librería la debe buscar en la misma carpeta donde se encuentra el sketch. Seguidamente se define donde está conectado (a que pin de E/S del ESP32) el LED incorporado en la placa Wemos y se le da un nombre fácil de entender, LED en mi caso y se definen los pines donde están las entradas de los tres pulsadores que disparan los tres eventos de este programa. La elección de estos pines no es aleatoria, no todos los pines del ESP32 soportan el uso de resistencias de puesta en alto o puesta en bajo en forma interna, les recomiendo siempre prestar atención a estos detalles a fin de evitar dolores de cabeza y extensas sesiones de trabajo en busca de errores pavos. En la función de configuración se define el modo de funcionamiento de los cuatro pines como se explicó recién y se inicia la memoria EEPROM interna del ESP32 en su capacidad máxima, 512 bytes aunque no se ocuparán todos. También se inicial la comunicación serie CDC con la PC a 115.200 baudios y se hace una pausa de medio segundo tiempo mas que sobrado para que se estabilice la UART interna y el administrador de EEPROM. Seguidamente el loop o bucle principal se encarga de mirar el estado de los tres pulsadores o mejor escrito sus entradas y en caso de no estar ninguna a GND cambia el estado del LED y espera 100 mili segundos con lo cual tenemos un LED destellando a 5 Hz dado que ofrece cinco destellos por segundo. En caso de presionarse alguno de los pulsadores su correspondiente entrada se irá a GND por lo que al ser detectado por el digitalRead correspondiente derivará el programa a alguna de las tres funciones que se explican a continuación:

apretoSeteaWIFI() cae aquí ni bien el pin es visto a GND pero se queda esperando durante 20 veces de 100 mili segundos o sea durante dos segundos. Tiempo durante el cual el LED sigue destellando como se puede ver pero tiempo durante el cual si el pin regresará a 1 por su pullup interna volvería al loop principal sin haberse hecho nada. Superados los 2.000 milisegundos o 2 segundos el programa llama a la función setearWIFI() la cual ya se encuentra en la librería miWIFI.h y luego explicare. Pero en resumidas para poder setear o configurar los parámetros de conexión hay que tener una pulsación firme y sostenida de dos segundos algo normal en casi todo tipo de aparato electrónico para evitar una involuntaria acción que pueda afectar el funcionamiento del equipo.

apretoLeeWFI() se ocupa de verificar que no sea una interferencia haciendo que el pulsador deba sostenerse a masa o GND durante al menos dos pasadas por la demora de 100 milisegundos osea 200 milisegundos y si durante ese breve tiempo volviera a estado lógico alto lo asume como un ruido o interferencia en tanto si trascurre los 200 milisegundos a nivel bajo llama a la función leeWIFI() ubicada en la librería miWIFI.h la cual se encarga de leer los parámetros almacenados en la EEPROM interna del micro y mostrarlos por terminal serie para luego regresar a esta función del sketch y quedar a la espera que el pulsador vuelva a estado alto (soltado) durante dicha espera, por supuesto, se atiende la intermitencia del LED. 

Por último la función apretoConectaWIFI() se encarga de iniciar la conexión a internet con los datos ya almacenados en la EEPROM interna no sin antes verificar como sucedió en la rutina anterior que el estado bajo del pin donde está conectado el pulsador de conectarse a internet se sostenga firmemente durante 200 milisegundos para evitar un disparo por interferencias o roces. Una ves establecida la conexión por medio de la función conectaWIFI() de la libería miWIFI.h que luego explicaré en detalle como funciona se queda esperando que suelte el pulsador manteniendo el destello del LED en tanto.

Hasta aquí todo lo que hace el sketch del programa si se preguntan porqué no hice mas nada es porque es un demo de librería, esta nota y su programa son para mostrar como se usa la librería el sketch sólo sirve para la aplicación principal y como tal no existe el sketch casi no existe tampoco!. Si alguno se pregunta porqué no incorporé en este sketch la librería EEPROM.h antes de inicializar la EEPROM con begin durante la función setup es porque dicha librería ya está incluída en el archivo miWIFI.h y al hacer el include a dicha librería ya se hizo el propio sobre la EEPROM.h.

Terminada la explicación del sketch de muestra ahora le toca a la verdadera estrella de la nota, la librería miWIFI.h

En sus dos primeras líneas incluye la librería estandar WiFi.h de Arduino la cual establece clases, funciones y tipos de datos propios de la comunicación y la librería EEPROM.h también de Arduino para el uso de dicha memoria dado que en ella se va a almacenar la configuración.

Se definen dos arreglos de char's o de bytes o cadenas de caracteres como mas les guste llamarlas donde se almacenarán el nombre de la red a la cual conectarse y la clave en caso de tenerla. Aquí hay que hacer una pausa y explicar que por estandarización un SSID o nombre de una red WIFI no puede tener mas de 32 caracteres así que 50 es demasiado, quedará para la próxima revisión modificar esto. Por tanto la clave puede tener como mínimo 5 caracteres de ser una WEP (ya casi nadie las usa) o de 8 a 63 caracteres de ser una WPA, WPA2, PSK o TRIP. En cuyo caso 50 caracteres le quedan chico! Si sumamos lo que hoy ocupamos tenemos 100 bytes de la EEPROM para nombre de red y clave y si sumamos lo que el estándar requiere tenemos 32 caracteres para el nombre y 63 para la clave 95 caracteres. En una próxima versión de esta librería espero contemplar dichos valores. El valor booleano (true / false o 1 / 0) llamado DHCP determina si los parámetros de conexión deberán ser obtenidos del modem o router (DHCP Client) o bien si serán provistos manualmente (lo que se suele denominar IP fija). Los cuatro arreglos de enteros siguiente contienen dichos parámetros en caso de no ser DHCP Client. Luego siguen cuatro posiciones de memoria, variables, registros o como quieran llamarlos utilizados en diferentes etapas de la librería en mas de una función por lo que lo he colocado para que existan en todas ellas. Para mencionarlas ciclo en general cuenta iteraciones en bucles, redes contendrá la cantidad de redes disponibles y si bien nadie tiene miles de redes WIFI como Roberto Carlos tiene amigos lo cierto es que poniendo 666 en el número de red nos permitirá ingresar manualmente el nombre de una red por lo que los ocho bits de un char no nos habría sido suficiente. La variable entero se ocupa durante el ingreso manual de direcciones como ser la IP fija, por ejemplo, para evitar que el usuario mande un 256 o mas y si fuera u char devolvería el complemento desde cero con lo cual sería un dato erróneo pero válido. En cambio al ocupar un int un 457 da eso mismo, 457 en vez de 202 que devolvería un char y con un simple if puedo determinar que ingresó un dato no válido. Por último el booleano conClave se encarga de preguntar la clave de acceso a una red WIFI ingresada manualmente algo que se explicará mas adelante cuando toque su turno.

Siguen los prototipos de funciones, algo normal en la programación C y ya de una se entra en la función setearWIFI() la cual es la mas grande de esta librería. Se declara un arreglo de caracteres de 50 posiciones donde se almacenarán temporalmente los caracteres recibidos por la función que se encarga de ello y devuelve un String. Luego se manda por comunicación serie a la terminal la identificación mecánica o MAC Address del módulo por si el punto de acceso inalámbrico donde se va a instalar requiere que la misma sea apuntada en la lista blanca. Seguidamente llama a la función que se encarga de listar las redes disponibles o dentro del alcance, función que no sólo envía por terminal dicho listado (ya veremos mas adelante como funciona) sino que devuelve además un valor correspondiente a la cantidad de redes detectadas y ese valor se guarda en la variable redes. Un ciclo infinito no condicionado conformado por el while(true) hace que lo que sigue a continuación se ejecute permanentemente para que el ingreso de un dato incorrecto por parte del usuario a través de la terminal no cancele todo el proceso de configuración y haya que hacer todo nuevamente desde cero, algo que a mi gusto es frustrante. Queda ahora el programa a la espera de recibir algo por el terminal lo cual quedará almacenado en recibido, el char array declarado al comienzo de esta función. Si lo recibido es el signo de pregunta ? se vuelve a generar el listado de redes en alcance. Cabe aclarar que cada vez que se llama a la función listarRedesWIFI() se escanea nuevamente el espectro por lo que no es una simple repetición de la misma lista dada primeramente, esto se hace así para encontrar en segundas o terceras pasadas redes antes no vistas. De no haber recibido el signo de interrogación se convierte el valor recibido (arreglo de caracteres) en un número entero y se lo trata como tal viendo que no sea el comando 666 y que no esté el valor fuera de rango. Si el listado de redes dio 15 redes y el usuario responde 20 recibe por terminal un aviso de fuera de rango y vuelve a esperar el ingreso de un número válido o el comando 666. Superada la verificación de dentro de rango se ejecuta el código que sigue al else entendiéndose que o bien se ha elegido una red listada ingresando su número dentro del rango listado o bien se ha ingresado el 666 indicando que se quiere ingresar una red manualmente. Lo primero que se atiende es la posibilidad del 666 lo cual es necesario si estamos configurando el acceso a una red cuyo SSID o nombre de red no es visible por cuestiones de seguridad o bien si estamos agregando al aparato una red que no está disponible en ese preciso momento pero ya queremos dejarlo configurado. Esto es, por ejemplo, útil cuando enviamos el aparato pre-configurado a su destino de uso final. Al ingresar 666 se le pide al terminal que reciba el nombre de la red oculta a agregar y se pregunta si la misma tiene o no tiene clave de acceso. En caso de recibir una S por respuesta a dicha pregunta pide la clave de red correspondiente. En el caso de no haber recibido un 666 por número de red seleccionada pone en pantalla de la terminal el nombre de dicha red (SSID) y verifica que tipo de seguridad tiene. De no ser una red abierta pide que el usuario ingrese la clave. Nótese que, al igual que cuando se ingresa manualmente el nombre de red, al ingresar la clave de acceso a la red inalámbrica el programa recibe desde la terminal una seguidilla de datos los cuales vuelven de la función recibirSerial() a vuelta de String (la función devuelve este tipo de dato) y como nosotros necesitamos acomodarlos en arreglo de caracteres usamos la clase toCharArray de String para hacerlo dicho pase quedando el nombre de red y la clave acomodados en sendos arreglos de chars. A continuación se utiliza la variable DHCP para indagar al usuario vía terminal si debe obtener los datos de comunicación automáticamente (cliente DHCP) o bien si deben ser ingresados manualmente por tratarse de IP fija. Estos datos son la dirección IP del módulo ESP32, la máscara de subred que suele ser 255.255.255.0, la puerta de enlace predeterminada (o gateway) que suele ser la misma IP que la del router de internet y la dirección IP del servidor de nombres de dominio o DNS que o bien suele ser la misma que la del router o bien alguno fijo preferido como el de google que es 8.8.8.8. La estructura de ingreso de estos valores es octeto a octeto sin poner los puntos. Por ejemplo: para poner la IP 192.168.0.1 habrá que poner 192 y presionar ENTER o enviar, 168 y enviar, 0 y enviar y por último 1 y enviar. Por ello el for donde la variable ciclo va de 0 a 3, esta variable es la que determina en que posición del arreglo de cuatro enteros de cada valor va el número recibido. Número que se recibe a través de la misma función que se recibieron el nombre de red en caso de haberse usado dicha opción y la clave de seguridad en caso de haber sido necesaria. recibirSerial().toCharArray(recibido, 50) precisamente guarda en el arreglo de caracteres recibido el número que el usuario envió por la comunicación serie como bien podría ser 192. El while(entero>255) se encarga de pedir repetidamente un valor válido para octeto de IP hasta que suceda, por ello arranca trampeado en 256 antes de entrar a cada while porque de no hacer esta precarga no entraría desde el vamos. Ahora queda en evidencia porqué entero tenía que ser una variable del tipo int y no del tipo char porque si bien para los octetos de una IP char es suficiente no se podría hacer la verificación de valor excedido si no fuera int. Recibido un número dentro del rango se lo almacena en el octeto correspondiente nuevamente apuntado por ciclo y si corresponde pinta el consabido punto entre octetos. Al finalizar el cuarto octeto un println vacío asegura el necesario salto de línea para el próximo parámetro de IP fija. Los restantes parámetros funcionan de la misma forma que el de IP por lo que no vale la pena explicarlos individualmente. Luego de recibidos los datos se procede a guardarlos en la EEPROM interna y para ello se emplea un for de 50 iteraciones nuevamente a través de la consabida variable ciclo. En las primeras cuatro iteraciones (cuando ciclo valga 0, 1, 2 y 3 se graban casi todos los parámetros menos DHCP que se graba por fuera del bucle. En la quinta iteración y hasta la última sólo se guardan nombre de red y clave de red. Terminado el for porque ciclo llegó a 49 graba en la posición 100 el valor del booleano DHCP (que sólo puede ser 0 o 1 por ser booleano) y terminado este proceso se informa al usuario por medio de un mensaje vía terminal que se ha establecido la configuración correctamente. Llamando a la función conectaWIFI() se inicia el proceso de conexión y se volverá de dicha función sólo cuando la conexión esté establecida. La última instrucción de esta función es la que devuelve la ejecución al sketch donde se llamó a la función evitado así la iteración permanente del while(true) inicial. 

La siguiente función de la librería, listarRedesWIFI() retorna un entero con la cantidad de redes detectadas por el ESP32 y además genera en la pantalla de terminal la lista de las mismas. La función de Arduino WiFi.scanNetworks() se encarga de obtener dicho valor y adicionalmente genera un listado en memoria al cual accederemos por medio de la función WiFi.SSID(indice). Aquí hay que tener presente que si scanNetworks() devolvió 14 porque hay esa cantidad de redes el índice de dichas redes es de 0 a 13 por ende para generar el listado usamos el for con un valor que arranca en 0 y llega a uno antes que redes pero para ponerle un número en pantalla de terminal le sumamos 1 así no arranca de la red 0 sino de la primera. Luego de cada nombre de red se llama a una función seguridadWIFI() la cual recibe como parámetro el indice de la red y nos devuelve en letras el tipo de seguridad de esa red. Terminado de emitir el listado por terminal se deja una línea de separación y se pide que el usuario ingrese datos, en este caso el número de la red que quiere elegir, o ? para volver a listar o bien 666 para agregarla manualmente. Vemos a continuación que la función seguridadWIFI() no hace mas que darle un print de terminal bonito y entendible a cada valor de seguridad recibido aunque no era algo muy necesario queda bien hacerlo.

Seguidamente la función recibirSerial() se encarga de quedarse a la espera de datos por el CDC, un detalle que habría que tener en mente para una próxima versión es un timeout en este punto puesto que si el tipo se desconecta de la PC o lo que fuera que impide recibir datos aquí quedo plantado el programa. Básicamente se encarga de esperar por el caracter 10 ó \n que es el encargado de indicar "hasta aquí llega el dato" esto es importante porque si enviamos por terminal HOLA y presionamos enter, nosotros en la placa recibimos una H, una O una L, una A y el 10 ó \n y si no procesamos lo recibido desde que comenzamos a esperar por el hasta el caracter 10 nunca sabremos que es lo recibido. Ahora que termine el programa y teniéndolo presente para una futura versión por ahí en vez de retornar un String como objeto usaría recibido como un char array global a todo el proyecto y me evito los tediosos (para el CPU) toCharArray del obtejo String. Será para la próxima!

La siguiente función, calidadEnlace(), también devuelve un String el cual se ocupa directamente sobre el terminal serie. Aquí también se podría haber omitido todo este asunto de la devolución de un objeto y su conversión a puntero para mandarlo por terminal y hacer que esta función directamente escriba por terminal no devolviendo nada!. Cabe aclarar como dice en los comentarios que los valores son referidos a información Googleada y no a datos propios del ESP32 y que teniendo presente que el módulo de WIFI del ESP es bastante precario seguramente en algún momento resuma esto a MALA, REGULAR y BUENA y basta! Pero por ahora queda así como esta.

La siguiente función leeWIFI() tiene como únicos dos pasos obtener de la EEPROM los datos de conexión previamente almacenados y luego mostrarlos por terminal serie.

La función datosConexion() precisamente envía por terminal serie los datos de conexión disponibles en variables de memoria, no en la EEPROM. Nótese como se utilizan los for para el muestreo de los octetos de los datos de conexión para IP fija.

Para la lectura de los parámetros almacenados en la EEPROM interna tenemos la función leeEEPROM() la cual básicamente recorre con un for las 117 posiciones destinadas a los distintos parámetros de conexión. Esta función sólo carga en variables de memoria los datos presentes en la EEPROM mas no los muestra por terminal.

La última pero no menos importante función de la librería es conectaWIFI() la cual se encarga como su nombre lo dice de conectarse a internet. Primeramente verifica si no se encuentra ya conectado y en caso de estarlo sale inmediatamente evitando ejecutar el resto de la función, esto se logra por medio de la función WiFi.status() propia de Arduino. De no estar conectado informa por terminal serie que se va a conectar a determinada red y comprueba si en la configuración se marcó a la misma como de IP fija. De ser así por medio de la función WiFi.config() del Arduino se establecen los parámetros de IP, máscara de subred, puerta de enlace y servidor DNS todo esto previo a la conexión. Ahora si se inicia la conexión especificando el nombre de la red (nombre del SSID) y clave de acceso en caso de ser requerida. Por medio de la misma función empleada al comienzo para ver si estaba ya conectado se espera que suceda la conexión y mientras se espera que suceda se va contando el tiempo que demanda y cada un segundo se agrega un punto vía terminal serie a modo de indicador de progreso, para evitar dar la impresión de un proceso colgado. Una vez establecida la conexión se muestra el tiempo demandado y los parámetros de la misma incluyendo el nivel de señal.

Hasta aquí la explicación de la librería, veamos ahora un poco de práctica. Conectar la placa ESP32 a la PC y de ser posible a alimentación externa aunque esto último no es del todo necesario si es preventivo. Luego abrir el Arduino IDE y setear todos los parámetros de la placa espressif en caso de no estar seteados ya. Luego abrir el programa serialesp y luego grabarlo en el ESP32. Una vez grabado el programa abrir el terminal serie de Arduino o cualquier otro terminal que prefieran y verificar la velocidad de conexión 115.200 para evitar errores de comunicación. Poner a masa el pin 27 y tras dos segundos aparecerá la dirección MAC en pantalla y la configuración podrá realizarse como se ve en la terminal a continuación:

Un detalle a tener presente para la próxima revisión de la librería es que aparezca en pantalla el número de red donde dice "Ingresa el número de la red a utilizar: " dado que si bien luego pone el nombre en Red seleccionada lo cierto es que quedaría bien que saliera dicho valor. Seleccionada la red se indica la clave, luego si debe obtener los datos en forma automática o no, yo le puse que si porque estaba compartiendo internet desde mi celular y luego aparece que guardó la configuración, que intenta conectarse y finalmente que está conectado y con qué parámetros. De haber respondido N a la pregunta de obtener los datos automáticamente me habría pedido la IP a asignarle al módulo ESP32, la máscara de subred, la puerta de enlace y el servidor DNS. Como se explicó antes la forma de ingresar dichos valores es un número como ser 192 y enter (sin el punto) otro número y enter y así hasta el cuarto y último octeto. En pantalla luego salen los números, el programa los va poniendo. 

Aquí vemos en la captura de pantalla del celular el módulo conectado a internet a través del mismo. Y en caso de no lograr ver al HotSpot del celular desde el espressif hay que recordar que los ESP32 sólo operan la banda de 2.4GHz ya sea en B, G y N mientras que algunos celulares sobre todo los que tienen capacidad de HotSpot tienen tanto la banda de 2.4GHz como la de 5GHz y en caso de estar configurado el HotSpot en esta última el ESP32 no podrá verlo. En algunos celulares la banda de 5GHz sale como AC.

Terminado el tema conectividad hasta ahora este programa sólo hace destellar un LED y por mas que los defensores de espressif me digan "eh! vos te olvidas lo que es manejar el TCP-IP y arriba la conexión WIFI???" mi respuesta es que claro que no me olvido, lo tengo muy presente pero así como lo ven este programa ya demanda el 48% de la memoria de programa del ESP32, unos 630.482 bytes y utiliza el 11% de la memoria RAM dejando libres de usarse otros 288.812 bytes de RAM para la aplicación el día que la tengamos! Para los mas conocedores les comento que lo he desarrollado con el esquema de partición estándar de 4MB con lo cual quedan 1.2MB para la aplicación (programa) y 1.5MB para el sistema de archivos SPIFFS. Con esta es la tercera vez que hago el intento de hacer un programa para configurar decentemente el WIFI de un ESP la primera vez lo hice empleando el Bluetooth lo cual me pareció lo mas natural dado que el ESP32 tiene dicho módulo internamente. Antes de terminar con el programa ya se me había llenado el espacio de 1.2MB que deja en configuración estándar y tuve que pasarlo a la configuración mas apretada de todas, el esquema HUGE APP en el cual 3MB se destinan al programa en sí, no hay espacio para las actualizaciones inalámbricas (no OTA) y 1MB queda destinado al sistema de archivos SPIFFS. De todas formas pronto voy a terminar dicho programa y con gusto lo voy a subir a esta sección del sitio porque seguramente a alguien le va a servir. Por último antes de esta versión hice otro programa que ofrecía configurarlo a través de un HotSpot, actuando el ESP32 como un punto de acceso inalámbrico al cual nos conectamos y generando un contenido el cual navegamos ya sea por celular o computadora con WIFI. Y si bien ocupaba muchísimo menos que la versión por Bluetooth lo cierto es que no me convencía demasiado y quedó en el camino, bastante inconclusa por cierto. Luego vino esta que para mi fué la versión mas prolija por ello quería compartirla con ustedes, espero que les sea de utilidad.

Pablo Canello, 26/04/2020