ESP32 SmartConfig-App

Para la configuración inicial de los dispositivos requiere una aplicación en un dispositivo tablet o móvil para configurar la conexión a la red WiFi con los datos de SSID y Password.

El concepto presentado por espressif con documentación actualizada al 2018.06.08 se encuentra en:

https://www.espressif.com/en/products/software/esp-touch/overview

https://www.espressif.com/sites/default/files/faq/screen_shot_2016-04-27_at_1.30.27_pm_0.png
Figura: Espressif https://www.espressif.com/sites/default/files/faq/screen_shot_2016-04-27_at_1.30.27_pm_0.png

La implementación de la aplicación que se usó para probar el ejercicio se encuentra en Google Play. Revisar el desarro de la aplicación realizará como otro tema.

https://play.google.com/store/apps/details?id=com.cmmakerclub.iot.esptouch

El procedimiento de conexión tiene dos partes:

  1. Modo configuración de WiFi, usando la aplición SmartConfig
  2. Modo normal de conexión WiFi, con los datos WiFi ya configurados

Para seleccionar los modos se usa una botonera «Configuración»  en un pin digital disponible con funcion y circuito semejante a RESET, en el ejemplo se usa GPIO14.

Modo configuración de WiFi

Para iniciar el modo configuración de la red se deben usar las botoneras «Configuración» y «RESET» con la secuencia:

1. pulsar Botonena GPIO14 y mantener pulsada
2. Luego pulsar y soltar reset
3. Mantener pulsado GPIO14 por 5 segundos después y soltar
4. Usar el móvil/tableta con la aplicación SmartConfig para configurar
5. Escribir SSID y password en móvil/tablet y «confirmar»
6. Esperar confirmación y estará conectado.

Modo normal de conexión WiFi

Es el modo predeterminado de operación, no requiere presionar el botón de «Configuración». Arranca con los valores almacenados de SSID y PASSWORD.

Monitor Serial

Los resultados del proceso de configuración y conexión a WiFi se muestran a continuación. Para fines de muestra, se ha demorado la activación con el móvil/tablet, note que la conexión a WiFI se realiza casi inmediatamente (tres puntos …)

....ets Jun  8 2016 00:22:57

rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
ets Jun  8 2016 00:22:57

