Está en la página 1de 32

APLICACIÓN WEB IoT

y
Conexión ESP32

P á g i n a 1 | 32
Índice

Crear dashboard web para IoT ........................................................................................ 3


Introducción .............................................................................................................. 3
Instalación de vuetfy .................................................................................................. 4
Configuración del router y el menú.............................................................................. 7
Ejemplos doble data binding..................................................................................... 14
Configuración tarjetas en HomeView.vue .................................................................. 16
Instalar librería MQTT en aplicación web, .................................................................. 18
programación del ESP 32 ............................................................................................. 22
Introducción ............................................................................................................ 22
Configurar entorno para programar ESP 32 ................................................................ 24
Programación del ESP32........................................................................................... 30

P á g i n a 2 | 32
Crear dashboard web para IoT

Introducción
Vue.js se utiliza para el desarrollo de la aplicación web porque proporciona una estructura
reactiva y por componentes, lo que facilita el manejo de la interfaz de usuario y la lógica de
la aplicación. Este framework se adapta tanto a proyectos pequeños como a aplicaciones
complejas gracias a su arquitectura modular y su integración con herramientas como Vuex
y Vue Router.

Vue.js también se basa en la coherencia que ofrece al trabajar con JavaScript tanto en el
cliente como en el servidor, lo que simplifica el flujo de desarrollo y permite a los equipos
centrarse en un único lenguaje de programación. El renderizado en el servidor con Vue.js
mejora la experiencia del usuario final al acelerar los tiempos de carga de las páginas y
optimizar la aplicación para los motores de búsqueda.

Además, desarrollaremos la aplicación utilizando Vuetify, que proporciona componentes


de Material Design listos para ser integrados en Vue.js. Esto facilita la implementación de
una interfaz consistente y profesional, permitiéndonos concentrarnos en la lógica de
negocio mientras mantenemos un estándar alto en el diseño visual. Vuetify es una
herramienta práctica para aplicar principios de diseño establecidos sin requerir esfuerzo
adicional en la creación de componentes de diseño desde cero.

En resumen, la elección de Vue.js y Vuetify nos permite construir una aplicación web
escalable y mantener la consistencia en el desarrollo, mientras que nos beneficiamos de
una amplia gama de componentes de interfaz de usuario que cumplen con los principios
de Material Design.1

1
Crear el código de todos los elementos que intervienen en nuestro sistema IoT nos permite un control total y
así implementar funcionalidades totalmente personalizadas, por ejemplo, conectar con Alexa, utilizar IA, usar
diferentes protocolos IoT, codificar las diferentes placas y hacer diseños de sus carcasas en 3D…

P á g i n a 3 | 32
Instalación de vuetfy
Para instalar vue.js con vuetfy utilizamos el comando

npm create vuetify

Para ejecutar la estructura que hemos creado se usa el comando “vite”

Para que no muestre tantos warnings en cada ejecución se puede crear un fichero vite-
dev.mjs
import { createServer } from 'vite';

async function start() {


const server = await createServer({
// Configuración de Vite si es necesario
});
await server.listen();
server.printUrls();
}

start();

y en package.json
"dev": "node --no-warnings vite-dev.mjs",

Ejecutando el comando “vite” en el directorio del proyecto arrancaremos un servidor de


desarrollo que ejecutará la página,

Podremos ver la página de ejemplo de vuetfy

P á g i n a 4 | 32
El proyecto de vuetfy nos genera una estructura de directorios para crear nuestra aplicación
web :

components: Contiene los archivos de los componentes Vue que puedes reutilizar en
diferentes partes de tu aplicación. Es aquí donde creas los bloques de construcción de tu
interfaz de usuario, como botones, tarjetas y diálogos. En tu caso, pondrás tarjetas que
representan las diferentes funcionalidades del dashboard.

P á g i n a 5 | 32
layouts: Define las plantillas de diseño para tu aplicación. Aquí puedes establecer el
diseño de la barra de navegación, los menús laterales, el pie de página, etc., que envuelven
a tus vistas de página.

