پروژه های AVR, پروژه‌ها

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

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

فهرست مطالب

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

قطعات مورد نیاز:

سنسور گاز : GAS SENSOR

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

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

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

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

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

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

مدار سنسور MQ

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

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

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

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

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

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

				
					#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&lt;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&lt;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.
}
 

				
			

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

				
					#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); 
   }
}
				
			

خروجی برنامه

نظرتان را درباره این مقاله بگویید 6 نظر

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

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

  1. parisa گفت:

    سلام خانم احمدی چطور میتونم سنسور flc100 مگنومتر ، که میزان تغییرات مغناطیس زمین رو میسنجه رو توسط این روش راه اندازی کنم و مغادیر رو به کامپیوتر منتقل کنم؟ ممنون میشم راهنمایی کنید

  2. parisa گفت:

    سلام چطور میتونم سنسور flc100 مگنومتر رو برای اندازه گیری تغییرات مغناطیس زمین به این روش راه اندازی کنم؟ ممنون

  3. مهدی گفت:

    سلام
    امکانش هست در مورد کتابخانه که نوشتید بیشتر توضیح بدید؟
    تابع ResistanceCalculation و SensorCalibration دقیقا چطور کار میکنند؟

  4. مهدی گفت:

    سلام
    امکانش هست کتابخانه acd.h هم قرار بدید؟

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

سه + 18 =