Ir al contenido

← Todas las funcionalidades

Bombeo de agua (saneamiento)ESP32 PLC 14 / 38ARLoRaWANComunicación

Empaquetar toda una estación de bombeo en un payload LoRaWAN de 4 bytes

La codificación del payload LoRaWAN es donde los proyectos de telemetría remota se ganan o se pierden. Este ejemplo, extraído de un despliegue real en una estación de bombeo de agua, empaqueta el estado completo de la estación — once entradas digitales, dos flags de error y una sonda de nivel analógica de 10 bits — en 4 bytes, enviados cada 60 s por OTAA en un ESP32 PLC 38AR. El mismo estado en JSON necesitaría ~200 bytes y no sobreviviría al duty cycle de EU868 con spreading factors altos.

La estructura de la trama de 4 bytes

El byte 0 y la parte alta del byte 1 llevan las once entradas digitales, un bit cada una (missatge[i/8] |= dades_i[i] << (7 - i%8)). El byte 2 aloja los flags de confirmación de contactor y de fallo térmico en sus bits altos más los tres bits altos de la sonda analógica; el byte 3 lleva el byte bajo de la sonda. Cada bit está justificado — no se desperdicia nada en nombres de campo ni separadores.

Por qué los payloads pequeños importan en LoRaWAN

El airtime crece con el tamaño del payload y el spreading factor. Una trama de 4 bytes cabe con holgura en el duty cycle del 1% de EU868 incluso a SF12, donde un mensaje JSON de 200 bytes es sencillamente ilegal. Tramas más pequeñas también significan mejor balance de enlace, menos retransmisiones y más batería en emplazamientos alimentados por solar.

Decodificar en el network server

El decodificador es el espejo del codificador: desplazar y enmascarar. En un payload formatter de TTN/ChirpStack, la entrada i es (bytes[i>>3] >> (7 - i%8)) & 1 y la sonda es ((bytes[2] & 0x07) << 8) | bytes[3]. Documenta la estructura de la trama junto al firmware — es el contrato entre el PLC y la plataforma.

Un fragmento de la implementación

Tal cual del ejemplo desplegado en el ESP32 PLC 14 / 38AR — cópialo libremente:

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

  for (uint8_t i = 0; i < NUM_INPUTS; i++) pinMode(pins[i], INPUT);
  pinMode(I_LEVEL_SENSOR, INPUT);
  pinMode(Q_P1, OUTPUT);
  pinMode(Q_P2, OUTPUT);

  // OTAA join: the network server derives the session keys on every join.
  // Credentials: placeholders — use the ones from your LoRaWAN application.
  lora_init(57600);                          // RN2xx3 via SerialSC1, EU868 band
  while (!lora_join_otaa("APP_EUI", "APP_KEY")) {
    Serial.println("[lora] join failed, retrying in 30 s");
    delay(30000);
  }
  Serial.println("[lora] OTAA join successful");
}

El ejemplo completo es un programa entero — cabecera de conexionado, setup y bucle principal — listo para adaptar a tu aplicación.

Preguntas frecuentes

¿Por qué no enviar JSON o CayenneLPP?

JSON es ~50 veces más grande y a menudo supera el payload máximo de LoRaWAN con spreading factors altos. CayenneLPP es un buen punto intermedio, pero las tramas empaquetadas a mano son las más pequeñas posibles y triviales de decodificar.

¿Cómo meto un valor analógico de 10 bits en la trama?

Divídelo — los tres bits altos van a los bits libres de un byte y los ocho bits restantes ocupan un byte completo. El decodificador lo reconstruye con un desplazamiento y un OR.

¿Qué pasa si el join OTAA falla al arrancar?

El ejemplo reintenta cada 30 segundos hasta que el join tiene éxito, y un firmware de producción debería además re-hacer el join periódicamente como watchdog de comunicaciones — mira el tutorial de FreeRTOS más abajo.

Funcionalidades relacionadas