pages: Aquí se crean los archivos de las vistas que corresponden a las rutas de tu
aplicación. Cada archivo representa una página completa en tu sitio web, la cual podría
estar compuesta de varios componentes.

plugins: Este directorio se usa para incluir scripts de JavaScript que deseas ejecutar antes
de instanciar la raíz de Vue. Es útil para instalar y configurar plugins como Vuetify, axios,
etc.

router: Contiene el archivo de configuración de Vue Router. Este archivo define las rutas de
tu aplicación y las asocia con los componentes de tus páginas.

store: Aquí se encuentra la configuración de Vuex, que es el estado centralizado para todos
los componentes de tu aplicación. Se utiliza para manejar el estado compartido.

styles: Usualmente este directorio se usa para almacenar archivos de estilo global como
CSS o SCSS.

assets: Este directorio se utiliza para guardar recursos estáticos como imágenes, fuentes
y hojas de estilo que no son específicas de un componente.

App.vue: Es el componente raíz de tu aplicación de Vue. Sirve como el contenedor principal


para tu proyecto.

main.js: Es el punto de entrada de tu aplicación Vue. Aquí se crea y se monta la instancia


de Vue, y se importan las configuraciones globales como Vuetify, Vuex, el enrutador, etc.

Los archivos .browserslistrc, .editorconfig y .eslintrc son archivos de configuración que no


pertenecen a Vue específicamente, sino que son usados para definir la compatibilidad de
navegadores, mantener un estilo consistente de codificación y establecer reglas de linting
para el código respectivamente.

Los directorios “components” y “pages” serán los que más se utilizarán durante el
desarrollo de la aplicación, ya que contienen los elementos esenciales de la interfaz de
usuario y las vistas de la aplicación, respectivamente. En el directorio components crearás
las tarjetas y otros elementos que formarán parte del dashboard, mientras que en pages se
desarrollan las distintas vistas que los usuarios verán al navegar por la aplicación web

P á g i n a 6 | 32
Configuración del router y el menú
Una vez iniciada la estructura del proyecto establecer una estructura de vistas de las que
ofrece en la propia página de vuetfy Wireframes — Vuetify (vuetifyjs.com)

Seleccionamos “baseline” vemos el código que necesita y lo pegamos en nuestro


“app.vue” (que es la que contendrá la pagina principal desde la que ir a diferentes vistas) y
así tendremos un menú principal para nuestro dash-board,

En este código añadiremos en la etiqueta <RouterView /> en el “main” donde se irán


cargando las diferentes vistas

<template>
<v-app id="inspire">
<v-navigation-drawer v-model="drawer" app fixed>
<!-- Botones dentro del menú lateral -->
<v-list>
<v-list-item link >
<v-list-item-icon>
<v-icon>mdi-home</v-icon>
</v-list-item-icon>
<v-list-item-content>Inicio</v-list-item-content>
</v-list-item>
<v-list-item link >
<v-list-item-icon>
<v-icon>mdi-information</v-icon>
</v-list-item-icon>
<v-list-item-content>Acerca de</v-list-item-content>

P á g i n a 7 | 32
</v-list-item>
</v-list>
</v-navigation-drawer>

<v-app-bar app>
<v-app-bar-nav-icon @click="drawer = !drawer"></v-app-
bar-nav-icon>
<v-app-bar-title>Título de la aplicación</v-app-bar-
title>
</v-app-bar>

<v-main>
<RouterView />
</v-main>
</v-app>
</template>

<script setup>
import { ref } from 'vue'
import { RouterView } from 'vue-router'
</script>

<script>
export default {
data: () => ({
drawer: true,
}),
}
</script>

Creamos dos vistas de ejemplo para probar que funciona el router

DevicesView.vue

Con este código de ejemplo que toma el componente Helloworld que viene con el
programa de ejemplo de vuetfy

<template>
<HelloWorld />
</template>

<script setup>
//
</script>

P á g i n a 8 | 32
Y la página HomeView.vue que contendrá una tarjeta por defecto para probar que usa
bien los componentes https://vuetifyjs.com/en/components/cards/#elevation, más
adelante, añadiremos tarjetas personalizadas de diferentes componentes a esta vista,

