Thank you! Your submission has been received!
Oops! Something went wrong while submitting the form.
Arduino
90 min
Share

Measure hydrogen gas concentration using the Arduino

Hydrogen gas is receiving very special attention now because hydrogen is being used as an alternative energy source to operate certain new automobiles coming out in the auto industry now. Engineers and car manufacturers are researching the possibility of using hydrogen gas as a viable car fuel.

Project Video

Overview

In this tutorial, we will learn how to measure the concentration of hydrogen gas in ppm using the MQ-8 gas sensor and Arduino, and we will display the concentration of gas on a TFT Display and we will use a buzzer to make alarm if the concentration exceeds a certain value, written in the code. You can use the same project in order to give a warning in the event of a hydrogen leak in a factory.

Getting the Items

Arduino Uno R3 (Voltaat Version)
Get Item
2.8 inch Touch Screen Module
Get Item
Passive Buzzer – 5V
Get Item
1/4 Watt Resistor (20 Pack)
Get Item
Half-size Breadboard
Get Item
Jumper Wires - Male to Male (40 Pack)
Get Item

Steps

Wiring it Up

It is important to connect resistors with a value of 10 kilo ohms to the pins of the TFT Display, as shown in the image.

Connect the wires between the TFT Display and the Arduino and the MQ-8 gas sensor as shown in the image below.


Connections from the Arduino to the breadboard:



• Arduino GND pin → Breadboard ground line


• Arduino 5V pin → Breadboard 5V line


Connections from the MQ-8 gas sensor:



• MQ-8 gas sensor VCC pin → Breadboard 5V line


• MQ-8 gas sensor GND pin → Breadboard ground line


• MQ-8 gas sensor A0 pin → Arduino pin A0



Connections from the passive buzzer :



• passive buzzer GND pin → Breadboard ground line


• passive buzzer VCC pin (+ pin) → Arduino pin 3




Connections from the TFT Display to the breadboard:



• TFT Display VCC pin → Breadboard 5V line


• TFT Display GND pin → Breadboard ground line


• TFT Display LED pin → Breadboard 5V line




Connections from the TFT Display to arduino :



• TFT Display CS pin → Arduino pin 10


• TFT Display RST pin → Arduino pin 8


• TFT Display DC pin → Arduino pin 9


• TFT Display MOSI pin → Arduino pin 11


• TFT Display SCK pin → Arduino pin 13


• TFT Display MISO pin → Arduino pin 12

Coding

/*
Voltaat learn (http://learn.voltaat.com)
Link for full tutorial:

Tutorial: Measure hydrogen gas concentration using the Arduino!
Adafruit_ILI9341 Library:
Adafruit_GFX Library:
Wire Library:


The purpose of this sketch is to display the concentration of hydrogen gas in ppm obtained from the MQ-8 gas sensor on the TFT Display.

Connections from the Arduino to the breadboard:

• Arduino GND pin → Breadboard ground line
• Arduino 5V pin → Breadboard 5V line


Connections from the MQ-8 gas sensor:

• MQ-8 gas sensor VCC pin → Breadboard 5V line
• MQ-8 gas sensor GND pin → Breadboard ground line
• MQ-8 gas sensor A0 pin → Arduino pin A0



Connections from the passive buzzer :

• passive buzzer GND pin → Breadboard ground line
• passive buzzer VCC pin (+ pin) → Arduino pin 3


Connections from the TFT Display to the breadboard:

• TFT Display VCC pin → Breadboard 5V line
• TFT Display GND pin → Breadboard ground line
• TFT Display LED pin → Breadboard 5V line


Connections from the TFT Display to arduino :

• TFT Display CS pin → Arduino pin 10
• TFT Display RST pin → Arduino pin 8
• TFT Display DC pin → Arduino pin 9
• TFT Display MOSI pin → Arduino pin 11
• TFT Display SCK pin → Arduino pin 13
• TFT Display MISO pin → Arduino pin 12

*/

#include "Adafruit_GFX.h"    
#include "Adafruit_ILI9341.h"
#include "Wire.h"
#include  "SPI.h"

//Define TFT Display pin numbers
#define TFT_DC 9              
#define TFT_CS 10            
#define TFT_RST 8            
#define TFT_MISO 12          
#define TFT_MOSI 11          
#define TFT_CLK 13          

Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC, TFT_MOSI, TFT_CLK, TFT_RST, TFT_MISO);
#define         MQ_PIN                       (A0)     //define which analog input channel you are going to use
#define         RL_VALUE                     (10)    //define the load resistance on the board, in kilo ohms
#define         RO_CLEAN_AIR_FACTOR          (9.21)  //RO_CLEAR_AIR_FACTOR=(Sensor resistance in clean air)/RO,
                                                    //which is derived from the chart in datasheet

/***********************Software Related Macros************************************/
#define         CALIBARAION_SAMPLE_TIMES     (50)    //define how many samples you are going to take in the calibration phase
#define         CALIBRATION_SAMPLE_INTERVAL  (500)   //define the time interal(in milisecond) between each samples in the
                                                    //cablibration phase
#define         READ_SAMPLE_INTERVAL         (50)    //define how many samples you are going to take in normal operation
#define         READ_SAMPLE_TIMES            (5)     //define the time interal(in milisecond) between each samples in
                                                    //normal operation

/**********************Application Related Macros**********************************/
#define         GAS_H2                      (0)

/*****************************Globals***********************************************/
float           H2Curve[3]  =  {2.3, 0.93,-1.44};    //two points are taken from the curve in datasheet.
                                                    //with these two points, a line is formed which is "approximately equivalent"
                                                    //to the original curve.
                                                    //data format:{ x, y, slope}; point1: (lg200, lg8.5), point2: (lg10000, lg0.03)

