LoRa-Node-Power Meter Soilsensor & Weather Condition

เรียกโครงการนี้ว่า  LoRa WiFi ฉบับสมบูรณ์ที่สุด  เป็นการจัดชุด LoRa Node ที่สามารถวัด RS485  เช่น Power Meter, Soil Sensor และ  สภาพอากาศได้ใน Node เดียวกัน  โดย  LoRa ยังคงมีฟังก์ชั่น OLED อย่างสมบูรณ์

Node จะทำการส่งค่าไปยัง Broker-LoRa-WiFi  ด้วยความสามารถของ LoRa  และเจ้า Gateway จะส่งเข้า WiFi  แทนการส่งตรงไปยัง Gateway  โดยทั่วไป

  

ศึกษารายละเอียดของการใช้งานขา  ESP32   จาก  Link

 

/*
  This is a simple example show the Heltec.LoRa sended data in OLED.

  The onboard OLED display is SSD1306 driver and I2C interface. In order to make the
  OLED correctly operation, you should output a high-low-high(1-0-1) signal by soft-
  ware to OLED's reset pin, the low-level signal at least 5ms.

  OLED pins to ESP32 GPIOs via this connecthin:
  OLED_SDA -- GPIO4
  OLED_SCL -- GPIO15
  OLED_RST -- GPIO16
  
  by Aaron.Lee from HelTec AutoMation, ChengDu, China
  成都惠利特自动化科技有限公司
  www.heltec.cn
  
  this project also realess in GitHub:
  https://github.com/Heltec-Aaron-Lee/WiFi_Kit_series
*/
#include "ModbusMaster.h" //https://github.com/4-20ma/ModbusMaster
/*!
  We're using a MAX485-compatible RS485 Transceiver.
  Rx/Tx is hooked up to the hardware serial port at 'Serial'.
  The Data Enable (DE) and Receiver Enable (RE) pins are hooked up as follows:
*/
#include <Adafruit_Sensor.h>
#include <DHT.h>  // กรณีนี้ต้องใช้คู่กันกับ  DHT_U.h
#include <DHT_U.h>
#define DHTPIN  12 // Pin which is connected to the DHT sensor.

//#define DHTTYPE   DHT22     // DHT 22 (AM2302)
#define DHTTYPE   DHT21     // DHT 21 (AM2301)

// See guide for details on sensor wiring and usage:
//   https://learn.adafruit.com/dht/overview

DHT_Unified dht(DHTPIN, DHTTYPE);
uint32_t delayMS;



#define MAX485_RE_NEG  25 //D4 RS485 has a enable/disable pin to transmit or receive data. Arduino Digital Pin 2 = Rx/Tx 'Enable'; High to Transmit, Low to Receive
#define Slave_ID1    1
#define Slave_ID2    2
#define RX_PIN      23 //RX2 
#define TX_PIN      22  //TX2 working is 17 , 22 as well working


#include "heltec.h"
#include "images.h"

#define BAND    510E6  //you can set band here directly,e.g. 868E6,915E6

// instantiate ModbusMaster object
ModbusMaster modbus1;
ModbusMaster modbus2;
float res_dbl0;
float res_dbl1;
float res_dbl ;
unsigned int counter = 0;
String rssi = "RSSI --";
String packSize = "--";
String packet ;
String datasend ;
String datasend1 ;
String datasend2 ;
String data2 ;
String data3 ;
String data4 ;
String data5 ;
String data6 ;
String data7 ;

float temp_0 = 0;
float humid_0 = 0;
float vHumidity = 0;
float vTemperature = 0;
String data1="177";
String cccode = "2036491";
long lastMillis = 0;
//===
void preTransmission()
{
  digitalWrite(MAX485_RE_NEG, HIGH); //Switch to transmit data
}
void postTransmission()
{
  digitalWrite(MAX485_RE_NEG, LOW); //Switch to receive data
}

//====

void logo()
{
  Heltec.display->clear();
  Heltec.display->drawXbm(0,5,logo_width,logo_height,logo_bits);
  Heltec.display->display();
}