Creamos las rutas que usaremos y las páginas que usaremos por el momento dos de
prueba

/**
* router/index.ts
*
* Automatic routes for `./src/pages/*.vue`
*/

// Composables
import { createRouter, createWebHistory } from 'vue-router'

const routes = [
{
path: '/',
name: 'Home',
component: () => import('../pages/HomeView.vue')
},
{
path: '/devices',
name: 'devices',
component: () => import('../pages/DevicesView.vue')
}
]

const router = createRouter({


history: createWebHistory(process.env.BASE_URL),
routes
})

export default router;

P á g i n a 9 | 32
Ahora es necesario crear esas dos páginas que más adelante mostraran los componentes
que vayamos creando

En DevicesView.vue por el momento dejamos que cargue el componente de helloWorld


que tiene de ejemplo vuetfy
<template>
<HelloWorld />
</template>

<script setup>
//
</script>

En HomeView.vue por el momento ponemos una vista de una tarjeta de ejemplo


<template>
<v-card
class="mx-auto my-8"
elevation="16"
max-width="344"
>
<v-card-item>
<v-card-title>
Card title
</v-card-title>
<v-card-subtitle>
Card subtitle secondary text
</v-card-subtitle>
</v-card-item>

<v-card-text>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
eiusmod tempor incididunt ut labore et dolore magna aliqua.
</v-card-text>
</v-card>
</template>

En el APP sustituimos el navigation-drawler que es el menula teral por un componente


con las opciones de navegación del menú

P á g i n a 10 | 32
Creamos el componente “MenuDashBoard.vue” que tenga un menú para ir a ambas
paginas

Se puede crear el componente utilizando copilot:

quiero crear un nuevo componente en la carpeta de componentes que sustituya el


<v-navigation-drawer v-model="drawer">
<!-- -->
</v-navigation-drawer>
<v-app-bar>
<v-app-bar-nav-icon @click="drawer = !drawer"></v-app-bar-nav-icon>

<v-app-bar-title>Application</v-app-bar-title>
</v-app-bar>

De esta página y tenga las dos opciones de ruta usando v-list-item-action y vaya a las
páginas HomeView.vue y DevicesView.vue y utilice iconos de V-icon, además tiene que
interactuar con el Drawer y mostrar en lugar de <v-app-bar-title>Application</v-app-bar-
title> la sección en la que se encuentra la ruta en ese momento.

P á g i n a 11 | 32
El componente para la barra de navegación MyNavigation.vue quedaría así

<template>
<div>
<v-navigation-drawer v-model="drawer">

<v-list density="compact">
<v-list-subheader>MENU</v-list-subheader>

<v-list-item
v-for="(item, i) in items"
:key="i"
:value="item"
color="primary"
@click="navigateTo(item.path)"
>
<template v-slot:prepend>
<v-icon :icon="item.icon"></v-icon>
</template>

<v-list-item-title v-text="item.text"></v-list-item-title>
</v-list-item>
</v-list>

</v-navigation-drawer>

<v-app-bar>
<v-app-bar-nav-icon @click="drawer = !drawer"></v-app-bar-nav-icon>
<v-app-bar-title> IoT DashBoard - {{ title }}</v-app-bar-title>
</v-app-bar>
</div>
</template>

<script>
import { ref } from 'vue'
import { useRouter } from 'vue-router'

export default {
setup() {
const router = useRouter()
const drawer = ref(true)
const title = ref('Application')

const items = ref([


{ text: 'Inicio', icon: 'mdi-home', path: '/' },
{ text: 'Devices', icon: 'mdi-devices', path: '/devices' }
])

const navigateTo = (path) => {


router.push(path)
title.value = items.value.find(item => item.path === path).text
drawer.value = true
}

return {
drawer,
title,
items,
navigateTo
}

P á g i n a 12 | 32
}
}
</script>

Y cambiamos el app.vue para que utilice el nuevo componente


<template>
<v-app id="inspire" >
<MyNavigation />

