Related with MQ2

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 :

Capture

First please learn to format your posts in stead of just dumping a lot of text in a message.

Regarding your MQ2, I would look into writing code that works alright to get the sensor value and write it to the serial port and next incorporate it into LoRaWAN code. That way you only have to debug one issue at a time.

BTW, showing a screen that shows a value 21 is not useful without telling us what you expect and why that value is wrong.

1 Like

Thank you sir. Its a great help for me.
Regarding the question which you ask about the sensing value 21.
Before the sensor reading and after the sensor reading it shows same value i.e. 21.
Thats why we resulted that it shows wrong reading.
Can you please tell me where i go wrong?

My best guess is that you are not updating the mySmoke variable that you declared at line 16.

I strongly agree with @kersing. Start a new program and only copy in the bits of code that you need to read the sensor. Don’t use timers or LoRaWAN until you can read the sensor.

Good luck.