آموزش آردوینو

نحوه کار تیلت سنسور و راه اندازی با Arduino

اگر هدف شما تشخیص حرکت، شیب یا تکان خوردن یک قطعه است ولی نمی خواهید با پیچیدگی های یک شتاب سنج سروکار داشته باشید، سنسور تیلت توپی می تواند ارزان ترین و ساده ترین گزینه باشد.

معرفی کلی تیلت سنسور

سنسور تیلت در واقع نوعی کلید است که می تواند حرکت ساده، جهت یا مقدار انحراف را شناسایی کند. این کلیدها طوری طراحی شده اند که هنگام رسیدن به زاویه کافی، اتصال الکتریکی برقرار یا قطع می شود. خروجی چنین سنسوری می تواند به عنوان یک نشانگر استفاده شود یا برای روشن و خاموش کردن چیزی به کار رود.

این سنسورها کوچک، ارزان، ساده در استفاده و عملاً بدون استهلاک هستند. سادگی آنها باعث شده در اسباب بازی ها، گجت ها، ربات ها و دستگاه هایی که عملکردشان به شیب وابسته است محبوب شوند. به همین دلیل گاهی از آنها به عنوان “poor man’s accelerometer” یاد می شود.

دوره آموزش آردوینو دوره آموزش ESP32 دوره آموزش اینترنت اشیا حرفه ای دوره آموزش AVR
چند نمونه سنسور تیلت توپی در اندازه کوچک

گرچه اصول عملکرد تمام تیلت سنسورها مشابه است، ابعاد و مشخصات آنها ممکن است کمی تفاوت داشته باشد.

ابعاد 5.5 میلی متر قطر و 13.5 میلی متر طول
حداکثر ولتاژ (VCC) تا 20 ولت
 حداکثر جریان مصرفی (Imax) 30mA
محدوده حساسیت بین 5 تا 10 درجه
طول عمر 50,000+ سوئیچ

تفاوت تیلت سنسور و شتاب سنج

اگرچه سنسور تیلت به اندازه یک شتاب سنج دقیق یا چندمنظوره نیست، اما برای تشخیص حرکت یا جهت عملکرد بسیار مناسبی دارد. مزیت دیگر استفاده از تیلت سنسور این است که می توان آن را به صورت مستقل به کار برد. در مقابل، خروجی شتاب سنج ولتاژ دیجیتال یا آنالوگ است که برای تفسیر آن نیاز به مدار یا پردازش اضافی وجود دارد.

روش کار سنسور تیلت توپی

سنسور تیلت معمولاً از یک لوله فلزی تشکیل شده که در داخل آن یک توپ فلزی کوچک آزادانه می تواند حرکت کند. در یک انتهای محفظه دو عنصر هادی (قطب) قرار دارند. طراحی طوری است که با رسیدن به زاویه مناسب، توپ به سمت قطب ها حرکت کرده و اتصال الکتریکی را برقرار یا قطع می کند.

نمای برش خورده از لوله فلزی و یک توپ فلزی داخل آن

وقتی سنسور به صورت عمودی قرار دارد، توپ با برخورد به قطب ها اتصال برقرار می کند. وقتی سنسور کج می شود توپ از روی قطب ها می غلتد و اتصال قطع می شود.

آزمایش سنسور تیلت توپی

آزمایش این سنسور بسیار ساده است. مولتی متر را در حالت «تست پیوستگی» قرار داده و پروب ها را به دو پایه سنسور متصل کنید. سپس سنسور را کج کنید تا زاویه ای که کلید باز یا بسته می شود را پیدا کنید.

وقتی سنسور به سمت بالا قرار گرفته است، کلید بسته است (پیوستگی کامل).

تست پیوستگی با مولتی متر وقتی سنسور به سمت بالا است

وقتی سنسور به سمت پایین است، کلید باز است (هیچ پیوستگی وجود ندارد).

تست پیوستگی با مولتی متر وقتی سنسور به سمت پایین است

سیم کشی سنسور تیلت به آردوینو

سیم کشی سنسور تیلت به آردوینو بسیار مستقیم است. کافی است یک پایه سنسور را به هر پایه دیجیتال آردوینو و پایه دیگر را به GND متصل کنید.

