در این مطلب، با راهاندازی سنسور DS18B20 با avr آشنا میشویم. بدین منظور، نحوه راهاندازی چند سنسور دمای DS18B20 با کمک یکی از سری میکروکنترلرهای AVR، یعنی میکروکنترلر ATmega328، را بررسی میکنیم. شاید در نگاه اول راهاندازی چند سنسور کار سختی به نظر برسد، اما همانطور که در این مطلب خواهیم دید، بهسادگی چندین سنسور دمای DS18B20 را به پین میکروکنترلر AVR متصل میکنیم و مقادیر دمای همه سنسورها را برحسب درجه سانتیگراد یا فارنهایت نمایش میدهیم. برای اتصال چند سنسور دمای DS18B20، فقط یک پین دیجیتال میکروکنترلر ATmega328 لازم است. لازم به ذکر است که میتوانیم حداکثر ۱۰۲۴ سنسور را با استفاده از پروتکل I2C متصل کنیم. اما در اینجا اتصال و راهاندازی ۳ سنسور دمای DS18B20 را با میکروکنترلر ATmega328 بررسی میکنیم.
سنسور DS18B20 یک سنسور دمای دیجیتال 1-Wire است. این سنسور امکان اندازهگیری دقیق دما را در محیطهای مرطوب با رابط ساده 1-Wire فراهم و از طریق باس مشترک ارتباط برقرار میکند. ارتباط از طریق باس مشترک به این معنی است که میتواند چندین دستگاه را به هم متصل کند و مقادیر آنها را فقط با استفاده از یک پین دیجیتال میکروکنترلر بخواند.
شاید برای شما مفید باشد: آموزش AVR از 0 تا 100
سنسور دمای دیجیتال ضد آب DS18B20
این نوع سنسور یک نسخه سیمکشی شده و ضد آب از سنسور DS18B20 بوده و برای زمانی که نیاز به اندازهگیری چیزی در فاصله دور یا در شرایط مرطوب داریم، گزینه مناسبی است. این نوع سنسور میتواند دمای بین ۵۵- تا ۱۲۵ درجه سانتیگراد (۶۷- تا ۲۵۷ درجه فارنهایت) را اندازهگیری کند. جنس کابل سنسور PVC است.
ازآنجاکه سنسور دیجیتال است، هیچگونه تخریب و افت سیگنال حتی در فواصل طولانی وجود ندارد. این سنسورهای دمای دیجیتال 1-Wire نسبتاً دقیق هستند و خطای آنها در حد ۰٫۵± درجه سانتیگراد است. همچنین، سنسور DS18B20 میتواند تا ۱۲ بیت دقت را از مبدل دیجیتال به آنالوگ آنبورد ارائه دهد. این سنسور با هر میکروکنترلری با استفاده از یک پین دیجیتال عملکرد بسیار خوبی دارد.
تنها نقطهضعف این سنسور استفاده از پروتکل Dallas 1-Wire است که تا حدودی پیچیده است و برای تجزیهوتحلیل ارتباطات نیاز به یک سری کد دارد. دقت کنید که در مدار از یک مقاومت ۴٫۷ کیلو اهم استفاده میکنیم که هنگام استفاده از سنسور بهعنوان pull-up از خط DATA به خط VCC موردنیاز است.
در ادامه، تجهیزات و قطعات موردنیاز را برای راهاندازی سنسور بیان میکنیم.
قطعات موردنیاز برای راهاندازی سنسور DS18B20 با avr
قطعات لازم برای مدار راهاندازی سنسور DS18B20 با avr عبارتاند از:
- میکروکنترلر ATmega328
- چند سنسور دمای ضد آب DS18B20
- نمایشگر LCD سایز ۱۶ در ۲
- مقاومتهای ۴٫۷ کیلو اهم، ۱ مگااهم و ۱۰۰ اهم
- خازنهای ۲۲ پیکوفاراد، ۱۰ میکروفاراد
- اسیلاتور کریستالی ۱۶ مگاهرتز
- منبع تغذیه یا باتری ۵ ولت
مدار اتصال سنسورها و میکروکنترلر
شماتیک مداری و اتصال بین قطعات مدار سنسور در شکل زیر نشاندادهشده است.
سختافزار و طراحی مدار
با اتصال تمام سنسورها به یک پین دیجیتال میکروکنترلر ATmega328، دماسنج دیجیتالی برای اندازهگیری دماهای متعدد بهسادگی طراحی میشود. تصویر زیر نشان میدهد که چگونه چندین سنسور دمای DS18B20 به میکروکنترلر ATmega328 متصل شده و دما را چگونه نمایش میدهند.
کد میکروکنترلر
از آردوینو برای نوشتن کد و آپلود آن در میکروکنترلر استفاده کردهایم. برای آپلود برنامه یا همان پروگرام کردن میکروکنترلر، ATmega328 را در برد Arduino UNO قرار دهید. ابتدا بوت لودر (bootloader) را آپلود کنید. سپس، بهسادگی کد زیر را کامپایل کرده و در میکروکنترلر آپلود کنید. اکنون میتوانید میکروکنترلر را خارج کرده و آن را در PCB قرار دهید.
برای اتصال راهاندازی سنسور DS18B20 با avr به دو کتابخانه زیر نیاز داریم:
۲. دانلود کتابخانه Dallas Temperature
کد میکروکنترلر در ادامه آورده شده است.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 | #include <LiquidCrystal.h> LiquidCrystal lcd(11, 12, 5, 4, 3, 2); #include <OneWire.h> #include <DallasTemperature.h> #define ONE_WIRE_BUS 9 // Data wire is plugged into port 9 on the Arduino #define precision 12 // OneWire precision Dallas Sensor int sen_number = 0; // Counter of Dallas sensors OneWire oneWire(ONE_WIRE_BUS); DallasTemperature sensors(&oneWire); // Pass our oneWire reference to Dallas Temperature. DeviceAddress T1, T2, T3, T4, T5, T6, T7, T8; // arrays to hold device addresses void setup(void) { lcd.begin(16,2); Serial.begin(9600); //Start serial port Serial.println("Dallas Temperature IC Control Library"); // Start up the library sensors.begin(); // locate devices on the bus Serial.print("Found: "); Serial.print(sensors.getDeviceCount(), DEC); Serial.println(" Devices."); // report parasite power requirements Serial.print("Parasite power is: "); if (sensors.isParasitePowerMode()) Serial.println("ON"); else Serial.println("OFF"); // Search for devices on the bus and assign based on an index. if (!sensors.getAddress(T1, 0)) Serial.println("Not Found Sensor 1"); if (!sensors.getAddress(T2, 1)) Serial.println("Not Found Sensor 2"); if (!sensors.getAddress(T3, 2)) Serial.println("Not Found Sensor 3"); if (!sensors.getAddress(T4, 3)) Serial.println("Not Found Sensor 4"); if (!sensors.getAddress(T5, 4)) Serial.println("Not Found Sensor 5"); if (!sensors.getAddress(T6, 5)) Serial.println("Not Found Sensor 6"); if (!sensors.getAddress(T7, 6)) Serial.println("Not Found Sensor 7"); if (!sensors.getAddress(T8, 7)) Serial.println("Not Found Sensor 8"); // show the addresses we found on the bus for (int k =0; k < sensors.getDeviceCount(); k++) { Serial.print("Sensor "); Serial.print(k+1); Serial.print(" Address: "); if (k == 0) { printAddress(T1); Serial.println(); } else if (k == 1) { printAddress(T2); Serial.println(); } else if (k == 2) { printAddress(T3); Serial.println(); } else if (k == 3) { printAddress(T4); Serial.println(); } else if (k == 4) { printAddress(T5); Serial.println(); } else if (k == 5) { printAddress(T6); Serial.println(); } else if (k == 6) { printAddress(T7); Serial.println(); } else if (k == 7) { printAddress(T8); Serial.println(); } } // set the resolution to 12 bit per device sensors.setResolution(T1, precision); sensors.setResolution(T2, precision); sensors.setResolution(T3, precision); sensors.setResolution(T4, precision); sensors.setResolution(T5, precision); sensors.setResolution(T6, precision); sensors.setResolution(T7, precision); sensors.setResolution(T8, precision); for (int k =0; k < sensors.getDeviceCount(); k++) { Serial.print("Sensor "); Serial.print(k+1); Serial.print(" Resolution: "); if (k == 0) { Serial.print(sensors.getResolution(T1), DEC); Serial.println(); } else if (k == 1) { Serial.print(sensors.getResolution(T2), DEC); Serial.println(); } else if (k == 2) { Serial.print(sensors.getResolution(T3), DEC); Serial.println(); } else if (k == 3) { Serial.print(sensors.getResolution(T4), DEC); Serial.println(); } else if (k == 4) { Serial.print(sensors.getResolution(T5), DEC); Serial.println(); } else if (k == 5) { Serial.print(sensors.getResolution(T6), DEC); Serial.println(); } else if (k == 6) { Serial.print(sensors.getResolution(T7), DEC); Serial.println(); } else if (k == 7) { Serial.print(sensors.getResolution(T8), DEC); Serial.println(); } } } // function to print a device address void printAddress(DeviceAddress deviceAddress) { for (uint8_t i = 0; i < 8; i++) { // zero pad the address if necessary if (deviceAddress[i] < 16) Serial.print("0"); Serial.print(deviceAddress[i], HEX); } } // function to print the temperature for a device void printTemperature(DeviceAddress deviceAddress) { float tempC = sensors.getTempC(deviceAddress); Serial.print("Temp : "); Serial.print(tempC); Serial.print(" Celcius degres "); // Serial.print(" Temp F: "); // Serial.print(DallasTemperature::toFahrenheit(tempC)); } // function to print a device's resolution void printResolution(DeviceAddress deviceAddress) { } void printData(DeviceAddress deviceAddress) { Serial.print("Device Address: "); printAddress(deviceAddress); Serial.print(" "); printTemperature(deviceAddress); Serial.println(); } void loop(void) { // call sensors.requestTemperatures() to issue a global temperature request to all devices on the bus Serial.print("Reading DATA..."); sensors.requestTemperatures(); Serial.println("DONE"); // print the device information for (int k =0; k < sensors.getDeviceCount(); k++) { Serial.print("Sensor "); Serial.print(k+1); Serial.print(" "); if (k == 0) { printData(T1); } else if (k == 1) { printData(T2); } else if (k == 2) { printData(T3); } else if (k == 3) { printData(T4); } else if (k == 4) { printData(T5); } else if (k == 5) { printData(T6); } else if (k == 6) { printData(T7); } else if (k == 7) { printData(T8); } } if (sen_number == sensors.getDeviceCount()) { sen_number = 0; // reset counter // lcd.clear(); // clear screen on LCD } lcd.setCursor(0,0); lcd.print("Sensor Number "); lcd.print(sen_number+1); lcd.setCursor(0,1); lcd.print(" Temp: "); if (sen_number == 0) { lcd.print(sensors.getTempC(T1)); lcd.write((char)223); lcd.print("C "); } else if (sen_number == 1) { lcd.print(sensors.getTempC(T2)); lcd.write((char)223); lcd.print("C "); } else if (sen_number == 2) { lcd.print(sensors.getTempC(T3)); lcd.write((char)223); lcd.print("C "); } else if (sen_number == 3) { lcd.print(sensors.getTempC(T4)); lcd.write((char)223); lcd.print("C "); } else if (sen_number == 4) { lcd.print(sensors.getTempC(T5)); lcd.write((char)223); lcd.print("C "); } else if (sen_number == 5) { lcd.print(sensors.getTempC(T6)); lcd.write((char)223); lcd.print("C "); } else if (sen_number == 6) { lcd.print(sensors.getTempC(T7)); lcd.write((char)223); lcd.print("C "); } else if (sen_number == 7) { lcd.print(sensors.getTempC(T8)); lcd.write((char)223); lcd.print("C "); } Serial.print("Sensor Number="); Serial.println(sen_number); delay(2000); sen_number++ ; } |
راهاندازی چند سنسور DS18B20 با AVR
سنسور DS18B20 میتواند دما را از ۹ تا ۱۲ بیت (قابلتنظیم) روی نمایشگر نمایش دهد. همچنین، از طریق یک باس 1-Wire ارتباط برقرار میکند که طبق تعریف فقط به یک خط داده (و زمین) برای ارتباط با یک ریزپردازنده مرکزی نیاز دارد. علاوه بر این، میتواند مستقیماً از خط داده (“توان پارازیتی”) توان دریافت کند و نیاز به منبع تغذیه خارجی را از بین ببرد.
عملکرد اصلی DS18B20 سنسور دمای مستقیم به دیجیتال بودن آن است. وضوح سنسور دما توسط کاربر قابلتنظیم به ۹، ۱۰، ۱۱ یا ۱۲ بیت است که به ترتیب متناظر با افزایش ۰٫۵ درجه سانتیگراد، ۰٫۲۵ درجه سانتیگراد، ۰٫۱۲۵ درجه سانتیگراد و ۰٫۰۶۲۵ درجه سانتیگراد به مکان. رزولوشن پیشفرض هنگام روشنشدن ۱۲ بیت است.
هر سنسور DS18B20 دارای آدرس دستگاه خاصی با فرمت HEX مانند {0x28، 0x1D، 0x39، 0x31، 0x2، 0x0، 0x0، 0xF0} است؛ بنابراین، برنامه بر اساس دمای خواندن از یک آدرس دستگاه خاص طراحی شده است. در نتیجه، ابتدا میکروکنترلر تعداد سنسورها را اسکن میکند. فرض کنید ۳ سنسور در اینجا متصل هستند؛ بنابراین، فقط مقادیر ۳ دمای مختلف را نمایش میدهد. اگر سنسورهای بیشتری متصل شوند، تعداد قرائتها به مقادیر متعدد تغییر خواهد کرد. مقدار دمای خواندهشده توسط هر سنسور پس از فاصله زمانی ۲ ثانیه بهعنوان دمای سنسور شماره ۱، سنسور شماره ۲ دمای سنسور و بزرگتر از آن برای شماره سنسورهای متصل بیشتر نمایش داده میشود.
منبع: How To Electronics
سلام یه برد دما و تایمر دارم که با اتمگا ۸ بوده و ای سی پوکیده برنامشو ندارم میشه راهنمایی کنید پروگرامرش کنم سنسور دماش همین سنسور هستش
سلام دوست عزیز
متاسفانه مساله به این سادگی ها هم نسیت و خیلی پیچیده تره
باید شماتیک وجود داشته باشه باید کارکرد مشخص شده باشه و …..
بعد در صورت وجود همه اینها باید برنامه بازنویسی بشه که خودش کلی ماجرا داره