Nestor Alejandro Ccencho Garcia
Published © CC BY-NC

Frost Monitoring

The implementation of a low temperature monitoring system applied to 3 sectors: household monitoring, monitoring of environments where anima

AdvancedWork in progressOver 4 days151
Frost Monitoring

Things used in this project

Hardware components

Seeed Studio Kit SenseCAP K1100
×1
Wio Terminal
Seeed Studio Wio Terminal
×1
Sensor NKP
×1
Battery, 3.7 V
Battery, 3.7 V
×2
USB Li Ion Battery Charger
Adafruit USB Li Ion Battery Charger
×1
Plastic Enclosure, Precision Miniature Case
Plastic Enclosure, Precision Miniature Case
×1

Software apps and online services

Node-RED
Node-RED
Arduino IDE
Arduino IDE

Story

Read more

Schematics

Test circuit

Helium - AWS IoT Core

Dashboard_n1

Dashboard_n2

Dashboard_n3

AWS_IoT Core

Decoder_Helium

Code

Sensor Soil Helium

Arduino
Ground sensor monitoring and environmental humidity and temperature sensors.
Helium was used for LoRAWAN communication
#include <SoftwareSerial.h>
#include <Arduino.h>
#include "disk91_LoRaE5.h"
#include <SensirionI2CSht4x.h>
#include <Wire.h>

SensirionI2CSht4x sht4x;
 
Disk91_LoRaE5 lorae5(&Serial); // Where the AT command and debut traces are printed

#define Frequency DSKLORAE5_ZONE_AU915
/*
Select your frequency band here.
DSKLORAE5_ZONE_EU868
DSKLORAE5_ZONE_US915
DSKLORAE5_ZONE_AS923_1
DSKLORAE5_ZONE_AS923_2
DSKLORAE5_ZONE_AS923_3
DSKLORAE5_ZONE_AS923_4
DSKLORAE5_ZONE_KR920
DSKLORAE5_ZONE_IN865
DSKLORAE5_ZONE_AU915
 */
 
char deveui[] = "6081F9577FB14225";
char appeui[] = "6081F96F8FDB0345";
char appkey[] = "95EBC52A4FA9FD2E0106909AE043DDE4";

// Variable de timer usando millis()
unsigned long lastTime = 0;
unsigned long timerDelay = 60000;

#define DE D2  //Pueden ser los 2 unidos
#define RE D3
 
const byte rh[] = {0x01,0x03, 0x00, 0x00, 0x00, 0x01, 0x84, 0x0a};
const byte temp[] = {0x01,0x03, 0x00, 0x01, 0x00, 0x01, 0xd5, 0xca};
const byte cond[] = {0x01,0x03, 0x00, 0x02, 0x00, 0x01, 0x25, 0xca};
const byte ph[] = {0x01,0x03, 0x00, 0x03, 0x00, 0x01, 0x74, 0x0a};
const byte nitro[] = {0x01,0x03, 0x00, 0x04, 0x00, 0x01, 0xc5, 0xcb};
const byte phos[] = {0x01,0x03, 0x00, 0x05, 0x00, 0x01, 0x94, 0x0b};
const byte pota[] = {0x01,0x03, 0x00, 0x06, 0x00, 0x01, 0x64, 0x0b};
const byte sali[] = {0x01,0x03, 0x00, 0x07, 0x00, 0x01, 0x35, 0xcb};

char text[8];


void data_decord(int val_1, int val_2, int val_3, int val_4, 
int val_5, int val_6,int val_7, int val_8, int val_9, int val_10, uint8_t data[20])
{
  int val[] = {val_1, val_2, val_3, val_4, val_5, val_6, val_7, val_8, val_9, val_10};

  for(int i = 0, j = 0; i < 10; i++, j += 2)
  {
    if(val[i] < 0)
    {
      val[i] = ~val[i] + 1;
      data[j] = val[i] >> 8 | 0x80;
      data[j+1] = val[i] & 0xFF;
    }
    else
    {
      data[j] = val[i] >> 8 & 0xFF;
      data[j+1] = val[i] & 0xFF;
    }
  }

}
 

void setup(void)
{
  Serial.begin(9600);
  Serial1.begin(9600); //Baud rate, parity mode, RX, TX
  pinMode(DE, OUTPUT);
  pinMode(RE, OUTPUT);
  digitalWrite(DE, LOW);
  digitalWrite(RE, HIGH);
  Serial.println("\r\nSistema Inicializado ! \r\n");


  
  uint32_t start = millis();
  while ( !Serial && (millis() - start) < 1500 );  // Open the Serial Monitor to get started or wait for 1.5"
  
  Wire.begin();

  uint16_t error;
  char errorMessage[256];

  sht4x.begin(Wire);

  uint32_t serialNumber;
  error = sht4x.serialNumber(serialNumber);
  delay(5000);
  if (error) {
      Serial.print("Error trying to execute serialNumber(): ");
      errorToString(error, errorMessage, 256);
      Serial.println(errorMessage);
  } else {
      Serial.print("Serial Number: ");
      Serial.println(serialNumber);
  }

  // init the library, search the LORAE5 over the different WIO port available
  if ( ! lorae5.begin(DSKLORAE5_SWSERIAL_WIO_P2) ) {
    Serial.println("LoRa E5 Init Failed");
    while(1); 
  }

  // Setup the LoRaWan Credentials
  if ( ! lorae5.setup(
        Frequency,
        deveui,
        appeui,
        appkey
     ) ){
    Serial.println("LoRa E5 Setup Failed");
    while(1);         
  }
}
 
