You dont have javascript enabled! Please enable it!

Caso práctico: nodo LoRaWAN agro MKR WAN 1310+BME680+DS18B20

Caso práctico: nodo LoRaWAN agro MKR WAN 1310+BME680+DS18B20 — hero

Objetivo y caso de uso

Qué construirás: Un nodo de microclima LoRaWAN utilizando Arduino MKR WAN 1310, BME680 y DS18B20 para medir y transmitir datos ambientales en agricultura.

Para qué sirve

  • Monitoreo de temperatura y humedad del suelo mediante el sensor BME680.
  • Medición de la temperatura del aire utilizando el sensor DS18B20.
  • Transmisión de datos en tiempo real a través de LoRaWAN para análisis remoto.
  • Optimización del riego basado en datos ambientales.
  • Integración con plataformas de gestión agrícola para visualización de datos.

Resultado esperado

  • Transmisión de datos cada 15 minutos con una latencia menor a 5 segundos.
  • Precisión de medición de temperatura de ±0.5 °C y humedad de ±3%.
  • Consumo de energía del nodo menor a 100 mA durante la transmisión.
  • Capacidad de enviar hasta 10.000 paquetes de datos por mes.
  • Alertas automáticas si los parámetros ambientales superan umbrales críticos.

Público objetivo: Ingenieros agrónomos y desarrolladores de IoT; Nivel: Avanzado

Arquitectura/flujo: Sensor BME680 y DS18B20 -> Arduino MKR WAN 1310 -> Transmisión LoRaWAN -> Plataforma de gestión.

Nivel: Avanzado

Prerrequisitos

  • Sistemas operativos probados:
  • Ubuntu 22.04 LTS (amd64)
  • Windows 11 23H2 (64-bit)
  • macOS 14 Sonoma (Apple Silicon o Intel)

  • Toolchain exacta (línea de comandos, sin IDE gráfico):

  • Arduino CLI 1.1.1
  • Core “Arduino SAMD Boards (32-bits ARM Cortex-M0+)” 1.8.14
  • Librerías Arduino (versiones probadas y fijadas para reproducibilidad):

    • MKRWAN 1.1.0
    • Adafruit BME680 Library 2.0.2
    • Adafruit BusIO 1.14.5 (dependencia de Adafruit BME680)
    • OneWire 2.3.7
    • DallasTemperature 3.11.0
  • Cuenta y aplicación en red LoRaWAN (The Things Stack v3 o compatible):

  • Región/frequency plan (ejemplos): EU868, US915, AU915, AS923, etc.
  • Dispositivo dado de alta en la aplicación (OTAA):

    • DevEUI (lo ideal: leerlo del módem y registrarlo)
    • JoinEUI/AppEUI
    • AppKey
  • Hardware y electricidad:

  • Conocimientos de 3.3 V lógicos (MKR WAN 1310 NO tolera 5 V en GPIO).
  • Sondas y herramientas:

    • Multímetro para verificación de 3.3 V y continuidad.
    • Resistencia 4.7 kΩ para pull‑up en la línea 1‑Wire del DS18B20.
  • Recomendaciones:

  • Editor de texto/código (p. ej., VS Code) con resaltado Arduino.
  • Cable micro‑USB de datos (no solo carga).

Materiales

  • Placa y sensores exactos:
  • Arduino MKR WAN 1310 (ATSAMD21 + CMWX1ZZABZ LoRaWAN)
  • Sensor ambiental BME680 (I2C, dirección típica 0x76)
  • Sensor de temperatura DS18B20 (tubo o encapsulado TO‑92)
  • Componentes y pasivos:
  • 1 × resistencia 4.7 kΩ (pull‑up para línea de datos del DS18B20)
  • Cables Dupont hembra‑macho
  • Protoboard (opcional, recomendado)
  • Alimentación:
  • Cable micro‑USB
  • Batería LiPo 3.7 V (opcional, para pruebas de campo)
  • Red:
  • Pasarela LoRaWAN operativa con cobertura, o acceso a la red pública (TTN) con gateway cercano.

Objetivo del proyecto: construir un nodo “lora‑agro‑microclima‑node” que mida microclima local (temperatura y humedad del aire, presión, resistencia de gas del BME680, temperatura de suelo con DS18B20) y envíe paquetes binarios por LoRaWAN (OTAA) a intervalos configurables.