<v-main style="background-color:#f8f8f8;">
<router-view />
</v-main>
</v-app>
</template>

<script setup>
import MyNavigation from '@/components/MyNavigation.vue'
</script>

P á g i n a 13 | 32
Ejemplos doble data binding
Vamos a probar varios ejemplos sustituyendo el código de HomeView.vue solo ver el
funcionamiento del doble data bindign de vue.js

Primero veremos como introducimos texto y a tiempo real se va modificando en el título


de la tarjeta
<template>
<v-card
class="mx-auto my-8"
elevation="16"
max-width="344"
>
<v-card-item>
<v-card-title>
{{ title }}
</v-card-title>
<v-card-subtitle>
Card subtitle secondary text
</v-card-subtitle>
</v-card-item>

<v-card-text>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
eiusmod tempor incididunt ut labore et dolore magna aliqua.
</v-card-text>

<v-text-field v-model="title" label="Enter title"></v-text-field>


</v-card>
</template>

<script>
import { ref } from 'vue'

export default {
setup() {
const title = ref('Homeview')

return {
title
}
}
}
</script>

P á g i n a 14 | 32
Ahora sustituiremos por un slider que muestra su valor a la derecha de manera numérica
a tiempo real, y también si se cambia el valor de la derecha se modifica el slider

<template>
<v-container class="mt-10">
<v-row>
<v-col cols="12" sm="6">
<v-slider
v-model="value"
color="blue"
thumb-label
label="Slider"
></v-slider>
</v-col>

<v-col cols="12" sm="6">


<v-text-field
v-model="value"
label="Caja de texto"
type="number"
></v-text-field>
</v-col>
</v-row>
</v-container>
</template>

<script>
import { ref } from 'vue'

export default {
setup() {
const value = ref(50)

return {
value
}
}
}
</script>

La vista del slider

P á g i n a 15 | 32
Configuración tarjetas en HomeView.vue
Ahora la HomeView solo será una página que contendrá diferentes tarjetas de los
componentes, en estas tarjetas se implementaran diferentes interacciones con los
dispositivos IoT tanto enviar información a los dispositivos como recibir información de los
sensores.

En la carpeta “components” creamos los componentes LightButton.vue, y


TemperatureSensor.vue (esta tarjeta la dejaremos para más adelante)
<template>
<v-card
class="mx-auto my-8"
elevation="2"
>
<v-card-item>
<v-card-title>
LUZ ESP32
</v-card-title>
</v-card-item>
<v-card-actions class="justify-center">
<v-spacer></v-spacer>
<v-btn
:color="lightStatus ? 'green' : 'red'"
fab
large
elevation="2"
dark
height="72"
min-width="164"
@click="toggleLight"
class="mb-14"
>
<v-icon>
mdi-lightbulb
</v-icon>
<span>{{ lightStatus ? 'ENCENDIDO' : 'APAGADO' }}</span>
</v-btn>
<v-spacer></v-spacer>
</v-card-actions>
</v-card>
</template>

<script>
import { ref } from 'vue'

export default {
setup() {
const lightStatus = ref(0)

const toggleLight = () => {


lightStatus.value = lightStatus.value ? 0 : 1
}

return {
lightStatus,
toggleLight
}
}
}
</script>

P á g i n a 16 | 32
La parte de
const toggleLight = () => {
lightStatus.value = lightStatus.value ? 0 : 1
}

Condensa esto
const toggleLight = () => {
if (lightStatus.value === 1) {
lightStatus.value = 0
} else {
lightStatus.value = 1
}
}

Finalmente editamos Homeview para que pueda mostra la nueva tarjeta o tarjetas que
utilicemos como estamos probando como funciona el tema de poner varios componentes
en una vista vamos a poner dos veces el mismo componente en formato de tarjeta y así
comprobar como quedaría otra tarjeta a su lado

<template >
<v-container>
<v-row>
<v-col cols="12" sm="6">
<LightButton />
</v-col>
<v-col cols="12" sm="6">
<LightButton />
</v-col>
</v-row>
</v-container>
</template>