void AM2301_setup() {
  Serial.begin(9600); 
  // Initialize device.
  dht.begin();
  Serial.println("DHTxx Unified Sensor Example");
  // Print temperature sensor details.
  sensor_t sensor;
  dht.temperature().getSensor(&sensor);
  Serial.println("------------------------------------");
  Serial.println("Temperature");
  Serial.print  ("Sensor:       "); Serial.println(sensor.name);
  Serial.print  ("Driver Ver:   "); Serial.println(sensor.version);
  Serial.print  ("Unique ID:    "); Serial.println(sensor.sensor_id);
  Serial.print  ("Max Value:    "); Serial.print(sensor.max_value); Serial.println(" *C");
  Serial.print  ("Min Value:    "); Serial.print(sensor.min_value); Serial.println(" *C");
  Serial.print  ("Resolution:   "); Serial.print(sensor.resolution); Serial.println(" *C");  
  Serial.println("------------------------------------");
  // Print humidity sensor details.
  dht.humidity().getSensor(&sensor);
  Serial.println("------------------------------------");
  Serial.println("Humidity");
  Serial.print  ("Sensor:       "); Serial.println(sensor.name);
  Serial.print  ("Driver Ver:   "); Serial.println(sensor.version);
  Serial.print  ("Unique ID:    "); Serial.println(sensor.sensor_id);
  Serial.print  ("Max Value:    "); Serial.print(sensor.max_value); Serial.println("%");
  Serial.print  ("Min Value:    "); Serial.print(sensor.min_value); Serial.println("%");
  Serial.print  ("Resolution:   "); Serial.print(sensor.resolution); Serial.println("%");  
  Serial.println("------------------------------------");
  // Set delay between sensor readings based on sensor details.
  delayMS = sensor.min_delay / 1000;
}

void RS485_setup()
{
  pinMode(MAX485_RE_NEG, OUTPUT);
  // Init in receive mode
  digitalWrite(MAX485_RE_NEG, LOW);
  // Modbus communication runs at 9600 baud
  Serial.begin(9600, SERIAL_8N1);
  Serial1.begin(9600, SERIAL_8N1, RX_PIN, TX_PIN); // serial can be no1 , no 2
  modbus1.begin(Slave_ID1, Serial1);
  modbus2.begin(Slave_ID2, Serial1);
  // Callbacks allow us to configure the RS485 transceiver correctly
  modbus1.preTransmission(preTransmission);
  modbus1.postTransmission(postTransmission);
  modbus2.preTransmission(preTransmission);
  modbus2.postTransmission(postTransmission);
  
}

void setup()
{
  //WIFI Kit series V1 not support Vext control
  Heltec.begin(true /*DisplayEnable Enable*/, true /*Heltec.Heltec.Heltec.LoRa Disable*/, true /*Serial Enable*/, true /*PABOOST Enable*/, BAND /*long BAND*/);
 
  Heltec.display->init();
  Heltec.display->flipScreenVertically();  
  Heltec.display->setFont(ArialMT_Plain_10);
  logo();
  delay(1500);
  Heltec.display->clear();
  
  Heltec.display->drawString(0, 0, "Heltec.LoRa Initial success!");
  Heltec.display->display();
  delay(1000);
  RS485_setup();
  AM2301_setup(); 
}

void loop()
{
  /*
  RS485_loop();
  datasend2 = String(res_dbl0)+","+String(res_dbl1)+","+String(45.00)+","+String(25.75)+","+String(100.05);
  datasend1 = String(cccode)+","+String(177)+","+String(res_dbl0)+","+String(res_dbl1);
  datasend = datasend1+","+datasend2;
  */
  Heltec.display->clear();
  Heltec.display->setTextAlignment(TEXT_ALIGN_LEFT);
  Heltec.display->setFont(ArialMT_Plain_10);
  
  Heltec.display->drawString(0, 0, "GeoShrimp Data packet: ");
  //Heltec.display->drawString(0, 10, String(counter));
  Heltec.display->drawString(0,10, String(datasend1));
  Heltec.display->drawString(0,30, String(datasend2));
  Heltec.display->display();
  
  // send packet
  LoRa.beginPacket();
  
/*
 * LoRa.setTxPower(txPower,RFOUT_pin);
 * txPower -- 0 ~ 20
 * RFOUT_pin could be RF_PACONFIG_PASELECT_PABOOST or RF_PACONFIG_PASELECT_RFO
 *   - RF_PACONFIG_PASELECT_PABOOST -- LoRa single output via PABOOST, maximum output 20dBm
 *   - RF_PACONFIG_PASELECT_RFO     -- LoRa single output via RFO_HF / RFO_LF, maximum output 14dBm
*/
/*
  LoRa.setTxPower(14,RF_PACONFIG_PASELECT_PABOOST);
  LoRa.print(datasend);
  //LoRa.print(counter);
  LoRa.endPacket();
 */
  RS485_loop1();  
  delay(2000);
  RS485_loop2();
  delay(1000);
  AM2301_loop();
  datasend2 = String(data4)+","+String(data5)+","+String(data6)+","+String(data7);
  datasend1 = String(cccode)+","+String(177)+","+String(data2)+","+String(data3);
  datasend = datasend1+","+datasend2;
  Serial.println(datasend);
 
  LoRa.setTxPower(14,RF_PACONFIG_PASELECT_PABOOST);
  LoRa.print(datasend);
  //LoRa.print(counter);
  LoRa.endPacket();

  //delay(3000);                       // wait for a second


}

