در این پروژه، خواهیم دید که چگونه یک ریموت کنترل یونیورسال با آردوینو طراحی کنیم. با استفاده از این برنامه از راه دور ،می توانید وسایل الکترونیکی مختلفی مانند T.V ، A.C، DVD پلیر و غیره را کنترل کنید.
من ریموت یونیورسال را با استفاده از Arduino Nano، کلید، منبع تغذیه و غیره بر روی یک بورد سوراخدار کوچک پیاده سازی کرده ام. ساخت نهایی این ریموت چیزی شبیه به این عکس است.
مقدمه
ریموت کنترل IR یک دستگاه ارتباط بی سیم مبتنی بر بینایی است که به طور همزمان با یک گیرنده IR کار می کند. تقریباً در تمام وسایل الکترونیکی اصلی مانند تلویزیون، تهویه هوا، رابط های هوشمند تلوزیونی(TV boxes)، پلیرها و موارد دیگر، می توانید ریموت کنترل IR و گیرنده های IR مربوطه را پیدا کنید.
مشکل اصلی این است که هر دستگاه ریموت کنترل IR خود را دارد و تعداد لوازم شما باعث جمع آوری تعداد زیادی ریموت در اطراف شما می شود.
چه میشود اگر یک ریموت کنترل تک داشته باشید که بتواند همه وسایل الکترونیکی شما را کنترل کند؟ این مفهوم به عنوان ریموت کنترل یونیورسال شناخته می شود و هم اکنون در بازار وجود دارد.
حال با آوردن همین مفهوم برای سازندگان و علاقمندان، به ساخت یک ریموت یونیورسال با استفاده از آردوینو در قالب یک پروژه DIY ساده به شما این امکان را می دهیم تا ضمن انجام یک پروژه علمی به وسیله خودتان هزینه های ناشی از خرید یک ریموت یونیورسال از بازار را به دور بزنید.
اصول ساخت یک ریموت یونیورسال با آردوینو
اصول اجرای یک ریموت یونیورسال مبتنی بر آردوینو بسیار ساده است. اول، با استفاده از ریموت کنترل موجود از هر دستگاهی مانند تلویزیون، سیگنالهای IR دیکد می شوند.
سپس این سیگنالهای بدست آمده در نهایت برای انتشار سیگنال های مادون قرمز مربوطه با استفاده از یک LED IR Emitter استفاده می شوند.
دیکد کردن سیگنالهای IR با استفاده از آردوینو
اولین مرحله، دیکد کردن تمام سیگنال های مادون قرمز از ریموت کنترل های موجود است. من یک تلویزیون سونی و یک (A.C (air conditioners دارم. با استفاده از این دو ریموت کنترل، دکمه های اصلی مانند Power ، Volume Up ، Volume Down، Previous،Next ، Source، برای تلویزیون و Power، Temperature Up، Temperature Down، Swing، Fan، Turboبرای AC را دیکد کرده ام.
مدار
فعلاً، مدار دیکدر تلویزیون و کلیدهای ریموت AC در شکل زیر نشان داده شده است، که من در آن از Arduino Nano به همراه گیرنده TSOP1740 IR استفاده کرده ام.
کد
کد دیکدینگ سیگنالهای IR در زیر آورده شده است.
#include <IRremote.h> IRrecv receiver(2); decode_results results; void setup() { Serial.begin(9600); receiver.enableIRIn(); // start receiving signals } void loop() { if(receiver.decode(&results)) { Serial.println(results.value, HEX); Serial.print(results.rawlen - 1); for(int i = 1; i < results.rawlen; i++) { unsigned int num = results.rawbuf[i] * USECPERTICK; Serial.print(","); Serial.print(num); } Serial.println(""); receiver.resume(); } }
تمام سیگنال های دیکد شده بر روی پنجره سریال ظاهر می شوند. به همه مقادیر دیکد شده توجه داشته باشید.
توجه: در این پروژه از کتابخانه ویژه ای به نام IRremote استفاده شده است. می توانید آن را با استفاده از Library manager در Arduino IDE مستقیماً نصب کنید یا فایل زیپ آن را از گیتهاب دانلود کنید.
https://github.com/z3t0/Arduino-IRremote/archive/master.zip
مدار ریموت یونیورسال با آردوینو
اکنون که همه سیگنال های لازم را از ریموت اصلی دیکد کرده ایم، می توانیم با استفاده از آردوینو، ساخت ریموت یونیورسال را انجام دهیم. نمودار مدار، در زیر نشان داده شده است.
اجزاء
- آردوینو نانو
- IR LED
- پوش باتن 8 عدد
- باتری CR2032 دو عدد
- هلدر باتری CR2032 دو عدد
- RGB LED یک عدد
- مقاومت 10KΩ دو عدد
- سیم
- بورد سوراخ دار
- نوارهای پین هدر مادگی (برای آردوینو نانو)
طراحی مدار
ابتدا، یک IR Led به پین Digital IO 3 وصل می شود. سپس دکمه ها به شرح زیر وصل می شوند:
دکمه | پین Digital IO در آردوینو |
Power | 4 |
Mode | 5 |
Up | 6 |
Down | 7 |
Left | 8 |
Right | 9 |
Select | 10 |
علاوه بر این، یک دکمه Wakeup متصل به پین 2 Digital IO وجود دارد. پین Digital IO با استفاده از یک مقاومت 10KΩ پول دان می شود، در حالی که تمام دکمه های پین های دیگر به صورت داخلی پول آپ می شوند. انتهای دیگر همه دکمه ها (به جز Wakeup) به GND متصل شده اند. انتهای دیگر دکمه Wakeup به VCC وصل شده است.
از LED RGB برای نشان دادن دستگاه انتخابی استفاده می شود. RGB LED استفاده شده در اینجا یک ترمینال آند مشترک دارد که از طریق یک مقاومت 10KΩ به VCC وصل می شود. انتهای R، G و B در LED به ترتیب به پین های 11 ، 12 و 13 وصل می شوند.
کل این سیستم توسط یک سری از سلول های لیتیومی CR2032 3V لیتیم تغذیه می شود.
کد
در زیر کد برنامه ریموت یونیورسال با استفاده از Arduino وجود دارد. از مقادیر قبلاً جمع آوری شده، مقادیر مربوطه را در آرایه های مناسب فراهم شده برای تلویزیون و AC در کد قرار دهید.
این آرایه ها با عنوان tv_onoff [] ، tv_volup []، tv_voldown []، tv_prev []، tv_next []، tv_source [] برای داده های مربوط به تلویزیون و ac_onoff []، ac_tempup []، ac_tempdown []، ac_swing []، ac_fan [ ] ، ac_turbo [] برای AC هستند.
#include <IRremote.h> #include "LowPower.h" IRsend sender; int power=4; int mode=5; int up=6; int down=7; int left=8; int right=9; int ok=10; int r=11;///////////////////// int g=12;// RGB LED (MODE LED) int b=13;///////////////////// int tv_repeat=3; // the data to be send 3 times for receivers like sony int tv_data_length=25; // length of mark and space - its the first number when we receives the data from any remote. int ac_repeat=1; // one time is sufficient for my ac int ac_data_length=33; int rgb=1; unsigned int timer=0; /////////////////////////////////////////////// TV remote DATA//////////////////////////// unsigned int tv_onoff[]={}; unsigned int tv_volup[]={}; unsigned int tv_voldown[]={}; unsigned int tv_prev[]={}; unsigned int tv_next[]={}; unsigned int tv_source[]={}; //////////////////////////////////////////////AC remote data////////////////////////////// unsigned int ac_onoff[]={}; unsigned int ac_tempup[]={}; unsigned int ac_tempdown[]={}; unsigned int ac_swing[]={}; unsigned int ac_fan[]={}; unsigned int ac_turbo[]={}; ////////////////////////////////////////////reserved for new data//////////////////////////// // // // // // ///////////////////////////////////////////////////////////////////////////////////////////// void (*reset)(void) = 0; void wakeUp() { timer = 0; if(rgb==1)//////////////////////////red light for tv { digitalWrite(r,LOW); digitalWrite(g,HIGH); digitalWrite(b,HIGH); } else if(rgb==2)/////////////////green light for ac { digitalWrite(r,HIGH); digitalWrite(g,LOW); digitalWrite(b,HIGH); } else if(rgb==3)////////////////blue light reserved { digitalWrite(r,HIGH); digitalWrite(g,HIGH); digitalWrite(b,LOW); } } void setup() { Serial.begin(9600); pinMode(power,INPUT_PULLUP); pinMode(mode,INPUT_PULLUP); pinMode(up,INPUT_PULLUP); pinMode(down,INPUT_PULLUP); pinMode(left,INPUT_PULLUP); pinMode(right,INPUT_PULLUP); pinMode(ok,INPUT_PULLUP); pinMode(r,OUTPUT); pinMode(g,OUTPUT); pinMode(b,OUTPUT); digitalWrite(r,LOW);//OFF digitalWrite(g,HIGH);//OFF digitalWrite(b,HIGH);//OFF timer = 0; } void loop() { attachInterrupt(0,wakeUp, HIGH); while (timer < 10000) { if(digitalRead(mode)==0) { while(digitalRead(mode)==0); timer = 0; if(rgb==3) { rgb=1; } else rgb+=1; if(rgb==1) { digitalWrite(r,LOW); digitalWrite(g,HIGH); digitalWrite(b,HIGH); } else if(rgb==2) { digitalWrite(r,HIGH); digitalWrite(g,LOW); digitalWrite(b,HIGH); } else if(rgb==3) { digitalWrite(r,HIGH); digitalWrite(g,HIGH); digitalWrite(b,LOW); } } else if(digitalRead(power)==0)///////////////////////////////////////////////////////////////////////////////////////////////////////// { while(digitalRead(power)==0); timer = 0; if(rgb==1)//tv mode { for(int i = 0; i < tv_repeat; i++) { sender.sendRaw(tv_onoff, tv_data_length , 40);//data + length of data + carrier frequency in KHz delay(50); } } else if(rgb==2)//ac mode { for(int i = 0; i < ac_repeat; i++) { sender.sendRaw(ac_onoff, ac_data_length , 40);//data + length of data + carrier frequency in KHz delay(50); } } else if(rgb==3)//reserved mode { /////////////////////////////////// /////////////////////////////////// /////////////////////////////////// } } else if(digitalRead(up)==0)///////////////////////////////////////////////////////////////////////////////////////////////////////// { if(rgb==1)//tv mode { while(digitalRead(up)==0) { timer = 0; for(int i = 0; i < tv_repeat; i++) { sender.sendRaw(tv_volup, tv_data_length , 40);//data + length of data + carrier frequency in KHz delay(50); } } } else if(rgb==2)//ac mode { while(digitalRead(up)==0); timer = 0; for(int i = 0; i < ac_repeat; i++) { sender.sendRaw(ac_tempup, ac_data_length , 40);//data + length of data + carrier frequency in KHz delay(50); } } else if(rgb==3)//reserved mode { /////////////////////////////////// /////////////////////////////////// /////////////////////////////////// } } else if(digitalRead(down)==0)///////////////////////////////////////////////////////////////////////////////////////////////////////// { if(rgb==1)//tv mode { while(digitalRead(down)==0) { timer = 0; for(int i = 0; i < tv_repeat; i++) { sender.sendRaw(tv_voldown, tv_data_length , 40);//data + length of data + carrier frequency in KHz delay(50); } } } else if(rgb==2)//ac mode { while(digitalRead(down)==0); timer = 0; for(int i = 0; i < ac_repeat; i++) { sender.sendRaw(ac_tempdown, ac_data_length , 40);//data + length of data + carrier frequency in KHz delay(50); } } else if(rgb==3)//reserved mode { /////////////////////////////////// /////////////////////////////////// /////////////////////////////////// } } else if(digitalRead(left)==0)///////////////////////////////////////////////////////////////////////////////////////////////////////// { while(digitalRead(left)==0); timer = 0; if(rgb==1)//tv mode { for(int i = 0; i < tv_repeat; i++) { sender.sendRaw(tv_prev, tv_data_length , 40);//data + length of data + carrier frequency in KHz delay(50); } } else if(rgb==2)//ac mode { for(int i = 0; i < ac_repeat; i++) { sender.sendRaw(ac_swing, ac_data_length , 40);//data + length of data + carrier frequency in KHz delay(50); } } else if(rgb==3)//reserved mode { /////////////////////////////////// /////////////////////////////////// /////////////////////////////////// } } else if(digitalRead(right)==0)///////////////////////////////////////////////////////////////////////////////////////////////////////// { while(digitalRead(right)==0); timer = 0; if(rgb==1)//tv mode { for(int i = 0; i < tv_repeat; i++) { sender.sendRaw(tv_next, tv_data_length , 40);//data + length of data + carrier frequency in KHz delay(50); } } else if(rgb==2)//ac mode { for(int i = 0; i < ac_repeat; i++) { sender.sendRaw(ac_fan, ac_data_length , 40);//data + length of data + carrier frequency in KHz delay(50); } } else if(rgb==3)//reserved mode { /////////////////////////////////// /////////////////////////////////// /////////////////////////////////// } } else if(digitalRead(ok)==0)///////////////////////////////////////////////////////////////////////////////////////////////////////// { while(digitalRead(ok)==0); timer = 0; if(rgb==1)//tv mode { for(int i = 0; i < tv_repeat; i++) { sender.sendRaw(tv_source, tv_data_length , 40);//data + length of data + carrier frequency in KHz delay(50); } } else if(rgb==2)//ac mode { for(int i = 0; i < ac_repeat; i++) { sender.sendRaw(ac_turbo, ac_data_length , 40);//data + length of data + carrier frequency in KHz delay(50); } } else if(rgb==3)//reserved mode { /////////////////////////////////// /////////////////////////////////// /////////////////////////////////// } } delay(1); timer = timer + 1; } digitalWrite(r,HIGH); digitalWrite(g,HIGH); digitalWrite(b,HIGH); LowPower.powerDown(SLEEP_FOREVER, ADC_OFF, BOD_OFF); }
توجه: از یک كتابخانه اضافي به نام LowPower استفاده شده است كه آردوينو را پس از مدت زماني تعيين شده براي صرفه جويي در مصرف باتری، به حالت خواب مي برد. این کتابخانه را از صفحه GitHub دانلود کنید.
https://github.com/rocketscream/Low-Power/archive/master.zip
نحوه کار ریموت کنترل یونیورسال با آردوینو
پس از وارد کردن مقادیر دیکد شده و بارگذاری کد در آردوینو نانو، می توانید از برنامه به عنوان ریموت کنترل یونیورسال استفاده کنید. ابتدا دکمه mode را فشار دهید تا دستگاه انتخاب شود. من LED قرمز را برای تلویزیون و LED سبز را برای AC اختصاص داده ام.
بنابراین، با فشار دادن دکمه mode می توانید بین TV و AC انتخاب کنید و Led نیزبه عنوان یک نشانگر تصویری عمل می کند. پس از تنظیم mode می توانید از ریموت برای آن وسیله خاص استفاده کنید. اگر به مدت 10 ثانیه هیچ کلیدی فشرده نشود، کتابخانه LowPower وارد خواهد شد و آردوینو را به حالت خواب می برد.
برای بیدار کردن آردوینو از دکمه Wakeup استفاده کنید.
Ref: electronicshub
نتیجه
ریموت کنترل یونیورسال با آردوینو یک پروژه ساده اما بسیار کاربردی است. و حتی میتوانید آن را توسعه بدید و بصورت تجاری بفروشید. با استفاده از این برنامه می توانید تعدادی از وسایل الکترونیکی را با کمک یک ریموت کنترل واحد کنترل کنید.
اگر این نوشته برایتان مفید بود لطفا کامنت بنویسید.
سلام ببخشید میخواستم بپرسم که کد های دیکد شده ی کنترل را کجا قرار میدین و چطوری این کد ها رو ارسال میکنید منظورم با IR LED میشه به من توضیح بدین ممنون میشم.
سلام کد های دیکد شده را باید در آرایه های داده شده در بخش کد آردوینو قرار دهید.
سلام، من میخوام یه چیزی بسازم که رو دکمه ها زدم مثلا یه مقدار رو برای اردوینو بفرسته..
مثلا یه دکمه مقدار یک رو بفرسته..
یه دکمه دیگه مقدار دو رو ارسال کنه..
ممنون میشم کمکم کنین..
با سپاس از سایت خوبتون.
سلام، منظورتان از کجا به کجا بفرسته؟ از آردوینوای به اردوینو دیگر؟ یا از آردوینو با IR بفرسته بیرون؟
نه.. از دکمه به آردوینو…
باید از داخل اردوینو اینکار را انجام دهید…وقتی دکمه را فشار میدید اردوینو صفر یا یک را متوجه میشه فقط و شما باید براش معادل تعریف کنید…مثلا ۱۰ تا پوشباتن وصل کردین به آردوینو و از داخل میگین اگر پوشباتن یکم فشار داده شد مقدار متغیر اکس را بذار یک …کارهای این چنینی…
با سیم اینکارو کردم!
اما میخوام بدون سیم اینکارو بکنم!
شبیه ریموت! اما ریموتی که خودم با پلکسی بسازمش..
نمیدونم تونستم منظورمو برسونم یا خیر…
ممنون میشم کمکم کنین..
سپاس
با سلام و خسته نباشید بخاطر اطلاعات خوبی که به اشتراک گذاشتید. سوالی که داشتم اینه که در قسمت ارسال کد از اردینو به تلویزیون کدهای مربوطه را در خط چندم و کجای برنامه قرار بدیم؟ ایا کد هگزا رو فقط کپی کنیم یا کد خام raw که در سریال مانیتور نمایش میده؟
سلام، کد را من ننوشتم ولی قسمت TV remote DATA را ببینید نوشته tv_onoff اونجا را فک کنم باید پر کنید. همچنین قسمت «کد» را بخونید زیرش نوشته.
تشکر بابت زحمتی که کشیدین
سلام دوست عزیز.
واقعا عالیه که مقاله های خارجی رو اینجا هم می نویسید . الان که ارتباطات سخته سایت شما راحت باز شد
من یکم به مشکل خوردم کد هایی که کنترلر های lg به من می دن ایناست (کنترلر ها با هم فرق دارند ):
7D0050AF
E0E040BF
20DF10EF
B4B40CF3
اما اینارو نمی تونم وارد کنم
unsigned int tv_onoff[]={E0E040BF};
sender.sendRaw(tv_onoff, 25 , 40);
——————————————————-
Arduino: 1.8.19 (Windows Store 1.8.57.0) (Windows 10), Board: “Arduino Uno”
batmanGates2.ino:5:26: error: ‘E0E040BF’ was not declared in this scope
unsigned int tv_onoff[]={E0E040BF};
^~~~~~~~
exit status 1
‘E0E040BF’ was not declared in this scope
This report would have more information with
“Show verbose output during compilation”
option enabled in File -> Preferences.
——————————————————————–
نمی شناسه کد را . کمک می خوام
سلام وقت بخیر به جای وو تا باتری سکه ای نمیتوانیم یک باتری کتابی بزاریم؟