پروژه-راه-اندازی-سنسور-mq2

پروژه راه اندازی سنسور های سری MQ با استفاده از مجموعه آموزشی AVR WIZARD توسط برد پلاریس به زبان C

0

راهنمای راه اندازی سنسور های سری MQ با استفاده از مجموعه آموزشی AVR WIZARD به زبان C

هدف از این آموزش راه اندازی واحد ADC میکروکنترلر AVR  به زبان  C  توسط مجموعه آموزشی AVR WIZARD میباشد    ( شما می توانید سنسور های آنالوگ مشابه را به این روش راه اندازی نمایید )

لوازم مورد نیاز

  1. برد اصلی AVR WIZARD
  2. برد جانبی SENSOR SHIELD
  3. LCD2X16
  4. سنسور MQ9
  5. تغذیه 9 ولت

سنسور گاز GAS SENSOR

سنسور GAS یا GAS Detector نوعی سنسور شیمیایی است که غلظت گاز در مجاورت آن را تشخیص و اندازه گیری می کند. سنسور گاز برای اندازه گیری غلظت ، با گاز در تعامل است. از آنها در صنایع مختلف اعم از پزشکی گرفته تا هوافضا استفاده می کنند. همچنین از فناوری های مختلفی برای اندازه گیری غلظت گاز مانند نیمه هادی ها ، اکسیداسیون ، کاتالیزوری ، مادون قرمز و غیره استفاده می شود. متداول ترین انواع آن به شرح زیر است:

  • سنسور GAS مبتنی بر اکسید فلزی.
  • سنسور GAS مبتنی بر ظرفیت.
  • سنسور GAS مبتنی بر آکوستیک.
  • سنسور کالریمتریک
  • سنسور GAS نوری.
  • سنسور GAS الکتروشیمیایی.

در اینجا ما بر روی متداول ترین سنسور GAS متمرکز می شویم که همان سنسور گاز اکسید فلزی یا نیمه هادی اکسید فلزی (MOS) است که به عنوان “Chemiresistors” نیز شناخته می شود. تشخیص گاز بر مبنای تغییر مقاومت ماده درون سنسور در هنگام تماس با  گاز است. این سنسورهای گاز اکسید فلزی، به دلیل کم هزینه بودن ، انعطاف پذیری در تولید ، سادگی در استفاده از آنها،تعداد گازهای قابل تشخیص و زمینه های کاربرد در صنعت بسیار مورد استفاده قرار می گیرند.

سنسور MQ

سنسورهای گازی مختلفی در بازار موجود است اما متداول ترین آنها سری MQ می باشد. با استفاده از این سنسورها می توان گازهای مختلفی مانند LPG ، منوکسید کربن CO ، متان ، دود ، الکل و غیره را کنترل کرد. نکته مفید در مورد این سری از سنسور ها این است که همه سنسورهای دارا فوتپرینت 6 پین با مدار رابط یکسان دارند و با هزینه کم به راحتی در دسترس هستند.

نمای داخل سنسور MQ.JPG

همانطور که در تصویر بالا مشاهده می کنید ، سنسورهای گازی سری MQ از یک هیتر کوچک در داخل با یک حسگر الکترو شیمیایی استفاده می کنند که به طیف وسیعی از گازها حساس هستند.

حسگر داخلی MQ.JPG

بهترین اتصال برای این دسته سنسور ها ، اتصال هر دو پین A  به یکدیگر و هر دو پین B نیز به یکدیگر است. در این صورت نتایج خروجی سنسور امن تر و قابل اطمینان تر می  باشد.

مدار سنسور MQ

از آنجا که خروجی سنسورهای گاز تغییر اهم یا مقاومت بوده ، یک مقاومت باید بین پین خروجی و زمین وصل شود(درتصویر بالا نشان داده شده است). همانطور که می بینید هیچ مؤلفه دیگری لازم نیست. مقدار مشخصی برای مقاومت بار وجود ندارد. مقدار آن می تواند از 2kΩ تا 47kΩ باشد. که هر چه مقدار آن کمتر باشد حساسیت مدار کمتر می شود و هرچه مقدار مقاومت بار بیشتر باشد ، دقت کمتری را در تراکم زیاد گاز خواهیم داشت .حال این ولتاژ خروجی را می توان مستقیماً به هر ADC یا هر مدار مقایسه گری داد و بر اساس  آن مقدار گاز را با استفاده از جدول دیتاشیت محاسبه کرد.

داخل سنسور mq

نحوه اتصال  سنسور MQ به برد SENSOR_SHIELD مجموعه آموزشی AVR WIZARD