Preparación y conexión

Instalación de Arduino CLI y toolchain

1) Instala Arduino CLI 1.1.1:
– Linux (x86_64):
– Descarga: https://github.com/arduino/arduino-cli/releases/download/1.1.1/arduino-cli_1.1.1_Linux_64bit.tar.gz
– Extrae y coloca en /usr/local/bin o en tu PATH.
– Windows 11:
– Descarga: arduino-cli_1.1.1_Windows_64bit.zip
– Añade la ruta de arduino-cli.exe al PATH del usuario.
– macOS 14:
– Descarga: arduino-cli_1.1.1_macOS_64bit.zip (o arm64 si aplica)
– Coloca arduino-cli en /usr/local/bin o en /opt/homebrew/bin.

2) Inicializa el entorno (primera vez):
– Crea el archivo de configuración si no existe:
– arduino-cli config init

3) Actualiza el índice e instala el core SAMD exacto:
– arduino-cli core update-index
– arduino-cli core install arduino:samd@1.8.14

4) Instala las librerías con versiones fijadas:
– arduino-cli lib install «MKRWAN@1.1.0»
– arduino-cli lib install «Adafruit BME680 Library@2.0.2»
– arduino-cli lib install «Adafruit BusIO@1.14.5»
– arduino-cli lib install «OneWire@2.3.7»
– arduino-cli lib install «DallasTemperature@3.11.0»

5) Verifica que el FQBN esté disponible:
– arduino-cli board listall | grep mkrwan
– Debe aparecer: arduino:samd:mkrwan1310

Conexiones eléctricas

  • Consideraciones:
  • Todos los módulos comparten GND.
  • Alimentación a 3.3 V desde la MKR WAN 1310.
  • La interfaz I2C del BME680 es 3.3 V; no uses 5 V.
  • El DS18B20 es 3.0–5.5 V; úsalo a 3.3 V en este montaje.
  • Añade pull‑up de 4.7 kΩ entre DATA (DS18B20) y 3.3 V.

Tabla de pines/puertos y cableado:

Módulo/SensorSeñalPin del sensorPin en MKR WAN 1310Notas
BME680VCCVCC3V33.3 V regulados de la placa
BME680GNDGNDGNDTierra común
BME680SDA (I2C)SDASDAPin etiquetado SDA en cabecera MKR
BME680SCL (I2C)SCLSCLPin etiquetado SCL en cabecera MKR
DS18B20VDDVDD3V33.3 V
DS18B20GNDGNDGNDTierra común
DS18B20DATADQD2Línea 1‑Wire; requiere pull‑up de 4.7 kΩ a 3.3 V
Pull‑up4.7 kΩDQ—3.3 VConectar entre DQ (D2) y 3.3 V

Notas:
– En placas MKR, los pines SDA y SCL están claramente etiquetados cerca de AREF. Usa la cabecera marcada (no confundir con D11/D12 en otros form factors).
– La dirección I2C del BME680 suele ser 0x76; si tu breakout usa 0x77, lo ajustaremos en el código.

Preparación de credenciales LoRaWAN

  • Registra un dispositivo OTAA en tu aplicación (TTN o similar).
  • Obtén:
  • JoinEUI/AppEUI (16 hex dígitos)
  • AppKey (32 hex dígitos)
  • DevEUI: puedes leer el DevEUI del módem y registrar ese valor en la consola para evitar errores.

Comprobación de DevEUI desde el propio sketch (lo implementaremos); alternativamente, se puede usar un sketch corto de ejemplo MKRWAN para imprimirlo por Serial.

Código completo (Arduino/C++)

Estructura del proyecto en disco:
– lora-agro-microclima-node/
– lora-agro-microclima-node.ino
– secrets.h

El archivo secrets.h contendrá tus claves OTAA. No lo publiques.

secrets.h (plantilla)

Crea lora-agro-microclima-node/secrets.h con el siguiente contenido y reemplaza las X:

#pragma once
// Claves OTAA (hex ASCII, sin 0x ni espacios)
static const char APP_EUI[] = "0011223344556677"; // JoinEUI/AppEUI, 16 hex
static const char APP_KEY[] = "00112233445566778899AABBCCDDEEFF"; // 32 hex

