Un sensor en la red
El paso de Un LED y un botón a un aparato conectado: lees un sensor, lo mides cada cierto tiempo y mandas el dato por internet con MQTT, el protocolo de mensajes de muchos aparatos IoT. El sensor es un potenciómetro, un mando que giras: en Windows, el del simulador GPIO; en tu placa, uno de verdad o cualquier sensor que dé una tensión.
Como antes, cada programa va en el fichero principal de tu proyecto, en lugar de lo que tenga.
Leer un valor analógico
use GPIO
const PIN_SENSOR = 34 // un pin con conversor analógico (ADC)
for (var vez = 1; vez <= 10; vez++)
var valor = GPIO.aread(PIN_SENSOR) // de 0 a 4095
var porcentaje = valor * 100 div 4095
println("Valor: ", valor, " (", porcentaje, " %)")
pause(500)
end
GPIO.areadlee la tensión del pin con el conversor analógico (ADC) y la da como un número de 0 (0 V) a 4095 (la tensión máxima). Un potenciómetro da más o menos según lo giras.dives la división entera:valor * 100 div 4095da el porcentaje sin decimales.
En Windows:
-
En el simulador (Build › Debug › GPIO Sim), añade el pin
34con Add GPIO Pin y conéctalo a Potentiometer. -
Pulsa Run y, mientras el programa escribe, gira el mando de la tarjeta. Cada línea sale con el valor del momento, por ejemplo:
Valor: 0 (0 %)
Valor: 1365 (33 %)
Valor: 4095 (100 %)
Al empezar, la VM pone todos los pines a cero: hasta que no tocas el mando, el programa lee 0, aunque la tarjeta enseñe otro valor.
Medir cada segundo, con un timer
En un aparato de verdad, el programa no acaba: mide cada cierto tiempo, para siempre. Para eso está Timer.
use GPIO
use Timer
const PIN_SENSOR = 34
func medir(id, periodico, dato)
var valor = GPIO.aread(PIN_SENSOR)
println("Valor: ", valor, " (", valor * 100 div 4095, " %)")
end
Timer.every(1000, medir) // medir() cada segundo
while (true)
pause(10) // los timers saltan entre pausa y pausa
end
Timer.every(1000, medir)llama amedircada 1000 milisegundos. La función recibe tres cosas: el número del timer, si es periódico y un dato que aquí no se usa.- El programa sigue vivo en el
while (true). Los timers saltan en momentos seguros del programa, como al dar la vuelta un bucle, nunca dentro depause(): por eso las pausas del bucle son cortas.
Pulsa Run: sale una línea por segundo, con lo que marque el potenciómetro. Para acabar, pulsa Stop.
Mandarlo por MQTT
Con MQTT, el programa publica cada dato en un tema, un nombre como casa/salon/temperatura, en un servidor que los reparte: el broker. Quien esté suscrito a ese tema, en cualquier sitio, recibe el dato. Aquí el programa se suscribe a su propio tema, así que ves llegar de vuelta lo que manda.
La conexión con el broker no se abre desde el programa. En Windows:
- Abre Config › Platform › Windows. En el apartado MQTT, enciende Enable MQTT. El broker de serie es
test.mosquitto.org, uno público y gratuito, en el puerto1883. - Pulsa Save Config.
use GPIO
use Timer
use MQTT
const PIN_SENSOR = 34
const TEMA = "jaru/prueba-empezar/sensor" // cámbialo por un tema tuyo
func alRecibir(tema, mensaje)
println("Llega de ", tema, ": ", mensaje)
end
func medir(id, periodico, dato)
var valor = GPIO.aread(PIN_SENSOR)
MQTT.publish(TEMA, valor.toString())
println("Enviado: ", valor)
end
println("Esperando al broker...")
while (not(MQTT.isConnect()))
pause(100)
end
println("Conectado")
MQTT.callback(alRecibir)
MQTT.subscribe(TEMA)
Timer.every(2000, medir) // un dato cada 2 segundos
while (true)
pause(10)
end
- Cambia el tema por uno tuyo, con algo que no use nadie más, como tu nombre: en un broker público, todo el mundo puede leer y escribir en cualquier tema.
MQTT.isConnect()dice si hay conexión. El programa la espera antes de suscribirse.MQTT.callback(alRecibir)dice qué función recibe los mensajes, yMQTT.subscribese suscribe al tema.MQTT.publishmanda el dato, como texto:toString()convierte el número.
Pulsa Run. Cada dos segundos, el programa manda el valor del potenciómetro, y enseguida le llega de vuelta del broker. La consola enseña esto, más una línea de la propia VM de Windows al suscribirse, que empieza por Subscrito a:
Esperando al broker...
Conectado
Enviado: 0
Llega de jaru/prueba-empezar/sensor: 0
Enviado: 0
Llega de jaru/prueba-empezar/sensor: 0
Los mensajes de MQTT llegan a alRecibir como saltan los timers: en los momentos seguros del programa, nunca dentro de pause(). Un programa que espera mensajes da vueltas con pausas cortas.
En la placa
- Conecta el potenciómetro: sus extremos a 3,3 V y a GND, y la pata del medio a un pin con conversor analógico de tu placa. Cuáles tienen ADC, en el esquema de tu placa; en el ESP32-P4, solo leen los del ADC1, y en el ESP32-S31
GPIO.areadda el valor en bruto de su ADC, con otra escala (ver GPIO). CambiaPIN_SENSORpor el tuyo: el 34 del ejemplo es del ESP32, y en el ESP32-S3 los pines del 33 al 37 son de su PSRAM (ver Pines que no valen para un botón). - Configura la red de la placa en la página Network de ESP32 Tools: en WiFi, enciende Enable WiFi y pon en SSID y Password el nombre y la contraseña de tu red; en MQTT, enciende Enable. El broker de serie es también
test.mosquitto.org. Todos los campos, en Pantalla, sonido, SD y red. - Con tu placa en Target, pulsa Run y abre el monitor serie.
Antes de tu programa, el monitor serie enseña cómo conecta la placa: «Connecting to», con tu red, y «WiFi connected» con su dirección IP. Con el broker conecta después, ya con el programa en marcha: por eso el programa espera a MQTT.isConnect() antes de suscribirse.
Cuando la placa vuelve a conectar con el broker, no repite tus suscripciones: los mensajes dejan de llegar a alRecibir, aunque los datos se sigan mandando. Para seguir recibiendo, suscríbete otra vez cuando MQTT.isConnect() vuelva a dar true.
Siguientes pasos
- Dibujar y mover: la pantalla, el bucle de un juego y los botones.
- Módulo MQTT: publicar, suscribirse, los comodines de los temas y los mensajes en JSON.
- Módulo Timer: timers de una vez y periódicos, y cómo pararlos.
- Pantalla, sonido, SD y red: la WiFi y el MQTT de la placa, campo a campo.