3.3 LoRa multipunto – Temperatura, Humedad: Dispositivo Archivo.ino

1. Instrucciones en Arduino IDE

Para facilitar la programación, se separan en funciones las acciones para enviar y recibir mensajes Lora y las de manejo de sensor/actuador.

El sensor DTH-11 se conecta al pin 13

El sensor de bateria se conecta al pin 36 como entrada analógica.

/*
  Dispositivo Sensor Temperatura y Humedad con DHT11
  Broker: MQTT/Home-Assistant
  Red ruta: LoRa/WiFi/Ethernet
  edelros@espol.edu.ec
  http://blog.espol.edu.ec/edelros/
  Referencia: Ejemplos de Aaron.Lee www.heltec.cn
*/
#include "heltec.h"
#include "DHT.h"

// Sensor de Temperatura&Humedad
#define DHTPIN 13
#define DHTTYPE DHT11 
DHT dht(DHTPIN, DHTTYPE);
String temperatura = "";
String humedad = ""; 

// Sensor de Bateria
# define BattPIN 36
String battNivel;

//Banda LoRa 915Mhz - ISM en Región 
#define BAND  915E6 // 433E6,868E6,915E6
// ranges from 6-12,default 7 see API docs
byte spread_factor = 8;

// Mensaje a enviar por direcciones
byte dir_local   = 0xD1; // Dispositivo  1
byte dir_destino = 0xC1; // Concentrador 1
// identificador de mensaje
byte msjContador = 0;
// tiempo entre lecturas
long t_anterior = 0;
int  t_intervalo = 5000;

// Mensaje Recibido
byte dir_envio = 0xC1; // Concentrador 1
int dir_remite = 0xD0; // Inicia Remitente
String paqueteRcb = "";
byte   paqrcbvID = 0;
byte   paqrcbEstado = 0;
  // 0:vacio, 1: nuevo, 2:incompleto
  // 3:otro destinatario, 4:Broadcast

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

void setup(){
  Heltec.begin(false /*DisplayEnable Enable*/,
    true /*Heltec.Heltec.Heltec.LoRa Disable*/,
    serial_msj /*Serial Enable*/,
    true /*PABOOST Enable*/,
    BAND /*long BAND*/);
    
  // ranges from 6-12,default 7 see API docs
  LoRa.setSpreadingFactor(spread_factor);
  //LoRa.onReceive(cbk);
  LoRa.receive();

  //inicializa sensores
  pinMode(DHTPIN, INPUT);
  dht.begin();
  pinMode(BattPIN, INPUT);
  }

void loop(){
  // Enviar mensajes entre intervalos
  long t_ahora = millis();
  long t_transcurrido = t_ahora - t_anterior;

  // parametros de recepción
  int rssi_lora = 0;
  int snr_lora = 0;
  
  if (t_transcurrido >= t_intervalo){
    sensorLeeDHT(); //actualiza estado del sensor
    sensorBateria(); // actualiza estado de bateria
    
    // Construye paquete a enviar
    String paqueteEnv = "";
    paqueteEnv = paqueteEnv + "t" + temperatura;
    paqueteEnv = paqueteEnv + "|";
    paqueteEnv = paqueteEnv + "h" + humedad;
    paqueteEnv = paqueteEnv + "|";
    paqueteEnv = paqueteEnv + "v" + battNivel;
    
    enviarlora(dir_destino, dir_local,
               msjContador, paqueteEnv);
    
    msjContador = msjContador + 1;
    
    // parametros de recepción
    rssi_lora = LoRa.packetRssi();
    snr_lora = LoRa.packetSnr();
    yield();
    
    // mensaje a serial
    if (serial_msj==true){
      Serial.print(String(dir_destino,HEX));
      Serial.print(",");
      Serial.print(String(dir_local,HEX));
      Serial.print(",");
      Serial.print(msjContador);Serial.print(",");
      Serial.print(paqueteEnv.length());Serial.print(",");
      Serial.print(paqueteEnv);Serial.print(",");
      Serial.print(rssi_lora);Serial.print(",");
      Serial.println(snr_lora);
    }
    
    t_anterior = millis();
    t_intervalo = 3000 + random(2000);
    
    // LED parpadea envio lora
    digitalWrite(LED, HIGH); delay(100);
    digitalWrite(LED, LOW);  delay(100);
    yield(); // procesa wifi
  }

  // Revisar mensajes LoRa entrantes
  int msjRcbLoRa = LoRa.parsePacket();
  if (msjRcbLoRa !=0){
    recibirlora(msjRcbLoRa);
    rssi_lora = LoRa.packetRssi();
    snr_lora = LoRa.packetSnr();
    
    if (serial_msj==true){
      if (paqrcbEstado == 1){
        Serial.println("Mensaje: " + paqueteRcb);
        Serial.println("RSSI: " + String(rssi_lora));
        Serial.println("Snr: " + String(snr_lora));
        Serial.println();
      }else{
        Serial.print("Paquete recibido Estado: ");
        Serial.println(paqrcbEstado);
      }
    }
    yield(); // procesa wifi
    
    // LED parpadea Recibido Lora
    digitalWrite(LED, HIGH); delay(50);
    digitalWrite(LED, LOW); delay(50);
    digitalWrite(LED, HIGH); delay(50);
    digitalWrite(LED, LOW);
  }
  delay(100);
  yield(); // procesa wifi
}

void enviarlora(byte destino, byte remite,
                byte paqueteID, String paquete){
  // espera que el radio esté listo
  // para enviar un paquete
  while(LoRa.beginPacket() == 0){
    if (serial_msj==true){
      Serial.println("Esperando radio disponible...");
    }
    yield(); // procesa wifi
    delay(100);
  }
  // envio del mensaje LoRa
  LoRa.beginPacket();
  LoRa.write(destino);
  LoRa.write(remite);
  LoRa.write(paqueteID);
  LoRa.write(paquete.length());
  LoRa.print(paquete);
  LoRa.endPacket();
}

void recibirlora(int tamano){
  if (tamano == 0){ 
    paqrcbEstado = 0; //vacio
    return;
    }
  // lectura de paquete
  paqueteRcb = "";
  dir_envio = LoRa.read();
  dir_remite  = LoRa.read();
  paqrcbvID = LoRa.read();
  byte paqrcbTamano = LoRa.read();
  while(LoRa.available()){
    paqueteRcb += (char)LoRa.read();
  }
  if (paqrcbTamano != paqueteRcb.length()){
    paqrcbEstado = 2; // Tamaño incompleto
    return;
  }
  if (dir_envio != dir_local){
    paqrcbEstado = 3; // otro destino
    return;
  }
  if (dir_envio == 0xFF) {
    paqrcbEstado = 4; // Broadcast
    return;
  }
  paqrcbEstado = 1;  // mensaje Nuevo
}

// Sensor lecturas
void sensorLeeDHT(){
  humedad = String(int(dht.readHumidity())).c_str();
  temperatura = String(dht.readTemperature()).c_str();
}

void sensorBateria(){
  int lectura = analogRead(BattPIN);
  // convierte a equivalente en voltios
  float voltaje = (float(lectura)/4096.0)*4.2*3.0/2.0;
  battNivel = String(voltaje).c_str();
}