// Opcional: si conoces el DevEUI de consola y quieres fijarlo,
// de lo contrario, lo leeremos del módem y lo mostraremos.
static const char DEV_EUI_OVERRIDE[] = ""; // deja vacío para usar el del módem

// Región LoRaWAN: usa uno de: EU868, US915, AU915, AS923, IN865, KR920
// Para compilar neutral, usamos define en código; aquí puedes documentar tu plan.

lora-agro-microclima-node.ino

El sketch implementa:
– Inicialización de sensores (BME680 por I2C, DS18B20 en D2).
– Inicialización de módem LoRaWAN (MKRWAN.h) y unión OTAA.
– Empaquetado binario compacto: T_air, RH, P, Gas, T_soil, VBAT.
– Ciclo con envío periódico y backoff si falla la red.

/*
  lora-agro-microclima-node
  Dispositivo: Arduino MKR WAN 1310 + BME680 + DS18B20
  Toolchain: Arduino CLI 1.1.1, SAMD Core 1.8.14, MKRWAN 1.1.0,
             Adafruit BME680 2.0.2, OneWire 2.3.7, DallasTemperature 3.11.0
*/

#include <Arduino.h>
#include <MKRWAN.h>
#include <Wire.h>
#include <Adafruit_BME680.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include "secrets.h"

// Región por compilación: ajusta EU868/US915/AU915/AS923/IN865/KR920
#ifndef LORA_REGION
#define LORA_REGION EU868
#endif

// Pines
static const uint8_t ONE_WIRE_PIN = 2; // D2 para DS18B20

// BME680: dirección por defecto 0x76 (ajusta a 0x77 si tu placa lo requiere)
Adafruit_BME680 bme; // I2C
OneWire oneWire(ONE_WIRE_PIN);
DallasTemperature ds18b20(&oneWire);

// Módem LoRa
LoRaModem modem;

// Configuración
static const uint32_t MEASUREMENT_INTERVAL_MS = 60UL * 1000UL; // 60 s (ajusta)
static const bool USE_CONFIRMED_UPLINK = false; // paquetes no confirmados por defecto
static const uint8_t FPORT = 1;

// Helpers de lectura de batería (ADC AREF = 3.3V, divisor interno del MKR)
float readBatteryVoltage() {
  // En MKR WAN 1310, el pin ADC interno puede leer VBAT a través de un canal dedicado.
  // Para simplificar, podemos usar analogRead(ADC_BATTERY) si está mapeado.
  // Alternativa: si tu core no expone ADC_BATTERY, deja 0.0f o implementa lectura externa.
#ifdef ADC_BATTERY
  uint16_t raw = analogRead(ADC_BATTERY);
  float v = (raw / 1023.0f) * 3.3f * 2.0f; // si hay divisor 1:1 interno (ajustar según placa)
  return v;
#else
  return 0.0f; // placeholder si no está disponible
#endif
}

// Empaquetado binario: escalado fijo
// Layout (12 bytes):
// [0-1]  T_air (°C * 100, int16)
// [2-3]  RH (% * 100, uint16)
// [4-5]  P (hPa * 10, uint16)
// [6-7]  Gas (kΩ * 10, uint16) – recorte a 65535
// [8-9]  T_soil (°C * 100, int16)
// [10-11] Vbat (mV, uint16)
uint16_t clamp_u16(int32_t v) {
  if (v < 0) return 0;
  if (v > 65535) return 65535;
  return (uint16_t)v;
}

void packPayload(uint8_t* buf, size_t len,
                 float t_air, float rh, float p_hpa, float gas_ohms, float t_soil, float vbat) {
  if (len < 12) return;
  int16_t t_air_i16 = (int16_t)roundf(t_air * 100.0f);
  uint16_t rh_u16 = clamp_u16(lroundf(rh * 100.0f));
  uint16_t p_u16 = clamp_u16(lroundf(p_hpa * 10.0f));
  float gas_kohm = gas_ohms / 1000.0f;
  uint16_t gas_u16 = clamp_u16(lroundf(gas_kohm * 10.0f));
  int16_t t_soil_i16 = (int16_t)roundf(t_soil * 100.0f);
  uint16_t vbat_u16 = clamp_u16(lroundf(vbat * 1000.0f));

  buf[0] = (uint8_t)(t_air_i16 >> 8);
  buf[1] = (uint8_t)(t_air_i16 & 0xFF);
  buf[2] = (uint8_t)(rh_u16 >> 8);
  buf[3] = (uint8_t)(rh_u16 & 0xFF);
  buf[4] = (uint8_t)(p_u16 >> 8);
  buf[5] = (uint8_t)(p_u16 & 0xFF);
  buf[6] = (uint8_t)(gas_u16 >> 8);
  buf[7] = (uint8_t)(gas_u16 & 0xFF);
  buf[8] = (uint8_t)(t_soil_i16 >> 8);
  buf[9] = (uint8_t)(t_soil_i16 & 0xFF);
  buf[10] = (uint8_t)(vbat_u16 >> 8);
  buf[11] = (uint8_t)(vbat_u16 & 0xFF);
}