در برد شیلد سنسور موسوم به SENSOR_SHIELD مدار راه انداز این سنسور طراحی شده است و فقط کاربر باید سنسور مورد نظر را در سوکت مربوطه قرار دهد و به راحتی شروع به کدنویسی کند.

اتصال سنسور MQ در سوکت

نحوه برنامه نویسی و خواندن مقادیر سنسور MQ

برای خواندن مقدار آنالوگ MQ کافیست خروجی را از کانال ADC مربوطه خوانده  و پس از خطی سازی نمودار موجود در دیتاشیت مقدار تراکم گاز را بر حسب PPM  نشان می دهیم:

جدول سنسور MQ

بدین منظور ابتدا کتابخانه “mq.h” را که در زیر امده است در ابتدای برنامه اصلی اضافه می کنیم:

[cpp]
#include <delay.h>

#include <math.h>
#include "adc.h"
#define RL_VALUE (10) //define the load resistance on the board, in kilo ohms
#define RO_CLEAN_AIR_FACTOR (9.83) //(Sensor resistance in clean air)/RO which is derived from the chart in datasheet

#define LPG (0) // Gas identity no.
#define SMOKE (1) // Gas identity no.

float LPGCurve[3] = {2.3,0.20,-0.45}; //two points from LPG curve are taken point1:(200,1.6) point2(10000,0.26)
//take log of each point (lg200, lg 1.6)=(2.3,0.20) (lg10000,lg0.26)=(4,-0.58)
//find the slope using these points. take point1 as reference
//data format:{ x, y, slope};

float SmokeCurve[3] ={2.3,0.53,-0.43}; //two points from smoke curve are taken point1:(200,3.4) point2(10000,0.62)
//take log of each point (lg200, lg3.4)=(2.3,0.53) (lg10000,lg0.63)=(4,-0.20)
//find the slope using these points. take point1 as reference
//data format:{ x, y, slope};

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

int GetPercentage(float rs_ro_ratio, float *pcurve);
int GetGasPercentage(float rs_ro_ratio, int gas_id);
float ReadSensor();
float ResistanceCalculation(int raw_adc);
float SensorCalibration();

float ResistanceCalculation(int raw_adc)
{ // sensor and load resistor forms a voltage divider. so using analog value and load value
return ( ((float)RL_VALUE*(1023-raw_adc)/raw_adc)); // we will find sensor resistor.
}

float SensorCalibration()
{
int i; // This function assumes that sensor is in clean air.
float val=0;

for (i=0;i<50;i++) { //take multiple samples and calculate the average value

val += ResistanceCalculation(read_adc(0));
delay_ms(200);
}
val = val/50;
val = val/RO_CLEAN_AIR_FACTOR; //divided by RO_CLEAN_AIR_FACTOR yields the Ro
//according to the chart in the datasheet

return val;
}

float ReadSensor()
{
int i;
float rs=0;

for (i=0;i<5;i++) { // take multiple readings and average it.
rs += ResistanceCalculation(read_adc(0)); // rs changes according to gas concentration.
delay_ms(10);
}

rs = rs/5;

return rs;
}

int GetGasPercentage(float rs_ro_ratio, int gas_id)
{
if ( gas_id == LPG ) {
return GetPercentage(rs_ro_ratio,LPGCurve);

} else if ( gas_id == SMOKE ) {
return GetPercentage(rs_ro_ratio,SmokeCurve);
}

return 0;
}

int GetPercentage(float rs_ro_ratio, float *pcurve)
{ //Using slope,ratio(y2) and another point(x1,y1) on line we will find
return (pow(10,( ((log(rs_ro_ratio)-pcurve[1])/pcurve[2]) + pcurve[0]))); //gas concentration(x2) using x2 = [((y2-y1)/slope)+x1]
// as in curves are on logarithmic coordinate, power of 10 is taken to convert result to non-logarithmic.
}
[/cpp]

و در ادامه مقدیر آن را با واحد ppm بر روی lcd نمایش می دهیم:

[cpp]
This program was created by the
CodeWizardAVR V3.12 Advanced
Automatic Program Generator
© Copyright 1998-2014 Pavel Haiduc, HP InfoTech s.r.l.
http://www.hpinfotech.com

Project :
Version :
Date : 5/31/2017
Author :
Company :
Comments:

Chip type : ATmega16A
Program type : Application
AVR Core Clock frequency: 16.000000 MHz
Memory model : Small
External RAM size : 0
Data Stack size : 256
*******************************************************/