// RS485 loop
void RS485_loop1() 
{
  long currentMillis = millis();
  if (currentMillis - lastMillis > 1000) 
  {
    uint8_t result = modbus1.readHoldingRegisters(0x02, 2);
    
    if (getResultMsg(&modbus1, result)) 
    {
      Serial.println();
      res_dbl0 = modbus1.getResponseBuffer(0) / 10;
      String res = "Humidity: " + String(res_dbl0) + " %\r\n";
      data2 = String(res_dbl0);
      res_dbl1 = modbus1.getResponseBuffer(1) / 10;
      data3 = String(res_dbl1);
      res += "Temperature: " + String(res_dbl1) + " C";
      Serial.println(res);
    }
    lastMillis = currentMillis;
  }
}
void RS485_loop2() 
{
  long currentMillis = millis();
  if (currentMillis - lastMillis > 1000) 
  {
    uint8_t result = modbus2.readHoldingRegisters(0x08, 2);
    
    if (getResultMsg(&modbus2, result)) 
    {
      Serial.println();
      res_dbl0 = modbus2.getResponseBuffer(0) / 100;
      data4 = String(res_dbl0);
      String res = "Volatge 1 : " + String(res_dbl0) + " Vac\r\n";
      res_dbl1 = modbus2.getResponseBuffer(1) / 100;
      data5 = String(res_dbl1);
      res += "Voltage 2 : " + String(res_dbl1) + " Vac";
      Serial.println(res);
    }
    lastMillis = currentMillis;
  }
}
bool getResultMsg(ModbusMaster *node, uint8_t result) 
{
  String tmpstr2 = "\r\n";
  switch (result) 
  {
  case node->ku8MBSuccess:
    return true;
    break;
  case node->ku8MBIllegalFunction:
    tmpstr2 += "Illegal Function";
    break;
  case node->ku8MBIllegalDataAddress:
    tmpstr2 += "Illegal Data Address";
    break;
  case node->ku8MBIllegalDataValue:
    tmpstr2 += "Illegal Data Value";
    break;
  case node->ku8MBSlaveDeviceFailure:
    tmpstr2 += "Slave Device Failure";
    break;
  case node->ku8MBInvalidSlaveID:
    tmpstr2 += "Invalid Slave ID";
    break;
  case node->ku8MBInvalidFunction:
    tmpstr2 += "Invalid Function";
    break;
  case node->ku8MBResponseTimedOut:
    tmpstr2 += "Response Timed Out";
    break;
  case node->ku8MBInvalidCRC:
    tmpstr2 += "Invalid CRC";
    break;
  default:
    tmpstr2 += "Unknown error: " + String(result);
    break;
  }
  Serial.println(tmpstr2);
  return false;
}
void AM2301_loop() {
  // Delay between measurements.
  delay(delayMS);
  // Get temperature event and print its value.
  sensors_event_t event;  
  dht.temperature().getEvent(&event);
  if (isnan(event.temperature)) {
    Serial.println("Error reading temperature!");
  }
  else {
    Serial.print("Temperature AM2301 : ");
    Serial.print(event.temperature);
    Serial.println(" *C");
    temp_0 = event.temperature;
    data6 = String(temp_0);
  }
  // Get humidity event and print its value.
  dht.humidity().getEvent(&event);
  if (isnan(event.relative_humidity)) {
    Serial.println("Error reading humidity!");
  }
  else {
    Serial.print("Humidity AM2301 : ");
    Serial.print(event.relative_humidity);
    Serial.println("%");
    humid_0 = event.relative_humidity;
    data7 =String(humid_0);
  }
  
}

การต่อขาสัญญาณ

Heltec LoRA ESP32                 Max485 

GPIO22                                             DI

GOIP23                                              RO

GPIO25                                             DE+RE Control

Vdc  3.3                                             Vcc

GND                                                  GND

Heltec Loar ESP32                  Nano

GPIO13                                            D5

GOIP17                                             D6

Vdc                                                     –

GND                                                 GND

 

 

803 total views, 2 views today