در این آموزش به شما نشان میدهیم با استفاده از فریمور میکروپایتون و با بردهای ESP32 و ESP8266، چگونه از سنسور دما DS18B20 استفاده کنید. شما یاد خواهید گرفت که دما را از یک سنسور DS18B20 و یا چند سنسور به صورت همزمان بخوانید. همچنین برای نمایش مقادیر خوانده شده از سنسور، یک وب سرور خواهید ساخت.
پیشنیازها
برای دنبال کردن این آموزش، شما نیاز دارید که فریمور میکروپایتون در برد ESP32/ESP8266 شما نصب باشد. همچنین برای نوشتن و آپلود کد در بردتان به یک IDE نیاز دارید. ما پیشنهاد میکنیم که از Thonny IDE یا uPyCraft IDE استفاده کنید.
معرفی سنسور دما DS18B20
سنسور دمای DS18B20، یک سنسور دمای دیجیتال تکسیم است؛ به این معنا است که برای اتصال به برد ESP32/ESP8266، فقط به یک خط داده (و زمین) نیاز دارد.
این سنسور میتواند از یک منبع تغذیه خارجی تغذیه شود و یا میتواند از خط داده(data line) تغذیه بگیرد(parasite mode) که نیاز به منبع تغذیه خارجی را برطرف میکند.
هر سنسور دما DS18B20، یک کد سریال ۶۴ بیتی منحصر به فرد دارد. این به شما امکان میدهد که چندین سنسور را به یک سیم داده یکسان وصل کنید. بنابراین شما میتوانید تنها با یک GPIO دما را از چند سنسور بگیرید.
سنسور دما DS18B20 در ورژن ضد آب نیز موجود است.
در اینجا خلاصهای از مرتبط ترین مشخصات سنسور دما DS18B20 آورده شده است:
- قابلیت ارتباط یک سیمه
- رنج منبع تغدیه: ۳ ولت تا ۵.۵ ولت
- رنج دمای کار: ۵۵- درجه سانتیگراد تا ۱۲۵ درجه سانتیگراد
- دقت: ۰.۵ -/+ درجه سانتیگراد (بین ۱۰- درجه سانتیگراد تا ۸۵ درجه سانتیگراد)
قطعات مورد نیاز
برای دنبال کردن این آموزش، به قطعات زیر احتیاج دارید:
ESP32 یا ESP8266
سنسور دما DS18B20 (یک یا چند سنسور)
مقاومت ۴.۷ کیلواهم
سیم جامپر
بردبرد
شماتیک ESP32
همانطور که قبلا هم اشاره شد، سنسور دما DS18B20 میتواند از طریق پین VDD تغذیه شود (normal mode) و یا میتواند از خط داده تغذیه شود (parasite mode). شما میتوانید هر کدام از دو حالت را انتخاب کنید.
اگر از ESP32 استفاده میکنید، یک از دو دیاگرام شماتیک زیر را دنبال کنید.
مود پارازیت (Parasite Mode)
مود نرمال (Normal Mode)
شماتیک ESP8266
اگر از ESP8266 استفاده میکنید، یک از دو دیاگرام شماتیک زیر را دنبال کنید.
مود پارازیت (Parasite Mode)
مود نرمال (Normal Mode)
توجه: در این آموزش، ما خط داده DS18B20 را به GPIO 4 وصل کردیم؛ اما شما میتوانید از هر GPIO مناسب دیگری استفاده کنید.
کد (یک سنسور DS18B20)
کد زیر را در main.py کپی کنید و آن را در برد آپلود کنید. این کد به آسانی دما را از سنسور دمای DS18B20 میگیرد و مقادیر خوانده شده را صفحه Shell نمایش میدهد.
import machine, onewire, ds18x20, time
ds_pin = machine.Pin(4)
ds_sensor = ds18x20.DS18X20(onewire.OneWire(ds_pin))
roms = ds_sensor.scan()
print('Found DS devices: ', roms)
while True:
ds_sensor.convert_temp()
time.sleep_ms(750)
for rom in roms:
print(rom)
print(ds_sensor.read_temp(rom))
time.sleep(5)
این کد برای ESP32 و ESP8266 و برای یک یا چند سنسور دما کار میکند.
کد چگونه کار میکند
برای ارتباط با GPIOها ماژول machine ، برای ارتباط با DS18B20 ماژول onewire و ds18x20 و برای تاخیر ماژول time را وارد کنید.
import machine, onewire, ds18x20, time
یک متغیر با نام ds_pin بسازید که به GPIO 4، همان پینی که به سیم داده سنسور DS18B20 وصل است، اشاره میکند.
ds_pin = machine.Pin(4)
در اینجا ما دما را از GPIO 4 میخوانیم، اما شما میتوانید از هر GPIO مناسب دیگری استفاده کنید.
سپس یک آبجکت ds18x20 با نام ds_sensor در ds_pin (که قبلتر تعریف شده است) ایجاد کنید.
ds_sensor = ds18x20.DS18X20(onewire.OneWire(ds_pin))
DS18B20 از طریق پروتکل ارتباطی یک سیمه ارتباط برقرار میکند و هر سنسور دارای یک کد سریال ۶۴ بیتی منحصر به فرد است. این به این معناست که شما میتوانید از یک GPIO یکسان، چند سنسور دما را بخوانید.
خط زیر برای اسکن سنسورهای DS18B20 از تابع ()scan استفاده میکند. آدرسهای پیدا شده در متغیر roms ذخیره میشوند.(متغیر roms از نوع list است.)
roms = ds_sensor.scan()
آدرس هر سنسور در صفحه Shell چاپ میشود:
print('Found DS devices: ', roms)
یک حلقه while داریم که هر ۵ ثانیه، دما را از سنسور(های) DS18B20 میگیرد.
هر وقت که بخواهید از دما نمونه برداری کنید، نیاز دارید که تابع ()convert_temp در آبجکت ds_sensor را فراخوانی کنید.
ds_sensor.convert_temp()
برای اینکه فرصت کافی برای تبدیل دما وجود داشته باشد، یک تاخیر ۷۵۰ میلی ثانیهای اضافه کنید.
time.sleep_ms(750)
با استفاده از متد ()read_temp میتوانید دما را از آدرسهای پیدا شده بخوانید. همانطور که در خط زیر آمده است، آدرس را به عنوان آرگومان ارسال کنید.
print(ds_sensor.read_temp(rom))
چون میتوان چند سنسور را به یک خط داده اضافه کرد، از حلقه for استفاده میکنیم که به همه آدرسها برود و دمای هر کدام را چاپ کند:
for rom in roms:
print(rom)
print(ds_sensor.read_temp(rom))
نمایش عملی
بعد از آپلود کد در بردتان، هر ۵ ثانیه دماهای جدید خوانده شده را باید بگیرید.
گرفتن دما از چند سنسور دما DS18B20
برای گرفتن دما از چند سنسور DS18B20، میتوانید از همان کد قبلی استفاده کنید؛ فقط نیاز دارید که سنسورهای DS18B20 بیشتری را وصل کنید. این سنسورها خط داده یکسانی دارند. در این حالت، همه سنسورها به GPIO 4 متصل میشوند.
اگر از ESP32 استفاده میکنید، از دیاگرام شماتیک زیر استفاده کنید.
و اگر از ESP8266 استفاده میکنید، از دیاگرام شماتیک زیر استفاده کنید.
کد (چند سنسور دما DS18B20)
بعد از آپلود کد، شما باید تمام دماهای خوانده شده را بگیرید.
import machine, onewire, ds18x20, time
ds_pin = machine.Pin(4)
ds_sensor = ds18x20.DS18X20(onewire.OneWire(ds_pin))
roms = ds_sensor.scan()
print('Found DS devices: ', roms)
while True:
ds_sensor.convert_temp()
time.sleep_ms(750)
for rom in roms:
print(rom)
print(ds_sensor.read_temp(rom))
time.sleep(5)
نمایش دماهای خوانده شده از سنسور DS18B20 در وب سرور
اکنون که میدانید چگونه میتوانید دما و رطوبت را از سنسورهای DS18B20 دریافت کنید، خواندن دماها را در وب سرور نمایش میدهیم که میتوانید در شبکه محلی خود به آنها دسترسی پیدا کنید.
برای این مثال، به فایلهای زیر احتیاج دارید:
boot.py: زمانی اجرا میشود که دستگاه شروع به کار کند و چندین گزینه پیکرهبندی را مانند اعتبارنامه شبکهتان، وارد کردن کتابخانهها،تنظیمات پینها و… تنظیم میکند.
main.py: این اسکریپت اصلی است که در آن وب سرور را مدیریت میکنیم این فایل بلافاصله بعد از boot.py اجرا میشود.
توجه: تمرین خوبی است که دو فایل boot.py و main.py را داشته باشد، هرچند که میتوانید تمام کد را در فایل main.py جا دهید.
boot.py (وب سرور DS18B20)
یک فایل جدید با نام boot.py در IDE ایجاد کنید و فایل زیر را در آن کپی کنید:
try:
import usocket as socket
except:
import socket
from time import sleep
from machine import Pin
import onewire, ds18x20
import network
import esp
esp.osdebug(None)
import gc
gc.collect()
ds_pin = Pin(4)
ds_sensor = ds18x20.DS18X20(onewire.OneWire(ds_pin))
ssid = 'REPLACE_WITH_YOUR_SSID'
password = 'REPLACE_WITH_YOUR_PASSWORD'
station = network.WLAN(network.STA_IF)
station.active(True)
station.connect(ssid, password)
while station.isconnected() == False:
pass
print('Connection successful')
print(station.ifconfig())
این فایل کتابخانههای لازم را وارد میکند، سنسور DS18B20 را تنظیم میکند و به شبکهتان وصل میکند.
اینجا ما پین داده DS18B20 را روی GPIO 4 تنظیم میکنیم.(شما میتوانید از هر پین مناسب دیگری استفاده کنید.)
ds_pin = Pin(4)
ds_sensor = ds18x20.DS18X20(onewire.OneWire(ds_pin))
شما باید اعتبارنامههای شبکهتان را در متغیرهای زیر وارد کنید تا ESP بتواند به شبکه شما وصل شود.
ssid = 'REPLACE_WITH_YOUR_SSID'
password = 'REPLACE_WITH_YOUR_PASSWORD'
main.py (وب سرور DS18B20)
در فایل main.py جایی است که ما وب سرور را ایجاد کرده و درخواستها را مدیریت میکنیم. کد زیر را در فایل main.py کپی کنید.
def read_ds_sensor():
roms = ds_sensor.scan()
print('Found DS devices: ', roms)
print('Temperatures: ')
ds_sensor.convert_temp()
for rom in roms:
temp = ds_sensor.read_temp(rom)
if isinstance(temp, float):
msg = round(temp, 2)
print(temp, end=' ')
print('Valid temperature')
return msg
return b'0.0'
def web_page():
temp = read_ds_sensor()
html = """<!DOCTYPE HTML><html><head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.7.2/css/all.css" integrity="sha384-fnmOCqbTlWIlj8LyTjo7mOUStjsKC4pOpQbqyi7RrhN7udi9RwhKkMHpvLbHG9Sr" crossorigin="anonymous">
<style> html { font-family: Arial; display: inline-block; margin: 0px auto; text-align: center; }
h2 { font-size: 3.0rem; } p { font-size: 3.0rem; } .units { font-size: 1.2rem; }
.ds-labels{ font-size: 1.5rem; vertical-align:middle; padding-bottom: 15px; }
</style></head><body><h2>ESP with DS18B20</h2>
<p><i class="fas fa-thermometer-half" style="color:#059e8a;"></i>
<span class="ds-labels">Temperature</span>
<span id="temperature">""" + str(temp) + """</span>
<sup class="units">°C</sup>
</p>
<p><i class="fas fa-thermometer-half" style="color:#059e8a;"></i>
<span class="ds-labels">Temperature</span>
<span id="temperature">""" + str(round(temp * (9/5) + 32.0, 2)) + """</span>
<sup class="units">°F</sup>
</p></body></html>"""
return html
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind(('', 80))
s.listen(5)
while True:
try:
if gc.mem_free() < 102000:
gc.collect()
conn, addr = s.accept()
conn.settimeout(3.0)
print('Got a connection from %s' % str(addr))
request = conn.recv(1024)
conn.settimeout(None)
request = str(request)
print('Content = %s' % request)
response = web_page()
conn.send('HTTP/1.1 200 OK\n')
conn.send('Content-Type: text/html\n')
conn.send('Connection: close\n\n')
conn.sendall(response)
conn.close()
except OSError as e:
conn.close()
print('Connection closed')
خواندن سنسور DS18B20
کد با ایجاد تابعی که ()read_ds_sensor نامیده میشود، شروع میشود که دما را از سنسور DS18B20 میگیرد. گر قسمت قبلی را دنبال کرده باشید، با متدهای استفاده شده در این بخش، آشنایی خواهید داشت:
def read_ds_sensor():
roms = ds_sensor.scan()
print('Found DS devices: ', roms)
ds_sensor.convert_temp()
for rom in roms:
temp = ds_sensor.read_temp(rom)
if isinstance(temp, float):
temp = round(temp, 2)
print('Valid temperature')
return temp
return '0'
Web Page
تابع ()web_page صفحه HTML را با آخرین دماهای خوانده شده برمیگرداند.
ایجاد وب سرور
پس از آن، روشهای معمول برای ایجاد یک socket server را انجام دهید.
while True:
try:
if gc.mem_free() < 102000:
gc.collect()
conn, addr = s.accept()
conn.settimeout(3.0)
print('Got a connection from %s' % str(addr))
request = conn.recv(1024)
conn.settimeout(None)
request = str(request)
print('Content = %s' % request)
response = web_page()
conn.send('HTTP/1.1 200 OK\n')
conn.send('Content-Type: text/html\n')
conn.send('Connection: close\n\n')
conn.sendall(response)
conn.close()
except OSError as e:
conn.close()
print('Connection closed')
اساسا هنگامی که ESP درخواستی را دریافت میکند، ما به عنوان پاسخ، صفحه وب را با آخرین مقادیر خوانده شده، ارسال میکنیم.
response = web_page()
conn.send('HTTP/1.1 200 OK\n')
conn.send('Content-Type: text/html\n')
conn.send('Connection: close\n\n')
conn.sendall(response)
نمایش وب سرور
بعد از آپلود فایلهای main,py و boot.py در بردتان، بر روی ESP RST کلیک کنید تا کد اجرا شود.
سپس مرورگر خود را باز کنید و آدرس ESP IP را تایپ کنید. شما باید به صفحه وب با آخرین مقادیر خوانده شده از سنسور برحسب درجه سلسیوس و فارنهایت، دسترسی داشته باشید.