اگر سنسور را به این شکل متصل کنید باید مقاومت pull-up داخلی آردوینو را برای پایه ورودی فعال کنید. در غیر این صورت باید از یک مقاومت 10K pull-up خارجی استفاده نمایید.

نمودار زیر سیم کشی را نشان می دهد.

شماتیک سیم کشی سنسور تیلت به یک پورت دیجیتال و GND آردوینو

کد آردوینو — خواندن سنسور تیلت

در ادامه یک اسکچ خیلی ساده قرار دارد که وقتی سنسور به یک سمت کج می شود LED داخلی متصل به پایه 13 را روشن و در حالت دیگر خاموش می کند.

const int tiltPin = 2;        // tilt sensor pin is connected to pin 2
const int ledPin = 13;        // built-in LED is connected to pin 13

void setup() {
    pinMode(tiltPin, INPUT);        // set sensor pin as an INPUT pin
    digitalWrite(tiltPin, HIGH);    // turn on the built in pull-up resistor
    pinMode(ledPin, OUTPUT);        // set LED pin as an OUTPUT pin
}

void loop() {
    if (digitalRead(tiltPin)) { // check if the pin is high
        digitalWrite(ledPin, HIGH);    // turn on the LED
    }
    else { // if it isn't
        digitalWrite(ledPin, LOW);    // do the opposite
    }
}

کد نسبتاً گویاست. ابتدا دو ثابت تعریف شده که پایه های آردوینو متصل به سنسور و LED داخلی را مشخص می کنند. در setup پایه سنسور به عنوان ورودی و پایه LED به عنوان خروجی تنظیم می شوند و pull-up داخلی برای پایه سنسور فعال می شود. در حلقه loop اگر پایه سنسور HIGH باشد LED روشن و در غیر این صورت خاموش می شود.

اگر در مورد این مطلب سوالی دارید در قسمت نظرات بپرسید

این اسکچ کوتاه و کاربردی است، اما یک مشکل وجود دارد. اگر هنگام کج کردن سنسور به LED نگاه کرده باشید احتمالاً مشاهده کرده اید که چشمک می زند. این پدیده به دلیل چیزی به اسم switch bounce است.

پدیده switch bounce و روش برطرف کردن آن

وقتی سنسور رو به بالا است توپ روی قطب ها قرار می گیرد و آنها را اتصال می دهد، درست مانند حرکت یک کلید. در حالت ایده آل اگر این سیگنال را با یک آنالیزور مشاهده کنیم باید شکلی مانند شکل زیر داشته باشد:

سیگنال ایده آل یک کلید بدون نوسان در لحظه اتصال

این همان عملکرد ایده آل یک سنسور تیلت است و همین چیزی است که اغلب مردم تصور می کنند. اما در واقعیت سیگنال شبیه شکل زیر است:

سیگنالی که اثر bounce مکانیکی را نشان می دهد

در حالی که ایده آل این است که تماس بلافاصله برقرار شود، توپ در برخورد نوسان می کند و تماس باز و بسته های متوالی ایجاد می کند. این یک پدیده مکانیکی است که به آن Switch Bounce گفته می شود؛ درست مثل زمانی که یک توپ را رها می کنید و قبل از رسیدن به زمین چند بار می پرد.

بنابراین سیگنال چندین بار بالا و پایین می رود تا سرانجام پایدار شود. این نوسانات در بازه زمانی t رخ می دهد. هرچند این بازه برای چشم ما خیلی کوتاه و تقریباً فوری به نظر می رسد، اما برای آردوینو زمان زیادی است و می تواند در همین بازه چند فرمان اجرا کند.

فرآیند حذف این نوسانات را Debouncing می نامند که می توان آن را برنامه نویسی کرد. معمولاً نوسان کلید در بازه 50ms رخ می دهد، بنابراین یک تأخیر 50ms پس از تشخیص تغییر وضعیت برای حذف اثر bounce کافی است.

کد آردوینو — خواندن سنسور تیلت به صورت قابل اعتمادتر

در اینجا یک اسکچ بازنویسی شده قرار دارد که نشان می دهد چگونه یک ورودی را debounc کنیم. در این اسکچ ما وضعیت سنسور را در یک بازه کوتاه دو بار می خوانیم تا مطمئن شویم واقعاً کج شده است.

کد را آپلود کنید. اکنون باید ببینید که LED هنگام کج کردن سنسور دیگر چشمک نمی زند (اگر هنوز مشکل باقی ماند مقدار debounce را افزایش دهید).

