Saltar al contenido principal

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.aread lee 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.
  • div es la división entera: valor * 100 div 4095 da el porcentaje sin decimales.

En Windows:

  1. En el simulador (Build › Debug › GPIO Sim), añade el pin 34 con Add GPIO Pin y conéctalo a Potentiometer.

  2. 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 %)
El simulador GPIO con un potenciómetro en el GP34: al girarlo, su valor pasa por 0, 1024, 2048, 3072 y 4095, en la tarjeta y en la columna Status

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 a medir cada 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 de pause(): 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:

  1. 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 puerto 1883.
  2. 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, y MQTT.subscribe se suscribe al tema.
  • MQTT.publish manda 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​

  1. 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.aread da el valor en bruto de su ADC, con otra escala (ver GPIO). Cambia PIN_SENSOR por 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).
  2. 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.
  3. 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.

Si la placa pierde la conexión

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​