bool initBME680() {
  if (!bme.begin(0x76)) {
    // Intenta en 0x77
    if (!bme.begin(0x77)) {
      Serial.println(F("[BME680] No detectado en 0x76/0x77"));
      return false;
    }
  }
  // Configura oversampling y filtro
  bme.setTemperatureOversampling(BME680_OS_8X);
  bme.setHumidityOversampling(BME680_OS_2X);
  bme.setPressureOversampling(BME680_OS_4X);
  bme.setIIRFilterSize(BME680_FILTER_SIZE_3);
  // Habilita gas heater
  bme.setGasHeater(320, 150); // 320°C durante 150 ms
  return true;
}

bool readBME680(float& t, float& h, float& p_hpa, float& gas_ohms) {
  // Realiza lectura forzada
  if (!bme.performReading()) return false;
  t = bme.temperature;          // °C
  h = bme.humidity;             // %
  p_hpa = bme.pressure / 100.0; // Pa -> hPa
  gas_ohms = bme.gas_resistance; // ohmios
  return true;
}

bool readDS18B20(float& t_soil) {
  ds18b20.requestTemperatures();
  float t = ds18b20.getTempCByIndex(0);
  if (t == DEVICE_DISCONNECTED_C) return false;
  t_soil = t;
  return true;
}

bool loraJoinOTAA() {
  Serial.println(F("[LoRa] Inicializando módem..."));
  if (!modem.begin(LORA_REGION)) {
    Serial.println(F("[LoRa] Error al iniciar el módem (begin)"));
    return false;
  }
  // Habilita ADR
  modem.setADR(true);

  // Muestra DevEUI real y permite override si se desea
  String devEUI = modem.deviceEUI();
  Serial.print(F("[LoRa] DevEUI (módem): ")); Serial.println(devEUI);

  if (strlen(DEV_EUI_OVERRIDE) == 16) {
    Serial.print(F("[LoRa] Usando DEV_EUI_OVERRIDE: ")); Serial.println(DEV_EUI_OVERRIDE);
    modem.setDevEUI(DEV_EUI_OVERRIDE);
  }

  // Configura AppEUI y AppKey
  if (strlen(APP_EUI) != 16 || strlen(APP_KEY) != 32) {
    Serial.println(F("[LoRa] APP_EUI/AppKey inválidos (tamaño)."));
    return false;
  }

  // Intenta unión con reintentos exponenciales
  const uint8_t MAX_TRIES = 6;
  uint32_t backoff = 3000; // ms
  for (uint8_t i = 1; i <= MAX_TRIES; ++i) {
    Serial.print(F("[LoRa] joinOTAA intento ")); Serial.println(i);
    if (modem.joinOTAA(APP_EUI, APP_KEY)) {
      Serial.println(F("[LoRa] ¡Unión OTAA exitosa!"));
      return true;
    }
    Serial.print(F("[LoRa] Fallo en join, esperando ")); Serial.print(backoff); Serial.println(F(" ms"));
    delay(backoff);
    backoff = min<uint32_t>(backoff * 2, 120000);
  }
  Serial.println(F("[LoRa] No se pudo unir tras varios intentos."));
  return false;
}