#include <mega16a.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <delay.h>
#include <alcd.h>
#include "mq.h"
// Declare your global variables here
float mq2_value =0.00;
char mq2[16];
void main(void)
{
// Declare your local variables here

// Input/Output Ports initialization
// Port A initialization
// Function: Bit7=In Bit6=In Bit5=In Bit4=In Bit3=In Bit2=In Bit1=In Bit0=In
DDRA=(0<<DDA7) | (0<<DDA6) | (0<<DDA5) | (0<<DDA4) | (0<<DDA3) | (0<<DDA2) | (0<<DDA1) | (0<<DDA0);
// State: Bit7=T Bit6=T Bit5=T Bit4=T Bit3=T Bit2=T Bit1=T Bit0=T
PORTA=(0<<PORTA7) | (0<<PORTA6) | (0<<PORTA5) | (0<<PORTA4) | (0<<PORTA3) | (0<<PORTA2) | (0<<PORTA1) | (0<<PORTA0);

// Port B initialization
// Function: Bit7=In Bit6=In Bit5=In Bit4=In Bit3=In Bit2=In Bit1=In Bit0=In
(0<<DDB0);
// State: Bit7=T Bit6=T Bit5=T Bit4=T Bit3=T Bit2=T Bit1=T Bit0=T
PORTB=(0<<PORTB7) | (0<<PORTB6) | (0<<PORTB5) | (0<<PORTB4) | (0<<PORTB3) | (0<<PORTB2) | (0<<PORTB1) | (0<<PORTB0);

// Port C initialization
// Function: Bit7=In Bit6=In Bit5=In Bit4=In Bit3=In Bit2=In Bit1=In Bit0=In
DDRC=(0<<DDC7) | (0<<DDC6) | (1<<DDC5) | (0<<DDC4) | (0<<DDC3) | (0<<DDC2) | (0<<DDC1) | (0<<DDC0);
// State: Bit7=T Bit6=T Bit5=T Bit4=T Bit3=T Bit2=T Bit1=T Bit0=T
PORTC=(0<<PORTC7) | (0<<PORTC6) | (0<<PORTC5) | (0<<PORTC4) | (0<<PORTC3) | (0<<PORTC2) | (0<<PORTC1) | (0<<PORTC0);

// Port D initialization
// Function: Bit7=In Bit6=In Bit5=In Bit4=In Bit3=In Bit2=In Bit1=In Bit0=In
DDRD=(0<<DDD7) | (0<<DDD6) | (0<<DDD5) | (0<<DDD4) | (1<<DDD3) | (0<<DDD2) | (0<<DDD1) | (0<<DDD0);
// State: Bit7=T Bit6=T Bit5=T Bit4=T Bit3=T Bit2=T Bit1=T Bit0=T
PORTD=(0<<PORTD7) | (0<<PORTD6) | (0<<PORTD5) | (0<<PORTD4) | (0<<PORTD3) | (0<<PORTD2) | (0<<PORTD1) | (0<<PORTD0);
// ADC initialization
// ADC Clock frequency: 125.000 kHz
// ADC Voltage Reference: AVCC pin
// ADC Auto Trigger Source: ADC Stopped
ADMUX=ADC_VREF_TYPE;
ADCSRA=(1<<ADEN) | (0<<ADSC) | (0<<ADATE) | (0<<ADIF) | (0<<ADIE) | (1<<ADPS2) | (1<<ADPS1) | (1<<ADPS0);
SFIOR=(0<<ADTS2) | (0<<ADTS1) | (0<<ADTS0);

lcd_init(16);
lcd_putsf( " HI Wellcom " ) ;
lcd_gotoxy( 0 , 1 );
lcd_putsf( "TO REDRONIC.COM" ) ;
delay_ms(2000);
lcd_clear();
lcd_putsf( " Waitting…" ) ;
lcd_gotoxy( 0 , 1 );
lcd_putsf( " MQ Calibration " ) ;
Ro = SensorCalibration();
lcd_clear();
// Global enable interrupts
#asm("sei")

while (1)
{
lcd_clear();
lcd_putsf("www.redronic.com");
mq2_value = ReadSensor(); //get sensor value
mq2_value =mq2_value/Ro; //turn to scale of callibrated Ro
mq2_value = log10(mq2_value); // according to datasheet chart
mq2_value = ((mq2_value-SmokeCurve[1])/SmokeCurve[2] + SmokeCurve[0]);
mq2_value = pow(10,mq2_value);
if(mq2_value < 10)
{
lcd_gotoxy(0,0);
lcd_putsf(" ");
}
ftoa(mq2_value,0,mq2);
lcd_gotoxy(0,1);
lcd_putsf("MQ:");
);
lcd_puts(mq2);
lcd_gotoxy(8,1);
lcd_putsf("ppm");
delay_ms(2000);
}
}
[/cpp]

خروجی برنامه

پروژه راه اندازی سنسور mq2

Choose your Reaction!
دیدگاه خود را بنویسید

آدرس ایمیل شما منتشر نخواهد شد.

redronic.com