float           Ro           =  10;                  //Ro is initialized to 10 kilo ohms

#define passive_buzzer    3  //define passive buzzer pin
float hydrogenppm;
char hydrogenppmChar[10];  
void setup(){
//tft.clear();
tft.begin();                      
tft.setRotation(0);
tft.fillScreen(ILI9341_RED);
printText("Calibrating ", ILI9341_WHITE,20,130,3);
printText("make sure the sensor is in clean air", ILI9341_WHITE,12,160,1);
Ro = MQCalibration(MQ_PIN); //Calibrating the sensor. Please make sure the sensor is in clean air  
Serial.begin(9600);          
tft.fillScreen(ILI9341_GREEN);
pinMode(passive_buzzer,OUTPUT); //define passive buzzer pin as an output pin

Wire.begin();
printText("H2 Concentration:", ILI9341_WHITE,20,130,2);

}

void loop()
{

int grafX = 0;   //int for x value of graph

hydrogenppm = (MQGetGasPercentage(MQRead(MQ_PIN)/Ro,GAS_H2));    //map value for atmospheric levels

String hydrogenppmString = String(hydrogenppm,1); //Convert float to string

hydrogenppmString.toCharArray(hydrogenppmChar,10);

tft.fillRect(10,175,150,40,ILI9341_BLACK); //Draw a Rectangle

printText(hydrogenppmChar, ILI9341_WHITE,30,180,4); //printing the hydrogen gas concentration on the TFT Display

printText("ppm", ILI9341_WHITE,160,180,4);

grafX = map(hydrogenppm,0,1000,0,127);           //map value to screen width

tft.fillRect(0, 235, grafX, 30, ILI9341_WHITE);  //print graph 400min 1000max

if(hydrogenppm>999){                             //if co2 ppm > 1000
   digitalWrite(passive_buzzer,HIGH);                   //turn on the buzzer
}
else{                                       //if not
   digitalWrite(passive_buzzer,LOW);                    //turn off the buzzer
}

delay(500);

}




float MQResistanceCalculation(int raw_adc) {
 return ( ((float)RL_VALUE*(1023-raw_adc)/raw_adc));
}

/***************************** MQCalibration ****************************************
Input:   mq_pin - analog channel
Output:  Ro of the sensor
Remarks: This function assumes that the sensor is in clean air. It use  
        MQResistanceCalculation to calculates the sensor resistance in clean air
        and then divides it with RO_CLEAN_AIR_FACTOR. RO_CLEAN_AIR_FACTOR is about
        10, which differs slightly between different sensors.
************************************************************************************/
float MQCalibration(int mq_pin) {
 int i;
 float val=0;

 for (i=0;i<CALIBARAION_SAMPLE_TIMES;i++) {            //take multiple samples
   val += MQResistanceCalculation(analogRead(mq_pin));
   delay(CALIBRATION_SAMPLE_INTERVAL);
 }
 val = val/CALIBARAION_SAMPLE_TIMES;                   //calculate the average value

 val = val/RO_CLEAN_AIR_FACTOR;                        //divided by RO_CLEAN_AIR_FACTOR yields the Ro
                                                       //according to the chart in the datasheet

 return val;
}
/*****************************  MQRead *********************************************
Input:   mq_pin - analog channel
Output:  Rs of the sensor
Remarks: This function use MQResistanceCalculation to caculate the sensor resistenc (Rs).
        The Rs changes as the sensor is in the different consentration of the target
        gas. The sample times and the time interval between samples could be configured
        by changing the definition of the macros.
************************************************************************************/
float MQRead(int mq_pin) {
 int i;
 float rs=0;

 for (i=0;i<READ_SAMPLE_TIMES;i++) {
   rs += MQResistanceCalculation(analogRead(mq_pin));
   delay(READ_SAMPLE_INTERVAL);
 }

 rs = rs/READ_SAMPLE_TIMES;

 return rs;  
}

/*****************************  MQGetGasPercentage **********************************
Input:   rs_ro_ratio - Rs divided by Ro
        gas_id      - target gas type
Output:  ppm of the target gas
Remarks: This function passes different curves to the MQGetPercentage function which
        calculates the ppm (parts per million) of the target gas.
************************************************************************************/
int MQGetGasPercentage(float rs_ro_ratio, int gas_id) {
 if ( gas_id == GAS_H2) {
    return MQGetPercentage(rs_ro_ratio,H2Curve);
 }  
 return 0;
}

/*****************************  MQGetPercentage **********************************
Input:   rs_ro_ratio - Rs divided by Ro
        pcurve      - pointer to the curve of the target gas
Output:  ppm of the target gas
Remarks: By using the slope and a point of the line. The x(logarithmic value of ppm)
        of the line could be derived if y(rs_ro_ratio) is provided. As it is a
        logarithmic coordinate, power of 10 is used to convert the result to non-logarithmic
        value.
************************************************************************************/
int  MQGetPercentage(float rs_ro_ratio, float *pcurve) {
 return (pow(10,( ((log(rs_ro_ratio)-pcurve[1])/pcurve[2]) + pcurve[0])));
}


//The function of writing words on the TFT Display
void printText(char *text, uint16_t color, int x, int y,int textSize)
{
 tft.setCursor(x, y);
 tft.setTextColor(color);
 tft.setTextSize(textSize);
 tft.setTextWrap(true);
 tft.print(text);
}


Testing it Out

Once you’ve uploaded the code to the Arduino board, you will find that the Arduino will take about half a minute to calibrate the gas sensor as shown in the image below:

And then you will find that the TFT Display displays the concentration of hydrogen gas in ppm as shown in the image below:

Resources

No items found.