🌡️ سنسور دما و رطوبت DHT11 و DHT22 با میکروپایتون روی رزبری پای پیکو
دماسنج و رطوبتسنج اولین «پروژهی واقعی» خیلی از ماست: ایستگاه هواشناسی کوچک، کنترل فن گلخانه یا هشدار رطوبت انبار. در این آموزش سنسورهای معروف DHT11 و DHT22 را با میکروپایتون روی رزبری پای پیکو میخوانیم، خطاهایشان را درست مدیریت میکنیم و در آخر عددها را روی یک LCD نشان میدهیم. همهی کدها را میتوانی قبل از خرید سنسور در یک شبیهساز آنلاین، مثل کاری که کاربران wokwi میکنند، این بار به فارسی امتحان کنی.
DHT11 و DHT22 چه فرقی دارند؟
| ویژگی | DHT11 (آبی) | DHT22 یا AM2302 (سفید) |
|---|---|---|
| بازهی دما | ۰ تا ۵۰ درجه | ۴۰- تا ۸۰ درجه |
| دقت دما | حدود ۲± درجه | حدود ۰٫۵± درجه |
| بازهی رطوبت | ۲۰ تا ۹۰ درصد | ۰ تا ۱۰۰ درصد |
| دقیقترین خروجی | عدد صحیح | یک رقم اعشار |
| فاصلهی دو خواندن | دستکم ۱ ثانیه | دستکم ۲ ثانیه |
| ولتاژ | ۳٫۳ تا ۵ ولت | ۳٫۳ تا ۶ ولت |
هر دو فقط با یک سیم داده با میکروکنترلر حرف میزنند و پروتکلشان یکی است، برای همین در میکروپایتون فقط اسم کلاس عوض میشود.
قطعههای لازم
- یک رزبری پای پیکو
- یک سنسور دما و رطوبت DHT (مدل ۱۱ یا ۲۲)
- یک مقاومت ۱۰ کیلواهم، فقط اگر سنسور تو خام و چهارپایه است (ماژولهای سهپایهی روی برد کوچک، این مقاومت را دارند)
- اختیاری: LCD 16×2 با ماژول I2C برای بخش آخر
سیمکشی
| پایهی DHT | پایهی پیکو |
|---|---|
| VCC (+) | 3V3(OUT)، پایهی فیزیکی ۳۶ |
| DATA (OUT) | GP15، پایهی فیزیکی ۲۰ |
| GND (-) | GND، مثلاً پایهی فیزیکی ۱۸ |
اگر سنسور خام چهارپایه داری، از جلو که نگاه کنی پایهها به ترتیب VCC، DATA، بدون اتصال و GND هستند، و مقاومت ۱۰ کیلواهم باید بین DATA و VCC قرار بگیرد. سنسور را با ۳٫۳ ولت تغذیه میکنیم تا سیگنال داده هم ۳٫۳ ولتی بماند و به پایهی پیکو فشار نیاید.
کد کامل میکروپایتون
from machine import Pin
import dht
import time
sensor = dht.DHT22(Pin(15)) # for a DHT11 write: dht.DHT11(Pin(15))
led = Pin(25, Pin.OUT) # on-board LED as a "too hot" alarm (Pico W: Pin("LED"))
MAX_TEMP = 30
while True:
try:
sensor.measure()
t = sensor.temperature()
h = sensor.humidity()
print("Temp:", t, "C Humidity:", h, "%")
if h < 30:
print(" air is dry")
elif h > 60:
print(" air is humid")
led.value(1 if t >= MAX_TEMP else 0)
except OSError as e:
print("Sensor read failed:", e)
time.sleep(2)
توضیح خط به خط
import dht: ماژول DHT داخل فرمور رسمی میکروپایتون پیکو هست؛ برخلاف درایور LCD، چیزی برای کپی کردن ندارد.dht.DHT22(Pin(15)): یک شیء سنسور روی GP15 میسازد. برای مدل آبی بنویسdht.DHT11. اگر مدل را اشتباه بنویسی، عددها بیمعنی (مثلاً دمای ۰ یا ۲۵۵۰) میشوند.sensor.measure(): مهمترین خط. سنسور را بیدار میکند و یک اندازهگیری تازه میگیرد. تا این را صدا نزنی،temperature()وhumidity()عدد قبلی را برمیگردانند.sensor.temperature()وsensor.humidity(): آخرین دما (درجهی سانتیگراد) و رطوبت نسبی (درصد) را میدهند. در DHT11 عدد صحیح و در DHT22 اعشاری است.tryوexcept OSError: سنسورهای DHT گاهی یک خواندن را از دست میدهند. بدون این دو خط، یک خطای کوچک کل برنامه را متوقف میکند؛ با آنها فقط یک پیام چاپ میشود و دو ثانیه بعد دوباره تلاش میکنیم.led.value(1 if t >= MAX_TEMP else 0): یک هشدار ساده؛ اگر دما به ۳۰ درجه رسید، LED روی برد روشن میشود. جای LED میتوانی رلهی فن بگذاری.time.sleep(2): فاصلهی دو خواندن. برای DHT22 کمتر از دو ثانیه نکن، وگرنه سنسور جواب نمیدهد یا عدد تکراری میدهد.
نمایش روی LCD
اگر LCD I2C با میکروپایتون را راه انداختهای، فقط چند خط لازم است تا عددها روی صفحه بیایند. LCD روی GP0 و GP1 است و سنسور روی GP15:
from machine import I2C, Pin
from i2c_lcd import I2cLcd
import dht
import time
i2c = I2C(0, sda=Pin(0), scl=Pin(1), freq=400000)
lcd = I2cLcd(i2c, 0x27, 2, 16)
sensor = dht.DHT11(Pin(15))
while True:
try:
sensor.measure()
lcd.move_to(0, 0)
lcd.putstr("Temp: %d C " % sensor.temperature())
lcd.move_to(0, 1)
lcd.putstr("Humidity: %d %% " % sensor.humidity())
except OSError:
lcd.move_to(0, 0)
lcd.putstr("Sensor error! ")
time.sleep(2)
یادت باشد روی برد واقعی فایلهای lcd_api.py و i2c_lcd.py باید روی پیکو کپی شده باشند. %% در رشته یعنی خود علامت درصد.
اجرا در شبیهساز
در تینکرکد فارسی پروژهی آمادهی LCD و دماسنج DHT11 با MicroPython روی پیکو تقریباً همین مدار را دارد. بعد از اجرا، روی قطعهی DHT کلیک کن؛ در پنل ویژگیها میتوانی مدل را بین DHT11 و DHT22 عوض کنی و با دو اسلایدر دما و رطوبت را بالا و پایین ببری. بهترین راه برای امتحان شرطهای برنامه همین است: دما را به ۳۱ درجه برسان و ببین LED روشن میشود. شبیهساز بازههای واقعی هر مدل را هم رعایت میکند. پیکو و میکروپایتون جزو اشتراک پلاساند: مثال برای خواندن رایگان است و برای اجرا پلاس لازم داری. دربارهی خود این سنسورها در صفحهی سنسور رطوبت بیشتر بخوان.
اشکالهای رایج
- OSError: [Errno 110] ETIMEDOUT: سنسور جواب نداده. سیم داده واقعاً به GP15 است؟ مقاومت بالاکش سر جایش است؟ سنسور برق دارد؟
- عددها عجیباند (دمای صفر یا خیلی بزرگ): کلاس را با مدل سنسور جور نکردهای؛ DHT11 را با
DHT22میخوانی یا برعکس. - هر چند بار یکبار خطا میگیرم: طبیعی است، به خصوص با سیم بلند. همان
try/exceptکافی است. اگر زیاد شد، سیم را کوتاهتر کن. - دما هیچوقت عوض نمیشود:
sensor.measure()را فقط یک بار، بیرون از حلقه صدا زدهای. - NameError: name 'dht' isn't defined: خط
import dhtجا افتاده.
قدم بعدی
نسخهی آردوینوی همین سنسور را در DHT22 و DHT11 با آردوینو ببین. اگر میخواهی دما را در مرورگر گوشی ببینی، سراغ صفحهی هواشناسی با ESP32 برو. و برای اینکه خواندن سنسور بقیهی برنامه را معطل نکند، Timer در میکروپایتون را یاد بگیر.
دماسنج پیکو را در شبیهساز امتحان کن 🌡️سؤالهای رایج
DHT11 بخرم یا DHT22؟
برای یادگیری و پروژهی داخل خانه DHT11 کافی و ارزان است. اگر دقت بالاتر، دمای زیر صفر یا رطوبت خیلی کم و زیاد مهم است، DHT22 بگیر. کد میکروپایتون هر دو فقط در یک کلمه فرق دارد.
چرا sensor.measure() خطای OSError میدهد؟
یعنی پیکو جوابی از سنسور نگرفته: سیم داده جابهجاست، مقاومت بالاکش نیست، یا سنسور را زودتر از حد مجاز دوباره خواندهای. بین دو خواندن DHT11 دستکم یک ثانیه و DHT22 دو ثانیه صبر کن و خطا را با try و except بگیر.
آیا باید کتابخانهی dht را جداگانه نصب کنم؟
نه. ماژول dht داخل فرمور رسمی میکروپایتون برای رزبری پای پیکو هست و فقط با import dht در دسترس است.
مقالههای مرتبط
Timer در میکروپایتون: چند کار همزمان روی رزبری پای پیکو بدون sleep
نصب میکروپایتون روی رزبری پای پیکو و راهاندازی Thonny، قدمبهقدم
برنامهنویسی رزبری پای پیکو با زبان آردوینو (C++ و هستهی arduino-pico)
سنسور گاز MQ-2 با آردوینو: تشخیص دود و گاز، گرم شدن، آستانه و آژیر
همهی آموزشهای رزبری پای پیکو و میکروپایتون ← · همهی مقالهها