در قسمت سیام از آموزش آردوینو به بررسی دریافت ورودی از سنسورها پرداختیم. در این قسمت قصد داریم درباره آردوینو با سنسورهای داخلی متعدد و تشخیص حرکت در آردوینو صحبت کنیم.
برد Arduino Nano 33 BLE Sense دقیقاً برای چنین شرایطی طراحی شده است. این برد بسیار کوچک، ارزان، سریع و دارای هشت قابلیت سنسوری مختلف است که توسط مجموعهای از قطعات داخلی روی برد فراهم شدهاند. جدول 1، قابلیتهای این قطعات و نام کتابخانههای مربوطه را فهرست کرده است. پیش از استفاده از Nano 33 BLE Sense، ابتدا در بخش «مدیر بردهای آردوینو» پکیج Arduino nRF528x Boards (Mbed OS) را نصب کنید. سپس با استفاده از «مدیر کتابخانهها»، هر یک از کتابخانههای ذکرشده در ستون نام کتابخانه را نصب نمایید.
نام کتابخانه | خصوصیات | قطعه |
---|---|---|
Arduino_APDS9960 | تشخیص ژست (Gesture)، مجاورت (Proximity)، رنگ RGB | Broadcom APDS-9960 |
Arduino_HTS221 | دما، رطوبت نسبی | ST HTS221 |
Arduino_LPS22HB | فشار بارومتریک | ST LPS22HB |
Arduino_LSM9DS1 | واحد اندازهگیری اینرسی 9 محوره (IMU): شتابسنج، ژیروسکوپ، مغناطیسسنج | ST LSM9DS1 |
(نصبشده بهطور پیشفرض با بسته برد Nano 33 BLE) | میکروفون دیجیتال | ST MP34DT05 |
جدول 1: سنسورهای داخلی برد Nano
پس از نصب پشتیبانی از برد Nano 33 BLE Sense و کتابخانههای مربوطه، از منوی Tools در محیط Arduino IDE استفاده کنید تا برد Nano 33 BLE را انتخاب کرده و پورت صحیح را تنظیم نمایید. در زمان نگارش این متن، هر دو برد Nano 33 BLE و Nano 33 BLE Sense از تنظیم برد یکسانی در IDE استفاده میکنند. در واقع، Nano 33 BLE همان Nano 33 BLE Sense است، فقط بدون سنسورهای پیشرفته. سپس کد زیر را روی برد آپلود کرده و Serial Monitor را باز کنید.
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 | * * Arduino Nano BLE Sense sensor demo */ #include <Arduino_APDS9960.h> #include <Arduino_HTS221.h> #include <Arduino_LPS22HB.h> #include <Arduino_LSM9DS1.h> void setup() { Serial.begin(9600); while (!Serial); if (!APDS.begin()) { // Initialize gesture/color/proximity sensor Serial.println("Could not initialize APDS9960."); while (1); } if (!HTS.begin()) { // Initialize temperature/humidity sensor Serial.println("Could not initialize HTS221."); while (1); } if (!BARO.begin()) { // Initialize barometer Serial.println("Could not initialize LPS22HB."); while (1); } if (!IMU.begin()) { // Initialize inertial measurement unit Serial.println("Could not initialize LSM9DS1."); while (1); } prompt(); // Tell users what they can do. } void loop() { // If there's a gesture, run the appropriate function. if (APDS.gestureAvailable()) { int gesture = APDS.readGesture(); switch (gesture) { case GESTURE_UP: readTemperature(); break; case GESTURE_DOWN: readHumidity(); break; case GESTURE_LEFT: readPressure(); break; case GESTURE_RIGHT: Serial.println("Spin the gyro!\nx, y, z"); for (int i = 0; i < 10; i++) { readGyro(); delay(250); } break; default: break; } prompt(); // Show the prompt again } } void prompt() { Serial.println("\nSwipe!"); Serial.println("Up for temperature, down for humidity"); Serial.println("Left for pressure, right for gyro fun.\n"); } void readTemperature() { float temperature = HTS.readTemperature(FAHRENHEIT); Serial.print("Temperature: "); Serial.print(temperature); Serial.println(" °F"); } void readHumidity() { float humidity = HTS.readHumidity(); Serial.print("Humidity: "); Serial.print(humidity); Serial.println(" %"); } void readPressure() { float pressure = BARO.readPressure(PSI); Serial.print("Pressure: "); Serial.print(pressure); Serial.println(" psi"); } void readGyro() { float x, y, z; if (IMU.gyroscopeAvailable()) { IMU.readGyroscope(x, y, z); Serial.print(x); Serial.print(", "); Serial.print(y); Serial.print(", "); Serial.println(z); } } void readHumidity() { float humidity = HTS.readHumidity(); Serial.print("Humidity: "); Serial.print(humidity); Serial.println(" %"); } void readPressure() { float pressure = BARO.readPressure(PSI); Serial.print("Pressure: "); Serial.print(pressure); Serial.println(" psi"); } void readGyro() { float x, y, z; if (IMU.gyroscopeAvailable()) { IMU.readGyroscope(x, y, z); Serial.print(x); Serial.print(", "); Serial.print(y); Serial.print(", "); Serial.println(z); } } |
در Serial Monitor پیامی نمایش داده میشود که نحوه تعامل با Arduino Nano 33 BLE Sense را توضیح میدهد. برای انجام حرکت کشیدن (swipe) در یک جهت خاص، دست خود را بالای برد نگه دارید و حرکتی مانند پاککردن انجام دهید. برای کشیدن به سمت بالا، دست خود را از سمت پورت USB برد به سمت ماژول u-blox در انتهای مقابل حرکت دهید.
کد این برنامه از چندین سنسور داخلی بورد Nano 33 BLE Sense استفاده میکند:
تابع setup منتظر میماند تا درگاه سریال (Serial Port) باز شود، سپس هر یک از این سنسورها را مقداردهی اولیه میکند. اگر هنگام راهاندازی هرکدام از سنسورها خطایی رخ دهد، یک پیام خطا در Serial Monitor نمایش داده میشود و برنامه با ورود به یک حلقه بیپایان (while(1);) متوقف میماند.
در پایان تابع setup، برنامه تابع prompt را فراخوانی میکند و پیامهایی را در Serial Monitor نمایش میدهد. درون حلقه loop، برنامه بررسی میکند که آیا سنسور APDS-9960 حرکتی را تشخیص داده یا نه. اگر حرکتی شناسایی شده باشد، اجرای برنامه به تابعی منتقل میشود که مربوط به سنسور موردنظر است.
هر یک از این توابع، وضعیت سنسور مربوطه را میخواند و در Monitor Serial نمایش میدهد.
برای ژیروسکوپ، برنامه از شما میخواهد که بورد را بچرخانید، سپس وارد یک حلقه میشود که در آن ۱۰ بار دادههای ژیروسکوپ را با کمی تأخیر میخواند تا بتوانید تغییر مقادیر را همراه با حرکت خود ببینید.
اگر میخواهید تشخیص دهید که یک جسم حرکت کرده، کج شده یا تکان خورده است، در ادامه این قسمت با ما همراه باشید.
این اسکچ از یک کلید استفاده میکند که هنگام کجشدن، مدار را میبندد؛ این قطعه سنسور شیب (Tilt Sensor) نام دارد.
اسکچ زیر (مدار آن در شکل 1 نشان داده شده) زمانی که سنسور شیب به یک سمت خم شود، LED متصل به پایه ۱۱ را روشن میکند و وقتی به سمت دیگر خم شود، LED متصل به پایه ۱۲ را روشن میکند.
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 | /* * tilt sketch * * a tilt sensor attached to pin 2 lights one of * the LEDs connected to pins 11 and 12 depending * on which way the sensor is tilted */ const int tiltSensorPin = 2; // pin the tilt sensor is connected to const int firstLEDPin = 11; // pin for one LED const int secondLEDPin = 12; // pin for the other void setup() { pinMode (tiltSensorPin, INPUT_PULLUP); // Tilt sensor connected to this pin pinMode (firstLEDPin, OUTPUT); // first output LED pinMode (secondLEDPin, OUTPUT); // and the second } void loop() { if (digitalRead(tiltSensorPin) == LOW){ // The switch is on (upright) digitalWrite(firstLEDPin, HIGH); // Turn on the first LED digitalWrite(secondLEDPin, LOW); // and turn off the second. } else{ // The switch is off (tilted) digitalWrite(firstLEDPin, LOW); // Turn the first LED off digitalWrite(secondLEDPin, HIGH); // and turn on the second. } } |
شکل 1: سنسور شیب (Tilt Sensor) و LEDها
رایجترین نوع سنسور شیب، یک ساچمه فلزی (ball bearing) درون یک لوله است که در یک سر آن، تماسهایی (کانتکتها) قرار دارند. وقتی لوله کج میشود، ساچمه از کانکتور ها دور شده و اتصال قطع میشود. اگر لوله به سمت دیگر کج شود، ساچمه با کانتکتها تماس پیدا کرده و مدار کامل میشود. علامتها یا نحوه قرارگیری پایهها (پیکربندی پینها) ممکن است نشان دهند که سنسور باید در چه جهتی قرار گیرد.
سنسورهای شیب نسبت به حرکتهای کوچک حدود ۵ تا ۱۰ درجه حساس هستند، بهویژه زمانی که طوری قرار گیرند که ساچمه فقط کمی با کانتکتها تماس داشته باشد.
اگر سنسور را طوری قرار دهید که ساچمه دقیقاً بالای کانتکتها باشد، وضعیت LED تنها زمانی تغییر میکند که سنسور کاملاً برعکس شود. از این ویژگی میتوان برای تشخیص ایستاده بودن یا وارونه بودن یک شیء استفاده کرد.
برای تشخیص اینکه یک جسم در حال تکانخوردن (لرزش) است یا نه، باید بررسی کنید که چه مدت از آخرین تغییر وضعیت سنسور شیب گذشته است.
اگر وضعیت سنسور برای مدتی که شما آن را قابلتوجه میدانید تغییر نکند، یعنی جسم در حال تکانخوردن نیست. تغییر جهتگیری سنسور شیب باعث میشود شدت تکان لازم برای فعالشدن آن نیز تغییر کند.
کد زیر، زمانی که سنسور تکان داده شود، LED داخلی بورد را روشن میکند:
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 | /* * shaken sketch * tilt sensor connected to pin 2 * using the built-in LED */ const int tiltSensorPin = 2; const int ledPin = LED_BUILTIN; int tiltSensorPreviousValue = 0; int tiltSensorCurrentValue = 0; long lastTimeMoved = 0; int shakeTime = 50; void setup() { pinMode (tiltSensorPin, INPUT_PULLUP); pinMode (ledPin, OUTPUT); } void loop() { tiltSensorCurrentValue = digitalRead(tiltSensorPin); if (tiltSensorPreviousValue != tiltSensorCurrentValue) { lastTimeMoved = millis(); tiltSensorPreviousValue = tiltSensorCurrentValue; } if (millis() - lastTimeMoved < shakeTime){ digitalWrite(ledPin, HIGH); } else { digitalWrite(ledPin, LOW); } } |
بسیاری از سنسورهای سوئیچی مکانیکی را میتوان به روشهای مشابه استفاده کرد.
برای مثال، سوئیچ شناور (Float Switch) زمانی فعال میشود که سطح آب در یک مخزن به حد مشخصی برسد. همچنین، پد فشاری (Pressure Pad) مانند آنچه در ورودی فروشگاهها استفاده میشود، میتواند تشخیص دهد که کسی روی آن ایستاده است یا خیر.
اگر سنسور شما یک سیگنال دیجیتال را روشن و خاموش میکند، برنامهای مشابه این نمونه میتواند برای آن مناسب باشد.
من کاپیتان آردوینو، اسمم میلاده و اینجا هستم تا تجربیاتم در رابطه با آردوینو رو با شما به اشتراک بزارم!
مقالات بیشتر
نویسنده شو !
سیسوگ با افتخار فضایی برای اشتراک گذاری دانش شماست. برای ما مقاله بنویسید.