پروژه دماسنج با میکروکنترلر AVR و سنسور LM35
محتویات
سلام. آموزش کامل پروژه دماسنج AVR با سنسور LM35 و سون سگمنت (آموزش AVR #12) را آماده کردیم.
آموزش ساخت پروژه دما سنج با میکروکنترلر AVR
در این آموزش AVR ، ما با استفاده از میکروکنترلر AVR ، سنسور دما LM35 و سون سگمنت 4 تایی و کامپایلر کدویژن یک دماسنج حرفه ای میسازیم. این دماسنج مقدار دما را بر حسب درجه سانتی گراد نشان میدهد.
در قسمت قبلی آموزش ما به طور کامل با کار با پورت های ورودی و خروجی در میکروکنترلر های AVR آشنا شدیم.
قسمت قبل : آموزش کار با پورت های ورودی و خروجی در میکروکنترلر AVR
در این آموزش مبحث های ADC ، سون سگمنت و … مورد استفاده قرار میگیرند پس از اگر آموزش های AVR را نخواندید شروع کنید از اول بخوانید.
این قسمت آموزش را کلا به پروژه دماسنج اختصاص میدهیم و با چیزهایی که تا الان یاد گرفتیم سنسور دمای LM35 را راه اندازی میکنیم.
در این آموزش به ترتیب با مسائل زیر آشنا میشویم.
- آشنایی کامل با سنسور دما LM35
- کانفیگ رجیستر های ADC
- کار با سون سگمنت
قطعات مورد نیاز آموزش ساخت دماسنج AVR
- میکروکنترلر AVR Atmega32 – دیتاشیت مگا 32
- سنسور دما LM35
- سون سگمنت 4 تایی آند مشترک
مشخصات سنسور دما LM35
سنسور دما LM35 یکی از محبوب ترین و سهل الاستفاده ترین سنسور های سنجش دما است.
ولتاژ ورودی این سنسور از 4 ولت تا 20 ولت است. این سنسور به ازای هر درجه سانتی گراد افزایش دما 10 میلی ولت را به خروجی خود اضافه میکنند. سنسور دما LM35 دارای ولتاژ کمترین صفر است ، بدین معنی که در 0 درجه سانتیگراد خروجی 0V خواهد بود. حداکثر ولتاژ خروجی آن 1.5 ولت است به این معنی که می تواند حداکثر دمای 150 درجه سانتیگراد را حس کند. حداکثر خطای این سنسور دماسنج 0.5 درجه سانتی گراد است.
خب برویم سراغ برنامه نویسی پروژه !
کد پروژه تشخیص دما با میکروکنترلر AVR
در ابتدا فرکانس کاری میکروکنترلر را 8 مگا هرتز در نظر میگیریم. در ابتدای کد همانطور که در قسمت قبل هم توضیح دادیم ، کتابخانه های مورد نیاز را فراخوانی میکنیم. در اینجا ما کتابخانه میکروکنترلر مگا 32 و کتابخانه تاخیر زمان را فراخوانی میکنیم.
#include <mega32.h> #include <delay.h> void adc_configuration(){} unsigned int temp(){} void main(){}
سپس در خط های بعد ما دو تابع را تعریف میکنیم. یعنی adc_configuration و temp. انتخاب نام توابع اختیاری است. ما در تابع adc_configuration پیکربندی آنالوگ به دیجیتال را انجام میدهیم و تابع temp دما را میخواند.
ابتدا تابع adc_configuration را پیکربندی میکنیم. همانطور که در قسمت های قبل گفتیم، یک رجیستر داشتیم به نام ADMUX. در این پروژه از کانال ADC0 استفاده میکنیم و ولتاژ مرجع را نیز روی 2.56 قرار میدهیم.
void adc_configuration(){ ADMUX |= (1<<REFS1)|(1<<REFS0); }
رجیستر دیگری نیز داشتیم به نام رجیستر ADCSRA.
ضریب تقسیم را 64 در نظر گرفته و فلگ ADEN را هم یک میکنیم تا واحد ADC فعال شود.
void adc_configuration(){ ADMUX |= (1<<REFS1)|(1<<REFS0); ADCSRA |= (1<<ADPS2)|(1<<ADPS1)|(1<<ADEN); }
حالا میرسیم به تابع temp.
unsigned int temp(){}
ما باید فرمان شروع تبدیل را بدهیم. اینکار را با 1 کردن فلگ ADSC انجام میدهیم.
unsigned int temp(){ ADCSRA |=(1<<ADSC); }
با این کار، یعنی صدور فرمان شروع تبدیل، باید منتظر بمانیم تا تبدیل انجام شود و سپس مقدار ADC را بخوانیم. حالا از کجا بفهمیم که چه زمانی تبدیل تمام شده است ؟
ما یک فلگ داریم به نام ADIF. کار این فلگ دقیقا همین است. وقتی که مقدار این فلگ 1 شود یعنی تبدیل انجام شده است. پس باید منتظر بمانیم تا این فلگ یک شود و وقتی که یک شود با یک کد دیگر دوباره آن را صفر میکنیم !
unsigned int temp(){ ADCSRA |=(1<<ADSC); while ((ADCSRA & (1<<ADIF))==0); ADCSRA |=(1<<ADIF); }
الان تبدیل انجام شده است و رجیستر های ADCH و ADCL که وظیفه نگهداری مقدار ADC را دارند پر شده اند و حاوی مقدار آنالوگ به دیجیتال هستند. نکته دیگر این است که به مجموع دو رجیستر ADCH و ADCL میگویند ADCW که در واقع یک عدد 10 بیتی را تحویل میدهد.
unsigned int temp(){ ADCSRA |=(1<<ADSC); while ((ADCSRA & (1<<ADIF))==0); ADCSRA |=(1<<ADIF); return ADCW; }
نمایش دما روی سون سگمنت
خب تا به اینجا دو تابع مورد نظر را نوشتیم. اما ما میخواستیم مقدار دما را روی سون سگمنت نمایش دهیم. پس میرویم سراغ تابع اصلی یعنی main.
void main(){}
روند کار ما به این صورت است.
- خواندن دما.
- ذخیره دما در متغیری به نام T.
- دما را به دو عدد تک رقمی تفکیک میکنیم.
- اعداد تفکیک شده از آرایه مربوط به اعدا یعنی seg انتخاب میشوند.
- اعداد با یک تکنین خاص روی سون سگمنت ها نمایش داده میشوند
پس برای خواندن دما ، مقدار برگردانده شده از تابع temp را در متغیر T قرار میدهیم. با توجه به فرمولی که در قسمت مربوط به آموزش آنالوگ به دیجیتال گفته شد، مقدار T جدید را محاسبه میکنیم. این مقدار مساوی با اندازه دما بر حسب درجه سلسیوس است. دلیل اضافه شدن عبارت 100* این است که حسگر LM35 دما را بر حسب میلی ولت به ما تحویل میدهد.
T = temp(); T = (((T*2.56)*100)/1023);
برای نمایش اعدا مورد نظر روی سون سگمنت ما باید کد آن هارا بسازیم. این کد ها را در دو باکس پایین برای سون سگمنت های کاتد مشترک و آند مشترک قرار داده ایم میتوانید استفاده کنید.
کاتد مشترک :
unsigned char seg[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x63,0x39};
آند مشترک :
unsigned char seg[]={0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10,0x1C,0x46};
ما یک تابع دیگر را نیز تعریف میکنیم به نام seg_display که مسائل مربوط به سون سگمنت را در آن قرار میدهیم.
void seg_display (unsigned int temp){}
این تابع دما را میگیرد آن را برای نمایش در سون سگمنت آماده میکند.
void seg_display (unsigned int temp){ unsigned char seg[]={0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10,0x1C,0x46}; unsigned char data[4]; DDRB=0xFF; DDRD=0x0F; data[0]=seg[temp/10]; data[1]=seg[temp%10]; data[2]=seg[10]; data[3]=seg[11]; for (i = 0; i < 4; i++) { PORTB=data[i]; PORTD=0x00; PORTD=1<<i; delay_us(500); } }
از آرایه زیر به عنوان بافر استفاده میکنیم تا مقادیر را از آرایه seg در خود بریزد.
unsigned char data[4];
پروژه دماسنج AVR با سنسور LM35
در کد زیر نیز پورت D و B را به عنوان خروجی تعریف میکنیم. پورت B برای کنترل abcdefg+dot و پورت D برای کنترل سون سگمنت 1234 استفاده میشود.
DDRB=0xFF; DDRD=0x0F;
خب حالا به طور مثال اگر ما بخواهیم دما را به صورت زیر نشان بدهیم.
27°C
این مقدار تشکیل شده از عدد دهگان یعنی 2 ، عدد یکان یعنی 7 ، علامت درجه یعنی ° و علامت سنتی گراد یعنی C است. همانطور که در مطلب آموزش کامل سون سگمنت ها گفتیم، برای نمایش عدد روی سون سگمنت چهار تایی باید از مولتی پلکس استفاده کنیم.
یعنی باید در سون سگمنت 1 عدد 2 – در سون سگمنت 2 عدد 7 – در سون سگمنت 3 علامت ° و در سون سگمنت 4 حرف C نمایش داده شود. پس در اولین مرحله باید اعداد را از هم تفکیک کنیم.
unsigned int temp(){}
حالا یک گریز میزنیم به ریاضی دوران دبستان،
فرض کنید عددی مثل 1453 را میخواهیم از هم تفکیک کنیم.
عدد مورد نظر از : یکان-دهگان-صدگان-هزارگان تشکیل شده است.
حالا اگر این عدد را بر 1000 تقسیم کنیم، خارج قسمت میشود : 1 (هزارگان)
باقی مانده اش هم میشود : 453
اگر 453 را بر 100 تقسیم کنیم، خارج قسمت میشود : 4 (صدگان)
باقی مانده هم میشود : 53
اگر 53 را بر 10 تقسیم کنیم، خارج قسمت میشود : 5 (دهگان)
باقی مانده هم میشود : 3 (یکان)
دقیقا از همین تکنیک برای تفکیک اعداد استفاده میکنیم. اما از آنجا که دمای ما 2 رقمی است کار بسیار آسان تر است. در کد زیر با تقسیم دما بر 10 ، دهگان را مشخص میکنیم و مقدار متناظر آن را از آرایه seg انتخاب کرده و در عضو صفرم آرایه data ذخیره میکنیم.
data[0]=seg[temp/10];
سپس در کد زیر یکان را مشخص میکنیم و مقدار متناظر آن را از آرایه seg انتخاب کرده و در عضو یکم آرایه data ذخیره میکنیم.
data[1]=seg[temp%10];
تا به اینجا عدد دو رقمی را به دو عدد تک رقمی تفکیک کردیم. همچنین علامت درجه و C را نیز در خانه 2 و 3 آرایه data قرار دادیم.
data[2]=seg[10]; data[3]=seg[11];
سپس ما یک حلقه 500 میکروثانیه ای ایجاد میکنیم تا مقدار را روی سون سگمنت های 1234 نمایش دهیم.
for (i = 0; i < 4; i++) { PORTB=data[i]; PORTD=0x00; PORTD=1<<i; delay_us(500); }
اطلاعات را روی پورت B قرار میدهیم.
PORTB=data[i];
و با کد زیر نیز بخش پایه های کنترلی 1234 را کنترل میکنیم.
PORTD=0x00; PORTD=1<<i;
شماتیک پروژه
کد کامل پروژه
#include <mega32.h> #include <delay.h> unsigned int i,T; void adc_configuration(){ ADMUX |= (1<<REFS1)|(1<<REFS0); ADCSRA |= (1<<ADPS2)|(1<<ADPS1)|(1<<ADEN); } unsigned int temp(){ ADCSRA |=(1<<ADSC); while ((ADCSRA & (1<<ADIF))==0); ADCSRA |=(1<<ADIF); return ADCW; } void seg_display(unsigned int temp){ unsigned char seg[]={0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10,0x1C,0x46}; unsigned char data[4]; DDRB=0xFF; DDRD=0x0F; data[0]=seg[temp/10]; data[1]=seg[temp%10]; data[2]=seg[10]; data[3]=seg[11]; for (i = 0; i < 4; i++) { PORTB=data[i]; PORTD=0x00; PORTD=1<<i; delay_us(500); } } int main(void) { while(1) { adc_configuration(); T = temp(); T=(T*256/1023); seg_display(T); } }
دوستان این کد برای آموزش مبحث نوشته شده است و بدلیل مشکلات جریان نمیتوان از این کد به صورت عملی استفاده کرد. در صورتی که نیاز به یک پروژه دماسنج به صورت عملی دارید از پروژه های دماسنج سایت دیدن فرمایید.
قسمت بعدی سری آموزش های AVR : آموزش تایمر / کانتر در میکروکنترلر AVR
با سلام و عرض ادب بنده یه مشکلی که دارم بعد از پروگرام کردن آی سی زمانی که سنسور را متصل میکنم دمای 0 را نشان میده خواهشن میتونین راهنمائی بفرمائید
سلام مجدد، چشم در اولین فرصت انجام میدم.
سلام مجدد، الان داخل اتمل استودیو هم به خط دوم گیر میده و یه ارور دیگه repice for target main.o falied میده.
سلام وقت بخیر
تمامی ارور ها را ارسال کنید و نشان بدهید دقیقا به کجا ایراد میگیرد. برای اینکه راحت تر باشید در انجمن مطرح کنید.
سلام،
من کد رو نوشتم اما کدویژن به خط 29 یا همون خط int main(void) ارور میده و نمیذاره کد ها تولید بشن.
چیکار کنم؟
ممنون.
سلام عزیز
این کد برای اتمل استودیو هست
سلام کدوم قسمت دانلود کنم
سلام عزیز
لینک دانلود فایل های پروژه در انتهای متن مقاله قرار گرفته است.
سلام ممنون از توضیحاتتون میشه لطفا بگید از کجا به بعد در while قرار میگیره؟ یعنی کدوم کد ها رو باید داخل while قرار بدیم؟
سلام عزیز
فایل کامل پروژه را میتوانید از انتهای صفحه دانلود کنید
سلام استاد من پروژه ی دماسنج با avr برداشتم ینی باید پروگرم کنم این پروژه کاربردی هست یا نه! چون نوشتین بدرد عملی نمیخوره لطفا ایمیل کنید برام
سلام وقت بخیر
اگر میخواهید با AVR دماسنج بسازید، میتوانید دوره AVR را مشاهده کنید. تمامی موارد توضیح داده شده است.
سلام درست کردن با نوع راحت تره یا با برد رادیونو من اولین بارمه میخام درست کنم ممنون میشم راهنمایی کنید
سلام عزیز
با اردوینو راحت تر هست
سلام پروژه تحقیقاتی دوره لیسانس میخواستم_ساخت دماسنج با میکروکنترلرAvrو Lm35و نمایشگر سون سگمنت
سلام عزیز، از همین پروژه میتونین استفاده کنید
بسیار عالی
باتشکر از توضیحات جامع شما
سلام عزیز، خوشحالم که براتون مفید واقع شده
پروژه ساخت دماسنج بااستفاده ازAvR میخوام ۰۹۱**۰۸۵۵۶۷
۶۰صفحه