rst:0x10 (RTCWDT_RTC_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:1
load:0x3fff0018,len:4
load:0x3fff001c,len:1100
load:0x40078000,len:10088
load:0x40080400,len:6380
entry 0x400806a4
configurando WiFi
Esperando conexión SmartConfig móvil/tablet
........................................
 Esperando conexión SmartConfig móvil/tablet
...............
 Finalizado SmartConfig.

 Conectando a WiFi
...
 WiFi conectado , Dirección IP: iotirni19 , 192.168.10.102
conectado a:
iotirni19 , 192.168.10.102 , -56
conectado a:
iotirni19 , 192.168.10.102 , -53
conectado a:
iotirni19 , 192.168.10.102 , -54
conectado a:
iotirni19 , 192.168.10.102 , -55
conectado a:
iotirni19 , 192.168.10.102 , -55
conectado a:
iotirni19 , 192.168.10.102 , -55

Instrucciones Arduino

Las instrucciones se han dividido por bloques: configura_wifi() y conecta_wifi(). En ambas funciones se presentan mensajes y parpadeos de led.

Configura_wifi() espera a que se obtenga un valor afirmativo para WiFi.smartConfigDone() y finalizar.

Conecta_wifi() es muy semejante a la función inicia_wifi() usada en los primeros ejemplos que usaba variables para SSID y Password()

/* ESP32 Smart Config de Espressif
modificado a partir de:
https://www.espressif.com/en/products/software/esp-touch/overview
Usa el GPIO14 en estado LOW para entrar en modo configuración.
Usar BOTONERA "CONFIGURACION" en pin14, con pullup (HIGH)
Para configurar:
1. pulsar Botonena GPIO14 y mantener pulsada
2. Luego pulsar y soltar reset
3. Mantener pulsado GPIO14 por 5 segundos después y soltar
4. Usar el móvil/tableta con la aplicación SmartConfig para configurar
5. Escribir SSID y password en móvil/tablet y "confirmar"
6. Esperar confirmación y estará conectado.
*/
#include <WiFi.h>

// PIN configuración
const PROGMEM uint8_t CONFIG_pin = 14; 

// LED monitor interno
//ESP01-pin=1, ESP07-pin=2; ESP32-pin=5
const PROGMEM uint8_t LED_pin = 5; 

void setup() {
    Serial.begin(115200);

    // PIN configuración
    pinMode(CONFIG_pin, INPUT);
    
    // LED monitor
    pinMode(LED_pin, OUTPUT);
    
    // Revisa si entra a modo configuración
    if (digitalRead(CONFIG_pin)==LOW){
        Serial.println("configurando WiFi");
        // configura con SmartConfig
        configura_wifi();
    }
    // Modo conexión a Router
    conecta_wifi();

}
void loop() {
    // Ejemplo de tarea a realizar.
    Serial.println("conectado a:");
    Serial.print(WiFi.SSID());
    Serial.print(" , ");
    Serial.print(WiFi.localIP());
    Serial.print(" , ");
    Serial.println(WiFi.RSSI());
    // LED interno enciende en LOW
    digitalWrite(LED_pin, HIGH);
    delay(100);
    digitalWrite(LED_pin, LOW);
    delay(100);
    digitalWrite(LED_pin, HIGH);
    delay(100);
    digitalWrite(LED_pin, LOW);
    delay(250);
    // termina ejemplo
    delay(1000);
}

void configura_wifi(){
    // inicia en modo estación
    WiFi.mode(WIFI_AP_STA);
    WiFi.beginSmartConfig();
    int cuenta = 0;
    // Espera por un paquete Smartconfig del móvil/tablet
    Serial.println("Esperando conexión SmartConfig móvil/tablet");
    while (!WiFi.smartConfigDone()) {
        delay(500);
        Serial.print(".");
        cuenta = cuenta+1;
        if (cuenta>=40){
            Serial.println("\n Esperando conexión SmartConfig móvil/tablet");
            cuenta = 0;}
        // LED interno enciende en LOW
        digitalWrite(LED_pin, HIGH);
        delay(50);
        digitalWrite(LED_pin, LOW);
        delay(50);
        }
    Serial.println("\n Finalizado SmartConfig.");
    }

void conecta_wifi() {
    // conexion WiFi
    Serial.println("\n Conectando a WiFi");
    
    WiFi.begin();//ssid, password);
    int cuenta = 0;
    while (WiFi.status() != WL_CONNECTED){
        Serial.print(".");
        cuenta = cuenta+1;
        if (cuenta>=40){
            Serial.println();
            cuenta = 0;}
        // LED interno enciende en LOW
        digitalWrite(LED_pin, LOW);
        delay(250);
        digitalWrite(LED_pin, HIGH);
        delay(250);
        }
    Serial.print("\n WiFi conectado , Dirección IP: ");
    Serial.print(WiFi.SSID());
    Serial.print(" , ");
    Serial.println(WiFi.localIP());
    delay(10);
}

Por desarrollar:
Personalizar la aplicación del móvil/tableta a partir del código básico de espressif.

Referencias:
https://www.espressif.com/en/products/software/esp-touch/overview

https://www.espressif.com/sites/default/files/documentation/esp-touch_user_guide_en.pdf

ESP32 BuscarRedes

Búsqueda de redes cercanas y sus respectivas potencias, la red marcada con rojo es el ESP32  revisado desde una laptop.

Busca redes WiFi cercanas
Busqueda completada 
29 redes encontradas
1: ESP_0A797B (-46) 
2: GUAIFAI (-62)*
3: Red Oculta
...

Instrucciones

Usando la libreria WiFi.h

/* Redes disponibles
 *  Realiza una búsqueda de redes Wifi cercanas
 */
#include <WiFi.h>

void setup()
{
    Serial.begin(115200);

    // Si estaba conectada como estación, se desconecta.
    WiFi.mode(WIFI_STA);
    WiFi.disconnect();
    delay(100);

    Serial.println("Configuración completada.");
}

void loop()
{
    Serial.println("Busca redes WiFi cercanas");

    //determina el número de redes cercanas
    int n = WiFi.scanNetworks();
    Serial.println("Busqueda completada ");
    
    if (n == 0) {
        Serial.println("NO se encontraron redes.");
    } else {
        Serial.print(n);
        Serial.println(" redes encontradas");
        for (int i = 0; i < n; ++i) {
            // Muestra el SSID y RSSI de cada red encontrada
            Serial.print(i + 1);
            Serial.print(": ");
            Serial.print(WiFi.SSID(i));
            Serial.print(" (");
            Serial.print(WiFi.RSSI(i));
            Serial.print(")");
            Serial.println((WiFi.encryptionType(i) == WIFI_AUTH_OPEN)?" ":"*");
            delay(10);
        }
    }
    Serial.println("");

    // Espera antes de la próxima búsqueda...
    delay(5000);
}

Referencia: https://github.com/espressif/arduino-esp32/blob/master/libraries/WiFi/examples/WiFiScan/WiFiScan.ino

ESP32 SoftAP

Para crear un Access Point se usa de la libreria la intrucción WIFI.softAP()

Como base se tiene el ejercicio de una página web para encender o apagar el LED incorporado.

En ésta ocasión no es necesario conectarse a un router, el AP aparece en la lista de dispositivos circundantes. Se selecciona y se ingresa con el nombre de red y la contraseña.

/* ESP32 Soft AP con web server para encender LED_Pin
forma básica con la función inicia_wifi
Referencia: https://www.arduino.cc/en/Tutorial/WiFiWebServer  
*/
#include <WiFi.h>

const char* ssid     = "iotirni19_AP";
const char* password = "xxxxx";

// puerto de servidor web 80
const PROGMEM uint8_t puertoweb = 80;
WiFiServer server(puertoweb);

// LED monitor interno
//ESP01-pin=1, ESP07-pin=2; ESP32-pin=5
const PROGMEM uint8_t LED_pin = 5; 
int LED_estado = 0;

void setup()
{
    // Conexion serial
    Serial.begin(115200);
    Serial.setTimeout(500);
    // espera inicializar serial
    while(!Serial) { }

    // LED monitor
    pinMode(LED_pin, OUTPUT);
    delay(10);

    // Convertir en AP
    WiFi.softAP(ssid, password);
    //inicia_wifi(); // no se conecta a un router
    server.begin();
}

void loop(){
    WiFiClient client = server.available();
    if (client){
        String linea = "";
        Serial.println();
        Serial.println("Nuevo cliente.");
        while (client.connected()) {
            if (client.available()) {
                char c = client.read();
                Serial.write(c);
                if (c == '\n') {
                    // Si recibe fin de linea y la linea es vacia,
                    // la peticion http finalizó, se responde:
                    if (linea.length() == 0) {
                        // HTTP headers inician con ésta secuencia:
                        client.println("HTTP/1.1 200 OK");
                        client.println("Content-type:text/html");
                        client.println();
                        // contenido despues de headers
                        client.print("LED estado: ");
                        client.print(String(LED_estado)+"
");
                        client.print("Click <a href=\"/H\">ENCIENDE LED</a><br>");
                        client.print("Click <a href=\"/L\">   APAGA LED</a><br>");
                        // finaliza contenido:
                        client.println();
                        // sale del lazo:
                        break;
                    } else {
                        linea = "";
                    }
                } else if (c != '\r') {
                    linea = linea + c;
                }
            // Revisa click del cliente "GET /H" or "GET /L":
            if (linea.endsWith("GET /H")) {
                digitalWrite(LED_pin, HIGH);
                LED_estado = 1;
            }
            if (linea.endsWith("GET /L")) {
                digitalWrite(LED_pin, LOW);
                LED_estado = 0;
            }
        }
    }
    delay(1); // espera que browser procese
    client.stop(); // cierra conexión:
    Serial.println("Cliente desconectado.");
    }
}

ESP32 WebServer Blink

Enciender y Apagar elLED incorporado (Pin 5) en el módulo ESP32 desde una página web.

https://learn.sparkfun.com/tutorials/esp32-thing-hookup-guide

El módulo se configura como un Web Server para responder a las petición desde un browser. La dirección mostrada en la figura es un ejemplo.

La librería  básica usada es WiFi.h con los valores de SSID y Password para acceder a la red existente, valores que se deben actualizar de acuerdo a la configuración de su red. El router asigna una dirección IP de forma automática, y su valor se muestra en el monitor serial, dirección usada en un brower para observar el resultado.

Monitor Serial

ets Jun 8 2016 00:22:57

rst:0x10 (RTCWDT_RTC_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:1
load:0x3fff0018,len:4
load:0x3fff001c,len:1100
load:0x40078000,len:10088
load:0x40080400,len:6380
entry 0x400806a4

Conectando a RedWifi
..
WiFi conectado 
Dirección IP: 192.168.10.104

Para simplificar las instrucciones, la sección de conexión a la red WiFi se realiza en la función inicia_wifi().

Instrucciones:

Para iniciar el modo servidor web se requiere WifiServer server(puertoweb), el puerto web es el 80.

En el programa se revisa el estado del cliente (client): conectado, disponible, leyendo cada caracter enviado por el browser e interpretando las instrucciones por cada fin de línea (‘\n’).

Si la línea recibida finaliza con «GET /H» o «GET /L» se realiza el cambio de estado del LED.

Al final se cierra la conexión, y se continua monitoreando el estado del cliente.

/* ESP32 web server para encender LED_Pin
forma básica con la función inicia_wifi
Referencia: https://www.arduino.cc/en/Tutorial/WiFiWebServer  
*/
#include <WiFi.h>

const char* ssid     = "";
const char* password = "";

// puerto de servidor web 80
const PROGMEM uint8_t puertoweb = 80;
WiFiServer server(puertoweb);


// LED monitor interno
//ESP01-pin=1, ESP07-pin=2; ESP32-pin=5
const PROGMEM uint8_t LED_pin = 5; 

void setup()
{
    // Conexion serial
    Serial.begin(115200);
    Serial.setTimeout(500);
    // espera inicializar serial
    while(!Serial) { }

    // LED monitor
    pinMode(LED_pin, OUTPUT);
    delay(10);

    inicia_wifi();
    server.begin();
}

void loop(){
    WiFiClient client = server.available();
    if (client){
        String linea = "";
        Serial.println();
        Serial.println("Nuevo cliente.");
        while (client.connected()) {
            if (client.available()) {
                char c = client.read();
                Serial.write(c);
                if (c == '\n') {
                    // Si recibe fin de linea y la linea es vacia,
                    // la peticion http finalizó, se responde:
                    if (linea.length() == 0) {
                        // HTTP headers inician con ésta secuencia:
                        client.println("HTTP/1.1 200 OK");
                        client.println("Content-type:text/html");
                        client.println();
                        // contenido despues de headers
                        client.print("Click <a href="\"/H\"">ENCIENDE LED</a>
");
                        client.print("Click <a href="\"/L\"">   APAGA LED</a>
");
                        // finaliza contenido:
                        client.println();
                        // sale del lazo:
                        break;
                    } else {
                        linea = "";
                    }
                } else if (c != '\r') {
                    linea = linea + c;
                }
            // Revisa click del cliente "GET /H" or "GET /L":
            if (linea.endsWith("GET /H")) {
                digitalWrite(LED_pin, HIGH);
            }
            if (linea.endsWith("GET /L")) {
                digitalWrite(LED_pin, LOW);
            }
        }
    }
    delay(1); // espera que browser procese
    client.stop(); // cierra conexión:
    Serial.println("Cliente desconectado.");
    }
}

void inicia_wifi() {
    // conexion WiFi
    Serial.print("\n Conectando a ");
    Serial.println(ssid);
    WiFi.begin(ssid, password);
    int cuenta = 0;
    while (WiFi.status() != WL_CONNECTED){
        Serial.print(".");
        cuenta = cuenta+1;
        if (cuenta>=40){
            Serial.println();
            cuenta = 0;}
        // LED interno enciende en LOW
        digitalWrite(LED_pin, LOW);
        delay(250);
        digitalWrite(LED_pin, HIGH);
        delay(250);
        }
    Serial.print("\n WiFi conectado \n Dirección IP: ");
    Serial.println(WiFi.localIP());
    delay(10);
}

Puntos por desarrollar

  • Añadir en la pagina el estado del LED. Sugerencia: aumentar una variable de estado para el led y usarla en la página html.
  • Conectar a un servidor MQTT e iniciar el estado del LED con el correspondiente en el Estado MQTT.

Referencia: https://www.arduino.cc/en/Tutorial/WiFiWebServer

ESP8266 versión ESP07

La versión del módulo ESP-07 ofrece más puntos de conexión que la versión ESP-01. http://wiki.ai-thinker.com/_media/esp8266/docs/aithinker_esp_07_datasheet_en.pdfPara la implementación básica ser recomienda usar la versión con antena incorporada y una placa para adaptar el módulo.

La placa permite conectarlo a un protoboard, pues la separación entre conectores del módulo es pequeña (2 mm).

Una de las ventajas del ESP-01 es convertidor Analógico-Digital (pin ADC), que tiene un rango de trabajo entre 0 y 1 voltio con pasos valorados entre 0-1023 (10 bits).

El pin ADC permite por ejemplo obtener lecturas de estado de voltaje de las baterias, obtenido con un divisor de voltaje  para asegurar que el voltaje máximo no supere 1V .

IDE Arduino

Para incorporar la tarjeta al programa IDE Arduino se se realizan los mismos que para la versión ESP-01, seleccionando la placa ESP8285.

Referencia: http://wiki.ai-thinker.com/_media/esp8266/docs/aithinker_esp_07_datasheet_en.pdf

 

ESP8266 versión ESP01

Distribución de Pines

Referencias: https://www.espressif.com/sites/default/files/esp8266-technical_reference_en_0.pdf

Para usa el módulo, se requeire además de alimentacion en VCC a 3.3V y GND  conectar los pines de configuración de modo de operación.

Estados de pines de configuración

Los estados de los pines de configuración son ALTO (HIGH) o BAJO(LOW).

El estado ALTO se establece conectar el pin a VCC de 3.3VDC mediante una resistencia de 10KΩ (pullup) para una corriente de activación de 0.033 mA.

El estado Bajo se realiza conectando el pin a GND con 0VDC.

Modo de Operación

Cargar o Ejecutar un programa se establece con estados de voltaje en los pines GPIO0 y GPI02.

Modos de operación
GPIO0 GPIO2 CH_PD RESET
 Cargar programa LOW HIGH HIGH HIGH
Ejecutar Programa HIGH HIGH HIGH HIGH

Observe que, el módulo ESP-01S, tiene incorporadas las resistencias a estado ALTO (HIGH,pull up), por lo que no es necesario añadirlas en éste caso.

Conexión a 3.3V

La alimentación de energía para el dispositivo es de 3.3V, preferible con una fuente o módulo de 3.3v .

Considere que puede resultar insuficiente si alimenta desde la salida de 3.3V de un módulo  USB-Serial con salida de 3.3V o desde el pin Arduino 3.3V.

La falta de energía en el dispositivo se presenta como error en la conexión al intentar subir instrucciones desde el IDE Arduino: «sincronizar la memoria del dispositivo.»

Si no dispone de la fuente externa, puede  al usar dos dispositivos USB-TTL para:

1. Alimentación (Vcc y GND)
2. Carga de datos (Tx y Rx)

Recuerde unir las referencias de cada dispositivo USB-Serial GND.