Hello Sir,
I am working on LORAWAN monitoring module with MQ2 smoke sensor and send sensing data to TheThings Network. On TTN smoke sensor are shown but not showing a exact value. Can you please tell me how i can write code for MQ2 sensor.I also provide result image.
Thank you.
Also I am using config.h for the OTTA and ABP configuration.
MONITORING
#include "LoRaWAN.h"
#include "TimerMillis.h"
#include "config.h"
TimerMillis getDataTimer;
TimerMillis sendDataTimer;
MQ2 mq2(MQ2_PIN);
bool isJoined = false; //LoRa Joined status
bool rts = false; //Ready to Send
int myCycle = 0; //Data to be send cycle
int sensorType = 0; //Sensor type from config
int myValue = 0; //Value to be sent
int mySmoke = MQ2_PIN;
void setup() {
#ifdef DBG_ON
Serial1.begin(115200);
#endif
initPins(); //Initialise Sensor Pins
initSensors(); //Initialise Connected sensors
LoRaWAN.begin(LORA_BAND); //Specify LoRa Band
sendDataTimer.start(sendDataCallback, 0, SEND_INTERVAL); //Send at an interval
getDataTimer.start(getDataCallback, 0, GET_INTERVAL); //Get data at an interval
LoRaWAN.onJoin(joinCallback);
#ifdef OTAA
LoRaWAN.joinOTAA(appEui, appKey, devEui);
#elif ABP
LoRaWAN.joinABP(devAddr, nwkSKey, appSKey);
#endif
void loop() {
if(rts && isJoined)
{
DBG("Sending sensor data");
cycleAround();
sendMyData(sensorType, myValue);
rts = false;
}
}
void initPins()
{
pinMode(MQ2_PIN, INPUT);
}
void initSensors()
{
mq2.begin();
mq2Setup();
}
void cycleAround()
{
myCycle ++;
if(myCycle > 1)
{
myCycle = 1;
}
switch(myCycle)
{
case 1: sensorType = SMOKE_SELECT;
myValue = mySmoke;
break;
}
void sendMyData(int senseType, int senseValue)
{
String encodedData = encodeData(senseType, senseValue);
byte output[10] = {0};
hexCharacterStringToBytes(output, encodedData.c_str());
dumpByteArray(output, 10);
LoRaWAN.beginPacket();
for(int i =0; i<10; i++)
{
LoRaWAN.write(output[i]);
}
LoRaWAN.endPacket();
}
/*
* Convert HEX String to byte array, helper function to sendMyData
*/
void hexCharacterStringToBytes(byte *byteArray, const char *hexString)
{
bool oddLength = strlen(hexString) & 1;
byte currentByte = 0;
byte byteIndex = 0;
for (byte charIndex = 0; charIndex < strlen(hexString); charIndex++)
{
bool oddCharIndex = charIndex & 1;
if (oddLength)
{
// If the length is odd
if (oddCharIndex)
{
// odd characters go in high nibble
currentByte = nibble(hexString[charIndex]) << 4;
}
else
{
// Even characters go into low nibble
currentByte |= nibble(hexString[charIndex]);
byteArray[byteIndex++] = currentByte;
currentByte = 0;
}
}
else
{
// If the length is even
if (!oddCharIndex)
{
// Odd characters go into the high nibble
currentByte = nibble(hexString[charIndex]) << 4;
}
else
{
// Odd characters go into low nibble
currentByte |= nibble(hexString[charIndex]);
byteArray[byteIndex++] = currentByte;
currentByte = 0;
}
}
}
}
/*
* Printing the Byte Array
*/
void dumpByteArray(const byte * byteArray, const byte arraySize)
{
for (int i = 0; i < arraySize; i++)
{
DBG("0x");
if (byteArray[i] < 0x10)
DBG("0");
DBG(byteArray[i], HEX);
DBG(", ");
}
DBG();
}
/*
* Get nibble for the byte, helper function to hexCharacterStringToBytes
*/
byte nibble(char c)
{
if (c >= '0' && c <= '9')
return c - '0';
if (c >= 'a' && c <= 'f')
return c - 'a' + 10;
if (c >= 'A' && c <= 'F')
return c - 'A' + 10;
return 0; // Not a valid hexadecimal character
}
/*
* Encode data according to the decided data packet
*/
String encodeData(int senseType, int senseValue)
{
String ret = "";
ret.concat(getHexString(DEV_ID, 6));
ret.concat(getHexString(DEV_TYPE, 2));
ret.concat(getHexString(senseType, 2));
ret.concat(getHexString(MODULE_TYPE, 2));
ret.concat(getHexString(senseValue, 4));
ret.concat(getHexString(0x0000, 4));
DBG("I encoded the data into 0x");
DBG(ret);
return ret;
}
String getHexString(int myValue, int len)
{
String ret = "";
char temp[10];
itoa(myValue, temp, 16);
for(int i=0;i<(len-strlen(temp));i++)
{
ret.concat( String(0));
}
ret.concat(String(temp));
return ret;
}
void SmokeSensor()
{
mySmoke = mq2.readSmoke();
}
void mq2Setup()
{
float mySmoke;
mySmoke = analogRead(MQ2_PIN);
DBG(mySmoke);
if(mySmoke > 250)
{
DBG(" | Smoke detected!" );
}
DBG("");
}
void sendDataCallback(void)
{
rts = true;
}
void joinCallback(void)
{
if (LoRaWAN.joined())
{
digitalWrite(MY_LED, HIGH);
DBG("JOINED");
isJoined = true;
}
else
{
digitalWrite(MY_LED, LOW);
DBG("REJOIN( )");
isJoined = false;
LoRaWAN.rejoinOTAA();
}
}
The code for MQ2 sensorConfig.h
#define SMOKE_SELECT 0X16
#define MODULE_TYPE 0x00 //Module Control: Monitoring module
//Timer definations
#define GET_INTERVAL 5000
#define SEND_INTERVAL 12000
//Pin definations
#define MQ2_PIN A5
#ifdef OTAA
//Change the devEui for every device
const char *devEui = ".....................................................";
const char *appEui = ".........'............................................";
const char *appKey = "....................................................";
#elif ABP
const char *devAddr = ".................................................................";
const char *nwkSKey = "................................................................";
const char *appSKey = ".................................................................";
#endif
#ifdef DBG_ON
#define DBG(...) Serial1.println(__VA_ARGS__)
#else
#define DBG(...) Serial1.begin(115200); Serial1.println("DEBUG_OFF"); Serial1.end()
#endif
RESULT :