bool loraSend(const uint8_t* payload, size_t len, uint8_t fport, bool confirmed) {
  if (!payload || len == 0) return false;
  int err = modem.beginPacket();
  if (err <= 0) {
    Serial.print(F("[LoRa] beginPacket err=")); Serial.println(err);
    return false;
  }
  modem.write(payload, len);
  // confirmed = true => uplink confirmado; false => no confirmado
  int res = modem.endPacket(confirmed);
  if (res > 0) {
    Serial.print(F("[LoRa] Uplink OK, bytes=")); Serial.println(len);
    // Cambia FPORT si la librería lo soporta por API; si no, envía en port por defecto
    modem.setPort(fport); // en algunas versiones se fija antes de enviar; lo hacemos aquí por compatibilidad
    return true;
  } else {
    Serial.print(F("[LoRa] Uplink FAIL, code=")); Serial.println(res);
    return false;
  }
}

void printHex(const uint8_t* buf, size_t len) {
  for (size_t i = 0; i < len; ++i) {
    if (buf[i] < 16) Serial.print('0');
    Serial.print(buf[i], HEX);
  }
}

void setup() {
  Serial.begin(115200);
  while (!Serial) { ; }
  Serial.println(F("\n[lora-agro-microclima-node] Inicio"));

  // Sensores
  Wire.begin();
  if (!initBME680()) {
    Serial.println(F("[BME680] ERROR inicialización"));
  } else {
    Serial.println(F("[BME680] OK"));
  }
  ds18b20.begin();
  Serial.print(F("[DS18B20] Dispositivos 1-Wire: "));
  Serial.println(ds18b20.getDeviceCount());
  if (!ds18b20.getAddress(NULL, 0)) {
    Serial.println(F("[DS18B20] Atención: no se encontró dirección en índice 0 (puede seguir, pero verifique cableado)"));
  }

  // LoRa
  if (!loraJoinOTAA()) {
    Serial.println(F("[LoRa] No unido. Se reintentará más tarde."));
  }
}

void loop() {
  float t_air = NAN, rh = NAN, p_hpa = NAN, gas_ohms = NAN, t_soil = NAN;
  bool ok_bme = readBME680(t_air, rh, p_hpa, gas_ohms);
  bool ok_ds = readDS18B20(t_soil);
  float vbat = readBatteryVoltage();

  if (!ok_bme) Serial.println(F("[BME680] Lectura fallida"));
  if (!ok_ds)  Serial.println(F("[DS18B20] Lectura fallida"));

  uint8_t payload[12];
  // Valores por defecto si falla lectura
  if (!ok_bme) { t_air = 0; rh = 0; p_hpa = 0; gas_ohms = 0; }
  if (!ok_ds)  { t_soil = 0; }
  if (!(vbat > 0.1f)) vbat = 0.0f;

  packPayload(payload, sizeof(payload), t_air, rh, p_hpa, gas_ohms, t_soil, vbat);

  Serial.print(F("[Payload HEX] "));
  printHex(payload, sizeof(payload));
  Serial.println();

  bool sent = loraSend(payload, sizeof(payload), FPORT, USE_CONFIRMED_UPLINK);
  if (!sent) {
    Serial.println(F("[LoRa] Reintentará unión y envío en próximo ciclo."));
    // Intentar re-unirse si se perdió sesión
    loraJoinOTAA();
  } else {
    // Opción: leer downlink en ventana RX (si librería lo expone)
    if (modem.available()) {
      Serial.print(F("[Downlink] "));
      while (modem.available()) {
        int b = modem.read();
        if (b < 0) break;
        if (b < 16) Serial.print('0');
        Serial.print(b, HEX);
      }
      Serial.println();
    }
  }

  // Espera
  delay(MEASUREMENT_INTERVAL_MS);
}

Puntos clave del código:
– Inicialización BME680: oversampling, filtro y gas heater para lecturas estables.
– DS18B20 en D2 con OneWire; el pull‑up de 4.7 kΩ es obligatorio.
– LoRaWAN: begin(LORA_REGION), setADR(true), joinOTAA con reintentos exponenciales.
– Empaquetado binario compacto de 12 bytes: fácil de decodificar en el backend.
– Envío no confirmado (endPacket(false)) para ahorro de aire y energía; ajustable.

Compilación/flash/ejecución

Asegúrate de que la placa se detecte y toma nota del puerto serie.

1) Detecta la placa y el puerto:
– arduino-cli board list
– Debe listar algo como:
– Port: /dev/ttyACM0 (Linux)
– Port: COM5 (Windows)
– Port: /dev/cu.usbmodemXXX (macOS)
– Board Name: Arduino MKR WAN 1310
– FQBN: arduino:samd:mkrwan1310

