در پست امروز قصد داریم در ابتدا از نحوه کارکرد کنترل های مبتنی بر RC5 را مشخص کنیم و توضیح بدیم RC5 دقیقا چی هست!؟ و چطور کار میکنه؟ و در آخر سورس یک پروژه راه اندازی RC5 با آردینو را قرار خواهیم داد.
ریموت یا کنترل تلویزیون یکی از وسائل پر مصرف امروزی در اکثر خانه ها هست و اکثر کنترل های امروزی از این پروتکل استفاده مینمایند.
RC5 چیست و چطور کار میکند؟
و به چه طریق میتوانم کد RC5 تولید کرد؟
کنترل ها دارای یک فرستند IR هستند که از طریق آن اطلاعات را به گیرنده که همان تلویزیون یا وسائل الکترونیکی مشابه هست انتقال میدهد.
یک کد RC5 تشکیل شده از سه قسمت: togglebit , آدرس و یک کامند مربوطه به Command , مانند تصویر زیر:
اولین نکته مهم اینه که چطور یک صفر یا یک توسط این پروتکل سمت فرستنده باید ایجاد بشود؟
جهت هر صفر یا یک ما لازم است طبق تصویر زیر اقدام کنیم:
به عبارتی ما سعی میکنید در یک بازه زمانی 889 میکرو ثانیه یک پالس با فرکانس 36 کیلو هرتز به خروجی فرستنده IR خودمون ارسال کنیم.
زمان بندی در پروتکل Rc5 بسیار مهم وحیاتی هست و همانطور که میبنید ما جهت ایجاد یک صفر یا یک باید دقیقا فرکانس 36KHZ را بر روی خروجی فرستنده خود ایجاد کنیم, با توجه به دو تصویر بالا لازم است کاملا مشخص هست که زمان بندی و بخصوص درک بیت استارت میتونه نقشی حیاتی ایفا کنه و در صورت عدم درک صحیح بیت استارت میتونه درک کل پکت را دچار مشکل نماید.
شاید برای شما مفید باشد: پروژه های آردوینو
زمان بندی کل یک فریم را در زیر مشاهده میکنید و همانطور که می بینید کل زمان یک فریم دقیقا برابر با 24.889 میلی ثانیه میباشد.
طبق موارد بالا ایجاد یک کد RC5 بسیار راحت تر از دیکد آن میباشد و شما به راحتی میتواند در منزل با دیکد کد RC5 کنترل تلویزیون خود یک کنترل تلویزون بسازید.
جالب انجاست که عملکردها و کامندها طبق استانداری هستند که به راحتی میتوانید اونها را در وب سایت ویکی پدیا مشاهده کنید مانند جدول زیر:
گیرنده RC5 چطور کار میکند؟
همانطور که در بالا مشاهده کردید لازم است جهت ارسال یک بیت صفر یا یک ما اصطلاحا یک فرکانسی را بر روی خروجی فرستنده مدوله کنیم.
خوشبختانه گیرنده RC5 تمام زحمت باز کردن اون فرکانس را انجام میدهد و خروجی صفر و یک را تحویل ما میدهد و ما در خروجی RC5 یک خروجی منطقی صفر و یک خواهیم داشت بدون در نظر گرفتن فرکانس های مدوله شده!
یکی از معروفترین گیرنده ها SFH506 و SFH507 هست که به راحتی در بازار الکترونیک و حتی تعمیرکارهای تلویزیون میتوان آنها را پیدا نمود.
پروژه رایگان دیکد RC5 با آردوینو
در اینجا پروژه راه اندازی RC5 توسط آردوینو که در اینجا منتشر کرده بود را منتشر میکنیم.
نویسنده کد زیر سعی کرده برخی کارکرد های متفاوت را برای ریموت نیز تفسیر نماید که در کد مشخص هست ومیتوانید براحتی آن را برای نیاز خود تغییر دهید.
کد آردوینو RC5
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 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 | #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]); } } } |
در فیلم زیر نحوه اجرای این برنامه را مشاهده میکنید:
چرا هیچ جا این گیرنده رو با کدویژن راه اندازی نکردن مردم از بس گشتم من باید اینو روی یه میکرو ک ن پورت سریال داره ن پین وقفه راه بندازم
پیشنهاد میکنم زحمتش را بکشید و حتما اینجا بازنشر کنید برای بقیه 🙂
سلام خسته نباشید،چطور میشه هر کدام از این کد های ریموت کنترل را به فرمت hex format یا decimal format قابل درک برای نرم افزار گوشی آندروید Galaxy Universal Remote تبدیل کرد؟ (با حالت دسیمال و هگزادسیمال معمولی متفاوت می باشد).
سلام
روال نوشتن برنامه برای یه سیستم عاملی مثل اندرویید خیلی متفاوته به برنامه ای که برای اندرویید نوشته میشه
مطمئنا برای گوشی هایی که IRدارند برنامه های سمپل زیادی برای ارسال کد RC5 وجود داره که میتونید از اونها استفاده کنید
سلام’ در کنسولهای بازی قدیمی معروف به میکرو علاوه بر دسته بازی یک عدد تفنگ هم وجود داشت که دستگاهو به هر تلویزیونی وصل میکردین با شلیک این تفنگ به هر قسمت از صفحه تلویزیون دستگاه یا تلویزیون تشخیص میداد که آیا به پرنده در حال پرواز داخل بازی تیر خورده یا نه’ مکانیزم و عملکرد این سیستم چه جوریه?آیا با آردوینو میشه همچین چیزی ساخت?ممنون میشم کمک کنید’ لطفا طرز کارشو شرح بدین ‘سپاسگذارم
خوب خیلی ساده است ، همونطور که مشخصه تصویر داره توسط کنسول بازی ایجاد میشه ، اگر دقت کرده باشید اردک مورد نظر از درخشندگی بالایی برخورداره ، وقتی که شما تفنگ رو به سمتش گرفته باشید با توجه به درخشندگی اون قسمت از تصویر سنسور تفنگ عمل خواهد کرد
بله کار پیچیده ای نیست و فکر میکنم با آردوینو هم بشه همچین الگویی پیاده سازی کرد.