void loop(void)
{

  //********* Funciones ************
  float val1 = getPH()*10;
  float val2 = getRH();
  float val3 = getTemp();
  int int_cond_soil = getCond()*100;
  int int_nit_soil = getNitrogen()*100;
  int int_pho_soil = getPhosphorous()*100;
  int int_pot_soil = getPotassium()*100;
  int int_sali_soil = getSalinidad()*100;
  //**********************************

  
    
  uint16_t error;
  float temperature, humidity, dt;
  int int_temp, int_humi, int_dt, int_ph_soil, int_rh_soil, int_temp_soil;
 
  dt=21.3;
  
  error = sht4x.measureHighPrecision(temperature, humidity);
  Serial.print("Temperature: "); Serial.print(temperature);
  Serial.print(" Humidity: "); Serial.println(humidity);

  int_temp = temperature*100;
  int_humi = humidity*100;
  int_ph_soil = val1*100;
  int_rh_soil = val2*100;
  int_temp_soil = val3*100;
  int_dt = dt*100;
  
  
  static uint8_t data[20] = { 0x00 };  //Use the data[] to store the values of the sensors

  data_decord(int_temp, int_humi, int_ph_soil, int_rh_soil, int_temp_soil, 
  int_cond_soil, int_nit_soil, int_pho_soil, int_pot_soil, int_sali_soil, data);
  
  if ( lorae5.send_sync(              //Sending the sensor values out
        8,                            // LoRaWan Port
        data,                         // data array
        sizeof(data),                 // size of the data
        false,                        // we are not expecting a ack
        12,                            // Spread Factor
        14                            // Tx Power in dBm
       ) 
  ) {
      Serial.println("Uplink done");
      if ( lorae5.isDownlinkReceived() ) {
        Serial.println("A downlink has been received");
        if ( lorae5.isDownlinkPending() ) {
          Serial.println("More downlink are pending");
        }
      }
  }
  delay(600000);
 // }
}


//************** Function sensor soil ********************
float getPH(){
  int16_t readPH;
  getDataSensor(ph, sizeof(ph), &readPH);
  return (float)readPH/100.0f;
}

float getRH(){
  int16_t readRH;
  getDataSensor(rh, sizeof(rh), &readRH);
  return (float)readRH/10.0f;
}

float getTemp(){
  int16_t readTemp;
  getDataSensor(temp, sizeof(temp), &readTemp);
  return (float)readTemp/10.0f;
}

int16_t getCond(){
  int16_t readCond;
  getDataSensor(cond, sizeof(cond), &readCond);
  return readCond;
}

int16_t getNitrogen(){
  int16_t readnitro;
  getDataSensor(nitro, sizeof(nitro), &readnitro);
  return readnitro;
}
 
int16_t getPhosphorous(){
  int16_t readphos;
  getDataSensor(phos, sizeof(phos), &readphos);
  return readphos;
}
 
int16_t getPotassium(){
  int16_t readPota;
  getDataSensor(pota, sizeof(pota), &readPota);
  return readPota;
}

int16_t getSalinidad(){
  int16_t readSali;
  getDataSensor(sali, sizeof(sali), &readSali);
  return readSali;
}

//********************** DataSensor ******************************
boolean getDataSensor(const byte* cmd, int len_cmd, int16_t* res){
  uint8_t values[16];
  *res = 0;
  emptyBufferSerial1();
  digitalWrite(DE, HIGH);
  digitalWrite(RE, HIGH);
  Serial1.setTimeout(200);
  Serial1.write(cmd, len_cmd);
  delayMicroseconds(140*(len_cmd*10)); //Calculado para 9600 baudios(140)
  //while(Serial1.availableForWrite() < 128);
  digitalWrite(DE, LOW);
  digitalWrite(RE, LOW);
  int cont = Serial1.readBytes(values, 7);
  Serial.println("Cantidad de datos recibidos: " + String(cont));
  if (cont == 7)
  {
    Serial.print("Datos recibidos: ");
    for(byte i=0;i<cont;i++){
    //Serial.print(mod.read(),HEX);
    //values[i] = Serial1.read();
    sprintf(text, "0x%02X ", values[i]);
    Serial.print(text);
    }
    Serial.println();
    *res = ((int16_t)values[3] << 8) | (int16_t)values[4];
    
    return true;
  }
  
  return false;
}

void emptyBufferSerial1(void){
  byte c;
  while(Serial1.available()){
    c = Serial1.read();
  }
}

Credits

Nestor Alejandro Ccencho Garcia

Nestor Alejandro Ccencho Garcia

2 projects • 1 follower
Thanks to Néstor Alejandro Ccencho García.

Comments