const int tiltPin = 2;        // tilt sensor pin is connected to pin 2
const int ledPin = 13;        // built-in LED is connected to pin 13

int ledState = HIGH;        // the current state of the LED
int tiltState;                // the current reading from the sensor
int lastTiltState = LOW;    // the previous reading from the sensor

unsigned long time = 0;        // the last time the output pin was toggled
unsigned long debounceDelay = 50;    // the debounce time, increase if the output flickers

void setup() {
    pinMode(tiltPin, INPUT);        // Set sensor pin as an INPUT pin
    digitalWrite(tiltPin, HIGH);    // turn on the built in pull-up resistor
    pinMode(ledPin, OUTPUT);        // Set LED pin as an OUTPUT pin
}

void loop() {
    // read the state of the tilt sensor
    tiltState = digitalRead(tiltPin);

    // If the sensor really tilted?
    if (tiltState != lastTiltState) {
        // reset the debouncing timer
        time = millis();
    }

    if ((millis() - time) > debounceDelay) {
        // whatever the switch is at, its been there for a long time
        // so lets settle on it!
        ledState = tiltState;
    }
    digitalWrite(ledPin, ledState);

    // Save the last tiltState so we keep a running tally
    lastTiltState = tiltState;
}

توضیح کد:

اسکچ با اعلام پایه های آردوینو که سنسور تیلت و LED داخلی به آنها وصل هستند شروع می شود.

const int tiltPin = 2;
const int ledPin = 13;

سه متغیر از نوع int یعنی ledState، tiltState و lastTiltState تعریف شده اند تا وضعیت فعلی LED، خواندن فعلی از سنسور و خواندن قبلی سنسور را به ترتیب ذخیره کنند.

int ledState = HIGH;
int tiltState;
int lastTiltState = LOW;

در همان بخش سراسری، دو متغیر دیگر برای نگهداری زمان آخرین رویداد کج شدن و زمان debounce تعریف شده اند. دقت کنید که این متغیرها از نوع unsigned long هستند زیرا زمان بر حسب میلی ثانیه می تواند به عدد بزرگی برسد و یک integer ممکن است سرریز کند.

unsigned long time = 0;
unsigned long debounceDelay = 50;

بخش setup همانند قبل است: پایه سنسور را به عنوان ورودی، پایه LED را به عنوان خروجی تنظیم می کنیم و pull-up داخلی را برای پایه سنسور فعال می نماییم.

void setup() {
    pinMode(tiltPin, INPUT);
    digitalWrite(tiltPin, HIGH);
    pinMode(ledPin, OUTPUT);
}

در حلقه loop ابتدا وضعیت سنسور را می خوانیم و بررسی می کنیم آیا این وضعیت با آخرین وضعیت خوانده شده متفاوت است یا نه (این تغییر می تواند ناشی از کجی واقعی یا نویز باشد). اگر متفاوت باشد زمان وقوع این تغییر را با فراخوانی millis() ثبت می کنیم؛ millis() مدت زمان گذشته از شروع اجرای برنامه فعلی روی برد آردوینو را بر حسب میلی ثانیه برمی گرداند.

tiltState = digitalRead(tiltPin);

if (tiltState != lastTiltState) {
    time = millis();
}

بعد بررسی می کنیم که آیا وضعیت سنسور برای مدت زمان بیشتر از فاصله زمانی debounce (50ms) ثابت مانده است یا نه. اگر بله، می پذیریم که وضعیت واقعی است (نه نوسان) و LED را مطابق با وضعیت سنسور تنظیم می کنیم. در پایان، lastTiltState را به روز می کنیم تا ردیابی تغییرات ادامه یابد.

if ((millis() - time) > debounceDelay) {
    ledState = tiltState;
}
digitalWrite(ledPin, ledState);

lastTiltState = tiltState;
5 (1 نفر)

برای دریافت مطالب جدید کانال تلگرام یا پیج اینستاگرام ما را دنبال کنید.

محمد رحیمی

محمد رحیمی هستم. سعی میکنم در آیرنکس مطالب مفید قرار بدهم. سوالات مربوط به این مطلب را در قسمت نظرات همین مطلب اعلام کنید. سعی میکنم در اسرع وقت به نظرات شما پاسخ بدهم.

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *