📡 کنترل آردوینو با ریموت کنترل مادون قرمز (IRremote نسخهی جدید)
ریموت تلویزیون خانهتان میتواند فرمان آردوینو هم باشد! با یک گیرندهی کوچک سهپایه و کتابخانهی IRremote، هر دکمهی ریموت یک عدد مخصوص به آردوینو میفرستد و تو تصمیم میگیری با آن عدد چه کار کند: چراغ روشن کند، ربات را جلو ببرد یا صدای بازر را کم و زیاد کند. در این آموزش ریموت کنترل مادون قرمز با آردوینو را با API جدید IRremote (نسخهی ۳ به بعد) راه میاندازیم؛ همان نسخهای که کدهای قدیمی اینترنت با آن خطا میدهند.
ریموت مادون قرمز چطور کار میکند؟
سر ریموت یک LED مادون قرمز است. نور مادون قرمز را چشم ما نمیبیند، ولی دوربین گوشی میبیند؛ دوربین را رو به ریموت بگیر و دکمه را بزن تا چشمکش را ببینی. ریموت این LED را ۳۸ هزار بار در ثانیه خاموش و روشن میکند و با قطع و وصل کردن همین «سوت» نامرئی، یک پیام میفرستد. پیام رایجترین پروتکل، یعنی NEC، دو بخش دارد: آدرس (این ریموت مال کدام دستگاه است) و فرمان (کدام دکمه زده شده).
گیرنده، مثلاً VS1838B، فقط به نوری که با ۳۸ کیلوهرتز چشمک میزند حساس است و نور لامپ و آفتاب را تا حد زیادی نادیده میگیرد. خروجیاش یک سیگنال دیجیتال تمیز است که کتابخانه آن را رمزگشایی میکند. بیشتر دربارهی این نوع حسگرها در سنسور مادون قرمز چیست آمده است.
پایههای گیرنده
| پایه | کار |
|---|---|
| OUT (یا S) | خروجی داده به آردوینو |
| VCC (یا +) | ۵ ولت |
| GND (یا −) | زمین |
مراقب باش: ترتیب پایهها در گیرندهی تنها و ماژولهای آماده یکی نیست. همیشه نوشتهی کنار پایهها یا برگهی مشخصات را نگاه کن؛ وصل کردن برعکس، گیرنده را داغ و خراب میکند.
قطعهها و سیمکشی
- یک آردوینو Uno
- یک گیرندهی مادون قرمز و یک ریموت (ریموت کوچک کیتها یا ریموت تلویزیون)
- سه LED با سه مقاومت ۲۲۰ اهم
| از | به |
|---|---|
| OUT گیرنده | D11 |
| VCC گیرنده | 5V |
| GND گیرنده | GND |
| D4، D5، D6 | هر کدام از راه یک مقاومت ۲۲۰ اهم به پایهی بلند یک LED |
| پایهی کوتاه LEDها | GND |
قدم ۱: پیدا کردن کد دکمهها
کتابخانهی IRremote (از Armin Joachimsmeyer، نسخهی ۳ یا ۴) را از Library Manager نصب کن. هر ریموت کدهای خودش را دارد، پس اول این برنامه را اجرا کن، سریال مانیتور را روی ۹۶۰۰ بگذار و دکمهها را یکییکی بزن و عددها را یادداشت کن.
// Step 1: print the command code of every button you press.
#include <IRremote.hpp>
const int IR_PIN = 11;
void setup() {
Serial.begin(9600);
IrReceiver.begin(IR_PIN);
Serial.println("Press buttons on the remote...");
}
void loop() {
if (IrReceiver.decode()) {
Serial.print("command = 0x");
Serial.println(IrReceiver.decodedIRData.command, HEX);
IrReceiver.resume(); // get ready for the next button
}
}
قدم ۲: کد کامل، سه LED با سه دکمه
دکمههای ۱، ۲ و ۳ هر کدام یک LED را روشن یا خاموش میکنند و دکمهی ۰ همه را خاموش میکند. عددهای بالای برنامه را با عددهایی که در قدم ۱ دیدی عوض کن.
// IR remote: keys 1, 2, 3 toggle three LEDs, key 0 turns them all off.
#include <IRremote.hpp>
const int IR_PIN = 11;
const int LEDS[3] = {4, 5, 6};
bool ledOn[3] = {false, false, false};
// Codes of YOUR remote - copy them from the step 1 sketch.
// Car MP3 remote on a real board: 1=0x0C 2=0x18 3=0x5E 0=0x16
// Virtual remote in the simulator: 1=0x30 2=0x18 3=0x7A 0=0x68
const uint8_t KEY_1 = 0x0C;
const uint8_t KEY_2 = 0x18;
const uint8_t KEY_3 = 0x5E;
const uint8_t KEY_0 = 0x16;
void toggle(int i) {
ledOn[i] = !ledOn[i];
digitalWrite(LEDS[i], ledOn[i] ? HIGH : LOW);
}
void setup() {
Serial.begin(9600);
for (int i = 0; i < 3; i++) pinMode(LEDS[i], OUTPUT);
IrReceiver.begin(IR_PIN);
}
void loop() {
if (!IrReceiver.decode()) return; // nothing received yet
uint8_t cmd = IrReceiver.decodedIRData.command;
Serial.println(cmd, HEX);
if (cmd == KEY_1) toggle(0);
else if (cmd == KEY_2) toggle(1);
else if (cmd == KEY_3) toggle(2);
else if (cmd == KEY_0) {
for (int i = 0; i < 3; i++) {
ledOn[i] = false;
digitalWrite(LEDS[i], LOW);
}
}
IrReceiver.resume();
}
توضیح خط به خط
#include <IRremote.hpp>سرفایل نسخهی ۴. اگر نسخهی ۳ نصب داری،IRremote.hبنویس؛ بقیهی کد یکی است.IrReceiver.begin(IR_PIN)در API جدید شیء گیرنده آماده است و دیگرIRrecv irrecv(11)وenableIRInنمیخواهد.IrReceiver.decode()اگر پیام کاملی رسیده باشدtrueمیدهد. اگر نه، باreturnاز این دورloopبیرون میرویم.decodedIRData.commandفقط بایت «فرمان» است؛ یک عدد کوچک بین ۰ و ۲۵۵ که برای هر دکمه ثابت است. کدهای قدیمی با عددهای هشترقمی مثل0xFF30CFکار میکردند که خواندن و مقایسهاش سختتر بود.IrReceiver.resume()گیرنده را برای پیام بعدی آماده میکند. فراموشش کنی، فقط اولین دکمه کار میکند.- تابع
toggleوضعیت هر LED را در آرایهیledOnنگه میدارد و برعکس میکند.
پروژهی کوچک: دیمر با ریموت
با دکمههای VOL+ و VOL− نور یک LED روی پایهی D9 را در ده پله کم و زیاد کن. همین کد با یک ترانزیستور میتواند سرعت یک فن کوچک را هم کنترل کند.
// Remote dimmer: VOL+ / VOL- change the brightness of the LED on pin 9.
#include <IRremote.hpp>
const int IR_PIN = 11;
const int LED = 9; // PWM pin on Timer1 - safe with IRremote
// Car MP3 remote: VOL+=0x15 VOL-=0x07 Simulator remote: VOL+=0xA8 VOL-=0xE0
const uint8_t KEY_UP = 0x15;
const uint8_t KEY_DOWN = 0x07;
int level = 0; // 0..10
void setup() {
Serial.begin(9600);
pinMode(LED, OUTPUT);
IrReceiver.begin(IR_PIN);
}
void loop() {
if (!IrReceiver.decode()) return;
uint8_t cmd = IrReceiver.decodedIRData.command;
if (cmd == KEY_UP && level < 10) level++;
if (cmd == KEY_DOWN && level > 0) level--;
analogWrite(LED, level * 25); // 0..250
Serial.print("level ");
Serial.println(level);
IrReceiver.resume();
}
چرا پایهی ۹؟ کتابخانهی IRremote روی آردوینو Uno از تایمر ۲ استفاده میکند و تایمر ۲ همان است که PWM پایههای ۳ و ۱۱ را میسازد. پس analogWrite روی این دو پایه درست کار نمیکند؛ پایههای ۵، ۶، ۹ و ۱۰ امناند.
اجرا در شبیهساز
گیرندهی IR و ریموت مجازی روی آردوینو Uno در تینکرکد فارسی رایگاناند. وقتی گیرنده در مدار باشد، یک ریموت ۲۱ دکمهای کنار صحنه ظاهر میشود. مثال آمادهی کنترل با ریموت یک LED رنگی را با دکمههای ۱ تا ۳ عوض میکند و درس کنترل با ریموت همین را با تمرین درس میدهد. کد قدم ۱ را هم آنجا اجرا کن تا عدد دکمههای ریموت مجازی را ببینی.
اشکالهای رایج
- خطای
'decode_results' was not declaredیا هشدار deprecated: کد برای نسخهی ۲ کتابخانه نوشته شده. آن را باIrReceiverوdecodedIRData.commandبازنویسی کن. - فقط اولین دکمه کار میکند:
IrReceiver.resume()را فراموش کردهای. - با نگه داشتن دکمه، LED چند بار روشن و خاموش میشود: ریموت تا وقتی دکمه پایین است «تکرار» میفرستد. روی برد واقعی میتوانی پیامهایی را که در
decodedIRData.flagsپرچمIRDATA_FLAGS_IS_REPEATدارند نادیده بگیری. - بعد از اضافه کردن IRremote،
tone()یا PWM پایهی ۳ و ۱۱ خراب شد: تداخل تایمر ۲. بازر را با پایهی دیگری و کتابخانهی دیگری راه بینداز یا LED را به ۹ یا ۱۰ ببر. - گاهی کد عجیب یا 0 میآید: نور مستقیم آفتاب یا لامپ کممصرف کنار گیرنده است. گیرنده را در سایه بگذار.
با ریموت میشود ربات را هم راند؛ ماشینها و موتورها را در سروو با آردوینو و استپر موتور 28BYJ-48 ببین. فهرست همهی کتابخانههای پشتیبانیشده در صفحهی کتابخانهها است.
ریموت مجازی را امتحان کن 📡سؤالهای رایج
چرا کدهای قدیمی IRremote روی کامپیوترم خطا میدهند؟
از نسخهی ۳ به بعد کتابخانه عوض شده و بهجای IRrecv و decode_results از شیء آمادهی IrReceiver و decodedIRData.command استفاده میشود. کدهای قدیمی را با API جدید بازنویسی کن.
هر ریموتی با این کد کار میکند؟
بیشتر ریموتهای تلویزیون و ریموتهای کوچک کیتها بله، چون کتابخانه پروتکلهای رایج را میشناسد. ولی عدد هر دکمه در هر ریموت فرق دارد؛ اول با برنامهی قدم ۱ کدها را پیدا کن.
ریموت در شبیهساز چطور کار میکند؟
وقتی گیرندهی IR در مدار باشد، یک ریموت مجازی ۲۱ دکمهای کنار صحنه باز میشود. ریموت و گیرنده روی آردوینو Uno رایگاناند.