Como programa en ESP32 S2 Mini con ESP-IDF: Control Automático de Foco
Introducción
En estas últimas semanas, me ha interesado bastante el mundo de la electrónica, específicamente las placas de desarrollo como Arduino y ESP32. Aprovechando que mi hermano menor tenía un proyecto de ciencias que involucraba el cultivo de una planta en un ambiente oscuro y proporcionarle luz mediante una lámpara durante 8 horas diarias, se me ocurrió utilizar estas placas de desarrollo para automatizar el proceso y de paso aprender a utilizar la placa ESP32 S2 mini. Por eso, este post del blog tratará sobre cómo programar la ESP32 S2 Mini con ESP-IDF para un proyecto de IoT.
Propuesta
El sistema consta de una placa ESP32-S2 mini conectada a un relé que controlará el flujo de energía hacia la lámpara. Dado que se requiere un control horario para encender o apagar la luz, la placa necesitará conectarse a Internet para obtener la hora actual y sincronizar su reloj interno. Esto es necesario ya que estas placas no disponen de una batería interna para mantener el reloj funcionando cuando están apagadas, como sucede en las computadoras y teléfonos. Adjunto un diagrama para facilitar la comprensión.
Como se puede observar en el diagrama, el relé se conecta al pin de 3.3 voltios y a tierra en sus respectivos pines positivo y negativo. El pin que controla el relé se conecta al GPIO34. Luego, en el relé, la corriente proveniente de la red eléctrica se conecta al conmutador y luego otro cable sale del puerto NC del relé. Este puerto NC significa Normally Closed, ya que solo va a suministrar energía durante 8 horas; el resto del tiempo debe permanecer apagado.
Materiales, Herramientas y Tecnologías Necesarias
- ESP32 S2 Mini
- Foco
- Plafón
- Módulo de relé
- Cables para conectar el módulo con la placa y la corriente con la bombilla y el relé
- Tener instalado ESP-IDF (revisar la documentación oficial de ESP-IDF para instalarlo)
- Cable USB-C que pueda transmitir datos (algunos no transmiten datos y no sirven para flashear la imagen)
Creación del Proyecto ESP-IDF para ESP32 S2 Mini
Con la extensión de ESP-IDF configurada en Visual Studio Code, seleccione la extensión y en 'New Project Wizard' para empezar a crear el proyecto. Una vez abierta la pantalla de nuevo proyecto, complete la información de dónde va a estar ubicado el proyecto, nombre del proyecto y puerto de la placa.
NOTA: Para que aparezca el puerto, antes de abrir la pantalla de creación de nuevo proyecto, debe colocar la placa en modo Device Firmware Upgrade. Simplemente mantenga presionado el botón
0
, luego presione el botónRST
y, finalmente, suelte el botón0
.
Procede a seleccionar el template del proyecto. Elige el template template-app
y crea el proyecto.
Una vez creado el proyecto, queda una última tarea por hacer, que es modificar el canal de salida de la consola. Mientras desarrollaba el código para este proyecto, me encontré con el problema de que la placa no mostraba nada al acceder a la consola serial. Después de investigar un poco en Internet, encontré este post del foro ESP32, el cual me ayudó a solucionar este problema. La solución es simple: solo hay que entrar en menuconfig >> Component config >> ESP System Settings >> Channelfor console output y seleccionar USB CDC.
Código del Proyecto
Esta parte puede resultar densa, así que solo daré una breve descripción del código y adjuntaré un enlace al repositorio de este proyecto. También proporcionaré un archivo ZIP del proyecto por si acaso decido eliminarlo de mi GitHub.
La estructura general del proyecto es la siguiente:
- components
- sntp_control
- sntp_control.c
- sntp_control.h
- wifi
- wifi.c
- wifi.h
- sntp_control
- main
- main.c
El archivo main.c
es el punto de entrada del proyecto y hace uso de los módulos de WiFi y control de SNTP. Su código es el siguiente:
// import components
#include "wifi.h"
#include "sntp_control.h"
#include "esp_sleep.h"
#include "esp_system.h"
#include "esp_event.h"
#include "esp_log.h"
#include "nvs_flash.h"
#include "driver/gpio.h"
void init_gpio()
{
// init the GPIO for Relay
...
}
void app_main(void)
{
esp_err_t ret = nvs_flash_init();
if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND)
{
ESP_ERROR_CHECK(nvs_flash_erase());
ret = nvs_flash_init();
}
ESP_ERROR_CHECK(ret);
init_gpio();
init_wifi();
if (!is_wifi_connected())
{
// restart the board
...
}
init_sntp();
if (!is_sntp_sincronized())
{
// restart the board
...
}
stop_wifi(); // WiFi is not more require
int current_hour = get_current_hour();
stop_sntp(); // sntp is not more require
if (current_hour < start_hour || current_hour >= end_hour)
{
// put on hibernation
return;
}
// turn on the light
...
}
En la parte final de la función app_main
es donde ocurre el proceso de verificar si está en el rango de horas en el que debe estar encendido o no. Si no debería estar encendido, se pone en estado de Deep Sleep para ahorrar energía, y si debe estar encendido, se activa el relé y se pone en suspensión.
La carpeta components
se encarga de almacenar los diferentes módulos del proyecto. En este caso, se tienen los siguientes:
El componente wifi
se encarga de iniciar, configurar y conectarse a una red WiFi. Su código es el siguiente:
#include "wifi.h"
static void event_handler(void *arg, esp_event_base_t event_base,
int32_t event_id, void *event_data)
{
// handle the diferents events
...
}
void stop_wifi()
{
// Stop the wifi connection
...
}
void start_wifi()
{
// start new wifi connection
...
}
bool is_wifi_connected()
{
// return if connected to wifi
...
}
void init_wifi(void)
{
// configure the board to connect to the wifi
...
}
El componente sntp_control
se encarga de sincronizar la placa con la hora obtenida de un servidor SNTP. Su código es el siguiente:
#include "sntp_control.h"
struct tm get_current_time()
{
// Get the current board time
...
}
int get_current_hour()
{
// get the hour
...
}
int get_current_minute()
{
// get the current hour minute
...
}
void stop_sntp()
{
// stop the SNTP sincronization
...
}
void start_sntp()
{
// start the SNTP sincronization
...
}
bool is_sntp_sincronized()
{
//return if is sincronized
...
}
void callback(struct timeval *tv)
{
// this will called when the board was sincronized
...
}
void init_sntp(void)
{
// configure and start the SNTP
...
}
Carga de Código en la Placa
Este es el proceso más sencillo. La extensión de ESP-IDF proporciona herramientas para realizar la compilación, la carga y la visualización de la consola serial. En la barra inferior, puedes encontrar los accesos directos. Primero, realiza la compilación del proyecto. Una vez compilado, procede a cargar el código y luego puedes abrir la consola para observar los mensajes de la placa.
Conclusiones
Como resultado, se obtuvo un sistema automatizado para encender y apagar una bombilla, con el objetivo de facilitar la ejecución del proyecto científico. La placa se encenderá durante 8 horas todos los días y se apagará cuando no esté activa. La planta estará en la oscuridad gracias a la caja, mientras que la bombilla en su interior le proporcionará la luz que necesite.