LORA Integration with Thingspeak using Dht-11
In this tutorial, we are going to explain, how to connect Dht11 sensor to the LoRa client and send data to the loRa gateway which send data further to Thingspeak. In this tutorial we are going to use LG01-N indoor gateway.
To learn more about LG01-N gateway click here.
To make this project , Follow these instructions-->
Step--1
Connect Dht 11 sensor in lora node: Set the antenne to node to send the data. Connect dht sensore vcc to lora vcc and data pin to any pin of digital as well as analog. I am using analog pin in this project, if you want to use digital pin than you can use.
Circuit Diagram--
Vcc-- A0 pin
ground -- Arduino ground
power -- +5v (see in Figure 1.1)
Step-2
Now we will upload code of Dht-11 client in LoRa client.
#include <SPI.h>
#include <RH_RF95.h>
#include <String.h>
RH_RF95 rf95;
#define dht_dpin A0 // Use A0 pin as Data pin for DHT11.
byte bGlobalErr;
char dht_dat[5]; // Store Sensor Data
String stringOne;
float frequency = 868.0;
void setup()
{
InitDHT();
Serial.begin(9600);
if (!rf95.init())
Serial.println("init failed");
// Setup ISM frequency
rf95.setFrequency(frequency);
// Setup Power,dBm
rf95.setTxPower(13);
Serial.println("Humidity and temperature\n\n");
}
void InitDHT()
{
pinMode(dht_dpin,OUTPUT);//Set A0 to output
digitalWrite(dht_dpin,HIGH);//Pull high A0
}
//Get Sensor Data
void ReadDHT()
{
bGlobalErr=0;
byte dht_in;
byte i;
//pinMode(dht_dpin,OUTPUT);
digitalWrite(dht_dpin,LOW);//Pull Low A0 and send signal
delay(30);//Delay > 18ms so DHT11 can get the start signal
digitalWrite(dht_dpin,HIGH);
delayMicroseconds(40);//Check the high level time to see if the data is 0 or 1
pinMode(dht_dpin,INPUT);
// delayMicroseconds(40);
dht_in=digitalRead(dht_dpin);//Get A0 Status
// Serial.println(dht_in,DEC);
if(dht_in){
bGlobalErr=1;
return;
}
delayMicroseconds(80);//DHT11 send response, pull low A0 80us
dht_in=digitalRead(dht_dpin);
if(!dht_in){
bGlobalErr=2;
return;
}
delayMicroseconds(80);//DHT11 send response, pull low A0 80us
for (i=0; i<5; i++)//Get sensor data
dht_dat[i] = read_dht_dat();
pinMode(dht_dpin,OUTPUT);
digitalWrite(dht_dpin,HIGH);//release signal and wait for next signal
byte dht_check_sum = dht_dat[0]+dht_dat[1]+dht_dat[2]+dht_dat[3];//calculate check sum
if(dht_dat[4]!= dht_check_sum)//check sum mismatch
{bGlobalErr=3;}
};
byte read_dht_dat(){
byte i = 0;
byte result=0;
for(i=0; i< 8; i++)
{
while(digitalRead(dht_dpin)==LOW);//wait 50us
delayMicroseconds(30);//Check the high level time to see if the data is 0 or 1
if (digitalRead(dht_dpin)==HIGH)
result |=(1<<(7-i));//
while (digitalRead(dht_dpin)==HIGH);//Get High, Wait for next data sampleing.
}
return result;
}
uint16_t calcByte(uint16_t crc, uint8_t b)
{
uint32_t i;
crc = crc ^ (uint32_t)b << 8;
for ( i = 0; i < 8; i++)
{
if ((crc & 0x8000) == 0x8000)
crc = crc << 1 ^ 0x1021;
else
crc = crc << 1;
}
return crc & 0xffff;
}
uint16_t CRC16(uint8_t *pBuffer,uint32_t length)
{
uint16_t wCRC16=0;
uint32_t i;
if (( pBuffer==0 )||( length==0 ))
{
return 0;
}
for ( i = 0; i < length; i++)
{
wCRC16 = calcByte(wCRC16, pBuffer[i]);
}
return wCRC16;
}
void loop()
{
ReadDHT();
char data[50] = {0} ;
// Use data[0], data[1],data[2] as Node ID
data[0] = 1 ;
data[1] = 1 ;
data[2] = 1 ;
data[3] = dht_dat[0];//Get Humidity
data[4] = dht_dat[2];//Get Temperature
switch (bGlobalErr)
{
case 0:
Serial.print("Current humdity = ");
Serial.print(data[3], DEC);//Show humidity
Serial.print(".");
Serial.print(dht_dat[1], DEC);//Show humidity
Serial.print("% ");
Serial.print("temperature = ");
Serial.print(data[4], DEC);//Show temperature
Serial.print(".");
Serial.print(dht_dat[3], DEC);//Show temperature
Serial.println("C ");
break;
case 1:
Serial.println("Error 1: DHT start condition 1 not met.");
break;
case 2:
Serial.println("Error 2: DHT start condition 2 not met.");
break;
case 3:
Serial.println("Error 3: DHT checksum error.");
break;
default:
Serial.println("Error: Unrecognized code encountered.");
break;
}
int dataLength = strlen(data);//CRC length for LoRa Data
//Serial.println(dataLength);
uint16_t crcData = CRC16((unsigned char*)data,dataLength);//get CRC DATA
//Serial.println(crcData);
unsigned char sendBuf[50]={0};
int i;
for(i = 0;i < 8;i++)
{
sendBuf[i] = data[i] ;
}
sendBuf[dataLength] = (unsigned char)crcData; // Add CRC to LoRa Data
//Serial.println( sendBuf[dataLength] );
sendBuf[dataLength+1] = (unsigned char)(crcData>>8); // Add CRC to LoRa Data
//Serial.println( sendBuf[dataLength+1] );
rf95.send(sendBuf, strlen((char*)sendBuf));//Send LoRa Data
//Serial.print(strlen((char*)sendBuf));
uint8_t buf[RH_RF95_MAX_MESSAGE_LEN];//Reply data array
uint8_t len = sizeof(buf);//reply data length
if (rf95.waitAvailableTimeout(3000))// Check If there is reply in 3 seconds.
{
// Should be a reply message for us now
if (rf95.recv(buf, &len))//check if reply message is correct
{
if(buf[0] == 1||buf[1] == 1||buf[2] ==1) // Check if reply message has the our node ID
{
pinMode(4, OUTPUT);
digitalWrite(4, HIGH);
Serial.print("got reply: ");//print reply
Serial.println((char*)buf);
delay(400);
digitalWrite(4, LOW);
//Serial.print("RSSI: "); // print RSSI
//Serial.println(rf95.lastRssi(), DEC);
}
}
else
{
Serial.println("recv failed");//
rf95.send(sendBuf, strlen((char*)sendBuf));//resend if no reply
}
}
else
{
Serial.println("No reply, is rf95_server running?");//No signal reply
rf95.send(sendBuf, strlen((char*)sendBuf));//resend data
}
delay(3000); // Send sensor data every 30 seconds
}
Step-3
Code for Server: After uploading the code in lora client we need to upload server code on lora gateway. We need Ethernet cable to upload code on lora gateway.
#include <SPI.h>
#include <RH_RF95.h>
#include <Console.h>
#include "ThingSpeak.h"
#include "YunClient.h"
YunClient client;
RH_RF95 rf95;
//If you use Dragino IoT Mesh Firmware, uncomment below lines.
//For product: LG01.
#define BAUDRATE 115200
unsigned long myChannelNumber = Thing Speak channel number;
const char * myWriteAPIKey = “thing speak write key api";
uint16_t crcdata = 0;
uint16_t recCRCData = 0;
float frequency = 868.0;
void setup()
{
Bridge.begin(BAUDRATE);
//Console.begin();// Don't use Console here, since it is conflict with the ThinkSpeak library.
ThingSpeak.begin(client);
if (!rf95.init())
//Console.println("init failed");
;
// Setup ISM frequency
rf95.setFrequency(frequency);
// Setup Power,dBm
rf95.setTxPower(13);
//Console.println("Start Listening ");
}
uint16_t calcByte(uint16_t crc, uint8_t b)
{
uint32_t i;
crc = crc ^ (uint32_t)b << 8;
for ( i = 0; i < 8; i++)
{
if ((crc & 0x8000) == 0x8000)
crc = crc << 1 ^ 0x1021;
else
crc = crc << 1;
}
return crc & 0xffff;
}
uint16_t CRC16(uint8_t *pBuffer, uint32_t length)
{
uint16_t wCRC16 = 0;
uint32_t i;
if (( pBuffer == 0 ) || ( length == 0 ))
{
return 0;
}
for ( i = 0; i < length; i++)
{
wCRC16 = calcByte(wCRC16, pBuffer[i]);
}
return wCRC16;
}
uint16_t recdata( unsigned char* recbuf, int Length)
{
crcdata = CRC16(recbuf, Length - 2); //Get CRC code
recCRCData = recbuf[Length - 1]; //Calculate CRC Data
recCRCData = recCRCData << 8; //
recCRCData |= recbuf[Length - 2];
}
void loop()
{
if (rf95.waitAvailableTimeout(2000))// Listen Data from LoRa Node
{
uint8_t buf[RH_RF95_MAX_MESSAGE_LEN];//receive data buffer
uint8_t len = sizeof(buf);//data buffer length
if (rf95.recv(buf, &len))//Check if there is incoming data
{
recdata( buf, len);
if(crcdata == recCRCData) //Check if CRC is correct
{
//Console.println("Get Data from LoRa Node");
if(buf[0] == 1||buf[1] == 1||buf[2] ==1) //Check if the ID match the LoRa Node ID
{
uint8_t data[] = " Server ACK";//Reply
data[0] = buf[0];
data[1] = buf[1];
data[2] = buf[2];
rf95.send(data, sizeof(data));// Send Reply to LoRa Node
rf95.waitPacketSent();
int newData[4] = {0, 0, 0, 0}; //Store Sensor Data here
for (int i = 0; i < 2; i++)
{
newData[i] = buf[i + 3];
}
int h = newData[0];
int t = newData[1];
ThingSpeak.setField(2,h); //
ThingSpeak.setField(1,t);
ThingSpeak.writeFields(myChannelNumber, myWriteAPIKey); // Send Data to IoT Server.
}
}
}
else
{
//Console.println("recv failed");
;
}
}
}
Step-4
In this step we will configure Thingspeak side.
- Signup in thingspeak
- Create a channel
- After creating a channel there is a channel ID and api key
- Copy api key and paste in program
- Also write your channel name in program.
(See in Figure 1.2)
Circuit diagram