Flammable Gas & Smoke Sensor- It is suitable for detecting the H2, LPG, CH4, CO, Alcohol or Propane. MQ3 sensor can sense LPG, CO, Smoke etc. For MQ3 sensor if the concentration is high the resistance decrease, if the concentration is low the resistance increase.
D0 : Indicates the presence of combined gases D0 becomes high, when the gas concentration exceeds the threshold value (as set the potentiometer) and low otherwise.
A0 : Produces an analog output proportional to gas concentration so a higher concentrations results in higher voltage and a lower concentration result in lower voltage

For pure air the resistance factor is 9.83. First step is to calculate the resistance in air, suppose it is R0. We use ATtiny85 for full program.

#define RO_CLEAN_AIR_FACTOR 9.83
volatile uint16_t adc_value;
float R0,R0_OLD,Rs;
void R0_resistancs(void)
{
adc_value=read_adc(2);
R0_OLD=MQResistanceCalculation(adc_value);
R0=R0_OLD/RO_CLEAN_AIR_FACTOR;
}
What is the resistance? Here for pure air R = 1, but for normal air the resistance is R0 = (1024/ADC Value)-1. So the function C:> float MQResistanceCalculation(uint16_t raw_adc)
#define RL_VALUE 1 //define the load resistance on the board, in kilo ohms
#define ADC_MAX 1023
float MQResistanceCalculation(uint16_t raw_adc)
{
return (((float)RL_VALUE*(ADC_MAX-raw_adc)/raw_adc));
}
Since the sensor need some time to initialize, so wait in a loop for calculating air resistance. Now look at the datasheet of the MQ3 sensor-

From curve the ration Rs/R0 indicates the presence of LPG, CO or Smoke. If we put the Rs/R0 value in the graph then we get the value of LPG, CO or Smoke in PPM. From the curve the value of slop, transient and constant value as follow-
float LPGCurve[3] = {1.413,0.21,-0.473}; //{2.3,0.21,-0.47};
float COCurve[3] = {1.413,0.72,-0.34}; //{2.3,0.72,-0.34};
float SmokeCurve[3] = {2.3,0.53,-0.44}; //{2.3,0.53,-0.44};
The desire PPM is – ![]()
int MQGetPercentage(float rs_ro_ratio, float *pcurve)
{
percentage=(pow(10,(((log10(rs_ro_ratio)-pcurve[1])/pcurve[2]) + pcurve[0])));
return percentage;
}
In order to read LPG, CO or Smoke
float MQGetGasPercentage(float rs_ro_ratio, int gas_id)
{
if ( gas_id == GAS_LPG ) {
return MQGetPercentage(rs_ro_ratio,LPGCurve);
} else if ( gas_id == GAS_CO ) {
return MQGetPercentage(rs_ro_ratio,COCurve);
} else if ( gas_id == GAS_SMOKE ) {
return MQGetPercentage(rs_ro_ratio,SmokeCurve);
}
return 0;
}
So the full function for calculating the PPM of LPG, CO or Smoke in air is
extern volatile float lpg,co,smoke; // extern variable
void air_ppm(void)
{
adc_value=read_adc(2);
Rs=MQResistanceCalculation(adc_value);
Rs=Rs/R0;
lpg = MQGetGasPercentage(Rs,GAS_LPG);
co = MQGetGasPercentage(Rs,GAS_CO);
smoke = MQGetGasPercentage(Rs,GAS_SMOKE);
}
We have the function ready, now let make a program that buzz when the smoke or lpg or co is present. According to datasheet of ATtiny85 to generate 20KHz fPWM at OC1A pin is-
void Buzzer_init(void)
{
DDRB|=(1<<DDB1);
TCCR1|=(1<<COM1A1)|(1<<PWM1A); //only OC1B is connected
TCCR1|=(1<<CS12)|(1<<CS10); //FP_PWM=F_CPU/16
OCR1C=199; //Top value with F_PWM=20KHz
Buzzer_off();
}
void Buzzer_on(void)
{
TCCR1|=(1<<PWM1A);
OCR1A=100; //50% duty cycle;
}
void Buzzer_off(void)
{
TCCR1&=~(1<<PWM1A); //PWM Mode disable;
}
We use extern volatile float lpg,co,smoke; -> global variable to display data any file. You can display the data in LCD module, but in this tutorial we chose ATtiny85 which doesn’t have enough pin for controlling LCD. We use OLED for display the data. Connect all the elements according to the connection diagram.
Let’s look at the main program that will help you in building your own logic-
/********************************************************************
****** D0- Digital Value 1(High Gas Concentration) *********
****** 0(Low gas Concentration) *********
****** A0- Analog Value of gas presence *********
****** D0 --- N/C & A0-ADC Channel 0 *********
*********************************************************************/
#include <avr/io.h>
#include <util/delay.h>
#include <stdio.h>
#include "smoke.h"
volatile char display_value[8]="text";
int main(void)
{
/* Initialize OLED Display */
adc_init();
init_OLED();
reset_display();
clear_display();
Buzzer_init();
/* Main program with logo and design */
OLCD_write_string(0,0,"MQ3 Sensor Init");
for(uint16_t i=6500;i>=1;i--)
{
R0_resistancs();
sprintf(display_value,"Time:%d ",i);
OLCD_write_string(1,0,display_value);
_delay_ms(1000);
}
clear_display();
_delay_ms(10);
OLCD_write_string(0,0,"Air Materials ");
while(1)
{
air_ppm();
sprintf(display_value,"LPG:%d PPM ",(int)lpg);
OLCD_write_string(1,0,display_value);
sprintf(display_value,"CO:%d PPM ",(int)co);
OLCD_write_string(2,0,display_value);
sprintf(display_value,"Smoke:%d PPM ",(int)smoke);
OLCD_write_string(3,0,display_value);
(((int)lpg>20)|((int)co>20)|((int)smoke>20))? Buzzer_on():Buzzer_off();
_delay_ms(1000);
}
return 0;
}








Visit Today : 41
Total Visit : 28456