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")); } }