آشنایی با Arduino IoT Cloud و نخستین قدمها برای ورود به دنیای اینترنت اشیا.
نیازمندیهای اجرای پروژه
- بورد Arduino MKR1000 (میتوان از MKR1010 هم استفاده کرد. و یا حتی در صورتی که به این دو دسترسی نداشتید، MKR IOT Bundle هم برای این پروژه قابل استفاده است)
- برد بورد
- LED از نوع 20mA
- مقاومت ۲۲۱ اهمی (البته ما در اینجا از مقاومت ۱۵۰ اهمی استفاده کردهایم تا جریانی که ازLED میآید را محدود کنیم. چرا که LED با سیگنال ولتاژ بالای ۳.۳ ولت تغذیه میشود)
- پتانسیومتر چرخشی
- کلید فشاری 12mm
- مقاومت 10K ( به عنوان مقاومت پول دان برای کلید فشاری)
Appها و سرویسهای آنلاین مورد نیاز
- Arduino Web Editor
- Arduino IoT Cloud
دربارهی پروژهای که می خواهیم انجام دهیم
در این آموزش میخواهیم پروژهای را با هم انجام دهیم که در آن بورد MKR1000 (و یا MKR1010) را به پلتفرم Arduino IoT Cloud متصل کنیم. یعنی دستاورد ما در پایان این پروژه این است که میتوان بوردمان را در هر کجا که باشیم، از طریق اینترنت و وبسایت این پلتفرم کنترل کنیم.
برای این کار ابتدا باید بوردمان را به عنوان یک شی به فضای cloud اضافه کنیم. همان طور که در جلسهی قبلی که مقدمات مربوط به این پلتفرم را توضیح دادیم گفته بودیم، منظور از شی در سیستم اینترنت اشیا، نمایشی برای دیوایسهایی است که میخواهیم در این سیستم داشته باشیم. پس از آنکه آن را به عنوان یک thing اضافه کردیم، باید برای آن یک مجموعه ویژگیها نیز تعریف کنیم. این ویژگیها شامل سنسورها، LEDها، موتورها و تمام دیوایسهایی است که در پروژه ما وجود دارند و ما میخواهیم از طریق cloud به آنها دسترسی داشته باشیم.
1. ایجاد یک شی و کنترل LED از طریق حافظه ابری
برای شروع یک قدم ساده برمیداریم. فرض میکنیم مداری داریم که شامل بورد MKR1000 (یا MKR1010) است که یک LED هم به آن متصل شده است. همان طور که در شماتیک مشخص است، پایهی مثبت LED را به پین دیجیتال شماره ۲ از بورد ، و پایهی منفی LED را با واسطهی یک مقاومت ۱۵۰ اهمی به زمین متصل میکنیم. توجه داشته باشید که تغذیه برد بورد از Vcc میآید نه از پین ۵ ولتی بورد MKR. اگر آن را به پین ۵ ولتی متصل کنیم، در ادامهی مراحل که کلید فشاری را به مدار اضافه میکنیم، بورد آسیب خواهد دید.
پس از متصل کردن LED، باید مدار را به IoT مجهز کنیم. به این منظور ابتدا باید تنظیمات بورد آردوینو را به گونهای قرار دهیم که بتواند به cloud متصل شود. یک از بوردهای MKR1000 یا MKR1010 را انتخاب میکنیم و به سراغ پلتفرم Arduino IoT Cloud میرویم تا تنظیمات لازم را انجام دهیم. مراحل این کار را که شامل نامگذاری بورد، نصب کلیدهایی برای برقراری ارتباط امن (از طریق یک کانال رمزگذاری شده) و … هستند، به ترتیب در تصاویر زیر میبینیم.
با کلیک کردن بر روی گزینهی BACK TO CLOUD؛ ما قادر خواهیم بود اولین Thing خود را به cloud اضافه کنیم و بورد MKR که تنظیمات آن را انجام دادهایم، به صورت خودکار با این Thing متناظر میشود. تنها کاری که حالا باید انجام دهیم این است که برای آن یک نام انتخاب کنیم. ما نام آن را IoTCloud_Tutorial_Thing میگذاریم و شما هم یا همین نام و یا هر نام دیگری که دوست دارید را انتخاب کنید.
پس از این مرحله صفحهی Thing’s edit view باز خواهد شد که میتوانیم در آن ویژگیهای هر شی را برای آن تعریف و یا ویژگیهای از قبل تعریف شده را اصلاح کنیم. این ویژگیها شامل نمایش سنسورها و عملگرهای مکانیکی (actuators) هستند که میخواهیم به کنترل آنها از طریق حافظه ابری دسترسی داشته باشیم.
در اینجا هدف خود را به این شکل تعریف میکنیم که اگر ما در صفحهی مرورگر خود سوییچی که به صورت گرافیکی در اختیار داریم را تغییر وضعیت دهیم، LED متصل به بورد خاموش و روشن شود. برای اجرای این هدف، باید یک ویژگی (property) تعریف کنیم. دکمهی ایجاد (+) را مانند تصویر زیر میزنیم.
در قسمت نام (name)، کلمهی light را قرار میدهیم. بهتر است نامی که انتخاب میکنیم یک نام معنادار باشد چرا که بعدا در sketch از آن استفاده میشود و معنادار بودن نامها به تشخیص راحتتر آنها و خواناتر شدن کد کمک خواهد کرد.
نوع (type) این ویژگی را بولین (ON/Off) انتخاب میکنیم.
Permission set را روی Read and Write قرار میدهیم تا بتوانیم از طریق مرورگر و از راه دور، وضعیت متغیر (ON یا Off بودن آن) را کنترل کنیم. بخش Update را هم روی When the value changes تنظیم میکنیم. به این ترتیب هر زمان که وضعیت متغیر در بورد تغییری کند، وضعیت جدید آن سریعا در Cloud آپدیت خواهد شد. در نهایت روی CREATE بزنید تا ایجاد شود.
در پنجرهی Edit روی گزینهی EDIT CODE میرویم. این کار ما را به صفحهی کد آماده شدهای میبرد که متناسب با Thing ساخته شده توسط ما و ویژگیهای تعریف شده برای آن، به صورت خودکار ایجاد شده است.
نام sketch دقیقا همان نامی خواهد بود که برای Thing انتخاب کرده بودیم، در کنار تاریخ ایجاد آن و شمارهی آن (شماره در صورتی قید میشود که sketch دیگری هم قبلا با همین نام ذخیره شده باشد) علاوه بر فایل main.ino، سه فایل دیگر را هم میبینیم که ایجاد شدهاند.
- فایل adoc: یک فایل text ساده که حاوی اطلاعاتی در مورد sketch ایجاد شده، ایجادکنندهی آن و توضیحاتی در رابطه با پروژه است.
- فایل h: کدی که توسط Arduino IoT Cloud ایجاد میشود. این کد زمانی ساخته شده است که ما ویژگی light را برای شی خود انتخاب کردیم. ما نیازی به اصلاح کردن این کد نداریم اما بد نیست که نگاهی به آن داشته باشید تا دقیقتر متوجه شوید که کدام متغیرها در فایل ino. قرار است با cloud سینک شوند.
- Secret: از طریق این tab میتوانیم مقادیر SECRET_SSID و SECRET_PASS را وارد کنیم. این دو متغیر به ترتیب نام و پسورد شبکه وایفایی هستند که بوردمان را به آن وصل میکنیم.
بسیار خب، حالا بیایید که به سراغ خطوط کدها برویم تا ببینیم که در هر کدام از آنها چه اتفاقاتی در حال رخ دادن است. از thingProperties.h شروع میکنیم.
#include <ArduinoIoTCloud.h>
در این خط از کد، کتابخانهی ArduinoIoTCloud را اضافه میکنیم. به این کتابخانه نیاز داریم تا بتوانیم متغیرهای محلی sketch خود را با ویژگیهایی که در IoT Cloud برای آنها تعریف کردهایم، هماهنگ و متناظر کنیم.
#include <Arduino_ConnectionHandler.h>
از WiFiConnectionManager استفاده میکنیم تا اتصال و باز اتصال (در صورت قطع شدن) بورد به شبکه وایفای را کنترل کنیم.
char ssid[] = SECRET_SSID; char pass[] = SECRET_PASS;
این مقادیر را از Secret tab بدست آوردهایم.
#define THING_ID "d276ab77-67cb-420b-9ea4-bd34cdf385d9"
ID منحصر به فردی که هر شی دارد.
void onLightChange();
در این خط تابعی تعریف کردهایم که هر زمان ویژگی light در داشبورد دچار تغییر شود، این تابع فراخوانی میشود. به این گونه توابع، callback گفته میشود.
bool light;
تعریف متغیر light:
void initProperties()
از این تابع در بلوک ()setup در فایل ino. استفاده خواهد شد.
ArduinoCloud.setThingId(THING_ID);
به sketch میگوییم که به کدام شی باید متصل شود.
ArduinoCloud.addProperty(light, READWRITE, ON_CHANGE, onLightChange);
در این بخش به sketch گفتهایم که با متغیر light به عنوان یک ویژگی از شی ما برخورد کند و تابع callback که با نام onLightChange تعریف کرده بودیم را در هر بار تغییر مقدار این متغیر از جانب Cloud بر روی آن اعمال کند.
پارامتر مربوط به اجازه دسترسی را هم در مقادیر تابع به صورت READWRITE قرار میدهیم تا با ویژگیهایی که برای شی خود تعریف کرده بودیم هماهنگ باشد.
WiFiConnectionHandler ArduinoIoTPreferredConnection(ssid, pass);
Connection Manager را با استفاده از WiFi Access Point name که همان SECRET_SSID بود و پسورد آن که SECRET_PASS تعیین شده در Secret tab بود، مقداردهی میکنیم.
حالا نوبت به فایل ino. است. مانند هر Arduino Sketch دیگری، در اینجا هم دو تابع اصلی داریم.
{…} ()void setup و {…} ()void loop.
تابع ()setup تنها یک بار فراخوانی میشود و آن زمانی است که Sketch شروع به کار میکند. اما تابع loop تا زمانی که تغذیهی بورد فراهم باشد، بارها و بارها اجرا شده و تکرار میشود.
#include "thingProperties.h"
متغیرها و توابعی که در thingProperties.h تعریف شده بودند را مانند کتابخانه به کد اضافه میکنیم.
setDebugMessageLevel(2);
در این بخش سطح مطلوبی که دوست داریم برای log messages روی مانیتور سریال نمایش داده شود را مشخص میکنیم. در اینجا سطح روی ۲ تنظیم شده است اما میتوانیم آن را روی ۰ هم قرار دهیم که در آن صورت تنها خطاها نمایش داده میشوند و یا در آخرین درجه آن که ۳ است و همه چیز را پرینت و log خواهد کرد. در حالتی که اتصال به اینترنت و ابر نداشته باشیم، بهتر است که این درجه را روی حداکثر یعنی ۳ قرار دهیم تا در صورت رخداد مشکل بتوانیم آن را ردیابی کنیم. در اینجا آن را تغییر نمیدهیم و اجازه میدهیم روی همان ۲ باقی بماند.
Serial.begin(9600);
مقداردهی اولیه به مانیتور سریال برای نمایش اطلاعات و خواندن دادهها از آن.
delay(1500);
۱.۵ ثانیه زمان برای initialize شدن serial monitor صبر میکنیم.
initProperties();
Initialize کردن ویژگیهایی که در thingProperties.h تعریف کرده بودیم.
ArduinoCloud.begin(ArduinoIoTPreferredConnection);
با استفاده از ArduinoCloud ،ConnectionManager هم initialize میشود.
و در تابع ()loop داریم:
ArduinoCloud.update();
این بخش از کد اتفاقات بسیاری را که به سنسورها مربوط میشوند، مدیریت میکند. مثلا سینک کردن ویژگیها بین بورد و cloud، بررسی اتصال به شبکه و cloud و مواردی از این قبیل. اگر مقدار یکی از ویژگیها در داخل sketch دچار تغییر شود، کتابخانههای موجود به صورت خودکار متوجه این تغییر شده و cloud را نیز مطلع خواهند کرد تا مقدار جدید آن را در دیتابیس خود بروزرسانی کند. دقیقا به همین صورت، اگر مقدار یک ویژگی از طریق داشبورد ابری هم دچار تغییر شود، کتابخانهها فورا این تغییر را در بورد نیز منعکس میکنند. به این ترتیب یک تعامل کاملا دو طرفه در این میان برقرار است.
void onLightChange() {...}
و در این بخش هم پیادهسازی تابع Callback را داریم. هر اتفاقی که بخواهیم در زمان تغییر ویژگیها رخ بدهد را در قالب کد در این تابع پیادهسازی و بیان میکنیم.
مثلا در اینجا ما میخواهیم بتوانیم LED را از طریق Arduino IoT Cloud Dashboard خاموش و روشن کنیم. در کدی که به این منظور مینویسیم، ابتدا باید پینی که LED به آن متصل شده است را مشخص کنیم و آن را دقیقا در بالای کد تابع ()setup قید میکنیم.
#define LED_PIN 2
و حالا در تابع ()setup باید این پین را به عنوان خروجی تعیین کنیم.
pinMode(LED_PIN, OUTPUT);
در نهایت به تابع ()onLightChange میرسیم که کار آن منعکس کردن وضعیت متغیر light در مانیتور سریال و روشن و خاموش کردن LED است.
توجه داشته باشید که هر زمان که بخواهیم ویژگیای به سیستم اضافه کنیم که به صورت READWRIGHT باشد، چنین تابع callback به صورت خودکار تولید خواهد شد.
void onLightChange() { digitalWrite(LED_PIN, light); Serial.print("The light is "); if (light) { Serial.println("ON"); } else { Serial.println("OFF"); } }
تمام شد. در این مرحله همه چیز آماده است که بر روی گزینه UPLOAD بزنیم و sketch را بر روی بورد بارگذاری کنیم.
و Serial Monitor را که در سمت چپ صفحه وجود دارد باز میکنیم تا ببینیم که آیا همه چیز به همان صورتی که میخواهیم کار میکند یا خیر.
از آنجا که logging level را روی ۲ گذاشته بودیم، میبینیم که مانیتور سریال اطلاعاتی را از پروسهی متصل شدن بورد ما به IoT Cloud نشان میدهد.
پس از اینکه بورد با موفقیت به وایفای متصل شده و یک کانال ارتباطی امن میان بورد و پلتفرم ابری ایجاد میشود، تبادل اطلاعات میان آنها آغاز خواهد شد.
[ 144313 ] Connecting to "FT Mobile" [ 148284 ] Connected to "FT Mobile" [ 148284 ] Acquiring Time from Network .... [ 148690 ] Network Time: 1550057496 [ 148910 ] Connecting to Arduino IoT Cloud... [ 152212 ] Connected to Arduino IoT Cloud
اگر احیانا هرکدام از مراحل بالا با موفقیت اجرا نشوند، پیغام خطا دریافت خواهیم کرد. در این صورت بورد را ریست کرده و دوباره تلاش میکنیم. اگر تمام مراحل توضیح داده شده را به دقت انجام داده باشید، احتمال رخ دادن خطا بسیار کم است.
اگر بر روی GO TO IOT CLOUD کلیک کنیم؛ به صفحهای هدایت خواهیم شد که منحصرا برای شی ما در Arduino IoT Cloud ساخته شده است. اینجا همان جایی است که میتوانیم داشبورد کاربری خود را برای کنترل از راه دور بورد داشته باشیم.
در این داشبورد یک ویجت میبینیم که وضعیت light property که تعریف کردهایم را به ما نشان میدهد. در ابتدای کار وضعیت آن باید در حالت OFF باشد و حال اگر بر روی آن کلیک کنید میبینید که LED روشن میشود. اگر دوباره کلیک کنید خاموش میشود و … .
در این نقطه میتوانیم اعلام کنیم که ماموریت این پروژه در مرحله اول خود به خوبی پایان یافته است و حالا میتوانیم وارد مرحلهی پیچیدهتری شویم.
2. اضافه کردن پتانسیومتر به مدار اولیه
حال که اطمینان پیدا کردهایم که تنظیمات اولیهی پروژه به درستی کار میکند و همه چیز سر جای خود است؛ میتوانیم ویژگیهای بیشتری نیز به پروژه اضافه کنیم. این ویژگی جدید را با یک پتانسیومتر که به مدار اضافه میشود تعریف میکنیم. اتصال پتانسیومتر به مدار به این ترتیب است که پایههای تغذیه (power) و زمین آن متناظرا به منابع مربوطه و پایهی سیگنال آن به پین A1 بورد آردوینو متصل میشوند.
برای اضافه کردن یک ویژگی جدید، همان مسیری که یک بار در قسمت اول پروژه طی کردیم را تکرار میکنیم، به پنجرهی Thing’s properties view میرویم و بر روی دکمهی ایجاد ویژگی جدید (+) کلیک میکنیم. نام ویژگی جدید را angle میگذاریم. نوع آن را Int انتخاب میکنیم و مقادیر max و min آن را به ترتیب ۲۷۰ و ۰ قرار میدهیم.
اجازه دسترسی را روی حالت Read only میگذاریم و تنظیم میکنیم که مقدار این ویژگی به محض تغییر آپدیت شود. اگر بخواهیم برای میزان تغییرات و آپدیت هم یک تلرانس تعریف کنیم، باید یک متغیر جدید به نام Delta با مقدار بزرگتر از صفر هم معرفی کنیم. توضیح دقیقتر آن به این صورت است که مثلا فرض کنید اگر متغیر تلرانس یعنی Delta را روی ۵ تنظیم کنیم، در این حالت تنها زمانی مقدار متغیر در cloud آپدیت میشود که اختلاف مقدار جدید و مقدار قبلی (در یک تغییر) بیشتر از ۵ باشد. در غیر این صورت آن تغییر در نظر گرفته نشده و مقدار متغیر در فضای cloud بروزرسانی نمیشود.
در این مرحله CREATE را میزنیم تا ویژگی جدید ساخته شده و به پنجرهی edit بازگردانده شویم.
درست است که ما در این لحظه نمیبینیم، اما به محض افزودن این ویژگی جدید، Sketch هم تغییر کرده و بروزرسانی میشود تا این ویژگی و اتفاقات متناظر با آن را در خود منعکس کند. به سراغ کدها میرویم تا این تغییرات را با هم بررسی کنیم.
گزینهی EDIT CODE را میزنیم.
اگر به کد thingProperties.h برویم؛ متوجه میشویم که دو خط کد جدید به آن اضافه شده است.
int angle;
این دو خط متغیرهای متناظر با ویژگی جدیدی که اضافه کردهایم را تعریف میکنند.
ArduinoCloud.addProperty(angle, READ, ON_CHANGE, NULL, 5.000000);
و در این بخش متغیر تعریف شدهی angle را به ویژگی مرتبط با آن در بورد متناظر میکنیم، دسترسی آن را در حالت READ تعریف میکنیم (به این ترتیب در داشبورد cloud تنها میتوانیم مقدار آن را بخوانیم و نمیتوانیم در آن تغییری ایجاد کنیم) وچون read- only است، پس هیچ تابع call back هم برای آن ساخته نخواهد شد؛ پس یکی مانده به آخرین پارامتر تابع به صورت NULL است و در نهایت آخرین پارامتر همان مقدار Delta است که بالاتر در مورد آن صحبت کردیم.
برای آنکه پتانسیومتر هم به cloud متصل شود، پین اتصال آن به بورد را مشخص میکنیم.
#define POTENTIOMETER_PIN A1
سپس در بخش تابع ()loop، باید مقدار آنالوگ به دست آمده از پتانسیومتر را بخوانیم و آن را به متغیر angle نظیر کنیم. به این ترتیب با چرخاندن پتانسیومتر در مدار، تغییرات ولتاژ بلافاصله در داشبورد cloud هم منعکس خواهد شد.
int angleSensor = analogRead(POTENTIOMETER_PIN); angle = map(angleSensor, 0, 1023, 0, 270);
اجازه دهید کدهای جدید را بر روی بورد آپلود کنیم و ببینیم که داشبورد جدید ما چه وضعیتی خواهد داشت و چرخاندن پیچ پتانسیومتر چگونه در آن نمایش داده میشود. طبق چیزی که تعریف کردهایم، باید ببینیم که با چرخاندن پیچ پتانسیومتر، مقدار متغیر angle از ۰ تا ۲۷۰ تغییر میکند.
3. اضافه کردن کلید فشاری به مدار و اتصال آن به پلتفرم ابری
در این مرحله میخواهیم باز هم پروژه را کاملتر کنیم و یک ویژگی دیگر هم به آن اضافه کنیم. این ویژگی جدید متناظر با یک کلید فشاری است که به مدار بدست آماده از مرحله ۲ و به صورتی که در شماتیک زیر نمایش داده شده است، اضافه میکنیم. یک پایهی کلید را به Vcc و پایهی دیگر آن را به پین دیجیتال شماره ۵ (در تصویر با سیم سفید رنگ مشخص شده است) و با یک مقاومت پول داون 10K به زمین وصل میکنیم. چنین آرایشی ولتاژ کلید را در زمان استراحت در حالت LOW level و در زمان فشرده شدن در حالت HIGH level قرار میدهد.
مجددا از همان مسیر قبلی به پنجره ادیتور بروید و از آنجا یک ویژگی جدید به نام toggle اضافه کنید. نوع آن را بولین (ON/Off) و اجازهی دسترسی آن را Read only قرار دهید. گزینهی آخر را هم روی Update When the value changes بگذارید. یعنی زمانی متغیر در حافظه ابری بروزرسانی شود که وضعیت آن در بورد تغییر کرده باشد.
دوباره به بخش کدها میرویم و نگاهی به تغییرات آنها میاندازیم. میبینیم که در thingProperties.h متغییر جدیدی به نام toggle تعریف شده است و ویژگیهایی که برای آن تعریف کرده بودیم نیز مشخص شدهاند.
در ino. فایل هم پین مربوطه تعریف شده و دو متغیر را هم برای کلید فشاری تعریف میکنیم.
#define BUTTON_PIN 5 int btnState; int btnPrevState = 0;
متغیر btnPrevState را به این دلیل استفاده میکنیم که به کمک آن بتوانیم به سیستم بفهمانیم که تنها زمانی وضعیت متغیر را آپدیت کند که کلید فشار داده میشود و در زمان رها شدن کلید نیازی نیست کاری انجام دهد.
جلوتر در تابع ()setup مود این پین را به صورت ورودی تعریف میکنیم.
pinMode(BUTTON_PIN, INPUT);
و در نهایت با این خطوط به انتهای تابع ()loop نزدیک میشویم.
btnState = digitalRead(BUTTON_PIN); if (btnPrevState == 0 && btnState == 1) { toggle = !toggle; } btnPrevState = btnState;
به این ترتیب ما کلید را به صورت یک سوییچ تاگل تعریف کردهایم که هر بار آن را فشار دهیم باید ببینیم که وضعیت آن در داشبورد cloud از ON به OFF یا برعکس تغییر میکند.
به نظر جالب است نه؟! بیایید کد جدید را هم بر روی مدار آپلود کنیم و ببینیم داشبورد جدید به چه شکل خواهد بود.
مسیری که تا این لحظه با هم طی کردهایم مسیر پر قدرت و ارزشمندی بوده است که اکنون میتوانیم به پشتوانهی آن ادعا کنیم که از این به بعد قادریم شبکههای مختلف از اشیای به هم پیوسته را به کمک این پلتفرم جذاب پیادهسازی و کنترل کنیم. بد نیست که در ادامه یک قدم فراتر نیز برویم و یاد بگیریم که چگونه میتوانیم با استفاده از یک کتابخانهی جدید، کدهای سادهتری برای این پروژه داشته باشیم.
3-1. استفاده از Debouncing Library
زمانی که در پروژهها مانند همین سیستمی که در این آموزش با هم پیادهسازی کردیم، از کلید فشاری استفاده میشود؛ یکی از چالشهای متداولی که ممکن است در آن سیستم ایجاد شود، مسئلهی نویز کلید (بانس(bounce) کلید) است که هرچند یک اشکال مداری است اما میتواند عملکرد سیستم ما را تحت تاثیر قرار داده و مختل کند. علت این امر این است که کد ما به گونهای نوشته شده است که حتی وضعیتهای موقتی متغیرها نیز در آن مورد توجه قرار میگیرند و براساس آنها روال سیستم رو به جلو میرود. حالا فرض کنید مداری داشته باشیم که در آن حتی به جای یک کلید از چندین کلید استفاده شده باشد؛ احتمالا حجم اختلال به وجود آمده در اثر مسئلهی بانس کلید غیرقابل کنترل خواهد بود.
اما یک راه حل بسیار ساده برای حل این مشکل وجود دارد و آن استفاده از کتابخانهی Debouncing است که به ما اطمینان میدهد در صورت رخ دادن بانس هم سیستم به درستی کار خواهد کرد.
ابتدا از منوی کناری صفحه به بخش کتابخانهها میرویم. FTDebouncer را در قسمت جستجو وارد کرده و اینتر را میزنیم. میبینیم که کتابخانه پیدا میشود. کافیست include را بزنیم تا به کد ما اضافه شود.
پس از آن میبینیم که خط زیر به کد ما اضافه شده است.
#include <FTDebouncer.h>
در قسمت قبل از تابع ()setup، تعریف متغیرهای مربوط به کلید فشاری را به این صورت اصلاح میکنیم.
int btnState; int btnPrevState = 0;
و یک متغیر FTDebouncer هم تعریف میکنیم.
FTDebouncer buttons;
و خطی که در آن پین مربوط به کلید را مقداردهی اولیه کرده بودیم هم،
pinMode(BUTTON_PIN, INPUT);
با دو خط زیر جایگزین میکنیم.
buttons.addPin(BUTTON_PIN, LOW); buttons.init();
در ابتدا کد حلقه این دستور را اضافه میکنیم.
buttons.update();
و کدهای قبلی که مربوط به کلید بودند را حذف میکنیم.
btnState = digitalRead(BUTTON_PIN); if (btnPrevState == 0 && btnState == 1) { toggle = !toggle; } btnPrevState = btnState;
و نهایتا در قسمت پایانی sketch تابع زیر را اضافه میکنیم.
void onPinActivated(uint8_t pinNr){ Serial.println(pinNr); toggle = !toggle; } void onPinDeactivated(uint8_t pinNr){ Serial.println(pinNr); }
به خاطر حضور کتابخانهای که اضافه کردیم، هر زمان که کلید فشار داده شود، تابع ()onPinActivated یک بار فراخوانی میشود و در این صورت به متغیر toggle اعلام میکنیم که به وضعیت مخالف وضعیت فعلی خود تغییر کند. یعنی اگر الان ON است، OFF شود و اگر OFF است، ON شود. این عمل معکوس شدن را با عملگر «!» بیان میکنیم که به عملگر NOT منطقی هم معروف است.
اگر برای زمان رها شدن کلید هم عملکرد بخصوصی مد نظر داشته باشیم، باید بعد از این تابع، تابع مربوط به آن عملکرد را که ()onPinDeactivated نام دارد بیاوریم. اگر تمایل داشته باشید میتوانید مثالی از این مورد را در کد این پروژه که به صورت کامل در انتهای آموزش برایتان قرار دادهایم، ببینید.
جمعبندی و نتایج
در این جلسه، به صورت جزئی و دقیق و با انجام مرحله به مرحلهی یک پروژه، یاد گرفتیم که چگونه با پلتفرم Arduino IoT Cloud کار کنیم.
اگر دربارهی این آموزش هرگونه سوال یا نظری داشته باشید، خوشحال خواهیم شد که آن را در قسمت نظرات همین مطلب با ما در میان بگذارید. ما همهی تلاشمان را خواهیم کرد که در صورت علاقهمند بودن شما به این گونه پروژههای جذاب در زمینهی اینترنت اشیا، موارد مشابه بیشتری را برایتان تدارک ببینیم.
کد
/* Sketch generated by the Arduino IoT Cloud Thing "testThing" https://create.arduino.cc/cloud/things/d276ab77-67cb-420b-9ea4-bd34cdf385d9 Site: Melec.ir Arduino IoT Cloud Properties description The following variables are automatically generated and updated when changes are made to the Thing properties bool switchState; int potentiometerValue; bool ledState; Properties which are marked as READ/WRITE in the Cloud Thing will also have functions which are called when their values are changed from the Dashboard. These functions are generated with the Thing and added at the end of this sketch. */ #include "thingProperties.h" #include <FTDebouncer.h> #define LED_PIN 2 #define POT_PIN A1 #define BUTTON_PIN 5 FTDebouncer buttons; void setup() { pinMode(LED_PIN, OUTPUT); buttons.addPin(BUTTON_PIN, LOW); buttons.init(); /* The following function allows you to obtain more information related to the state of network and IoT Cloud connection and errors the higher number the more granular information you’ll get. The default is 0 (only errors). Maximum is 3 */ setDebugMessageLevel(2); // Initialize serial and wait for port to open: Serial.begin(9600); // This delay gives the chance to wait for a Serial Monitor without blocking if none is found delay(1500); // Defined in thingProperties.h initProperties(); // Connect to Arduino IoT Cloud ArduinoCloud.begin(ArduinoIoTPreferredConnection); } void loop() { buttons.update(); ArduinoCloud.update(); // Your code here int angleSensor = analogRead(A1); angle = map(angleSensor, 0, 1023, 0, 270); } void onLightChange() { digitalWrite(LED_PIN, light); Serial.print("The light is "); if (light) { Serial.println("ON"); } else { Serial.println("OFF"); } } void onPinActivated(uint8_t pinNr) { // do something according to the _pinNR that is triggered. For instance: Serial.println(pinNr); toggle = !toggle; } void onPinDeactivated(uint8_t pinNr) { // do something according to the _pinNR that is triggered. For instance: Serial.println(pinNr); }
شماتیک
- منبع: ترجمه از سایت create.arduino.cc
لطفا سوالات و نظرات خودتان را در قسمت کامنتها⇓ بنویسید.
اگر این نوشته برایتان مفید بود لطفا کامنت بنویسید.