در پست امروز قصد داریم درابتدا ازنحوه کارکرد کنترلهای مبتنی بر RC5 را مشخصکنیم و توضیحبدیم RC5 دقیقا چی هست!؟ و چطور کارمیکنه؟ و در آخر سورس یک پروژه راهاندازی RC5 با آردینو را قرارخواهیمداد. ریموت یا کنترل تلویزیون یکیاز وسائل پرمصرف امروزی در اکثر خانهها هست و اکثر کنترلهای امروزی از این پروتکل استفاده مینمایند.
RC5 چیست و چطور کار میکند؟
به چه طریق میتوانم کد RC5 تولید کرد؟
کنترل ها دارای یک فرستنده IR هستند که ازطریق آن اطلاعات را به گیرنده که همان تلویزیون یا وسائل الکترونیکی مشابه هست انتقال میدهد. یک کد RC5 تشکیلشده از سه قسمت: togglebit , آدرس و یک کامند مربوطهبه Command، مانند تصویرزیر:
اولین نکته مهم اینه که چطور یک صفر یا یک توسط این پروتکل سمت فرستنده باید ایجاد بشود؟ جهت هر صفر یا یک ما لازم است طبق تصویر زیر اقدام کنیم: به عبارتی ما سعی میکنید در یک بازه زمانی ۸۸۹ میکرو ثانیه یک پالس با فرکانس ۳۶ کیلو هرتز به خروجی فرستنده IR خودمون ارسال کنیم.
زمانبندی در پروتکل Rc5 بسیارمهم و حیاتی هست و همانطورکه میبنید ما جهتایجاد یک ۰ یا ۱ باید دقیقا فرکانس ۳۶KHZ را برروی خروجی فرستنده خود ایجادکنیم، باتوجهبه دو تصویر بالا لازم است کاملا مشخص هست که زمانبندی و بخصوص درک بیت استارت میتونه نقشی حیاتی ایفا کنه و درصورت عدم درک صحیح بیت استارت میتونه درک کل پکت را دچار مشکلنماید. زمانبندی کل یک فریم را درزیر مشاهده میکنید و همانطورکه میبینید کل زمان یک فریم دقیقا برابر با ۲۴.۸۸۹ میلیثانیه میباشد.
طبق مواردبالا ایجاد یک کد RC5 بسیار راحتتر از دیکد آن میباشد و شما بهراحتی میتوانید در منزل با دیکد کد RC5 کنترل تلویزیون خود یک کنترل تلویزون بسازید.
جالب انجاست که عملکردها و کامندها طبق استانداری هستند که بهراحتی میتوانید اونها را در وبسایت ویکیپدیا مشاهده کنید. مانند جدولزیر:
گیرنده RC5 چطور کار میکند؟
همانطورکه دربالا مشاهدهکردید لازماست جهت ارسال یک بیت ۰ یا ۱ ما اصطلاحا یک فرکانسی را برروی خروجی فرستنده مدوله کنیم. خوشبختانه گیرنده RC5 تمام زحمت بازکردن ان فرکانس را انجام میدهد و خروجی ۰ و ۱ را تحویل ما میدهد و ما در خروجی RC5 یک خروجی منطقی ۰ و ۱ خواهیمداشت بدون درنظرگرفتن فرکانسهای مدولهشده! یکیاز معروفترین گیرندهها SFH506 و SFH507 هست که بهراحتی در بازارالکترونیک و حتی تعمیرکارهای تلویزیون میتوان آنها را پیدا نمود.
پروژه رایگان دیکد RC5 با آردوینو
در اینجا پروژه راهاندازی RC5 توسط آردوینو که در اینجا منتشر کردهبود را منتشرمیکنیم.
نویسنده کد زیر سعیکرده برخی کارکردهای متفاوت را برای ریموت نیز تفسیرنماید که در کد مشخص هست ومیتوانید براحتی آن را برای نیاز خود تغییردهید.
کد آردوینو RC5
#include<LiquidCrystal.h> int NumDispCount = 0; int NumberToBeDisplayed = 0; long int TempNum; LiquidCrystal lcd(A0,A1,A2,A3,A4,A5); long int ans,var1,var2; long int i,Index_of_Operator,j,k; static int CurrentIndexOfArray = -1; char ArrayforNum1[10]={0}; char ArrayforNum2[10]={0}; char LCD_Data_String[25]={0}; void setup() { Serial.begin(9600); pinMode(4,OUTPUT); //LCD RW pinMode(6,OUTPUT); //RC-5 Decoder GND pinMode(7,OUTPUT); //RC-5 Decoder +Vcc digitalWrite(4,0); digitalWrite(6,0); digitalWrite(7,1); lcd.begin(16,2); lcd.setCursor(0,0); lcd.print(“–RC-5 REMOTE—“); lcd.setCursor(0,1); lcd.print(“ROHIT DHARAVIYA-“); delay(2000); lcd.clear(); lcd.setCursor(0,0); lcd.print(“–RC-5 REMOTE—“); lcd.setCursor(0,1); } void loop() { String str; int num,n; if(Serial.available() > 0) { delay(50); str = Serial.readString(); if(str == “IR”) { return; } num = str.toInt(); n = num; switch(n) { case 380: case 300: { NumberToBeDisplayed = 0; LCD_Data_String[0] = ‘\0’; CurrentIndexOfArray = -1; lcd.clear(); lcd.setCursor(0,0);//column,row lcd.print(“–RC-5 REMOTE—“); lcd.setCursor(0,1); break; } case 302: case 382: { NumberToBeDisplayed = 0; lcd.clear(); lcd.setCursor(0,0);//column,row lcd.print(“1] CONVERT NUM -“); lcd.setCursor(0,1); lcd.print(“2] CACLCULATOR -“); delay(3000); NumberToBeDisplayed = 0; LCD_Data_String[0] = ‘\0’; CurrentIndexOfArray = -1; lcd.clear(); lcd.setCursor(0,0);//column,row lcd.print(“–RC-5 REMOTE—“); lcd.setCursor(0,1); break; } case 3823: case 3023: { if(NumDispCount == 4) NumDispCount = 1; else NumDispCount++;LCD_Data_String[0] = ‘\0’; CurrentIndexOfArray = -1; lcd.clear(); lcd.setCursor(0,0);//column,row if(NumDispCount == 1) { lcd.clear(); lcd.print(“—- OCTAL —–“); lcd.setCursor(0,1); TempNum = ConvertDecimalToBase(NumberToBeDisplayed,8); lcd.print(TempNum); } else if(NumDispCount == 2) { lcd.clear(); lcd.print(“—- BINARY —-“); lcd.setCursor(0,1); for(int i=15;i>=0;i–) { lcd.print((NumberToBeDisplayed >> i & 1)); } } else if(NumDispCount == 3) { lcd.clear(); lcd.print(“— DECIMAL —-“); lcd.setCursor(0,1); lcd.print(NumberToBeDisplayed); } else if(NumDispCount == 4) { lcd.clear(); lcd.print(“- HEXADECIMAL –“); lcd.setCursor(0,1); TempNum = NumberToBeDisplayed; ConvertDecimalToHex(TempNum); } break; } case 3811: case 3011: { CurrentIndexOfArray++; LCD_Data_String[CurrentIndexOfArray] = ‘-‘; lcd.print(“-“); break; } case 3821: case 3021: { CurrentIndexOfArray++; LCD_Data_String[CurrentIndexOfArray] = ‘*’; lcd.print(“*”); break; } case 3810: case 3010: { CurrentIndexOfArray++; LCD_Data_String[CurrentIndexOfArray] = ‘+’; lcd.print(“+”); break; } case 3820: case 3020: { CurrentIndexOfArray++; LCD_Data_String[CurrentIndexOfArray] = ‘/’; lcd.print(“/”); break; } case 3824: case 3024: { LCD_Data_String[++CurrentIndexOfArray] = ‘\0’; lcd.print(“=”); CurrentIndexOfArray = -1; ans = 0; for(i=0;LCD_Data_String[i];i++) { if(LCD_Data_String[i] == ‘+’ || LCD_Data_String[i] == ‘-‘ || LCD_Data_String[i] == ‘*’ || LCD_Data_String[i] == ‘/’) { Index_of_Operator= i; break; } } for(i=0,j=0,k=0;LCD_Data_String[i];i++) { if(i < Index_of_Operator) ArrayforNum1[j++] = LCD_Data_String[i]; if(i>Index_of_Operator) ArrayforNum2[k++] = LCD_Data_String[i]; } ArrayforNum1[j] = ‘\0’; ArrayforNum2[k] = ‘\0’; var1 = atoi_number(ArrayforNum1); var2 = atoi_number(ArrayforNum2); if(LCD_Data_String[Index_of_Operator] == ‘+’) ans = var1 + var2; if(LCD_Data_String[Index_of_Operator] == ‘-‘) ans = var1 – var2; if(LCD_Data_String[Index_of_Operator] == ‘*’) ans = var1 * var2; if(LCD_Data_String[Index_of_Operator] == ‘/’) ans = var1 / var2; NumberToBeDisplayed = ans; lcd.print(ans); CurrentIndexOfArray = -1;break; } case 3800: case 3000: { NumberToBeDisplayed = (NumberToBeDisplayed*10) + 0; CurrentIndexOfArray++; LCD_Data_String[CurrentIndexOfArray] = ‘0’; lcd.print(“0”); break; } case 3801: case 3001: { NumberToBeDisplayed = (NumberToBeDisplayed*10) + 1; CurrentIndexOfArray++; LCD_Data_String[CurrentIndexOfArray] = ‘1’; lcd.print(“1”); break; } case 3802: case 3002: { NumberToBeDisplayed = (NumberToBeDisplayed*10) + 2; CurrentIndexOfArray++; LCD_Data_String[CurrentIndexOfArray] = ‘2’; lcd.print(“2”); break; } case 3803: case 3003: { NumberToBeDisplayed = (NumberToBeDisplayed*10) + 3; CurrentIndexOfArray++; LCD_Data_String[CurrentIndexOfArray] = ‘3’; lcd.print(“3”); break; } case 3804: case 3004: { NumberToBeDisplayed = (NumberToBeDisplayed*10) + 4; CurrentIndexOfArray++; LCD_Data_String[CurrentIndexOfArray] = ‘4’; lcd.print(“4”); break; } case 3805: case 3005: { NumberToBeDisplayed = (NumberToBeDisplayed*10) + 5; CurrentIndexOfArray++; LCD_Data_String[CurrentIndexOfArray] = ‘5’; lcd.print(“5”); break; } case 3806: case 3006: { NumberToBeDisplayed = (NumberToBeDisplayed*10) + 6; CurrentIndexOfArray++; LCD_Data_String[CurrentIndexOfArray] = ‘6’; lcd.print(“6”); break; } case 3807: case 3007: { NumberToBeDisplayed = (NumberToBeDisplayed*10) + 7; CurrentIndexOfArray++; LCD_Data_String[CurrentIndexOfArray] = ‘7’; lcd.print(“7”); break; } case 3808: case 3008: { NumberToBeDisplayed = (NumberToBeDisplayed*10) + 8; CurrentIndexOfArray++; LCD_Data_String[CurrentIndexOfArray] = ‘8’; lcd.print(“8”); break; } case 3809: case 3009: { NumberToBeDisplayed = (NumberToBeDisplayed*10) + 9; CurrentIndexOfArray++; LCD_Data_String[CurrentIndexOfArray] = ‘9’; lcd.print(“9”); break; } } } } int atoi_number(char *p) { int num=0,i;for(i=0;p[i];i++) { if((p[i] >= ‘0’) && (p[i] <= ‘9’)) num = num * 10 + p[i] – 48; } return num; } int ConvertDecimalToBase(int n, int b) { int r=0, digitPos=1;while (n) { r += (n%b)*digitPos; n /= b; digitPos *= 10; } return r; } void ConvertDecimalToHex(long int num) { long int rem[50],i=0,length=0;while(num>0) { rem[i]=num%16; num=num/16; i++; length++; } for(i=length-1;i>=0;i–) { switch(rem[i]) { case 10: lcd.print(“A”); break; case 11: lcd.print(“B”); break; case 12: lcd.print(“C”); break; case 13: lcd.print(“D”); break; case 14: lcd.print(“E”); break; case 15: lcd.print(“F”); break; default : lcd.print(rem[i]); } } }
منبع:سیسوگ