2) Compila el proyecto (desde la carpeta que contiene lora-agro-microclima-node):
– arduino-cli compile \
-b arduino:samd:mkrwan1310 \
–warnings all \
–build-property compiler.cpp.extra_flags=»-DLORA_REGION=EU868″ \
lora-agro-microclima-node

Observaciones:
– Cambia -DLORA_REGION=EU868 por tu plan de frecuencias (US915, AU915, etc.).
– Asegúrate de haber creado secrets.h con APP_EUI y APP_KEY válidos.

3) Sube el firmware:
– Linux/macOS:
– arduino-cli upload \
-b arduino:samd:mkrwan1310 \
-p /dev/ttyACM0 \
–verify \
lora-agro-microclima-node
– Windows (ejemplo COM5):
– arduino-cli upload \
-b arduino:samd:mkrwan1310 \
-p COM5 \
–verify \
lora-agro-microclima-node

4) Abre el monitor serie para validar:
– Linux/macOS:
– arduino-cli monitor -p /dev/ttyACM0 -c baudrate=115200
– Windows:
– arduino-cli monitor -p COM5 -c baudrate=115200

5) Cambios de región:
– Recompila alterando el flag:
– … –build-property compiler.cpp.extra_flags=»-DLORA_REGION=US915″ …

6) Instalación/actualización del core y librerías (si faltan):
– arduino-cli core update-index
– arduino-cli core install arduino:samd@1.8.14
– arduino-cli lib install «MKRWAN@1.1.0» «Adafruit BME680 Library@2.0.2» «OneWire@2.3.7» «DallasTemperature@3.11.0»

Validación paso a paso

1) Validación eléctrica rápida:
– Con multímetro:
– 3V3 de la MKR: ~3.28–3.32 V.
– Continuidad GND entre sensores y placa.
– Pull‑up de 4.7 kΩ entre D2 y 3.3 V.

2) Validación de detección de placa:
– arduino-cli board list
– Si no aparece, prueba otro cable o puerto USB.

3) Validación de sensores por consola serie:
– Tras reset, debes ver:
– [BME680] OK (o mensaje de error si no detectado)
– [DS18B20] Dispositivos 1-Wire: N (N ≥ 1)
– Cuando hay lectura, se mostrará el payload HEX; por ejemplo:
– [Payload HEX] 07D00FA00E10002A03E807D005DC
– Esto varía según tus mediciones.

4) Validación de unión LoRaWAN:
– Mensajes esperados:
– [LoRa] Inicializando módem…
– [LoRa] DevEUI (módem): XXXXXXXXXXXXXXXX
– [LoRa] joinOTAA intento 1
– [LoRa] ¡Unión OTAA exitosa!
– Si falla, verás reintentos con backoff.

5) Validación de uplink en la consola de la red:
– Abre tu aplicación en The Things Stack (TTN v3).
– En “Live data” del dispositivo, deberías ver uplinks cada ~60 s.
– Payload Length = 12 bytes; Port = 1.

6) Decodificación del payload (servidor):
– Crea un decodificador personalizado con el layout descrito:
– T_air = int16 (big-endian) / 100
– RH = uint16 / 100
– P = uint16 / 10 (hPa)
– Gas = uint16 / 10 (kΩ)
– T_soil = int16 / 100
– Vbat = uint16 (mV)
– Verifica que T_air y T_soil son razonables (20–35 °C según ambiente/suelo), RH (20–90 %),
presión ~ 980–1050 hPa, gas suele fluctuar ampliamente, Vbat según alimentación.

7) Estabilidad:
– Deja el nodo 10–15 minutos:
– Sin pérdida de sesiones (sin rejoin continuos).
– Uplinks regulares a tu intervalo.
– Observa ADR en la red: la tasa de datos podría adaptarse.

Troubleshooting (errores típicos y soluciones)

1) No se detecta el BME680 ([BME680] No detectado en 0x76/0x77)
– Causas:
– Cable SDA/SCL invertido o mal pin.
– Breakout con dirección 0x77; ajusta el begin(0x77).
– Falta de GND común o VCC incorrecto.
– Solución:
– Revisa tabla de pines.
– Prueba ambas direcciones en el código (ya está implementado).
– Ejecuta un I2C scanner para verificar dirección.