<script>
import LightButton from '@/components/LightButton.vue'

export default {
components: {
LightButton
}
}
</script>

P á g i n a 17 | 32
Instalar librería MQTT en aplicación web,

Recordar añadir la siguiente línea (que faltaba en el broker.js del API REST y por eso no
funcionaba la aplicación web de prueba ) con esto hace que funcione MQTT por Websokets

ws.createServer({ server: WsServer }, aedes.handle);

y arrancamos nuestro servidor API-REST también disponible en github


https://github.com/joseAveleira/API_REST (se encuentra actualizado)

Existen varias librerías para clientes web de mqtt como MQTT.js pero seria necesario
adaptar el código para que funcione con el framework de vue.js, otra es vue-mqtt pero ya
se encuentra desatendida, la más actual es “vue-paho-mqtt” que en su página de github
tiene una versión demo que podemos probar contra nuestro bróker indicando el puerto
donde se encuentra WS en este caso el 8888

https://kaandesu.github.io/vue-paho-mqtt/

P á g i n a 18 | 32
Una vez hemos probado que funciona correctamente lo instalamos en nuestra aplicación
web con el comando
npm install vue-paho-mqtt

Añadimos un nuevo plugin en la carpeta plugins de nuestro proyecto llamado pahoMqtt.js


que tiene la configuración de la conexión
// plugins/pahoMqtt.js
import { createPahoMqttPlugin } from 'vue-paho-mqtt';

export default createPahoMqttPlugin({


PluginOptions: {
autoConnect: true,
showNotifications: true,
},
MqttOptions: {
host: '127.0.0.1',
port: 8888,
protocol: 'ws',
clientId: `MyID-${Math.random() * 9999}`,
mainTopic: 'MAIN',
},
});

Y lo añadimos al index.js de la carpeta plugins

// Plugins
import vuetify from './vuetify'
import pinia from '@/store'
import router from '@/router'
import pahoMqtt from './pahoMqtt'
export function registerPlugins (app) {
app
.use(vuetify)
.use(router)
.use(pinia)
.use(pahoMqtt)
}

Ahora añadimos el código para que finalmente envíe un cambio de estado cada vez que se
pulse el botón al topic “ledesp32”
<template>
<v-card
class="mx-auto my-8"
elevation="2"
>
<v-card-item>
<v-card-title>
LUZ ESP32
</v-card-title>
</v-card-item>

<v-card-actions class="justify-center">
P á g i n a 19 | 32
<v-spacer></v-spacer>
<v-btn
:color="lightStatus ? 'green' : 'red'"
fab
large
elevation="2"
dark
height="72"
min-width="164"
@click="toggleLight"
class="mb-14"
>
<v-icon>
mdi-lightbulb
</v-icon>
<span>{{ lightStatus ? 'ENCENDIDO' : 'APAGADO' }}</span>
</v-btn>
<v-spacer></v-spacer>
</v-card-actions>
</v-card>
</template>

<script>
import { ref, onMounted } from 'vue'
import { $mqtt } from 'vue-paho-mqtt'

export default {
setup() {
const lightStatus = ref(0)

const toggleLight = () => {


// $mqtt.publish('ledesp32', lightStatus.value ? '1' : '0', 'B');

if (lightStatus.value === 0) {
lightStatus.value = 1
$mqtt.publish('ledesp32', '1', 'B');
} else {
lightStatus.value = 0
$mqtt.publish('ledesp32', '0', 'B');
}
}

onMounted(() => {
$mqtt.subscribe('ledesp32', (data) => {
// lightStatus.value = data === '1' ? 1 : 0
if (data === '1') {
lightStatus.value = 1
} else if (data === '0') {
lightStatus.value = 0
}
})
})

return {
lightStatus,
toggleLight
}
}
}
</script>

P á g i n a 20 | 32
Con esto ya conocemos como suscribirnos desde la aplicación web al bróker y como
publicar y que esto se vea reflejado en la interfaz ahora el siguiente paso es conectar un
dispositivo IoT que se comunique con bróker MQTT y pueda interactuar con los topics y
mensajes de la aplicación web

