وبلاگ
پیادهسازی پروتکل MQTT برای اینترنت اشیا (IoT) با MicroPython در Vscode
فهرست مطالب
“تسلط به برنامهنویسی پایتون با هوش مصنوعی: آموزش کدنویسی هوشمند با ChatGPT”
"تسلط به برنامهنویسی پایتون با هوش مصنوعی: آموزش کدنویسی هوشمند با ChatGPT"
"با شرکت در این دوره جامع و کاربردی، به راحتی مهارتهای برنامهنویسی پایتون را از سطح مبتدی تا پیشرفته با کمک هوش مصنوعی ChatGPT بیاموزید. این دوره، با بیش از 6 ساعت محتوای آموزشی، شما را قادر میسازد تا به سرعت الگوریتمهای پیچیده را درک کرده و اپلیکیشنهای هوشمند ایجاد کنید. مناسب برای تمامی سطوح با زیرنویس فارسی حرفهای و امکان دانلود و تماشای آنلاین."
ویژگیهای کلیدی:
بدون نیاز به تجربه قبلی برنامهنویسی
زیرنویس فارسی با ترجمه حرفهای
۳۰ ٪ تخفیف ویژه برای دانشجویان و دانش آموزان
0 تا 100 عطرسازی + (30 فرمولاسیون اختصاصی حامی صنعت)
دوره آموزش Flutter و برنامه نویسی Dart [پروژه محور]
دوره جامع آموزش برنامهنویسی پایتون + هک اخلاقی [با همکاری شاهک]
دوره جامع آموزش فرمولاسیون لوازم آرایشی
دوره جامع علم داده، یادگیری ماشین، یادگیری عمیق و NLP
دوره فوق فشرده مکالمه زبان انگلیسی (ویژه بزرگسالان)
شمع سازی و عودسازی با محوریت رایحه درمانی
صابون سازی (دستساز و صنعتی)
صفر تا صد طراحی دارو
متخصص طب سنتی و گیاهان دارویی
متخصص کنترل کیفی شرکت دارویی
مقدمه: پیوند قدرت MQTT و MicroPython در بستر VSCode برای اینترنت اشیا
در دنیای پرشتاب و همواره در حال تحول اینترنت اشیا (IoT)، نیاز به پروتکلهای ارتباطی کارآمد و سبکوزن برای دستگاههای محدود از نظر منابع، بیش از پیش احساس میشود. پروتکل MQTT (Message Queuing Telemetry Transport) به دلیل سادگی، قابلیت اطمینان و مصرف بهینه پهنای باند و انرژی، به استاندارد طلایی برای ارتباطات IoT تبدیل شده است. از سوی دیگر، ظهور MicroPython، یک پیادهسازی از زبان برنامهنویسی پایتون برای میکروکنترلرها، انقلابی در توسعه دستگاههای IoT ایجاد کرده است. MicroPython با ارائه سادگی و قدرت پایتون در سختافزارهای کوچک، امکان نمونهسازی سریع و توسعه آسانتر را برای مهندسان و توسعهدهندگان فراهم آورده است.
این پست جامع، سفری عمیق به دنیای پیادهسازی پروتکل MQTT با MicroPython را ارائه میدهد و از محیط توسعه قدرتمند VSCode به عنوان بستر اصلی برای این فرآیند بهره میبرد. هدف ما این است که نه تنها شما را با مفاهیم نظری این تکنولوژیها آشنا کنیم، بلکه راهنمایی گام به گام و عملی برای راهاندازی، کدنویسی و بهینهسازی پروژههای IoT خود ارائه دهیم. ما به تفصیل به بررسی جوانب مختلف از درک پروتکل MQTT، راهاندازی محیط توسعه VSCode، پیادهسازی کلاینت MQTT بر روی بردهای MicroPython مانند ESP32 و ESP8266، و در نهایت پرداختن به بهینهسازیها، ملاحظات امنیتی و چالشهای پیشرفته خواهیم پرداخت. این راهنما برای توسعهدهندگان، مهندسان و علاقهمندان به IoT که به دنبال افزایش دانش و مهارتهای عملی خود در این حوزه هستند، طراحی شده است تا بتوانند از قدرت این ترکیب در پروژههای واقعی خود نهایت بهره را ببرند. با ما همراه باشید تا معماریهای پیچیده IoT را با استفاده از ابزارهای قدرتمند و کارآمد سادهسازی کنیم.
درک پروتکل MQTT: ستون فقرات ارتباطات IoT
پروتکل MQTT (Message Queuing Telemetry Transport) یک پروتکل پیامرسانی سبک، باز و انتشار/اشتراک (Publish/Subscribe) است که به طور خاص برای محیطهایی با پهنای باند محدود و دستگاههایی با منابع محاسباتی پایین طراحی شده است. این پروتکل که در ابتدا توسط IBM توسعه یافت، به سرعت به یکی از پرکاربردترین پروتکلها در زمینه اینترنت اشیا تبدیل شد و دلیل اصلی این محبوبیت، کارایی بالا و سادگی آن است. MQTT بر پایه TCP/IP عمل میکند و امکان برقراری ارتباط پایدار و قابل اعتماد بین دستگاههای مختلف را فراهم میآورد. این پروتکل برای انتقال دادههای تلهمتری (مانند خوانش سنسورها) در شبکههایی که قابلیت اطمینان و حفظ منابع از اهمیت بالایی برخوردار است، ایدهآل است. در ادامه، به بررسی عمیقتر مفاهیم کلیدی و مزایای MQTT میپردازیم.
MQTT چیست و چرا برای IoT مناسب است؟
در هسته خود، MQTT یک پروتکل پیامرسانی است که از الگوی انتشار/اشتراک استفاده میکند. این بدان معناست که به جای ارتباط مستقیم فرستنده و گیرنده (مانند مدل کلاینت/سرور)، یک واسطه به نام “بروکر” (Broker) وجود دارد که مسئول مسیریابی پیامها است. این معماری عدم اتصال (decoupled architecture) مزایای بسیاری دارد، از جمله:
- کاهش وابستگی: فرستندهها (Publishers) و گیرندهها (Subscribers) نیازی به دانستن موقعیت یکدیگر ندارند و فقط با بروکر در ارتباط هستند.
- مقیاسپذیری بالا: یک بروکر میتواند هزاران کلاینت را مدیریت کند و به راحتی امکان افزودن دستگاههای جدید را فراهم میکند.
- کارایی بالا: هدر (header) پیامهای MQTT بسیار کوچک است (معمولاً 2 بایت)، که منجر به کاهش مصرف پهنای باند و انرژی میشود.
این ویژگیها MQTT را به گزینهای ایدهآل برای اینترنت اشیا تبدیل کرده است، جایی که دستگاهها معمولاً منابع محدودی دارند (باتری، پردازنده، حافظه) و نیاز به ارسال دادههای کوچک به صورت مکرر دارند.
مفاهیم کلیدی MQTT: بروکر، کلاینت، تاپیک و QoS
برای درک کامل MQTT، آشنایی با مفاهیم زیر ضروری است:
- بروکر (Broker): قلب شبکه MQTT است. بروکر مسئول دریافت پیامها از منتشرکنندگان، فیلتر کردن آنها بر اساس تاپیکها و ارسال آنها به مشترکین مربوطه است. بروکرها میتوانند نرمافزارهایی مانند Mosquitto، HiveMQ یا سرویسهای ابری مانند AWS IoT Core باشند.
- کلاینت (Client): هر دستگاهی که به بروکر متصل میشود، یک کلاینت MQTT نامیده میشود. این میتواند یک سنسور، یک عملگر، یک برنامه موبایل یا یک سرور باشد. کلاینتها میتوانند هم منتشرکننده و هم مشترک باشند.
- تاپیک (Topic): یک رشته متنی است که بروکر از آن برای فیلتر کردن پیامها استفاده میکند. تاپیکها سلسله مراتبی هستند و با اسلش (/) جدا میشوند (مثال:
home/livingroom/temperature). کلاینتها میتوانند در تاپیکهای خاصی مشترک شوند یا پیامهایی را در آنها منتشر کنند. - انتشار (Publish): عملیاتی است که یک کلاینت پیامی را به یک تاپیک خاص بر روی بروکر ارسال میکند.
- اشتراک (Subscribe): عملیاتی است که یک کلاینت علاقه خود را به دریافت پیامها از یک یا چند تاپیک خاص به بروکر اعلام میکند.
- کیفیت سرویس (Quality of Service – QoS): MQTT سه سطح QoS را ارائه میدهد که میزان تضمین تحویل پیام را مشخص میکند:
- QoS 0 (At Most Once): پیام حداکثر یک بار تحویل داده میشود، بدون تضمین رسیدن یا عدم تکرار. کمترین سربار و بیشترین کارایی.
- QoS 1 (At Least Once): پیام حداقل یک بار تحویل داده میشود. اگر پیام به مقصد نرسد، دوباره ارسال میشود، که ممکن است منجر به دریافت تکراری شود.
- QoS 2 (Exactly Once): پیام دقیقاً یک بار تحویل داده میشود. این سطح بالاترین تضمین را دارد اما با سربار بیشتری همراه است.
- پیام ماندگار (Retain Message): یک پرچم در پیام منتشر شده است که به بروکر دستور میدهد آخرین پیام منتشر شده در یک تاپیک را برای مشترکین جدیدی که بعداً به آن تاپیک ملحق میشوند، ذخیره و ارسال کند.
- وصیتنامه آخر (Last Will and Testament – LWT): پیامی است که کلاینت هنگام اتصال به بروکر مشخص میکند. اگر کلاینت به طور غیرمنتظره قطع شود، بروکر این پیام را در یک تاپیک مشخص منتشر میکند تا سایر کلاینتها از وضعیت قطع اتصال مطلع شوند.
مزایای MQTT برای IoT: کارایی، پایداری و انعطافپذیری
مزایای استفاده از MQTT در پروژههای IoT بسیار گسترده است:
- مصرف پهنای باند پایین: هدر کوچک پیامها و استفاده کارآمد از TCP/IP، مصرف پهنای باند را به حداقل میرساند که برای شبکههای با ظرفیت محدود یا پرهزینه بسیار مهم است.
- مصرف انرژی کم: به دلیل سربار کم و امکان استفاده از حالتهای خواب (sleep modes) برای دستگاهها، عمر باتری دستگاههای IoT به میزان قابل توجهی افزایش مییابد.
- قابلیت اطمینان: سطوح مختلف QoS تضمین میکند که پیامها با سطح اطمینان مورد نیاز تحویل داده شوند، حتی در شبکههای ناپایدار. قابلیت LWT نیز به نظارت بر وضعیت دستگاهها کمک میکند.
- مقیاسپذیری بالا: معماری بروکر-محور به راحتی امکان مدیریت هزاران (و حتی میلیونها) دستگاه را فراهم میکند.
- امنیت: MQTT میتواند از TLS/SSL برای رمزگذاری ارتباطات و احراز هویت با نام کاربری/گذرواژه برای کنترل دسترسی استفاده کند.
- سادگی پیادهسازی: پروتکل نسبتاً سادهای دارد و کتابخانههای کلاینت متعددی برای زبانهای مختلف برنامهنویسی موجود است، از جمله MicroPython.
با درک این اصول، میتوانیم گام بعدی را برداریم و به سمت پیادهسازی عملی با MicroPython حرکت کنیم، جایی که این مزایا در دنیای واقعی به کار گرفته میشوند.
MicroPython: انتخابی هوشمند برای سختافزارهای محدود در IoT
در قلب توسعه IoT، انتخاب زبان و محیط برنامهنویسی مناسب برای میکروکنترلرها، اهمیت بسزایی دارد. MicroPython به عنوان یک پیادهسازی کامل و بهینه از زبان پایتون 3، به طور خاص برای اجرا بر روی میکروکنترلرهای کممصرف و با منابع محدود طراحی شده است. این زبان، پلی بین سادگی و قدرت پایتون و محدودیتهای سختافزارهای امبدد (embedded) ایجاد میکند و به توسعهدهندگان این امکان را میدهد که با سرعت و کارایی بالا، پروژههای IoT خود را از ایده به واقعیت تبدیل کنند. در ادامه به معرفی MicroPython، مزایای آن برای IoT و محدودیتهایی که باید در نظر گرفت، میپردازیم.
معرفی MicroPython: پایتون در دنیای میکروکنترلرها
MicroPython یک کامپایلر و رانتایم (runtime) پایتون است که تقریباً تمام ویژگیهای پایتون استاندارد را حفظ میکند اما با بهینهسازیهایی برای کاهش مصرف حافظه و فضای ذخیرهسازی. این بدان معناست که شما میتوانید کدهای پایتون را مستقیماً بر روی سختافزارهایی مانند ESP32، ESP8266، Raspberry Pi Pico (RP2040) و بسیاری دیگر از بردهای مبتنی بر میکروکنترلر اجرا کنید. هدف اصلی MicroPython ارائه یک تجربه برنامهنویسی پایتونیک در محیطهای محدود است، که با حذف یا بهینهسازی برخی از ماژولهای پایتون استاندارد و افزودن ماژولهای خاص سختافزار (مانند machine برای کنترل GPIOها، ADC، I2C، SPI و …)، به این هدف دست یافته است.
یکی از بزرگترین مزایای MicroPython این است که توسعهدهندگان میتوانند از تمام دانش و ابزارهای اکوسیستم پایتون، مانند IDEها، کتابخانهها و رویکردهای شیگرا، در توسعه سختافزار استفاده کنند. این امر به ویژه برای کسانی که از قبل با پایتون آشنا هستند، منحنی یادگیری را به شدت کاهش میدهد و امکان نمونهسازی سریع (rapid prototyping) را فراهم میآورد. به جای درگیر شدن با پیچیدگیهای C/C++ و محیطهای توسعه میکروکنترلری سنتی، MicroPython به شما اجازه میدهد تا بر روی منطق کاربردی پروژه خود تمرکز کنید.
چرا MicroPython برای IoT؟ سادگی، سرعت و جامعه فعال
دلایل متعددی وجود دارد که MicroPython را به یک انتخاب جذاب برای پروژههای IoT تبدیل کرده است:
- سادگی و خوانایی کد: پایتون به دلیل سینتکس ساده و خوانا شناخته شده است. این ویژگی به توسعهدهندگان کمک میکند تا کدهای کمتری بنویسند و نگهداری از آنها آسانتر باشد. این مزیت به ویژه در پروژههای IoT که اغلب شامل تعامل با سنسورها و عملگرهای متعدد هستند، بسیار ارزشمند است.
- نمونهسازی سریع (Rapid Prototyping): با MicroPython، میتوانید ایدههای خود را به سرعت تست و پیادهسازی کنید. نیازی به کامپایل مجدد کامل پروژه برای هر تغییر نیست؛ کافی است فایل
.pyرا بر روی بورد آپلود کرده و اجرا کنید. این سرعت توسعه، زمان رسیدن به بازار را برای محصولات IoT به شدت کاهش میدهد. - اکوسیستم غنی: اگرچه MicroPython یک زیرمجموعه از پایتون است، اما از بسیاری از الگوها و کتابخانههای پایتون استاندارد بهره میبرد. علاوه بر این، جامعه فعال MicroPython، کتابخانههای خاص سختافزاری و پروتکلهای ارتباطی (مانند
umqttبرای MQTT) را توسعه داده است که کار با IoT را بسیار آسانتر میکند. - پشتیبانی از سختافزارهای محبوب: MicroPython از طیف وسیعی از میکروکنترلرهای پرکاربرد در IoT پشتیبانی میکند، از جمله خانواده ESP (ESP32، ESP8266) و RP2040. این بردها با قابلیتهای Wi-Fi و بلوتوث داخلی، گزینههای عالی برای پروژههای متصل هستند.
- اشکالزدایی (Debugging) آسانتر: محیطهای توسعه مدرن مانند VSCode با افزونههای MicroPython، ابزارهای اشکالزدایی را فراهم میکنند که میتوانند به طور مستقیم با بورد ارتباط برقرار کرده و فرآیند عیبیابی را سادهتر کنند.
محدودیتها و چالشها: مدیریت منابع
با وجود تمام مزایا، MicroPython نیز با محدودیتهایی همراه است که باید در نظر گرفته شوند:
- مصرف حافظه (RAM): اگرچه MicroPython بهینه شده است، اما پایتون به طور کلی نسبت به زبانهایی مانند C/C++ مصرف حافظه بیشتری دارد. در بردهایی با حافظه RAM بسیار محدود (مانند 64KB یا کمتر)، ممکن است با مشکلاتی در اجرای کدهای پیچیده یا استفاده از کتابخانههای سنگین مواجه شوید.
- فضای ذخیرهسازی (Flash Memory): فایل سیستم MicroPython بر روی حافظه فلش بورد قرار میگیرد. اگرچه بردهای مدرن مانند ESP32 دارای چندین مگابایت فلش هستند، اما برای پروژههای بسیار بزرگ یا با نیاز به ذخیرهسازی حجم زیادی از داده، ممکن است محدودیتهایی وجود داشته باشد.
- سرعت پردازش: پایتون یک زبان تفسیر شده است و معمولاً کندتر از کدهای کامپایل شده C/C++ اجرا میشود. برای وظایف زمانبندی دقیق (real-time) یا محاسبات سنگین، MicroPython ممکن است انتخاب مناسبی نباشد. با این حال، برای اکثر کاربردهای IoT (مانند خواندن سنسور و ارسال داده)، سرعت MicroPython کاملاً کافی است.
- عدم دسترسی مستقیم به همه رجیسترها: اگرچه ماژول
machineدسترسی خوبی به سختافزار فراهم میکند، اما برای کنترل بسیار دقیق و low-level رجیسترهای میکروکنترلر که در C/C++ امکانپذیر است، در MicroPython ممکن است نیاز به راهحلهای جایگزین یا ماژولهای سفارشی داشته باشید.
با آگاهی از این محدودیتها، میتوان پروژههای MicroPython را به گونهای طراحی کرد که از نقاط قوت آن بهرهمند شده و چالشهای احتمالی را به حداقل برساند. در بخش بعدی، به راهاندازی محیط توسعه VSCode خواهیم پرداخت تا بتوانیم به صورت عملی شروع به کار کنیم.
راهاندازی محیط توسعه VSCode برای MicroPython
برای شروع توسعه پروژههای MicroPython و MQTT، نیاز به یک محیط توسعه یکپارچه (IDE) قدرتمند و کارآمد داریم. VSCode (Visual Studio Code) به دلیل سبکی، انعطافپذیری، پشتیبانی عالی از افزونهها و جامعه کاربری بزرگ، به یکی از محبوبترین انتخابها در میان توسعهدهندگان تبدیل شده است. در این بخش، به طور کامل نحوه راهاندازی VSCode برای توسعه MicroPython را بررسی میکنیم، از نصب پیشنیازها گرفته تا پیکربندی بورد و افزونههای مورد نیاز.
پیشنیازها: ابزارهای اساسی برای شروع
قبل از نصب VSCode و افزونههای آن، اطمینان حاصل کنید که ابزارهای زیر بر روی سیستم عامل شما (ویندوز، مک، لینوکس) نصب شدهاند:
- پایتون 3 (Python 3): MicroPython بر اساس پایتون 3 است. مطمئن شوید که پایتون 3 و مدیر بسته آن،
pip، بر روی سیستم شما نصب شدهاند و در PATH سیستم قابل دسترسی هستند. میتوانید آن را از وبسایت رسمی پایتون دانلود کنید.python --version pip --version - esptool: این ابزار خط فرمان برای فلش کردن (flash) فریمور MicroPython بر روی بردهای ESP8266 و ESP32 استفاده میشود.
pip install esptool - ampy (Adafruit MicroPython Tool):
ampyابزاری مفید برای مدیریت فایلها بر روی بورد MicroPython از طریق خط فرمان است. این ابزار به شما امکان آپلود، دانلود، حذف و اجرای فایلها را میدهد.pip install adafruit-ampy - drivers for your board: بسته به نوع بورد MicroPython شما (مثلاً ESP32 Dev Kit، NodeMCU، Feather)، ممکن است نیاز به نصب درایورهای USB به سریال (مانند CP210x یا CH340) داشته باشید تا کامپیوتر شما بتواند با بورد ارتباط برقرار کند. این درایورها معمولاً با جستجو برای “CP210x driver” یا “CH340 driver” قابل یافتن هستند.
نصب VSCode و افزونههای مرتبط
- نصب VSCode:
VSCode را از وبسایت رسمی code.visualstudio.com دانلود و نصب کنید. مراحل نصب بسیار ساده و سرراست هستند. - نصب افزونههای ضروری:
پس از نصب VSCode، آن را باز کرده و به بخش Extensions (با آیکون مربعها در نوار کناری چپ) بروید و افزونههای زیر را جستجو و نصب کنید:- Python (توسط Microsoft): این افزونه پشتیبانی کامل از زبان پایتون، از جمله IntelliSense، اشکالزدایی و مدیریت محیطهای مجازی را فراهم میکند.
- Pylance (توسط Microsoft): Pylance یک افزونه پیشرفته برای پشتیبانی از زبان پایتون است که تکمیل کد سریعتر، تحلیل استاتیک پیشرفتهتر و پیشنهادات بهتر را ارائه میدهد.
- MicroPython (توسط Tommy Chiang): این افزونه به طور خاص برای توسعه MicroPython طراحی شده است و قابلیتهایی مانند آپلود فایل، اجرای کد، نظارت بر پورت سریال و یک کنسول تعاملی (REPL) را فراهم میکند. این افزونه کار با MicroPython را در VSCode بسیار ساده میکند و جایگزین مناسبی برای افزونههای قدیمیتر مانند Pymakr است.
پیکربندی بورد MicroPython: فلش کردن فریمور
قبل از اینکه بتوانید کدهای MicroPython را اجرا کنید، بورد شما باید با فریمور MicroPython فلش شود. این فرآیند معمولاً یک بار انجام میشود:
- دانلود فریمور: جدیدترین فریمور MicroPython را برای بورد خود (مثلاً
esp32-xxxx.binیاesp8266-xxxx.bin) از وبسایت رسمی micropython.org/download/ دانلود کنید. - پاک کردن فلش بورد (اختیاری اما توصیه شده): این کار اطمینان حاصل میکند که هیچ دادهی قدیمی یا خراب شدهای روی بورد باقی نمانده باشد.
esptool.py --port COMx erase_flash(
COMxرا با پورت سریال بورد خود جایگزین کنید، مثلاًCOM3در ویندوز یا/dev/ttyUSB0در لینوکس/مک) - فلش کردن فریمور:
esptool.py --port COMx --baud 460800 write_flash --flash_size=detect 0x1000 YOUR_FIRMWARE.bin(
YOUR_FIRMWARE.binرا با نام فایل فریمور دانلود شده جایگزین کنید. سرعت460800برای فلش کردن سریعتر است، اما میتوانید از115200نیز استفاده کنید اگر با مشکل مواجه شدید.)
پس از فلش موفقیتآمیز، بورد شما آماده دریافت کدهای MicroPython است. میتوانید با استفاده از یک ابزار ترمینال سریال (مثل PuTTY یا ترمینال داخلی VSCode) به بورد متصل شوید و با فشردن کلید Enter، وارد REPL (Read-Eval-Print Loop) شوید و پیام >>> را مشاهده کنید.
تنظیمات اولیه VSCode برای MicroPython
با نصب افزونه MicroPython، باید آن را برای ارتباط با بورد خود پیکربندی کنید:
- انتخاب پورت سریال:
در پایین نوار وضعیت VSCode، گزینهای به نام “MicroPython” (یا آیکون پلاگین) را مشاهده خواهید کرد. روی آن کلیک کنید یا بهCtrl+Shift+P(یاCmd+Shift+Pدر مک) بروید و “MicroPython: Select Port” را جستجو کنید. پورت سریال مربوط به بورد خود را از لیست انتخاب کنید. - تنظیمات پروژه:
یک پوشه جدید برای پروژه MicroPython خود ایجاد کنید و آن را در VSCode باز کنید (File > Open Folder).
سپس، برای تنظیمات افزونه MicroPython، میتوانید یک فایل.vscode/settings.jsonدر ریشه پوشه پروژه خود ایجاد کنید (اگر وجود ندارد) و تنظیمات زیر را اضافه کنید:{ "micropython.port": "COMx", // پورت سریال خود را اینجا وارد کنید "micropython.syncWhenSave": true, // برای آپلود خودکار فایل هنگام ذخیره "micropython.deployOnSave": true // برای اجرای خودکار پس از آپلود }این تنظیمات به افزونه میگوید که از کدام پورت استفاده کند و آیا فایلها را به صورت خودکار هنگام ذخیره به بورد آپلود کند یا خیر. تنظیم
deployOnSaveمیتواند برای تست سریع مفید باشد. - اتصال به REPL:
افزونه MicroPython یک کنسول REPL داخلی را فراهم میکند. میتوانید از طریق نوار وضعیت یا با دستور “MicroPython: Connect” به آن متصل شوید. این کنسول به شما امکان میدهد دستورات پایتون را مستقیماً بر روی بورد اجرا کنید و خروجی را مشاهده کنید، که برای اشکالزدایی و آزمایش سریع بسیار مفید است.
با این پیکربندی، اکنون محیط توسعه شما کاملاً آماده است تا کدهای MicroPython را نوشته، آپلود و اجرا کنید. در بخش بعدی، به سراغ پیادهسازی کلاینت MQTT با MicroPython خواهیم رفت.
پیادهسازی کلاینت MQTT با MicroPython
پس از آمادهسازی محیط توسعه، نوبت به پیادهسازی قلب پروژه، یعنی کلاینت MQTT، میرسد. MicroPython کتابخانههای سبکی را برای ارتباط با بروکر MQTT ارائه میدهد که به راحتی میتوان از آنها در دستگاههای محدود استفاده کرد. در این بخش، به معرفی این کتابخانهها، نحوه نصب آنها و سپس نوشتن کدهای نمونه برای اتصال، انتشار و اشتراک پیامها خواهیم پرداخت.
انتخاب کتابخانه MQTT: umqtt.simple و umqtt.robust
MicroPython دو کتابخانه اصلی برای MQTT ارائه میدهد:
umqtt.simple: این کتابخانه یک پیادهسازی ساده و مینیمال از کلاینت MQTT است. برای کاربردهایی که نیاز به پیچیدگی کمتری دارند و میخواهند مصرف حافظه را به حداقل برسانند، مناسب است. با این حال،umqtt.simpleقابلیت مدیریت خودکار قطع اتصال و تلاش برای اتصال مجدد را ندارد و باید این منطق را به صورت دستی در کد خود پیادهسازی کنید.umqtt.robust: این کتابخانه بر پایهumqtt.simpleساخته شده و قابلیتهای اضافی برای مدیریت خودکار اتصال مجدد (reconnection) در صورت قطع شدن شبکه یا بروکر را فراهم میکند.umqtt.robustبرای پروژههای IoT که نیاز به پایداری بالا و مقاومت در برابر قطعیهای شبکه دارند، توصیه میشود. استفاده از این کتابخانه پیچیدگیهای مدیریت وضعیت اتصال را از دوش توسعهدهنده برمیدارد.
در اکثر سناریوهای واقعی IoT، استفاده از umqtt.robust به دلیل قابلیت اطمینان بالاتر، ارجحیت دارد. با این حال، هر دو کتابخانه از طریق upip (مدیر بسته MicroPython) یا به صورت دستی قابل نصب هستند.
نصب کتابخانه MQTT بر روی بورد
برای استفاده از کتابخانههای MQTT، ابتدا باید آنها را بر روی بورد MicroPython خود نصب کنید. دو روش اصلی برای این کار وجود دارد:
- با استفاده از
upip(اگر بورد دسترسی به اینترنت دارد):
اگر بورد شما به اینترنت متصل است، میتوانید ازupip(MicroPython’s pip) به طور مستقیم از REPL استفاده کنید:import upip upip.install('micropython-umqtt.simple') upip.install('micropython-umqtt.robust')این دستورات فایلهای کتابخانه را دانلود و در پوشه
/libبورد شما نصب میکنند. - نصب دستی با
ampyیا افزونه VSCode:
اگر بورد شما به اینترنت دسترسی ندارد یا ترجیح میدهید کنترل بیشتری داشته باشید، میتوانید فایلهای کتابخانه را به صورت دستی دانلود کرده و به بورد منتقل کنید.- فایلهای
umqtt.simple.pyوumqtt.robust.py(وmqtt.pyکه توسطumqtt.simpleاستفاده میشود) را از مخزن GitHub MicroPython برای MQTT (معمولاً درmicropython-lib/umqtt) دانلود کنید. - سپس، با استفاده از
ampyیا قابلیت “Upload File” در افزونه MicroPython VSCode، این فایلها را به ریشه بورد خود یا در پوشه/libبورد (که باید دستی ایجاد شود) آپلود کنید.ampy -p COMx put umqtt/simple.py ampy -p COMx put umqtt/robust.py ampy -p COMx put umqtt/mqtt.py # اگر umqtt/mqtt.py وجود داردیا از طریق VSCode، روی فایل کلیک راست کرده و “MicroPython: Upload File” را انتخاب کنید.
- فایلهای
نمونه کد: اتصال به Wi-Fi
قبل از برقراری ارتباط MQTT، بورد MicroPython شما باید به شبکه Wi-Fi متصل شود. کد زیر یک مثال اساسی برای اتصال ESP32/ESP8266 به Wi-Fi است:
# main.py
import network
import time
# اطلاعات شبکه Wi-Fi خود را اینجا وارد کنید
WIFI_SSID = "Your_WiFi_SSID"
WIFI_PASSWORD = "Your_WiFi_Password"
def connect_wifi(ssid, password):
sta_if = network.WLAN(network.STA_IF)
if not sta_if.isconnected():
print("Connecting to network...")
sta_if.active(True)
sta_if.connect(ssid, password)
# منتظر بمانید تا اتصال برقرار شود
max_wait = 10
while max_wait > 0:
if sta_if.isconnected():
break
max_wait -= 1
print("Waiting for connection...")
time.sleep(1)
if sta_if.isconnected():
print("Network config:", sta_if.ifconfig())
print("Connected to Wi-Fi successfully!")
return True
else:
print("Failed to connect to Wi-Fi.")
return False
# فراخوانی تابع اتصال
# connect_wifi(WIFI_SSID, WIFI_PASSWORD)
# بقیه کد MQTT در ادامه این تابع قرار میگیرد
این کد را میتوانید در فایل boot.py (برای اجرای خودکار در هنگام راهاندازی) یا در ابتدای فایل اصلی پروژه خود قرار دهید.
نمونه کد: اتصال به بروکر MQTT
پس از اتصال به Wi-Fi، نوبت به اتصال به بروکر MQTT میرسد. از کتابخانه umqtt.robust برای پایداری بیشتر استفاده میکنیم:
# ادامه main.py پس از تابع connect_wifi
from umqtt.robust import MQTTClient
import machine
# اطلاعات بروکر MQTT
MQTT_BROKER = "broker.hivemq.com" # یا آدرس IP/دامنه بروکر خودتان
MQTT_PORT = 1883 # پورت استاندارد MQTT
MQTT_CLIENT_ID = b"esp32_client_123" # شناسه منحصر به فرد کلاینت (بایت استرینگ)
# اگر بروکر نیاز به نام کاربری و رمز عبور دارد
MQTT_USER = b"your_mqtt_username"
MQTT_PASSWORD = b"your_mqtt_password"
# تابع برای اتصال به بروکر
def mqtt_connect():
global client
client = MQTTClient(
client_id=MQTT_CLIENT_ID,
server=MQTT_BROKER,
port=MQTT_PORT,
user=MQTT_USER, # اگر نیاز نیست، None قرار دهید
password=MQTT_PASSWORD, # اگر نیاز نیست، None قرار دهید
keepalive=60 # interval (in seconds) to send MQTT ping to broker
)
try:
client.connect()
print("Connected to MQTT broker: %s" % MQTT_BROKER)
return client
except Exception as e:
print("Failed to connect to MQTT broker: %s" % e)
return None
# اتصال به Wi-Fi و سپس به MQTT
if connect_wifi(WIFI_SSID, WIFI_PASSWORD):
client = mqtt_connect()
if client:
# کلاینت MQTT با موفقیت متصل شد، میتوانید انتشار یا اشتراک را انجام دهید
pass
else:
print("Could not connect to MQTT. Restarting in 10 seconds...")
time.sleep(10)
machine.reset() # ریست کردن بورد
else:
print("Could not connect to Wi-Fi. Restarting in 10 seconds...")
time.sleep(10)
machine.reset() # ریست کردن بورد
نمونه کد: انتشار پیام (Publish)
پس از اتصال موفقیتآمیز، میتوانید پیامها را به تاپیکهای مختلف منتشر کنید:
# ادامه main.py
# تاپیک برای انتشار داده
PUBLISH_TOPIC = b"home/esp32/sensor_data"
def publish_message(topic, message):
if client and client.is_connected():
try:
client.publish(topic, message, qos=0) # qos=0 برای انتشار سریع و بدون تضمین بالا
print(f"Published to {topic.decode()}: {message.decode()}")
except Exception as e:
print(f"Failed to publish message: {e}")
else:
print("Client not connected, cannot publish.")
# مثال انتشار پیام
# publish_message(PUBLISH_TOPIC, b"Hello from MicroPython!")
دقت کنید که تاپیکها و پیامها باید از نوع بایت (b"...") باشند.
نمونه کد: اشتراک پیام (Subscribe) و دریافت Callback
برای دریافت پیامها از بروکر، باید در یک تاپیک مشترک شوید و یک تابع Callback برای پردازش پیامهای دریافتی تعریف کنید:
# ادامه main.py
# تاپیک برای اشتراک
SUBSCRIBE_TOPIC = b"home/esp32/commands"
# تابع callback برای پیامهای دریافتی
def sub_cb(topic, msg):
print(f"Received message on topic {topic.decode()}: {msg.decode()}")
if topic == SUBSCRIBE_TOPIC:
if msg == b"ON":
print("Turning LED ON")
# مثلاً یک LED را روشن کنید
elif msg == b"OFF":
print("Turning LED OFF")
# مثلاً یک LED را خاموش کنید
def subscribe_to_topic(topic):
if client and client.is_connected():
client.set_callback(sub_cb) # تنظیم تابع callback
client.subscribe(topic)
print(f"Subscribed to topic: {topic.decode()}")
else:
print("Client not connected, cannot subscribe.")
# مثال اشتراک
# subscribe_to_topic(SUBSCRIBE_TOPIC)
# حلقه اصلی برنامه برای پردازش پیامهای دریافتی
# در یک حلقه while True، نیاز به بررسی پیامهای ورودی داریم
# اگر از umqtt.robust استفاده میکنید، خودش به صورت داخلی مدیریت میکند
# اما برای پردازش callbackها، نیاز به فراخوانی check_msg دارید
# یا در umqtt.robust، اگر loop() را فراخوانی کنید، آن را مدیریت میکند.
# در umqtt.robust، این کار به صورت خودکار انجام میشود، اما گاهی اوقات برای واکنش سریعتر به پیام ها،
# یا اگر میخواهید یک فعالیت دیگر در حلقه اصلی خود داشته باشید،
# میتوانید client.check_msg() را به صورت دوره ای فراخوانی کنید.
# اما برای سادگی، اجازه دهید فرض کنیم که umqtt.robust بخش زیادی از این بار را بر عهده می گیرد.
# برای loop اصلی که فعالیت های دیگر را نیز انجام می دهد
# مثلا در یک حلقه while True:
# client.check_msg() # برای پردازش پیام های دریافتی
# time.sleep(1) # یا هر زمان دیگری
مدیریت قطع اتصال و Reconnection
یکی از مزایای اصلی umqtt.robust، مدیریت خودکار قطع اتصال و تلاش برای اتصال مجدد است. اگر اتصال به بروکر قطع شود (مثلاً به دلیل قطع شدن شبکه Wi-Fi یا خاموش شدن بروکر)، umqtt.robust به صورت خودکار تلاش میکند تا اتصال را برقرار کند. شما فقط باید اطمینان حاصل کنید که تابع client.wait_msg() (برای مسدود کردن و انتظار برای پیام) یا client.check_msg() (برای بررسی پیامهای دریافتی بدون مسدود کردن) را به صورت دورهای در حلقه اصلی برنامه خود فراخوانی میکنید.
# ادامه main.py - حلقه اصلی برنامه
# ... (کدهای اتصال Wi-Fi و MQTT) ...
if client:
subscribe_to_topic(SUBSCRIBE_TOPIC)
# یک مثال حلقه اصلی که هر 5 ثانیه یک پیام منتشر میکند و پیامها را چک میکند
counter = 0
while True:
try:
client.check_msg() # بررسی پیام های دریافتی و فراخوانی callback
if counter % 5 == 0: # هر 5 ثانیه
message = f"Sensor reading: {time.time()}"
publish_message(PUBLISH_TOPIC, message.encode())
counter += 1
time.sleep(1) # هر یک ثانیه یک بار حلقه را چک کنید
except OSError as e:
print(f"Connection error: {e}. Reconnecting...")
# umqtt.robust معمولاً این را خودکار مدیریت می کند، اما در صورت نیاز می توانید اینجا
# منطق ریستارت یا reconnect دستی را اضافه کنید.
# برای مثال:
# client.connect() # تلاش برای اتصال مجدد
# time.sleep(5)
pass # allow umqtt.robust to handle reconnection
except KeyboardInterrupt:
print("Program interrupted by user.")
break
client.disconnect()
print("Disconnected from MQTT broker.")
با این کدها، شما یک کلاینت MQTT کامل و پایدار در MicroPython خواهید داشت که میتواند به Wi-Fi متصل شود، با بروکر MQTT ارتباط برقرار کند، پیام منتشر کند و پیامها را دریافت کند. این پایه و اساس هر پروژه IoT مبتنی بر MicroPython و MQTT است.
مثال عملی: سنسور دما و رطوبت با MQTT
برای درک عمیقتر و عملی مفاهیم آموخته شده، یک مثال کاربردی پیادهسازی سنسور دما و رطوبت DHT11/DHT22 با MicroPython و ارسال دادهها از طریق MQTT را بررسی میکنیم. این مثال شامل اتصال سختافزاری، کدنویسی و انتشار دادههای سنسور به یک بروکر MQTT خواهد بود.
انتخاب سنسور: DHT11 و DHT22
سنسورهای DHT11 و DHT22 سنسورهای رایج و ارزانقیمت برای اندازهگیری دما و رطوبت هستند.
- DHT11: ارزانتر، دقت کمتر (±1°C, ±5% RH)، محدوده اندازهگیری محدودتر (0-50°C, 20-90% RH)، فرکانس نمونهبرداری پایینتر (حداقل 1 ثانیه).
- DHT22 (AM2302): دقیقتر (±0.5°C, ±2-5% RH)، محدوده اندازهگیری وسیعتر (-40-80°C, 0-100% RH)، فرکانس نمونهبرداری بالاتر (حداقل 2 ثانیه)، کمی گرانتر.
برای این مثال، هر دو سنسور میتوانند استفاده شوند و کدنویسی مشابهی دارند. ما یک کتابخانه عمومی برای کار با این سنسورها را معرفی خواهیم کرد.
اتصال سختافزاری: سیمکشی سنسور به ESP32/ESP8266
سنسورهای DHT11/DHT22 معمولاً دارای سه پایه هستند: VCC (برق)، GND (زمین) و DATA (داده). برخی ماژولهای DHT دارای چهار پایه هستند که پایه NC (No Connect) اضافه دارند، یا مقاومت پولآپ (pull-up resistor) داخلی دارند. اگر سنسور شما ماژول نیست و فقط سه پایه دارد، نیاز به یک مقاومت پولآپ 10 کیلواهمی بین پایه DATA و VCC خواهید داشت.
برای ESP32:
- VCC: به پایه 3.3V یا 5V (بسته به سنسور شما) در ESP32 متصل شود.
- GND: به پایه GND در ESP32 متصل شود.
- DATA: به یکی از پینهای GPIO دیجیتال ESP32 متصل شود (مثلاً GPIO 27).
برای ESP8266:
- VCC: به پایه 3.3V یا 5V (بسته به سنسور شما) در ESP8266 متصل شود.
- GND: به پایه GND در ESP8266 متصل شود.
- DATA: به یکی از پینهای GPIO دیجیتال ESP8266 متصل شود (مثلاً D2 یا GPIO4).
توصیه میشود قبل از اتصال، دیتاشیت سنسور خود را بررسی کنید. همیشه سیمکشی را با دقت انجام دهید تا از آسیب به سنسور یا بورد جلوگیری شود.
کد MicroPython برای خواندن سنسور DHT
برای خواندن داده از سنسورهای DHT، به یک درایور MicroPython نیاز داریم. این درایور را میتوانید به صورت یک فایل dht.py در پروژه خود قرار دهید. ابتدا، این فایل را در ریشه پروژه خود (یا در پوشه /lib بورد) آپلود کنید.
# dht.py (کتابخانه درایور DHT برای MicroPython)
# این کد معمولا از قبل موجود است، فقط باید آن را روی بورد قرار دهید
import machine
import time
import struct
class DHTBase:
__gpio = None
_timeout_cycles = 6000 # 6000 / 10 = 600 us
def __init__(self, pin):
self.__gpio = machine.Pin(pin, machine.Pin.OUT)
self.__gpio.value(1) # pin output high
self.__pin = machine.Pin(pin, machine.Pin.IN, machine.Pin.PULL_UP)
def _trigger_read(self):
self.__gpio.init(self.__gpio.OUT)
self.__gpio.value(0)
time.sleep_ms(18) # datasheet says 18ms
self.__gpio.value(1)
time.sleep_us(40) # pull up for 40 us
self.__gpio.init(self.__gpio.IN)
def _read_byte(self):
buf = 0
for i in range(8):
while self.__pin.value() == 0: # Wait for start of bit
pass
t = time.ticks_us()
while self.__pin.value() == 1: # Wait for end of bit
pass
if (time.ticks_us() - t) > 40: # Check if it's a '1'
buf |= (1 << (7 - i))
return buf
def read_data(self):
self._trigger_read()
while self.__pin.value() == 1:
pass # Wait for DHT to pull low
while self.__pin.value() == 0:
pass # Wait for DHT to pull high
while self.__pin.value() == 1:
pass # Wait for DHT to pull low
# Read 5 bytes
h_int = self._read_byte()
h_dec = self._read_byte()
t_int = self._read_byte()
t_dec = self._read_byte()
checksum = self._read_byte()
total = h_int + h_dec + t_int + t_dec
if total & 0xFF == checksum:
return h_int, h_dec, t_int, t_dec
else:
raise ValueError("Checksum error")
class DHT11(DHTBase):
def read(self):
h_int, h_dec, t_int, t_dec = self.read_data()
humidity = h_int + h_dec / 10.0
temperature = t_int + t_dec / 10.0
return humidity, temperature
class DHT22(DHTBase):
def read(self):
h_int, h_dec, t_int, t_dec = self.read_data()
humidity = ((h_int << 8) | h_dec) / 10.0
temperature = (((t_int & 0x7F) << 8) | t_dec) / 10.0
if t_int & 0x80: # Check for negative temperature
temperature = -temperature
return humidity, temperature
ادغام با MQTT: انتشار دادههای سنسور
اکنون، کد اصلی (main.py) را به گونهای تغییر میدهیم که دادههای سنسور را بخواند و آنها را از طریق MQTT منتشر کند. همچنین یک قابلیت برای دریافت فرمان از طریق MQTT برای کنترل یک LED اضافه میکنیم.
# main.py - کد کامل
import network
import time
import machine
import ujson # برای کار با JSON
from umqtt.robust import MQTTClient
from dht import DHT22 # یا DHT11 بسته به سنسور شما
# اطلاعات Wi-Fi
WIFI_SSID = "Your_WiFi_SSID"
WIFI_PASSWORD = "Your_WiFi_Password"
# اطلاعات بروکر MQTT
MQTT_BROKER = "broker.hivemq.com" # یا آدرس IP/دامنه بروکر خودتان
MQTT_PORT = 1883
MQTT_CLIENT_ID = b"esp32_dht_client_XYZ" # شناسه منحصر به فرد (تغییر دهید)
MQTT_USER = None # اگر نیاز نیست، None قرار دهید
MQTT_PASSWORD = None # اگر نیاز نیست، None قرار دهید
# تاپیک ها
PUBLISH_TOPIC_TEMP = b"home/esp32/temperature"
PUBLISH_TOPIC_HUMID = b"home/esp32/humidity"
SUBSCRIBE_TOPIC_LED = b"home/esp32/led_control"
# پیکربندی سنسور DHT و LED
DHT_PIN = 27 # پین GPIO که سنسور DHT به آن متصل است
LED_PIN = 2 # پین GPIO برای LED (مثلا LED داخلی ESP32)
dht_sensor = DHT22(DHT_PIN) # یا DHT11(DHT_PIN)
led = machine.Pin(LED_PIN, machine.Pin.OUT)
client = None # متغیر گلوبال برای کلاینت MQTT
def connect_wifi(ssid, password):
sta_if = network.WLAN(network.STA_IF)
if not sta_if.isconnected():
print("Connecting to network...")
sta_if.active(True)
sta_if.connect(ssid, password)
max_wait = 10
while max_wait > 0:
if sta_if.isconnected():
break
max_wait -= 1
print("Waiting for connection...")
time.sleep(1)
if sta_if.isconnected():
print("Network config:", sta_if.ifconfig())
print("Connected to Wi-Fi successfully!")
return True
else:
print("Failed to connect to Wi-Fi.")
return False
def mqtt_connect():
global client
client = MQTTClient(
client_id=MQTT_CLIENT_ID,
server=MQTT_BROKER,
port=MQTT_PORT,
user=MQTT_USER,
password=MQTT_PASSWORD,
keepalive=60
)
try:
client.connect()
print(f"Connected to MQTT broker: {MQTT_BROKER}")
return client
except Exception as e:
print(f"Failed to connect to MQTT broker: {e}")
return None
def sub_cb(topic, msg):
print(f"Received message on topic {topic.decode()}: {msg.decode()}")
if topic == SUBSCRIBE_TOPIC_LED:
if msg == b"ON":
led.value(1) # روشن کردن LED
print("LED ON")
elif msg == b"OFF":
led.value(0) # خاموش کردن LED
print("LED OFF")
def subscribe_to_topic(topic):
if client and client.is_connected():
client.set_callback(sub_cb)
client.subscribe(topic)
print(f"Subscribed to topic: {topic.decode()}")
else:
print("Client not connected, cannot subscribe.")
def publish_sensor_data():
global client
if client and client.is_connected():
try:
humidity, temperature = dht_sensor.read()
print(f"Temperature: {temperature}°C, Humidity: {humidity}%")
# انتشار دما
temp_payload = ujson.dumps({"temperature": temperature, "unit": "C"})
client.publish(PUBLISH_TOPIC_TEMP, temp_payload.encode(), qos=0)
# انتشار رطوبت
humid_payload = ujson.dumps({"humidity": humidity, "unit": "%"})
client.publish(PUBLISH_TOPIC_HUMID, humid_payload.encode(), qos=0)
print("Sensor data published.")
return True
except ValueError as e:
print(f"Error reading sensor data: {e}")
return False
except Exception as e:
print(f"Error publishing sensor data: {e}")
return False
else:
print("Client not connected, cannot publish sensor data.")
return False
# ----- حلقه اصلی برنامه -----
if connect_wifi(WIFI_SSID, WIFI_PASSWORD):
client = mqtt_connect()
if client:
subscribe_to_topic(SUBSCRIBE_TOPIC_LED)
publish_interval = 10 # هر 10 ثانیه یک بار
last_publish_time = time.time()
while True:
try:
client.check_msg() # بررسی پیام های دریافتی
if time.time() - last_publish_time >= publish_interval:
publish_sensor_data()
last_publish_time = time.time()
time.sleep(1) # برای جلوگیری از مصرف بیش از حد CPU
except OSError as e:
print(f"Connection error: {e}. Attempting to reconnect by MicroPython robust client...")
# umqtt.robust reconnection handled internally, just wait
time.sleep(5) # Wait before next check
except KeyboardInterrupt:
print("Program interrupted by user.")
break
else:
print("MQTT client not connected. Restarting in 10 seconds...")
time.sleep(10)
machine.reset()
else:
print("Wi-Fi not connected. Restarting in 10 seconds...")
time.sleep(10)
machine.reset()
# قطع اتصال از MQTT قبل از خروج
if client:
client.disconnect()
print("Disconnected from MQTT broker.")
تنظیم بروکر MQTT و تست
برای تست این پروژه، نیاز به یک بروکر MQTT دارید:
- بروکر عمومی: میتوانید از بروکرهای عمومی مانند
broker.hivemq.com(پورت 1883) استفاده کنید که برای تست و توسعه مناسب هستند. - Mosquitto Local: برای پروژههای جدیتر یا تست آفلاین، میتوانید Mosquitto را به صورت محلی بر روی کامپیوتر خود نصب کنید.
- پلتفرمهای ابری IoT: سرویسهایی مانند AWS IoT Core، Azure IoT Hub یا Google Cloud IoT Core نیز از MQTT پشتیبانی میکنند و گزینههایی برای پروژههای در مقیاس بزرگ هستند.
برای مشاهده و ارسال پیامها به بروکر، میتوانید از ابزارهای کلاینت MQTT مانند MQTT Explorer (برای دسکتاپ) یا اپلیکیشنهای موبایل (مثلاً MQTT Dash) استفاده کنید.
مراحل تست:
- کد
dht.pyوmain.pyرا بر روی بورد خود آپلود کنید. - بورد را ریستارت کنید.
- در کنسول VSCode (یا هر ترمینال سریال دیگر)، خروجی بورد را مشاهده کنید که نشاندهنده اتصال به Wi-Fi و MQTT است.
- در MQTT Explorer، به بروکر
broker.hivemq.comمتصل شوید. - تاپیکهای
home/esp32/temperatureوhome/esp32/humidityرا مشترک شوید. باید دادههای دما و رطوبت را که هر 10 ثانیه ارسال میشوند، مشاهده کنید. - برای تست کنترل LED، یک پیام
ONیاOFFرا در تاپیکhome/esp32/led_controlمنتشر کنید. باید LED متصل به بورد شما روشن یا خاموش شود و پیامی در کنسول بورد نیز ظاهر شود.
این مثال جامع به شما نشان میدهد که چگونه میتوان یک پروژه IoT عملی با MicroPython و MQTT را از ابتدا تا انتها پیادهسازی کرد.
بهینهسازی، امنیت و بهترین روشها
پس از پیادهسازی اولیه، برای اطمینان از عملکرد پایدار، کارآمد و امن پروژه IoT خود، توجه به بهینهسازی، امنیت و رعایت بهترین روشها حیاتی است. این بخش به بررسی این جنبههای مهم میپردازد.
بهینهسازی مصرف حافظه و انرژی
در دستگاههای MicroPython، منابع محدود هستند، بنابراین بهینهسازی بسیار مهم است:
- مدیریت حافظه (RAM):
- استفاده از
gc.collect(): MicroPython دارای یک Garbage Collector (GC) است. میتوانید باimport gc; gc.collect()به صورت دورهای حافظه را آزاد کنید، به خصوص پس از عملیاتهای سنگین یا زمانی که اشیاء بزرگی را از حافظه پاک میکنید. - رشتههای بایت به جای رشتههای UTF-8: برای دادههای ثابت و تاپیکها، استفاده از
b"topic_name"به جای"topic_name"میتواند کمی در مصرف حافظه صرفهجویی کند زیرا رشتههای بایت نیازی به UTF-8 decode/encode ندارند. - اجتناب از متغیرهای گلوبال غیرضروری: متغیرهای گلوبال تا زمانی که برنامه در حال اجراست در حافظه باقی میمانند. سعی کنید از آنها به صورت محلی در توابع استفاده کنید.
- وارد کردن ماژولهای خاص: به جای
import library، ازfrom library import specific_functionاستفاده کنید تا فقط قسمتهای مورد نیاز ماژول بارگذاری شوند.
- استفاده از
- بهینهسازی مصرف انرژی:
- حالتهای خواب (Deep Sleep / Light Sleep): برای دستگاههایی که نیاز به ارسال داده به صورت دورهای دارند (مثلاً هر چند دقیقه یا ساعت)، استفاده از حالت Deep Sleep (با
machine.deepsleep()) میتواند مصرف انرژی را به شدت کاهش دهد. در این حالت، میکروکنترلر تقریباً خاموش میشود و پس از یک بازه زمانی مشخص یا رویداد خارجی، بیدار میشود. - کاهش فرکانس ارتباط: دادهها را فقط زمانی که نیاز است یا در بازههای زمانی طولانیتر ارسال کنید. هرچه کمتر Wi-Fi یا MQTT فعال باشد، انرژی کمتری مصرف میشود.
- خاموش کردن تجهیزات جانبی غیرضروری: اگر از LEDهای داخلی، پینهای GPIO اضافی یا سنسورهایی استفاده نمیکنید، آنها را خاموش کنید تا انرژی مصرف نکنند.
- استفاده از QoS پایینتر: QoS 0 در MQTT کمترین سربار و در نتیجه کمترین مصرف انرژی را دارد. اگر از دست دادن یک پیام مشکلی ایجاد نمیکند، از QoS 0 استفاده کنید.
- حالتهای خواب (Deep Sleep / Light Sleep): برای دستگاههایی که نیاز به ارسال داده به صورت دورهای دارند (مثلاً هر چند دقیقه یا ساعت)، استفاده از حالت Deep Sleep (با
امنیت در MQTT: رمزنگاری، احراز هویت و مجوزها
امنیت در IoT از اهمیت بالایی برخوردار است، به خصوص زمانی که دادههای حساس منتقل میشوند:
- TLS/SSL (Encryption): برای رمزگذاری ارتباطات بین کلاینت و بروکر، از TLS/SSL استفاده کنید. بروکرها معمولاً پورتهای جداگانهای برای این منظور دارند (معمولاً 8883). در MicroPython، هنگام تعریف
MQTTClient، میتوانید پارامترssl=Trueرا اضافه کنید و در صورت نیاز، گواهیها را نیز پیکربندی کنید.client = MQTTClient(..., port=8883, ssl=True, ssl_params={'cert': 'client.crt', 'key': 'client.key', 'server_hostname': 'your_broker_domain'})پیادهسازی کامل TLS/SSL در MicroPython ممکن است به دلیل محدودیتهای حافظه و پردازشی چالشبرانگیز باشد و نیاز به کامپایل فریمور با پشتیبانی از TLS دارد.
- احراز هویت (Authentication): همیشه از نام کاربری و رمز عبور برای اتصال به بروکر MQTT استفاده کنید. این کار از دسترسی کلاینتهای غیرمجاز جلوگیری میکند. نام کاربری و رمز عبور را در کد خود به صورت hardcoded ذخیره نکنید؛ در عوض، آنها را از طریق فایل تنظیمات یا از طریق یک روش امنتر بارگذاری کنید.
- مجوزها (Authorization - ACLs): در بروکر MQTT خود (مثلاً Mosquitto)، ACL (Access Control List) را پیکربندی کنید تا کلاینتها فقط بتوانند در تاپیکهای مجاز منتشر یا مشترک شوند. به عنوان مثال، یک سنسور فقط باید بتواند در تاپیک
/sensors/dataمنتشر کند، نه در/control/commands. - شناسههای کلاینت منحصر به فرد (Unique Client IDs): همیشه از شناسههای کلاینت منحصر به فرد برای هر دستگاه استفاده کنید. این کار به بروکر کمک میکند تا کلاینتها را به درستی مدیریت کند و از تداخل جلوگیری میکند.
مدیریت خطا و Resilience
یک سیستم IoT باید در برابر خطاها مقاوم باشد:
- بلوکهای
try-except: از بلوکهایtry-exceptبرای مدیریت خطاها در عملیاتهایی مانند خواندن سنسورها، اتصال به Wi-Fi یا MQTT استفاده کنید. این کار از کرش کردن برنامه جلوگیری کرده و به شما امکان میدهد تا به خطاها واکنش نشان دهید. - Watchdog Timer: Watchdog Timer یک ویژگی سختافزاری در میکروکنترلرها است که برنامه را نظارت میکند. اگر برنامه برای مدت طولانی "گیر کند" و watchdog را ریست نکند، بورد را به صورت خودکار ریست میکند. این یک راهکار موثر برای ریکاوری از حالتهای نامطلوب است.
import machine wdt = machine.WDT(timeout=5000) # 5 ثانیه # در حلقه اصلی برنامه به صورت دوره ای wdt.feed() - ریستارت مجدد (Graceful Restarts): در صورت بروز خطاهای غیرقابل رفع، به جای کرش کردن، بورد را به صورت کنترل شده ریستارت کنید (
machine.reset()). - زمانبندی مجدد (Exponential Backoff): هنگام تلاش برای اتصال مجدد به Wi-Fi یا MQTT پس از قطع اتصال، از الگوریتم Exponential Backoff استفاده کنید. یعنی فاصله بین تلاشها را به صورت تصاعدی افزایش دهید (مثلاً 1، 2، 4، 8 ثانیه) تا از اشباع شبکه و بروکر جلوگیری شود.
umqtt.robustاین قابلیت را تا حدودی مدیریت میکند.
QoS و Retain Messages در عمل
- QoS مناسب:
- QoS 0: برای دادههایی که از دست دادن آنها مشکلی ندارد (مثلاً خوانشهای مکرر سنسور که با دادههای بعدی جایگزین میشوند). کمترین سربار، بیشترین کارایی.
- QoS 1: برای دادههایی که باید حتماً به مقصد برسند، اما تکرار آنها مشکلساز نیست (مثلاً وضعیت روشن/خاموش یک دستگاه که میتوان آن را دوبار دریافت کرد).
- QoS 2: برای دادههای حیاتی که باید دقیقاً یک بار تحویل داده شوند (مثلاً دستورات مالی یا تنظیمات حیاتی). بالاترین سربار، کمترین کارایی.
- Retain Message:
از پرچم Retain برای تاپیکهایی استفاده کنید که آخرین وضعیت مهم را نشان میدهند (مثلاًhome/thermostat/current_state). هنگامی که یک کلاینت جدید به این تاپیک مشترک میشود، بلافاصله آخرین پیام Retained را دریافت میکند و از وضعیت فعلی مطلع میشود، حتی اگر قبلاً منتشر شده باشد.client.publish(topic, message, retain=True)از استفاده بیش از حد از Retain Message خودداری کنید، زیرا بروکر باید تمام پیامهای Retained را ذخیره کند.
ساختار تاپیکهای MQTT: بهترین روشها
طراحی خوب تاپیکهای MQTT برای مقیاسپذیری و مدیریتپذیری سیستم شما بسیار مهم است:
- سلسله مراتبی (Hierarchical): از ساختار سلسله مراتبی با اسلش (
/) استفاده کنید. مثال:کشور/شهر/ساختمان/طبقه/اتاق/نوع_سنسور. - انعطافپذیری: تاپیکها را به گونهای طراحی کنید که انعطافپذیر باشند و بتوانید از wildcard (
+برای یک سطح،#برای چند سطح) استفاده کنید.
مثلاً، باhome/+/temperatureمیتوانید دمای تمام اتاقها را مشترک شوید. باhome/#تمام پیامهایhomeرا دریافت میکنید. - خوانا و با معنی: نام تاپیکها باید واضح و گویا باشند تا به راحتی بتوانید اطلاعات منتقل شده را حدس بزنید.
- فشرده و کوتاه: هرچند تاپیکها طولانی میتوانند معنیدارتر باشند، اما در محیطهای محدود، تاپیکهای کوتاهتر سربار کمتری دارند. تعادل را رعایت کنید.
- استفاده از شناسههای منحصر به فرد: در تاپیکها از شناسههای منحصر به فرد دستگاه (مثلاً MAC Address یا Client ID) استفاده کنید تا هر دستگاه تاپیک مخصوص به خود را داشته باشد (مثلاً
home/devices/ESP32-ABC123/status). - تفکیک داده و کنترل: تاپیکها را برای دادهها (مثلاً
/sensor_data) و کنترل (مثلاً/commands) جدا کنید.
مثال:home/device_id/sensor/temperature(برای انتشار داده) وhome/device_id/control/light(برای دریافت فرمان).
با رعایت این نکات، نه تنها پروژههای IoT شما کارآمدتر خواهند بود، بلکه امنیت و قابلیت نگهداری آنها نیز به میزان قابل توجهی بهبود خواهد یافت.
چالشها و راهحلهای پیشرفته در پیادهسازی MQTT با MicroPython
با پیشرفت پروژههای IoT و افزایش پیچیدگی آنها، چالشهای جدیدی نیز پدید میآیند که نیازمند راهحلهای پیشرفتهتر هستند. در این بخش، به برخی از این چالشها و رویکردهای ممکن برای حل آنها در زمینه MQTT و MicroPython میپردازیم.
Over-the-Air (OTA) Updates: بهروزرسانی فریمور از راه دور
یکی از مهمترین قابلیتها در توسعه IoT، امکان بهروزرسانی فریمور دستگاهها از راه دور (OTA) است. این قابلیت به شما امکان میدهد تا باگها را رفع کنید، ویژگیهای جدید اضافه کنید یا بهبودهای امنیتی را بدون نیاز به دسترسی فیزیکی به دستگاهها اعمال کنید.
چالشها:
- محدودیت حافظه: دانلود فریمور جدید و ذخیره آن در حافظه فلش قبل از نصب، نیاز به فضای کافی دارد که در MicroPython ممکن است چالشبرانگیز باشد.
- قطع برق در حین بهروزرسانی: اگر برق در حین فرآیند بهروزرسانی قطع شود، ممکن است دستگاه brick شود.
- امنیت: اطمینان از اینکه فریمور دانلود شده معتبر و از منبع قابل اعتماد است.
راهحلها در MicroPython:
- MicroPython به طور رسمی یک ماژول OTA داخلی مشابه آنچه در ESP-IDF (برای C/C++) وجود دارد، ندارد. با این حال، جامعه MicroPython راهحلهایی را توسعه داده است.
- استفاده از کتابخانههای شخص ثالث: برخی کتابخانههای MicroPython مانند
micropython-ota-updaterسعی در ارائه این قابلیت دارند. این کتابخانهها معمولاً فریمور جدید را از یک سرور HTTP یا حتی از طریق MQTT دانلود میکنند و سپس آن را در حافظه فلش جایگزین میکنند. - روش تقسیمبندی فلش (Flash Partitioning): بردهای ESP32 دارای قابلیت دو بوتلودر (dual-boot) و تقسیمبندی فلش هستند که میتوان یک پارتیشن را برای فریمور فعلی و دیگری را برای فریمور جدید رزرو کرد. این رویکرد امنیت بیشتری در برابر قطع برق فراهم میکند. پیادهسازی این قابلیت در MicroPython ممکن است به دانش عمیقی از معماری ESP32 و نحوه کامپایل فریمور نیاز داشته باشد.
- بهروزرسانی کد پایتون: به جای بهروزرسانی کامل فریمور MicroPython، میتوانید فقط فایلهای
.pyخود را از راه دور بهروزرسانی کنید. با استفاده از MQTT، میتوانید یک پیام حاوی لینک دانلود فایل جدید را ارسال کنید و دستگاه آن را از طریق HTTP دانلود و جایگزین کند. این روش سادهتر است اما برای بهروزرسانی هسته MicroPython مناسب نیست.
دستهبندی دادهها (Batching Data): بهینهسازی ارسال پیام
در بسیاری از کاربردهای IoT، سنسورها ممکن است هر چند ثانیه یک بار داده تولید کنند. ارسال هر خوانش به صورت یک پیام MQTT جداگانه میتواند منجر به سربار شبکه و مصرف انرژی بیش از حد شود. دستهبندی دادهها یک راهحل موثر برای این مشکل است.
چالشها:
- تأخیر: دستهبندی دادهها به معنای انتظار برای جمعآوری چندین نقطه داده قبل از ارسال است که منجر به تأخیر در دریافت اطلاعات میشود.
- مدیریت بافر: نیاز به بافر کردن دادهها در حافظه دستگاه تا زمان ارسال.
راهحل:
- جمعآوری چندین خوانش سنسور در یک بازه زمانی مشخص (مثلاً هر 5 دقیقه 60 نقطه داده) و سپس ارسال همه آنها در قالب یک پیام JSON به بروکر MQTT.
# مثال دستهبندی داده import ujson import time sensor_readings = [] BATCH_INTERVAL = 300 # 5 دقیقه def collect_and_publish_batch(client): global sensor_readings if sensor_readings: payload = ujson.dumps({"readings": sensor_readings, "timestamp": time.time()}) client.publish(b"home/esp32/batch_data", payload.encode(), qos=1) print(f"Published {len(sensor_readings)} readings in a batch.") sensor_readings = [] # بافر را پاک کنید else: print("No readings to publish in batch.") # در حلقه اصلی # هر زمان که سنسور خوانده میشود: # sensor_readings.append({"temp": temperature, "hum": humidity, "time": time.time()}) # و هر BATCH_INTERVAL: # collect_and_publish_batch(client) - این رویکرد به ویژه برای دستگاههایی که از حالت Deep Sleep برای صرفهجویی در انرژی استفاده میکنند، بسیار مفید است. دستگاه میتواند چندین بار بیدار شود، داده جمعآوری کند و در نهایت یک بار در بازههای طولانیتر، همه دادهها را ارسال کرده و سپس دوباره به Deep Sleep برود.
یکپارچهسازی با پلتفرمهای ابری IoT
پلتفرمهای ابری مانند AWS IoT Core، Azure IoT Hub و Google Cloud IoT Core، زیرساختهای قدرتمندی را برای مدیریت و پردازش دادههای IoT فراهم میکنند. همه این پلتفرمها از MQTT به عنوان پروتکل ارتباطی اصلی برای دستگاهها پشتیبانی میکنند.
چالشها:
- پیچیدگی احراز هویت: اتصال به این پلتفرمها معمولاً نیازمند احراز هویت مبتنی بر گواهی X.509 و TLS است که پیادهسازی آن در MicroPython (به دلیل محدودیتهای حافظه و کتابخانههای SSL) میتواند پیچیده باشد.
- سیاستهای دسترسی (Policies): نیاز به پیکربندی دقیق سیاستهای دسترسی در هر پلتفرم برای کنترل مجوزهای هر دستگاه.
راهحل:
- پیکربندی MQTTClient: هنگام استفاده از
MQTTClientدر MicroPython، باید پارامترهایsslرا به درستی تنظیم کنید و مسیر فایلهای گواهی دستگاه (device certificate)، کلید خصوصی (private key) و گواهی مرجع (root CA certificate) را مشخص کنید. این فایلها باید قبلاً بر روی بورد MicroPython آپلود شده باشند.client = MQTTClient( client_id=b"YOUR_CLIENT_ID", server=b"YOUR_AWS_IOT_ENDPOINT", port=8883, user=None, password=None, keepalive=60, ssl=True, ssl_params={ "key": "device_private.key", "cert": "device_cert.crt", "cert_reqs": ssl.CERT_REQUIRED, # برای تأیید اعتبار سرور "ca_certs": "root_ca.pem", "server_hostname": "YOUR_AWS_IOT_ENDPOINT" } ) - تولید گواهیها: برای هر دستگاه در پلتفرم ابری، گواهیها و کلیدهای خصوصی مخصوص به آن دستگاه را تولید کنید و به صورت امن بر روی بورد بارگذاری کنید.
- استفاده از Bridges MQTT: در برخی موارد، میتوانید یک بروکر Mosquitto محلی راهاندازی کنید و آن را به عنوان یک Bridge به پلتفرم ابری متصل کنید. دستگاههای MicroPython به بروکر محلی متصل میشوند و Mosquitto پیامها را به ابر منتقل میکند. این رویکرد سربار امنیتی را از دستگاههای MicroPython برمیدارد اما یک نقطه شکست اضافه میکند.
استفاده از Last Will and Testament (LWT)
قابلیت Last Will and Testament در MQTT برای اطلاعرسانی در مورد قطع اتصال غیرمنتظره دستگاهها بسیار مفید است.
کاربرد:
- هنگام تعریف
MQTTClient، میتوانید پارامترهایlwttopicوlwtmessageرا تنظیم کنید. اگر دستگاه به طور غیرمنتظره قطع شود، بروکر پیامی را درlwttopicبا محتوایlwtmessageمنتشر میکند.client = MQTTClient( client_id=MQTT_CLIENT_ID, server=MQTT_BROKER, port=MQTT_PORT, lwttopic=b"home/esp32/status", lwtmessage=b"OFFLINE", lwtqos=1, lwtretain=True ) - سایر کلاینتها (مانند یک سرور نظارت) میتوانند در این تاپیک مشترک شوند و بلافاصله از وضعیت آفلاین شدن دستگاه مطلع شوند، حتی اگر دستگاه بدون ارسال پیام
DISCONNECTقطع شود. - هنگامی که دستگاه با موفقیت متصل میشود، میتوانید پیامی با محتوای "ONLINE" در همان تاپیک منتشر کنید تا وضعیت آنلاین بودن آن مشخص شود.
با درک و پیادهسازی این چالشها و راهحلهای پیشرفته، میتوانید سیستمهای IoT قویتر، مقیاسپذیرتر و پایدارتری را با MicroPython و MQTT توسعه دهید.
نتیجهگیری: قدرت همافزایی MQTT و MicroPython برای آینده اینترنت اشیا
در طول این پست جامع، به بررسی عمیق و عملی پیادهسازی پروتکل MQTT با MicroPython در محیط توسعه VSCode پرداختیم. از معرفی مفاهیم بنیادی MQTT و MicroPython گرفته تا راهاندازی گام به گام محیط توسعه، پیادهسازی کلاینت MQTT، و ارائه یک مثال عملی با سنسور دما و رطوبت، تلاش کردیم تا تصویری کامل و کاربردی از این ترکیب قدرتمند را ارائه دهیم. همچنین، بهینهسازیها، ملاحظات امنیتی و بهترین روشها و چالشهای پیشرفته در این حوزه را مورد بحث قرار دادیم تا پروژههای شما نه تنها کارآمد، بلکه پایدار و امن نیز باشند.
همانطور که مشاهده شد، MQTT با ویژگیهای سبکوزن بودن، مدل انتشار/اشتراک و سطوح مختلف کیفیت سرویس (QoS)، راهحلی ایدهآل برای ارتباطات در اکوسیستم اینترنت اشیا است. این پروتکل به دستگاههای محدود اجازه میدهد تا به صورت مؤثر و با حداقل مصرف منابع، با یکدیگر و با سرورها ارتباط برقرار کنند. در همین حال، MicroPython، با آوردن قدرت و سادگی پایتون به دنیای میکروکنترلرها، فرایند توسعه دستگاههای IoT را به میزان قابل توجهی تسریع کرده است. این زبان، با کاهش پیچیدگیهای برنامهنویسی سطح پایین و ارائه یک محیط توسعه کارآمد، امکان نوآوری و نمونهسازی سریع را برای مهندسان و توسعهدهندگان فراهم میآورد.
استفاده از VSCode به عنوان محیط توسعه، با افزونههای اختصاصی MicroPython، تجربهای یکپارچه و کارآمد را برای برنامهنویسی، دیباگ و مدیریت فایلها بر روی بورد فراهم میکند. این ابزار قدرتمند، به توسعهدهندگان کمک میکند تا با تمرکز بیشتر بر روی منطق کاربردی، از جزئیات فنی زیربنایی فاصله بگیرند.
آینده اینترنت اشیا به شدت به قابلیت اتصال پایدار، کارآمد و امن دستگاههای میلیاردها گره متکی است. ترکیب MQTT و MicroPython یک راهکار اثبات شده و مقیاسپذیر برای دستیابی به این هدف است. از خانههای هوشمند و کشاورزی دقیق گرفته تا نظارت صنعتی و شهرهای هوشمند، این دو تکنولوژی در کنار هم میتوانند پروژههای IoT را به سطوح جدیدی از عملکرد و کارایی برسانند.
امیدواریم این راهنما به شما کمک کرده باشد تا دانش لازم برای شروع یا پیشبرد پروژههای IoT خود را کسب کنید. با دانش و ابزارهایی که اکنون در اختیار دارید، شما آمادهاید تا ایدههای خلاقانه خود را به واقعیت تبدیل کرده و نقش فعالی در شکلدهی آینده اینترنت اشیا ایفا کنید. فراموش نکنید که دنیای IoT همواره در حال تغییر است و یادگیری مداوم کلید موفقیت در این حوزه خواهد بود. اکنون زمان آن است که دستان خود را آلوده به کد کنید و شروع به ساختن کنید!
“تسلط به برنامهنویسی پایتون با هوش مصنوعی: آموزش کدنویسی هوشمند با ChatGPT”
"تسلط به برنامهنویسی پایتون با هوش مصنوعی: آموزش کدنویسی هوشمند با ChatGPT"
"با شرکت در این دوره جامع و کاربردی، به راحتی مهارتهای برنامهنویسی پایتون را از سطح مبتدی تا پیشرفته با کمک هوش مصنوعی ChatGPT بیاموزید. این دوره، با بیش از 6 ساعت محتوای آموزشی، شما را قادر میسازد تا به سرعت الگوریتمهای پیچیده را درک کرده و اپلیکیشنهای هوشمند ایجاد کنید. مناسب برای تمامی سطوح با زیرنویس فارسی حرفهای و امکان دانلود و تماشای آنلاین."
ویژگیهای کلیدی:
بدون نیاز به تجربه قبلی برنامهنویسی
زیرنویس فارسی با ترجمه حرفهای
۳۰ ٪ تخفیف ویژه برای دانشجویان و دانش آموزان