LoRaWan – Sensor Humedad y Temperatura. Archivo.ino

El desarrollo del ejercicio se simplifica al tratarse como una extensión del ejemplo base de comunicación Lora al que se añade el Sensor DHT11.

ChirpStack – Añadir un dispositivo

El archivo de instrucciones se presenta en tres secciones o pestañas. La primera contiene la declaración de variables, la parte de configuración y el lazo principal. Las siguientes dos secciones son procedimientos para preparación de trama y lectura de sensor.

Preparación de trama

El valor de temperatura se almacena en tipo real (float) que usa 4 bytes. En la trama se separan los bytes en orden LSB (Byte menos significativo primero, detalle que hay que recordar para decodificar en ChirpStack.

    unsigned char *puc;
    puc = (unsigned char *)(&temperaturaC);
    appDataSize = 8;//AppDataSize max value is 64
    appData[0] = puc[0];
    appData[1] = puc[1];
    appData[2] = puc[2];
    appData[3] = puc[3];

De utilizar el mismo formato para el valor de Humedad, el formato es muy semejante.

Intrucciones Principales

 /*
 * HelTec Automation(TM) LoRaWAN 1.0.2 OTAA example use OTAA, CLASS A
 * Solo ESP32+LoRa series boards con licencia http: / /www.heltec.cn /search /);
 *https: / /github.com /HelTecAutomation /ESP32_LoRaWAN
* /
#include <ESP32_LoRaWAN.h>
#include "Arduino.h"
#include <DHT.h>

 /*licencia Heltec ESP32 LoRaWan http: / /resource.heltec.cn /search * /
uint32_t  license[4] = {0xBE21335B, 0xAEC3C5CE, 0xCC0A1CF4, 0xB836F981};

 /* OTAA parametros* /
uint8_t DevEui[] = { 0x01, 0x20, 0x08, 0x93, 0xdf, 0x80, 0x37, 0x74 };
uint8_t AppEui[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
uint8_t AppKey[] = { 0x05, 0x8e, 0xeb, 0xff, 0x24, 0xf1, 0x01, 0x84, 0xd0, 0x07, 0xbe, 0xd4, 0x65, 0xe7, 0x6b, 0xb5 };

 /* ABP parametros* /
uint32_t DevAddr =  ( uint32_t )0x0174b1fd;
uint8_t NwkSKey[] = { 0xc1, 0x45, 0x31, 0x28, 0x5f, 0xb2, 0x56, 0x3b, 0x9d, 0x5f, 0x27, 0x15, 0xed, 0x3a, 0x0e, 0xbc}; 
uint8_t AppSKey[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};

 / /LoraWan channelsmask, default channels 0-7 /
uint16_t userChannelsMask[6]={ 0x00FF,0x0000,0x0000,0x0000,0x0000,0x0000 };

DeviceClass_t  loraWanClass = CLASS_A;   /*Soporte de A and C* /
uint32_t appTxDutyCycle = 300000;         /*15000; en [ms]* /
bool overTheAirActivation = true;        /*OTAA or ABP* /
bool loraWanAdr = true;                  /*ADR enable* /
bool isTxConfirmed = true;               /*confirmed or unconfirmed messages * /
uint8_t appPort = 2;                     /* Application port * /

 /* reintentos de transmisión, en caso de no recibir ack * /
uint8_t confirmedNbTrials = 8;

 /* Seleccionado de Arduino IDE tools * /
uint8_t debugLevel = LoRaWAN_DEBUG_LEVEL; 
LoRaMacRegion_t loraWanRegion = ACTIVE_REGION;

 / / variables de sensor /actuador
uint8_t contador = 0;  
float humedad = 0;
float temperaturaC = 0;
float temperaturaF = 0;

 / / Mensajes por Puerto Serial
volatile boolean serial_msg = true;

 / / Sensor humedad y temperatura
#define DHTPIN 4
#define DHTTYPE DHT11
DHT dht(DHTPIN, DHTTYPE);

void setup(){
  if (serial_msg){
    Serial.begin(115200);
    while (!Serial);
  }
  SPI.begin(SCK,MISO,MOSI,SS);
  Mcu.init(SS,RST_LoRa,DIO0,DIO1,license);
  deviceState = DEVICE_STATE_INIT;

   / / SENSOR Temperatura&Humedad
  dht.begin();
}
void loop(){
  
  switch( deviceState )  {
    case DEVICE_STATE_INIT:    {
      LoRaWAN.init(loraWanClass,loraWanRegion);
      break;
    }
    case DEVICE_STATE_JOIN:    {
      LoRaWAN.join();
      break;
    }
    case DEVICE_STATE_SEND:    { 
      prepareTxFrame( appPort );
      LoRaWAN.send(loraWanClass);
      deviceState = DEVICE_STATE_CYCLE;
      break;
      
    }
    case DEVICE_STATE_CYCLE:    {
       / / Schedule next packet transmission
      txDutyCycleTime = appTxDutyCycle + randr( -APP_TX_DUTYCYCLE_RND,
                                                APP_TX_DUTYCYCLE_RND );
      LoRaWAN.cycle(txDutyCycleTime);
      deviceState = DEVICE_STATE_SLEEP;
      break;
    }
    case DEVICE_STATE_SLEEP:    {
      LoRaWAN.sleep(loraWanClass,debugLevel);
      break;
    }
    default:    {
      deviceState = DEVICE_STATE_INIT;
      break;
    }
  }
}

Preparación de trama

// Trama - integra datos
static void prepareTxFrame( uint8_t port ){
    contador = contador + 1;
    // Sensor de Temperatura y Humedad
    SensorTempHum();

    if (isnan(humedad) || isnan(temperaturaC) || isnan(temperaturaF)) {
      humedad = 0;
      temperaturaC = 0;
      temperaturaF = 0;
    }
    unsigned char *puc;
    puc = (unsigned char *)(&temperaturaC);
    appDataSize = 8;//AppDataSize max value is 64
    appData[0] = puc[0];
    appData[1] = puc[1];
    appData[2] = puc[2];
    appData[3] = puc[3];

    puc = (unsigned char *)(&humedad);
    appData[4] = puc[0];
    appData[5] = puc[1];
    appData[6] = puc[2];
    appData[7] = puc[3];
    if (serial_msg){
      Serial.print("tx: "+String(temperaturaC)+"  ");
      Serial.print(appData[0]);
      Serial.print(appData[1]);
      Serial.print(appData[2]);
      Serial.println(appData[3]);
      Serial.print("tx: "+String(humedad)+"  ");
      Serial.print(appData[4]);
      Serial.print(appData[5]);
      Serial.print(appData[6]);
      Serial.println(appData[7]);
    }
}

Lectura de sensor

void SensorTempHum(){
  // SENSOR Temperatura&Humedad
  dht.begin(); // regresa de sleep
  delay(2000); // espera minina entre lecturas de sensor
  humedad = dht.readHumidity();
  temperaturaC = dht.readTemperature();
  temperaturaF = dht.readTemperature(true);

  if (isnan(humedad) || isnan(temperaturaC) || isnan(temperaturaF)) {
    if (serial_msg){
      Serial.println(F("Failed to read from DHT sensor!"));
    }
    // espera minina entre lecturas de sensor
    delay(100); 
    return;
  }

  float hif = dht.computeHeatIndex(temperaturaF, humedad);
  float hic = dht.computeHeatIndex(temperaturaC, humedad, false);

  if (serial_msg){
    Serial.print(F(" Humidity: "));
    Serial.print(humedad);
    Serial.print(F("%  \n Temperature: "));
    Serial.print(temperaturaC);
    Serial.print(F("°C "));
    Serial.print(temperaturaF);
    Serial.print(F("°F \n Heat index: "));
    Serial.print(hic);
    Serial.print(F("°C "));
    Serial.print(hif);
    Serial.println(F("°F"));
  }
}