/*
  LoRa Temperature and Air Node.

  This code send Temperatur and MQ135 data to a Gateway for Arduino IOT data collection.
  
  created 25 07 2022
  by Carlo Stramaglia
*/

#include <SPI.h>              // include libraries
#include <LoRa.h>
#include <MQ135.h>
#include <DHT.h>

const int csPin = 10;          // LoRa radio chip select
const int resetPin = 7;       // LoRa radio reset
const int irqPin = 4;         // change for your board; must be a hardware interrupt pin

String outgoing;              // outgoing message

byte msgCount = 0;            // count of outgoing messages
byte localAddress = 0x02;     // address of this device
byte destination = 0x01;      // destination to send to

int Temperature = 0;        // Temperature Integer
int Humidity = 0;           // Humidity Integer
int Rzero = 0;
int cRzero = 0;
int Resistance = 0;
int Ppm = 0;
int Cppm = 0;

int payloadLenght = 19;
byte Data[19];

#define PIN_MQ135 A0 // MQ135 Analog Input Pin
#define DHTPIN 3 // DHT Digital Input Pin
#define DHTTYPE DHT22 // DHT11 or DHT22, depends on your sensor

MQ135 mq135_sensor(PIN_MQ135);
DHT dht(DHTPIN, DHTTYPE);

float temperature, humidity; // Temp and Humid floats, will be measured by the DHT

void setup() {
  Serial.begin(9600);                   // initialize serial
  dht.begin();
  delay (1000);  
  
  // override the default CS, reset, and IRQ pins (optional)
  LoRa.setPins(csPin, resetPin, irqPin);// set CS, reset, IRQ pin

  if (!LoRa.begin(868E6)) {             // initialize ratio at 868 MHz
    Serial.println("LoRa init failed. Check your connections.");
    while (true);                       // if failed, do nothing
  }

  Serial.println("LoRa init succeeded.");
}

void loop() {

  delay(4000);
  
  humidity = dht.readHumidity();
  temperature = dht.readTemperature();

  // Check if any reads failed and exit early (to try again).
  if (isnan(humidity) || isnan(temperature)) {
    Serial.println(F("Failed to read from DHT sensor!"));
    return;
  }

  float rzero = mq135_sensor.getRZero();
  float correctedRZero = mq135_sensor.getCorrectedRZero(temperature, humidity);
  float resistance = mq135_sensor.getResistance();
  float ppm = mq135_sensor.getPPM();
  float correctedPPM = mq135_sensor.getCorrectedPPM(temperature, humidity);

  Serial.print("MQ135 RZero: ");
  Serial.print(rzero);
  Serial.print("\t Corrected RZero: ");
  Serial.print(correctedRZero);
  Serial.print("\t Resistance: ");
  Serial.print(resistance);
  Serial.print("\t PPM: ");
  Serial.print(ppm);
  Serial.print("ppm");
  Serial.print("\t Corrected PPM: ");
  Serial.print(correctedPPM);
  Serial.println("ppm");
  Serial.println("Temperature and Humidity before the calculation");
  Serial.print(temperature);
  Serial.print("  ");
  Serial.println(humidity);

  Temperature = int (temperature*10);
  Humidity = int (humidity*10);
  Rzero = int (rzero*100);
  cRzero = int (correctedRZero*100);
  Resistance = int (resistance*100);
  Ppm = int(ppm*100);
  Cppm = int (correctedPPM*100);
  // prepare and schedule data for transmission 
    Data[0] = Temperature >> 8; 
    Data[1] = Temperature;
    Data[2] = Humidity >> 8;
    Data[3] = Humidity;
    Data[4] = Rzero >> 16;
    Data[5] = Rzero >> 8;
    Data[6] = Rzero;
    Data[7] = cRzero >> 16;
    Data[8] = cRzero >> 8;
    Data[9] = cRzero;
    Data[10] = Resistance >> 16;
    Data[11] = Resistance >> 8;
    Data[12] = Resistance;
    Data[13] = Ppm >> 16;
    Data[14] = Ppm >> 8; 
    Data[15] = Ppm;
    Data[16] = Cppm >> 16;
    Data[17] = Cppm >> 8; 
    Data[18] = Cppm;
    //Data[0] = 0xa; 
    //Data[1] = 0xb;
    //Data[2] = 0xc;
    //Data[3] = 0xd;
    Serial.println("Data of Temp and Hum after manipulation");
    Serial.println(Temperature);
    Serial.println(Humidity);
    //Serial.println(Data[2],DEC);
    //Serial.println(Data[3],DEC);
     
  sendMessage(Data);
}

void sendMessage(byte* outgoing) {
  LoRa.beginPacket();                   // start packet
  LoRa.write(destination);              // add destination address
  LoRa.write(localAddress);             // add sender address
  LoRa.write(msgCount);                 // add message ID
  //LoRa.write(outgoing.length());        // add payload length
  LoRa.write(payloadLenght);        // add payload length
  LoRa.write(outgoing, payloadLenght);                 // add payload
  LoRa.endPacket();                     // finish packet and send it
  msgCount++;                           // increment message ID
}