P á g i n a 21 | 32
programación del ESP 32
Introducción
El ESP32 es un microcontrolador de bajo costo y bajo consumo de energía que cuenta con
conectividad Wi-Fi y Bluetooth integrada, lo cual lo hace ideal para aplicaciones de Internet
de las Cosas (IoT). Se puede programar con diversos entornos, incluido el Arduino IDE, lo
que facilita su uso.

En cuanto a sus funcionalidades:

Wi-Fi: El ESP32 puede conectarse a redes Wi-Fi y actuar tanto en modo estación
(conectándose a un router) como en modo punto de acceso (permitiendo que otros
dispositivos se conecten a él).

Bluetooth: También admite Bluetooth clásico y BLE (Bluetooth de baja energía), lo cual es
útil para la comunicación con smartphones, sensores y otros dispositivos Bluetooth.

Pines de E/S (Entrada/Salida): Como se observa en la imagen, el ESP32 tiene una gran
cantidad de pines que soportan diversas funciones:

• GPIO (General Purpose Input/Output): Pines que se pueden configurar como


entrada o salida para controlar dispositivos externos, como LEDS, motores,
sensores, etc.
• ADC (Analog to Digital Converter): Pines capaces de leer niveles de voltaje
analógicos y convertirlos en un valor digital. Esto es útil para sensores analógicos
como los de temperatura, humedad o luz.
• DAC (Digital to Analog Converter): Pines que pueden generar un voltaje analógico a
partir de un valor digital, útiles para controlar dispositivos como potenciómetros
digitales o para generar señales analógicas.
• Touch: Pines capacitivos que pueden detectar el tacto o la proximidad de un dedo
humano, lo que permite crear interfaces táctiles sin necesidad de botones físicos.
• UART (Universal Asynchronous Receiver/Transmitter): Pines utilizados para la
comunicación serial, como conectar a una computadora o a otros
microcontroladores.
P á g i n a 22 | 32
• SPI (Serial Peripheral Interface): Pines para comunicación serial rápida,
comúnmente usada para comunicarse con pantallas o memorias flash.
• I2C (Inter-Integrated Circuit): Pines para comunicación serial que utilizan dos
líneas, una para la señal de reloj y otra para los datos. Utilizado para sensores,
EEPROMs, LCDs, entre otros.
• Alimentación: Los pines de alimentación proporcionan energía al módulo y a otros
componentes externos. El ESP32 opera a 3.3V, pero muchos módulos tienen
reguladores que permiten ser alimentados con 5V (como el pin Vin en la imagen).
• Programación y Flash: El ESP32 tiene memoria flash incorporada para almacenar
programas y datos. Los pines como RX/TX se utilizan para cargar programas al
módulo, mientras que otros pines flash están involucrados en el proceso de inicio
del microcontrolador.

Para comenzar a programar estos dispositivos, se conectan usualmente a una


computadora a través de un cable USB a serial. Se utiliza un entorno de desarrollo para
escribir el código y cargarlo en el dispositivo. Una vez programado, el ESP32 puede ejecutar
el código de manera autónoma y comunicarse con internet o dispositivos cercanos de
acuerdo con el programa que le fue cargado.

P á g i n a 23 | 32
Configurar entorno para programar ESP 32
Programar con platfromIO que es una extensión de visual studio Code que permite trabajar
con código de diferentes placas y usar el código de Arduino con el entorno de Visual studio
Code además de facilitar la gestión de librerías de los proyectos.

Una vez instalado nos aparecerá un nuevo icono en el podemos gestionar los proyectos
de las diferentes placas sus conexiones y librerías,”

P á g i n a 24 | 32
Para crear un nuevo proyecto vamos a “Open” y “new proyect” le llamamos testESP32
para probar la conexión con el ESP32, y utilizamos el framework de Arduino que es el que
mas Código y librerías tiene

Esto nos crea un proyecto con la estructura y el código de prueba que se encuentra dentro
del directorio “src”, se puede probar a subir aunque no podremos ver el resultado