2) DS18B20 devuelve DEVICE_DISCONNECTED_C o lectura fallida
– Causas:
– Falta pull‑up de 4.7 kΩ en la línea D2.
– GND/VDD invertidos o cable roto.
– Sensor sumergible con cable demasiado largo sin pull‑up adecuado.
– Solución:
– Añade o verifica la resistencia 4.7 kΩ entre D2 y 3.3 V.
– Usa cables más cortos o baja la frecuencia de sondeo.

3) No aparece el puerto serie en arduino-cli board list
– Causas:
– Cable solo de carga.
– Controladores USB (Windows).
– Puerto bloqueado por otro programa.
– Solución:
– Cambia a un cable de datos.
– Cierra programas que usan el puerto.
– En Windows, actualiza drivers USB nativos (MKR usa CDC estándar, no requiere drivers especiales).

4) joinOTAA falla repetidamente
– Causas:
– Región/banda incorrecta (EU868 vs US915/AU915).
– AppKey/AppEUI con formato o longitud incorrecta.
– Gateway fuera de cobertura o sin backhaul.
– Lista de sub‑bandas en US915/AU915 (TTN usa sub‑band específicas).
– Solución:
– Recompila con -DLORA_REGION adecuado.
– Verifica que APP_EUI = 16 hex y APP_KEY = 32 hex (sin espacios).
– Ubica el nodo cerca del gateway.
– Para US915/AU915, configura sub‑banda si tu librería/firmware lo permite; si no, asegúrate de la compatibilidad del gateway.

5) Uplinks no llegan a la consola, pero el nodo dice “Uplink OK”
– Causas:
– Port incorrecto filtrado por integración.
– Desfase de canales/frecuencias por región.
– RX windows desalineadas (raro si join OK).
– Solución:
– Verifica FPORT=1.
– Asegura misma región en dispositivo y aplicación.
– Re‑join para resincro.

6) Lecturas de gas del BME680 anómalas o lentas en estabilizar
– Causas:
– BME680 requiere “burn‑in” (tiempo de calentamiento) para lecturas significativas de gas.
– Cambios bruscos ambientales.
– Solución:
– Deja el sensor operando ~5–20 minutos para estabilización.
– Evita flujos de aire directos.

7) Vbat siempre 0.0 V
– Causas:
– El macro ADC_BATTERY no está disponible en tu core/placa, o no hay batería conectada.
– Solución:
– Conecta una LiPo a la MKR para lectura real.
– Implementa medición con pin analógico y divisor externo si lo requieres.
– O deja el campo en 0 y evita usarlo en análisis.

8) Error de compilación por librerías/cores en otra versión
– Causas:
– Versiones diferentes a las fijadas.
– Solución:
– Verifica versiones exactas:
– arduino-cli core list
– arduino-cli lib list
– Ajusta con:
– arduino-cli core install arduino:samd@1.8.14
– arduino-cli lib install «MKRWAN@1.1.0» …

Mejoras/variantes

  • Eficiencia energética:
  • Uso de modos de bajo consumo y RTCZero para dormir entre mediciones, reduciendo el consumo a pocos µA.
  • Incrementar el intervalo de envío (5–15 min) según el caso agro, para alargar la batería.

  • Payload y decodificación:

  • Cambiar a CayenneLPP para compatibilidad con plataformas sin decodificador custom.
  • Añadir checksum simple en payload si tu backend lo solicita.

  • Calidad de datos:

  • Integrar la librería BSEC (Bosch) para índices IAQ/VOC/CO2e; requiere más memoria y gestión de licencia/arquitectura.
  • Calibración de sensores (offset de temperatura en DS18B20, validación con termómetro de referencia).

  • LoRaWAN:

  • Confirmed uplink solo para mensajes críticos; activar con USE_CONFIRMED_UPLINK = true.
  • Manejar downlinks para reconfigurar intervalo de medición sobre FPORT 10 (p. ej., 1 byte con minutos).
  • Persistir frame counters y sesión (OTAA) en flash para evitar join frecuente tras reinicios.

  • Hardware:

  • Carcasa IP65 con desecante y filtro sinterizado para BME680 (protección y respuesta de gas).
  • Añadir sensor de humedad de suelo (capacitivo 3.3 V) y pluviómetro de pulsos para un nodo agro más completo.

  • Robustez:

  • Watchdog por software/hardware para recuperación ante bloqueos.
  • Registro de errores en EEPROM/flash para diagnóstico.

Checklist de verificación

  • [ ] Arduino CLI 1.1.1 instalado y en PATH.
  • [ ] Core arduino:samd@1.8.14 instalado.
  • [ ] Librerías instaladas con versiones: MKRWAN 1.1.0, Adafruit BME680 2.0.2, OneWire 2.3.7, DallasTemperature 3.11.0.
  • [ ] Proyecto creado: lora-agro-microclima-node/ con .ino y secrets.h.
  • [ ] APP_EUI (16 hex) y APP_KEY (32 hex) configurados en secrets.h.
  • [ ] BME680 cableado a SDA/SCL, 3V3 y GND.
  • [ ] DS18B20 en D2 con pull‑up 4.7 kΩ a 3.3 V; GND y VDD correctos.
  • [ ] Compilación exitosa con FQBN arduino:samd:mkrwan1310 y región correcta.
  • [ ] Subida exitosa al puerto correcto (/dev/ttyACM0, COMx, etc.).
  • [ ] Consola serie a 115200 bps muestra BME680 OK, conteo DS18B20 y payload HEX.
  • [ ] Unión OTAA exitosa y uplinks visibles en la consola LoRaWAN.
  • [ ] Decodificador en backend interpreta los 12 bytes en unidades correctas.
  • [ ] Ciclo estable durante 10–15 min con uplinks a intervalos regulares.

Apéndice: comandos clave (resumen rápido)

  • Listar placas:
  • arduino-cli board list
  • Actualizar e instalar core:
  • arduino-cli core update-index
  • arduino-cli core install arduino:samd@1.8.14
  • Instalar librerías:
  • arduino-cli lib install «MKRWAN@1.1.0» «Adafruit BME680 Library@2.0.2» «OneWire@2.3.7» «DallasTemperature@3.11.0»
  • Compilar (EU868):
  • arduino-cli compile -b arduino:samd:mkrwan1310 –build-property compiler.cpp.extra_flags=»-DLORA_REGION=EU868″ lora-agro-microclima-node
  • Subir (Linux ejemplo):
  • arduino-cli upload -b arduino:samd:mkrwan1310 -p /dev/ttyACM0 –verify lora-agro-microclima-node
  • Monitor serie:
  • arduino-cli monitor -p /dev/ttyACM0 -c baudrate=115200

Con esto, dispones de un nodo “lora‑agro‑microclima‑node” fiable en Arduino MKR WAN 1310 que integra BME680 y DS18B20, con toolchain y versiones fijadas, conexiones claras, código reproducible y validación end‑to‑end en LoRaWAN.

Encuentra este producto y/o libros sobre este tema en Amazon

Ir a Amazon

Como afiliado de Amazon, gano con las compras que cumplan los requisitos. Si compras a través de este enlace, ayudas a mantener este proyecto.

Quiz rápido

Pregunta 1: ¿Cuál es el sistema operativo probado para el uso de Arduino CLI?




Pregunta 2: ¿Qué versión de la librería MKRWAN es la recomendada?




Pregunta 3: ¿Cuál es el voltaje lógico que el MKR WAN 1310 no tolera?




Pregunta 4: ¿Qué tipo de sensor es el BME680?




Pregunta 5: ¿Qué herramienta se recomienda para verificar la continuidad?




Pregunta 6: ¿Qué tipo de conexión se requiere para el sensor DS18B20?




Pregunta 7: ¿Qué tipo de batería es opcional para pruebas de campo?




Pregunta 8: ¿Qué es necesario para dar de alta un dispositivo en la aplicación LoRaWAN?




Pregunta 9: ¿Qué cable se recomienda para la conexión de datos?




Pregunta 10: ¿Cuál es la resistencia recomendada para el pull-up en la línea 1-Wire?




Carlos Núñez Zorrilla
Carlos Núñez Zorrilla
Electronics & Computer Engineer

Ingeniero Superior en Electrónica de Telecomunicaciones e Ingeniero en Informática (titulaciones oficiales en España).

Sígueme:
Scroll al inicio