ESP32 Demos
ESP32 Demos
ESP32 Demos
• Sensor de temperatura.
• 4 × SPI, 2 × I²S, 2 × I²C, 3 × UART .
• SD / SDIO / host MMC .
• Interfaz MAC Ethernet con soporte dedicado DMA y IEEE 1588.
• CAN bus 2.0.
• IR (TX / RX).
• PWM.
• LED PWM hasta 16 canales.
• Sensor de efecto Hall.
• Preamplificador analógico de potencia ultrabaja
• Funciones de seguridad IEEE 802.11 compatibles, incluidas WFA, WPA / WPA2 y WAPI.
• Cifrado de Flash .
• OTP de 1024 bits, hasta 768 bits para los clientes.
• Aceleración de hardware criptográfico: AES, SHA-2, RSA.
En los siguientes ejemplos estaremos usando esta placa. Con un costo muy bajo la convierte en una
alternativa interesante para el ESP32.
Algunos detalles de la placa:
• Frecuencia de reloj de 240MHz.
• Memoria SRM interna de 520kB.
• WiFi 802.11.
• Modulo Bluetooth
• Opera en un rango de voltajes que va desde 2.2 a 3.6V
• 28 Pines GPIO
• 10 Pines con sensibilidad capacitiva para sistemas Touch.
• Acelerador de Hardware.
• Memoria SPI externa del tipo Flash con 4MB (Aquí se guardan las aplicaciones).
• Integra un cargador de baterias.
• Procesador Dual-core Tensilica LX6.
Los siguientes son algunos comandos que podemos ejecutar desde la línea de comandos.
• Make menuconfig: Configura el hardware del ESP32.
• Make : Construye y compila el proyecto completo. Siempre se ejecuta luego de menuconig.
• Make app: Compila solo la aplicación.
• Make flash: Programa en memoria Flash todo el proyecto.
• Make app-flash: Programa solo la aplicación. (Siempre que no sea necesario compilar el
NOTA:
Para instalar tarjetas con ESP32 desde Archivos→Preferencias (ver imagen) modificar el gestor de
URLs para las tarjetas agregando la siguiente línea.
Si observa la siguiente imagen verá los archivos y su ubicación dentro de la carpeta Arduino.
Es importante para que todo funcione que las carpetas y archivos se vean de esta forma.
Resultado en el navegador.
Para enviar el sitio web al navegador solo es necesario escribir los tag secuencialmente en HTTP,
distintas herramientas para distintos microcontroladores tienen distintas sintaxis pero todos hacen lo
mismo, enviar una secuencia de bytes conteniendo los tag para darle formato a un sitio web.
En el caso de Arduino, Serial.print(") envía información al puerto serial y cliente.println("<html>")
envía un tag al navegador. La palabra cliente (o cualquier palabra) estará asociada al WiFi o
Ethernet dependiendo del tipo comunicación que se esté usando, entre comillas están los ASCII
enviados al navegador, de la misma forma que enviariamos un texto por la UART.
Para enviar la página solo enviamos la secuencia de ASCII conteniendo los tag, algo como esto:
cliente.println("HTTP/1.1 200 OK");
cliente.println("Content-Type: text/html");
cliente.println("Connection: keep-alive");
cliente.println();
cliente.println("<meta charset='UTF-8'>");
cliente.println("<!DOCTYPE html>");
cliente.println("<html>");
cliente.println("<center>");
….....
..…...
….....
Se ha marcado en azul las funciones JavaScript que modifican la variable “dato” que usaremos
como contador.
JavaScript define las variables anteponiendo la palabra “var “.
Los “;” al final de cada linea no son obligatorios pero si de “buenas costumbres”.
Las funciones JavaScript, o los bloques de código que corresponden a JavaScript se contienen
dentro de “<script>” donde inicia y “</script>” donde termina. Adentro de estas etiquetas las
reglas de sintaxis y semántica son JavaScript y puede haber tantas como necesitemos en una web.
Normalmente una función JavaScript realiza un trabajo cuyo resultado se muestra en algún lugar de
la página, para esto podemos definir una sección donde mostrar los datos.
“<div id="textoDiv"></div>” hace justamente eso, crea una sección con el identificador textoDiv.
En la función JavaScript vemos la línea “var div = document.getElementById("textoDiv")” donde se
define la variable div que es igual a “conseguir un elemento por el ID que coincida con textoDiv”.
Esto dicho de manera muy simplista porque como vamos a ver mas adelante, el método GET() es
bastante complejo con muchas posibilidades y propiedades.
TextContent es una propiedad de document.getElementById por lo tanto cuando vemos la línea
“div.textContent = dato”el punto que conecta con textContent permite el acceso a la propiedad y el
dato con el estado del contador se muestra en la página en el lugar indicado por la sección <div>.
</center>
</body>
</html>
En este caso no es de interés que el servidor nos informe el estado real del pin, solo buscamos
cambiarlo desde la página web.
Para esto solo necesitamos HTML, Ajax es necesario cuando se necesita leer información desde el
servidor (el ESP32), cuando solo enviamos información HTML es suficiente.
Por comodidad vamos a escribir el código usando el IDE de Arduino por lo tanto trabajamos bajo el
“Formato Arduino” donde siempre hay una función setup() para las configuraciones de hardware y
un bucle loop() donde el núcleo del programa se ejecuta.
Antes de ver el código en su totalidad vamos a tratar algunos aspectos puntuales. Las solicitudes
HTPP desde el cliente (el navegador) se almacenarán en una variable tipo string que se ha definido
como HTTP_req, esta variable será el puente entre el cliente y el servidor. También usaremos el
puerto serial para verificar lo que está pasando en la red.
Con cualquier terminal serie podemos verificar el envío de mensajes y estado de las transacciones
HTTP.
El encabezado del programa y la función setup() contienen el siguiente código.
Para poder usar este sensor necesitamos manejar el puerto I2C, en el ESP32 los pines GPIO_21
corresponde a SDA y GPIO_22 es SCL.
El BUS I2C.
Desarrollado originalmente en 1982 por Philips para varios chips propios. La especificación
original permitía solo comunicaciones de 100 kHz, y solo se podían direccionar 127 vectores, de los
cuales solo 112 podían ser chips (hay varias direcciones reservadas, que nunca se usarán para
direcciones I2C válidas). En 1992, se publicó la primera especificación pública, agregando un modo
rápido de 400 kHz y un espacio de direcciones ampliado de 10 bits. Para muchas placas
compatibles con Arduino este es límite para I2C. Hay tres modos adicionales de uso: fast-mode que
llega a 1MHz, el modo de alta velocidad, a 3.4MHz y modo ultra rápido, a 5MHz.
Intel introdujo una variante en 1995 llamada "System Management Bus" (SMBus), es un formato
más estrictamente controlado, destinado a maximizar la predictibilidad de las comunicaciones entre
los circuitos integrados de soporte en placas base de PC. La diferencia más significativa entre
SMBus es que limita las velocidades de 10 kHz a 100 kHz, mientras que I2C puede admitir
dispositivos de 0kHz a 5MHz. SMBus incluye un modo de tiempo de espera del reloj que hace que
las operaciones de baja velocidad sean ilegales, aunque muchos dispositivos SMBus lo admitirán de
todos modos para maximizar la compatibilidad con los sistemas I2C integrados.
ESP32 tiene dos pines vinculados al puerto I2C nativo, GPIO_21 y GPIO_22.
def mi_menu(parent):
menubar = Frame(parent)
menubar.pack(side=TOP, fill=X)
fbutton = Menubutton(menubar, text='Menu', underline=0)
fbutton.pack(side=LEFT)
file = Menu(fbutton)
frm.pack(expand=YES, fill=BOTH)
Label(frm, bg='black', height=5, width=15).pack(expand=YES,
fill=BOTH)
Button(root, text="Salir", command=root.quit).pack( )
root.mainloop( )
El código escrito se reduce bastante al importar módulos ya construidos, además con un correcto
funcionamiento ya que han sido probado en la aplicación desde donde se importa.
Vemos otro ejemplo. Imaginemos que necesitamos ingresar una cadena de texto en una ventana que
serviría para algún propósito determinado, por ejemplo configurar un puerto COM, establecer una
IP, ajustar un termostato, etc.
Vemos la siguiente imagen.
El programa abre una ventana con un campo de edición para escribir una cadena de texto que al
apretar el botón “Mostrar Texto” el mismo se escribe en la pantalla de salida.
También se invoca a un objeto que contiene una función de salida que se encuentra en otro archivo
llamado Salir.py y la única condición es que ambos archivos residan en la misma carpeta.
Está claro que podemos invocar cualquier objeto, función o método que se ha creado y probado en
otros proyectos. En definitiva no es que el programa final sea mas pequeño, solo evitamos tener que
escribirlo todo reutilizando código ya existente.
# -*- coding: utf-8 -*-
#!/usr/bin/env python
from Tkinter import *
from quitter import Salir
import sys
Lectura de un sensor DHT22 con un Socket UDP con ESP32.
Con este sensor también podemos medir temperatura y humedad, es un sensor simple útil en
proyectos semi profesionales o domésticos. Sus principales características generales son:
• Alimentación: 3.3v – 5.5v, tomando como valor recomendado 5v.
• Resolución decimal, es decir, los valores tanto para humedad como para temperatura serán
números con una cifra decimal.
• Tiempo de muestreo: 2 segundos, es decir, sólo nos puede ofrecer datos cada 2 segundos.
En cuanto a sus prestaciones leyendo temperatura:
• Rango de valores desde -40ºC hasta 80ºC de temperatura.
• Precisión: ±0.5ºC, ±1ºC como máximo en condiciones adversas.
• Tiempo de respuesta: <10 segundos, es decir, de media, tarda menos de 10 segundos en
reflejar un cambio de temperatura real en el entorno.
Si hablamos de sus prestaciones leyendo humedad relativa:
• Rango de valores desde 0% hasta 99.9% de Humedad Relativa.
• Precisión: ±2%RH, a una temperatura de 25ºC.
• Tiempo de respuesta: <5 segundos, es decir, de media, tarda menos de 5 segundos en
reflejar un cambio de humedad relativa real en el entorno. Además, para darse esta
afirmación, las verificaciones indicaron que la velocidad del aire debe ser de 1 m/s.
El servidor Python que recibe los datos puestos en el Socket por ESP32 es el mismo que se usó para
el sensor HDC1000, solo se han cambiado los textos de presentación.
Serial.print("payload: ");
for (int i = 0; i < length; i++) {
Serial.print((char)payload[i]);
}
Serial.println();
if ((char)payload[0] == '1') {
digitalWrite(led, HIGH); // Si es 1 encender el LED
} else {
digitalWrite(led, LOW); // Si es 0 apagar el LED
}
}
Si observa nuevamente la pantalla del móvil verá que hay una lengüeta para Subscribir y otra para
Publicar.
if (client.connect(clientId.c_str())) {
Serial.println("conectado!!");
client.subscribe(LED_TOPIC); // Subscribir al tópico con QoS 0
} else {
Detección del Índice de Luz Ultravioleta con MQTT.
Puede resultar interesante contar con un dispositivo que nos informe la intensidad de la radiación
ultravioleta, por ejemplo en los días de verano cuando las playas se llenan de gente informar el
índice de radiación UV para protegerse adecuadamente del sol.
El ejemplo propuesto funciona con el nuevo sensor SI1145 de SiLabs con un algoritmo de
detección de luz ya calibrado que puede calcular el índice UV.
En realidad no contiene un elemento de detección de UV real, sino que lo calcula a partir de la
radiación infrarroja y la cantidad de luz visible del sol.
Es un sensor realmente muy preciso, digital que funciona con I2C, por lo que cualquier
microcontrolador puede usarlo.
Como el sensor también tiene elementos para la detección del radiación infrarroja y luz visible, es
posible cuantificar estas variables, sin embargo se remarca que los algoritmos internos de este
sensor están ajustados para la medición del índice de radiación ultravioleta.
Suscribe al los tres tópicos de la misma forma solo cambia el tópico y el nombre..
Medición de la presión barométrica con MQTT.
Con el sensor BMP280 podemos medir la presión barométrica y la humedad.
Se puede acceder a la herramienta NODE-RED desde cualquier lugar con el navegador apuntado a
la dirección IP donde se encuentre y el puerto 1880, por ejemplo 192.168.0.124:1880 y el
DashBoard se encuentra en la misma dirección con el agregado 1880/ui. (El programa para el
ESP32 es el mismo usado en el ejemplo para el HDC1000 y MQTT).
Sensor BME280 con NODE-RED.
En este ejemplo vamos a conectar el sensor BME280 a la placa ESP32 mediante una conexión I2C.
Vamos a necesitar tres nodos MQTT para cada una de las variables (temperatura, presión y
humedad) estos nodos se conectan a tres instrumentos provistos por el DashBoard donde vamos a
mostrar los datos recibidos desde el sensor.
La configuración de cada nodo MQTT es muy simple, haciendo doble click en el bloque se abre la
lengüeta para configurar el nodo.
En la imagen anterior se puede ver como configurar el nodo MQTT para recibir la temperatura,
observe que solo es necesario el tópico publicado por el broker y la dirección y puerto donde se
encuentra, en este caso Mosquitto corriendo en Rasberry PI.
Recuerde que Mosquitto se conecta por el puerto 1883 no confundirlo con el puerto 1880 que
usa NODE-RED.
Para ver los datos se ha definido una interfaz como la anterior donde se ha agregado un instrumento
mas para la presión.
#include <WiFi.h>
#include <PubSubClient.h>
Una vez que tenemos todo los elementos de la interfaz desplegados en la pantalla se envía la
programación a la propia pantalla usando una simple conexión serial.
Este editor de Nextion es la mejor solución, en realidad casi la única para crear proyectos con estas
pantallas inteligentes.
Lamentablemente solo existe en versión para Windows que se descarga a través del enlace oficial de
Nextion.
Conexión de la pantalla.
La pantalla dispone solamente de 4 pines. Dos de ellos son de alimentación (cable rojo y negro) y
los otros dos son de recepción (RX ) y transmisión (TX) de datos a través de su puerto serie.
La pantalla se programa por medio de una conexión serial desde el propio editor Nextion, y también
se conecta con ESP32 por una conexión serial.
Cuando queremos mostrar un dato en la pantalla solo “apuntamos”al componente de la pantalla
donde queremos enviar los datos y enviamos la información que se me mostrará donde se indicó,
por ejemplo imaginemos que tenemos un termómetro dibujado en la pantalla y queremos enviar los
datos para que cambie su aspecto según la temperatura, la sintaxis seria algo como esto:
Serial2.print("j0.val=") donde j0 es la variable y val es el valor a mostrar.
Editor Nextion.
Vamos a realizar un ejemplo rápido para ver nuestro entorno de edición y cargar un primer proyecto
a nuestra pantalla.
En el momento de crear un proyecto nuevo, deberemos seleccionar el modelo de pantalla con el que
vamos a trabajar. Observe la siguiente imagen el aspecto del editor al crear la pantalla.
Pretendemos crear una interfaz para el sensor BME280 que muestre los datos de temperatura,
presión y humedad al mismo tiempo que cambia los iconos de acuerdo al estado del tiempo.
La predicción del clima se realiza en base a los datos atmosféricos obtenidos por el sensor.
En la imagen se puede ver el proyecto funcionando con la pantalla conectada al puerto serial 2
(pines 16 y 17) del ESP32.
En este caso no se usa el Touch sin embargo podríamos haber creado una pantalla con botones que
cambien de estado pines en el Hardware.
Los mensajes que intercambia la pantalla con el microcontrolador tienen el siguiente formato.
Son siete los Bytes enviados y siempre terminado con FF FF FF, en el siguiente código se puede
ver como se ensambla el mensaje a la pantalla.
El código completo para ESP32 es el siguiente.
#include <Wire.h>
#include "SparkFunBME280.h"
BME280 mySensorA; //Uses default I2C address 0x77
BME280 mySensorB; //Uses I2C address 0x76 (jumper closed)
float temperatura = 0;
float humedad = 0;
float presion = 0;
int weatherID = 300;
#define LED_PIN 5
void setup(){
Activar el Blueooth del ESP32 es realmente simple, como puede ver en la siguiente imagen.ESP32
Bluetooth visible desde una computadora Linux.
Una simple aplicación escrita en el IDE de Arduino enviará por el Bluetooth el estado del botón
colocado en GPIO_0.
Es necesario tener presente que el Bluetooth es de nueva generación, es un Bluetooth de baja
energía. Algunos dispositivos pueden necesitar actualización de software para permitir una
conectividad plena con estos nuevos BLE o Bluetooth de baja energía. Por ejemplo las versiones de
Android anteriores a 4.3 no tienen soporte para BLE. Esto significa que no todos los dispositivos
pueden conectar con el ESP32 solo aquellas que tienen soporte para BLE.
A nivel de protocolo BLE tiene algunas diferencias con el Bluetooth convencional.
Ejemplo de uso para el BLE.
#include "SimpleBLE.h"
SimpleBLE ble;
void onButton(){
String out = "Bluetooth_SI!!! ";
out += String(millis() / 1000);
Serial.println(out);
ble.begin(out); // Función para el envío de información
}
void setup() {
Serial.begin(115200);
Serial.setDebugOutput(true);
pinMode(0, INPUT);
Serial.print("ESP32 SDK: ");
Serial.println(ESP.getSdkVersion());
ble.begin("ESP32_Firtec"); // Identificador en la red