En platformio.ini se encuentra el documento donde se especifica la placa y aparecerán


las librerías y su versión según se vayan utilizando

P á g i n a 25 | 32
[env:esp32dev]
platform = espressif32
board = esp32dev
framework = arduino

En Windows 11 puede que no tenga los drivers para detectar el módulo ESP32

Es necesario descargar los drivers para que lo detecte

https://www.silabs.com/developers/usb-to-uart-bridge-vcp-drivers?tab=downloads

P á g i n a 26 | 32
Creamos un primer ejemplo para mostrar por la terminal un hola mundo,

Primero añadimos el siguiente parámetro en platformio.ini

monitor_speed = 115200

El siguiente código en main.cpp

Un ejemplo simple de un programa que imprime el mensaje "hola mundo" en el puerto


serial cada segundo. La estructura del código se divide en dos funciones principales que
son esenciales en todos los sketches de Arduino:

• setup(): Esta función se ejecuta una sola vez cuando el programa inicia. Se utiliza
para configurar la placa, inicializar las bibliotecas, definir los modos de los pines,
iniciar comunicaciones, etc. En este caso, se utiliza para iniciar la comunicación
serial con una velocidad de 115200 bits por segundo.
• loop(): Esta función se ejecuta en un bucle infinito después de que setup() finaliza.
Aquí es donde pones el código que quieres que se ejecute continuamente. En este
ejemplo, se está enviando el mensaje "hola mundo" al puerto serial y luego se hace
una pausa de 1000 milisegundos (1 segundo) con delay(1000);.
#include <Arduino.h>

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

void loop() {
// put your main code here, to run repeatedly:
Serial.println("hola mundo");
delay(1000);

Una vez suba el código al modulo

Podemos ver lo que nos muestra por terminal pulsando en el siguiente icono

P á g i n a 27 | 32
Ahora vamos a hacer otro código de prueba en main.cpp que enciende y apaga el led que
tiene integrada la placa ESP32 y muestra el estado del led por la terminal cada tres
segundos,

*En caso de que la placa no disponga de led integrado (la placa de las clases presenciales
por lo visto no lo tiene)

Se puede conectar un led cualquiera

Donde el cable largo o curvado es el positivo y el corto el negativo, el corto ira al pin GND y
el largo al GPIO que queramos que queramos usar para enceder y apagar el led por ejemplo
el Pin 23
#include <Arduino.h>
#define LED_BUILTIN 2 // Define el pin del LED integrado

void setup() {
Serial.begin(115200);
pinMode(LED_BUILTIN, OUTPUT); // Configura el pin del LED como salida
}

void loop() {
digitalWrite(LED_BUILTIN, HIGH); // Enciende el LED
Serial.println("Encendido");
delay(3000); // Espera tres segundos

digitalWrite(LED_BUILTIN, LOW); // Apaga el LED


Serial.println("Apagado");
delay(3000); // Espera tres segundos
}

P á g i n a 28 | 32
Como el módulo esp32 tiene conectividad Wi-Fi lo siguiente que vamos probar que
funciona
#include <Arduino.h>
#include <WiFi.h>

const char* ssid = "***";


const char* password = "***";

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

WiFi.begin(ssid, password);
Serial.println("Conectando a WiFi...");

while (WiFi.status() != WL_CONNECTED) {


delay(1000);
Serial.print(".");
}

Serial.println("Conectado a la WiFi");
}

void loop() {
// Tu código aquí
}

Ahora para que se conecte por MQTT es necesario instalar la librería pubsubclient, las
librerías se instalan desde el ID de platformio

En “add to Project” y seleccionamos nuestro proyecto testESP32

P á g i n a 29 | 32
Programación del ESP32
Añadimos el Código para que se suscriba al topic “MAIN/ledesp32” y cambie el estado del
led integrado según el dato recibido

#include <Arduino.h>
#include <WiFi.h>
#include <PubSubClient.h>

#define LED_BUILTIN 2 // Define el pin del LED integrado

const char* ssid = "***";


const char* password = "***";
const char* mqtt_server = "192.168.0.178";

WiFiClient espClient;
PubSubClient client(espClient);

void setup_wifi() {
delay(10);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.println("Conectando a WiFi...");
}
Serial.println("Conectado a la WiFi");
}

void reconnect() {
while (!client.connected()) {
Serial.print("Conectando al servidor MQTT...");
if (client.connect("ESP32Client")) {
Serial.println("conectado");
client.subscribe("MAIN/ledesp32");
} else {
Serial.print("falló, rc=");
Serial.print(client.state());
Serial.println(" intentando de nuevo en 5 segundos");
delay(5000);
}
}
}

void callback(char* topic, byte* message, unsigned int length) {


Serial.print("Mensaje recibido en topic: ");
Serial.println(topic);

Serial.print("Mensaje: ");
String msg;
for (int i = 0; i < length; i++) {
msg += (char)message[i];
}
Serial.println(msg);

if (msg == "1") {
digitalWrite(LED_BUILTIN, HIGH); // Enciende el LED
} else if (msg == "0") {
digitalWrite(LED_BUILTIN, LOW); // Apaga el LED
}
}

P á g i n a 30 | 32
void setup() {
Serial.begin(115200);
setup_wifi();
client.setServer(mqtt_server, 1883);
client.setCallback(callback);
pinMode(LED_BUILTIN, OUTPUT); // Configura el pin del LED como salida
}

void loop() {
if (!client.connected()) {
reconnect();
}
client.loop();
}

Ahora vamos a probar los pines capacitivos del ESP32 de tal manera que cuando se puse
el pin D4 cambié el estado del led de encendido a apagado, podremos ver como esto afecta
a la aplicación web cambiando el estado a tiempo real

#include <Arduino.h>
#include <WiFi.h>
#include <PubSubClient.h>

#define LED_BUILTIN 2 // Define el pin del LED integrado


#define TOUCH_PIN T0 // Define el pin capacitivo que vas a usar
#define TOUCH_THRESHOLD 30

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


const char* password = "****";
const char* mqtt_server = "192.168.0.178";

WiFiClient espClient;
PubSubClient client(espClient);

int lastTouchValue = 0;
bool ledState = false;
void setup_wifi() {
delay(10);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.println("Conectando a WiFi...");
}
Serial.println("Conectado a la WiFi");
}

void reconnect() {
while (!client.connected()) {
Serial.print("Conectando al servidor MQTT...");
if (client.connect("ESP32Client")) {
Serial.println("conectado");
client.subscribe("MAIN/ledesp32");
} else {
Serial.print("falló, rc=");
Serial.print(client.state());
Serial.println(" intentando de nuevo en 5 segundos");
delay(5000);
}

P á g i n a 31 | 32
}
}

void callback(char* topic, byte* message, unsigned int length) {


Serial.print("Mensaje recibido en topic: ");
Serial.println(topic);

Serial.print("Mensaje: ");
String msg;
for (int i = 0; i < length; i++) {
msg += (char)message[i];
}
Serial.println(msg);

if (msg == "1") {
digitalWrite(LED_BUILTIN, HIGH); // Enciende el LED
} else if (msg == "0") {
digitalWrite(LED_BUILTIN, LOW); // Apaga el LED
}
}

void setup() {
Serial.begin(115200);
setup_wifi();
client.setServer(mqtt_server, 1883);
client.setCallback(callback);
pinMode(LED_BUILTIN, OUTPUT); // Configura el pin del LED como salida
}

void loop() {
if (!client.connected()) {
reconnect();
}
client.loop();

int touchValue = touchRead(TOUCH_PIN);


if (touchValue < TOUCH_THRESHOLD && lastTouchValue >= TOUCH_THRESHOLD) {
ledState = !ledState; // Cambia el estado del LED
digitalWrite(LED_BUILTIN, ledState ? HIGH : LOW); // Actualiza el estado
del LED
client.publish("MAIN/ledesp32", ledState ? "1" : "0"); // Publica el
nuevo estado del LED
}
lastTouchValue = touchValue;
}

P á g i n a 32 | 32

También podría gustarte