Components and supplies
5 mm LED: Red
Toggle Switch, (Off)-On
Blue LED
Arduino Nano R3
5 mm LED: Green
SparkFun Breadboard Power Supply Stick 5V/3.3V
Jumper wires (generic)
5 mm LED: Yellow
Solderless Breadboard Full Size
IR receiver (generic)
Project description
Code
IR Remote repurposing sketch
arduino
1/* 2 3 Toggle 6 LEDs using an IR remote to illustrate 4 how to re-purpose surpulus remotes so they can be 5 used to control almost any device. 6 7 This sketch learns the manufacturer's codes for 8 the 1,2,3,4,5,6 and 0 buttons on any IR remote 9 when the toggle switch is in the "Learn" or program 10 position. These values are saved in the Arduino Nano's 11 EEPROM. When the toggle switch is put in the "Run" mode, 12 these values are used to determine which key is pressed. 13 14 6 associated LEDs are then be toggled on and off by 15 the remote. This is to demonstrate how to learn and 16 ise the codes regardless of the type of IR remote. In 17 addition to LEDs, the outputs can be expanded to turn 18 on or off devices with relays, high-power transistors,etc. 19 20 Paul M Dunphy VE1DX 21 22 March 2020 23 24*/ 25 26// Include IR Remote Library developed by Ken Shirriff 27#include <IRremote.h> 28// Give the ability to read/write to the 1024 bytes of EEPROM 29#include <EEPROM.h> 30 31long unsigned int intIRCode; 32long unsigned int savedIRCodes[6]; 33long unsigned int dupeCheck[6]; 34 35// Define pin for the IR sensor 36const int Recv_Pin = 2; 37 38// Define pin constants to toggle the LEDs 39const int PinOne = 12; 40const int PinTwo = 11; 41const int PinThree = 10; 42const int PinFour = 9; 43const int PinFive = 8; 44const int PinSix = 7; 45 46// Define pin constants to read and indicate the 47// status of Run/Learn toggle switch. 48const int switchPin = 4; 49const int statusPin = 5; 50 51const unsigned long int repeatKeyPress = 0xFFFFFFFF; 52 53boolean learnMode; // Used to keep track of which 54 // mode we are in as per the toggle switch. 55boolean first_iteration; 56 57// Define integers to remember toggle states of each LED 58int togglestate1; 59int togglestate2; 60int togglestate3; 61int togglestate4; 62int togglestate5; 63int togglestate6; 64 65int current_remote_code; 66 67int remote_code_1; 68int remote_code_2; 69int remote_code_3; 70int remote_code_4; 71int remote_code_5; 72int remote_code_6; 73 74 75// Define IR Receiver and Results Objects 76IRrecv irrecv(Recv_Pin); 77decode_results results; 78 79 80 81 82void EEPROMWritelong(int address, long value) 83 84// Write a 4 byte (32bit) long integer to the EEPROM 85// Since they are 4 bytes long, they are stored at 86// address to address + 3 87 { 88 // Decompose a long integer into 4 bytes by using bitshift. 89 // One = Most significant -> Four = Least significant byte 90 byte four = (value & 0xFF); 91 byte three = ((value >> 8) & 0xFF); 92 byte two = ((value >> 16) & 0xFF); 93 byte one = ((value >> 24) & 0xFF); 94 EEPROM.write(address, four); 95 EEPROM.write(address + 1, three); 96 EEPROM.write(address + 2, two); 97 EEPROM.write(address + 3, one); 98 } 99 100 101 102 103long EEPROMReadlong(long address) 104 105// Read a 4 byte (32bit) long integer from the EEPROM. 106// Since they are 4 bytes long, they were stored at 107// address to address + 3 108 { 109 long four = EEPROM.read(address); 110 long three = EEPROM.read(address + 1); 111 long two = EEPROM.read(address + 2); 112 long one = EEPROM.read(address + 3); 113 114 //Assemble the bytes into a long integer and return 115 return ((four << 0) & 0xFF) + ((three << 8) & 0xFFFF) + 116 ((two << 16) & 0xFFFFFF) + ((one << 24) & repeatKeyPress); 117 } 118 119 120 121 122 123 124int Flip_LED(int led, int toggle_state) 125 126 { 127 if(toggle_state==0) 128 { 129 digitalWrite(led, HIGH); 130 toggle_state=1; 131 } 132 else 133 { 134 digitalWrite(led, LOW); 135 toggle_state=0; 136 } 137 return toggle_state; 138 } 139 140 141 142 143 144void Reset() 145 { 146 // Turn all LEDs off and set the toggle 147 // flags to off (0) 148 digitalWrite(PinOne, LOW); 149 digitalWrite(PinTwo, LOW); 150 digitalWrite(PinThree, LOW); 151 digitalWrite(PinFour, LOW); 152 digitalWrite(PinFive, LOW); 153 digitalWrite(PinSix, LOW); 154 togglestate1 = 0; 155 togglestate2 = 0; 156 togglestate3 = 0; 157 togglestate4 = 0; 158 togglestate5 = 0; 159 togglestate6 = 0; 160 } 161 162 163 164 165void guessType() 166 { 167 Serial.print("Remote appears to be a "); 168 switch (results.decode_type){ 169 case NEC: 170 Serial.println("NEC "); 171 break; 172 case SONY: 173 Serial.println("SONY "); 174 break; 175 case RC5: 176 Serial.println("RC5 "); 177 break; 178 case RC6: 179 Serial.println("RC6 "); 180 break; 181 case DISH: 182 Serial.println("DISH "); 183 break; 184 case SHARP: 185 Serial.println("SHARP "); 186 break; 187 case JVC: 188 Serial.println("JVC "); 189 break; 190 case SANYO: 191 Serial.println("SANYO "); 192 break; 193 case MITSUBISHI: 194 Serial.println("MITSUBISHI "); 195 break; 196 case SAMSUNG: 197 Serial.println("SAMSUNG "); 198 break; 199 case LG: 200 Serial.println("LG "); 201 break; 202 case WHYNTER: 203 Serial.println("WHYNTER "); 204 break; 205 case AIWA_RC_T501: 206 Serial.println("AIWA_RC_T501 "); 207 break; 208 case PANASONIC: 209 Serial.println("PANASONIC "); 210 break; 211 case DENON: 212 Serial.println("DENON "); 213 break; 214 default: 215 case UNKNOWN: 216 Serial.println("UNKNOWN "); 217 break; 218 } 219 } 220 221 222 223 224int learnCodeRead(int pinCode) 225 226 { 227 if (irrecv.decode(&results)) 228 { 229 pinCode = results.value; 230 } 231 return pinCode; 232 } 233 234 235 236void Confirm() 237 { 238 int i; 239 240 for(i=0; i<=20; i++) 241 { 242 digitalWrite(statusPin, HIGH); 243 delay(50); 244 digitalWrite(statusPin, LOW); 245 delay(50); 246 } 247 digitalWrite(statusPin, HIGH); // Leave "Learn" LED high 248 } 249 250 251 252 253 254void learn_Mode() 255 { 256 boolean goodCode; 257 int i, j; 258 int location; 259 int pins[6] = {12,11,10,9,8,7}; 260 261 // Start listening for each in sequence 262 if (first_iteration) 263 { 264 Serial.println(); 265 Serial.println("Entering learn mode"); 266 Serial.println(); 267 } 268 intIRCode = 0; 269 location = 0; 270 goodCode = true; 271 j = 0; 272 while ((goodCode=true) and (j<=5)) 273 { 274 for(i=0; i<=25; i++) 275 { 276 digitalWrite(pins[j], HIGH); 277 delay(200); 278 intIRCode = learnCodeRead(intIRCode); 279 digitalWrite(pins[j], LOW); 280 delay(200); 281 intIRCode = learnCodeRead(intIRCode); 282 goodCode = ((intIRCode !=repeatKeyPress) and (intIRCode !=0)); 283 if (goodCode) 284 { 285 i=30; // Trick to bail out of loop because 'break' 286 // doesn't work on loops 287 } 288 irrecv.resume(); // Start listening again 289 } 290 goodCode = (intIRCode !=repeatKeyPress and intIRCode !=0); 291 if (goodCode) 292 { 293 if (j==0) 294 { 295 guessType(); 296 } 297 Serial.print("Writing to EEPROM Location ");Serial.print(location); 298 Serial.print(" IR code = ");Serial.println(intIRCode,HEX); 299 EEPROMWritelong(location, intIRCode); 300 location = location + 4; 301 j++; 302 Confirm(); 303 intIRCode = 0; 304 irrecv.resume(); // Start listening again 305 } 306 307 } 308 Serial.println(); 309 Serial.println("Put Arduino back in run mode."); 310 while (digitalRead(switchPin) == HIGH) 311 { 312 digitalWrite(statusPin, HIGH); 313 delay(1000); 314 digitalWrite(statusPin, LOW); 315 delay(1000); 316 } 317 Serial.println(); 318 Serial.println("Returning to run mode."); 319 320 // Probably don't need to be so drastic here, but 321 // This is a "reset" to be sure we get out of learn 322 // mode and restart properly. It's *likely* OK to 323 // remove the following 4 lines. 324 delay(50); 325 Serial.flush(); 326 delay(50); 327 asm volatile (" jmp 0"); 328 } 329 330 331 332 333 334 335void run_Mode() 336 { 337 if (first_iteration) 338 { 339 Serial.println("Entering run mode"); 340 } 341 if (irrecv.decode(&results)) 342 { 343 if (results.value!=repeatKeyPress) { 344 current_remote_code = results.value; 345 Serial.print("Key press detected, IR code = "); 346 Serial.println(current_remote_code,HEX); 347 if (current_remote_code == remote_code_1) 348 { 349 togglestate1 = Flip_LED(PinOne,togglestate1); 350 } 351 else if (current_remote_code == remote_code_2) { 352 togglestate2 = Flip_LED(PinTwo,togglestate2); 353 } 354 else if (current_remote_code == remote_code_3) { 355 togglestate3 = Flip_LED(PinThree,togglestate3); 356 } 357 else if (current_remote_code == remote_code_4) { 358 togglestate4 = Flip_LED(PinFour,togglestate4); 359 } 360 else if (current_remote_code == remote_code_5) { 361 togglestate5 = Flip_LED(PinFive,togglestate5); 362 } 363 else if (current_remote_code == remote_code_6) { 364 togglestate6 = Flip_LED(PinSix,togglestate6); 365 } 366 else { 367 Reset(); 368 } 369 } 370 delay(500); // Used to get around the rapid string of data 371 // if a button is held down. Slows down response time 372 // by introducing a lag in the loop. 373 irrecv.resume(); // Start listening again 374 } 375 } 376 377 378 379 380 381void setup() 382 { 383 first_iteration = true; 384 int i,j,k; 385 int location; 386 int dupeFlash[6] = {12,11,10,9,8,7}; // Pin numbers to flash 387 // if duplicates found 388 389 Serial.begin(9600); 390 irrecv.enableIRIn(); // Enable the IR Receiver 391 392 /* The following section of code should never need to be reset the EEPROM. 393 * However, some new, off "the shelf" NANOs show up with their EEPROMs set 394 * to FFFFFFFFs. This happens to be the code sent by many IR Remotes when 395 * a key is held down. This sketch checks for that code in several places 396 * and it won't work properly if a "key" is assigned a hex FFFFFFFF. To 397 * prevent this gotcha, we check for FFFFFFFFs and if we find one, we set 398 * the 6 key locations to Sony RM-YD104 codes. If this happens, unless you 399 * are using that particular remote, you'll need to run the sketch in "learn" 400 * mode to initialise it. 401 */ 402 403// ============= Begin New Arduino ================== 404 405 boolean defaultToSony = false; 406 long unsigned int IRCode = 0; 407 location = 0; 408 for(i=0; i<=5; i++) 409 { 410 IRCode = EEPROMReadlong(location); 411 if (IRCode==repeatKeyPress) 412 { 413 defaultToSony = true; 414 } 415 location = location + 4; 416 } 417 if (defaultToSony) 418 { 419 Serial.println("HEX FFFFFFFF found in EEPROM memory. Setting codes"); 420 Serial.println("for a Sony RM-YD104 remote. Running 'learn' mode now"); 421 Serial.println("is recommended unless that's the remote you have."); 422 EEPROMWritelong(0, 0x10); 423 delay(50); 424 EEPROMWritelong(4, 0x810); 425 delay(50); 426 EEPROMWritelong(8, 0x410); 427 delay(50); 428 EEPROMWritelong(12, 0xC10); 429 delay(50); 430 EEPROMWritelong(16, 0x210); 431 delay(50); 432 EEPROMWritelong(20, 0xA10); 433 delay(50); 434 } 435 436 437// ============= End New Arduino ================== 438 439 // Set LED pins as outputs 440 pinMode(PinOne, OUTPUT); 441 pinMode(PinTwo, OUTPUT); 442 pinMode(PinThree, OUTPUT); 443 pinMode(PinFour, OUTPUT); 444 pinMode(PinFive, OUTPUT); 445 pinMode(PinSix, OUTPUT); 446 447 Reset(); // Start out with them all off 448 449 pinMode(statusPin, OUTPUT); 450 pinMode(switchPin, INPUT); 451 452 //Get codes from last used remote 453 Serial.println(); 454 Serial.println("Reading stored IR remote codes . . . "); 455 location = 0; 456 for(j=0; j<=5; j++) 457 { 458 savedIRCodes[j] = EEPROMReadlong(location); 459 Serial.print("Reading from EEPROM Location ");Serial.print(location); 460 Serial.print(" IR code = ");Serial.println(savedIRCodes[j],HEX); 461 location = location + 4; 462 dupeCheck[j]=savedIRCodes[j]; // Save a copy for duplicate checking 463 } 464 465 // Look for consecutive duplicate codes assigned to the 466 // outputs. We don't look for overall duplicates because 467 // they are unlikely to happen. Experience has shown that 468 // during programming, the most likely mistake is to press 469 // the same key twice on bacl-to-back LEDs. If duplicates 470 // are found, indicate this by flashing the suspect LEDs. 471 // There are only 6 LEDs, so it only takes 21 comparisons 472 // to find any duplicates (6 + 5 + 4 + 3 + 2 + 1 = 21). This 473 // section could be enhanced to look for any duplicates by 474 // sorting the array first, etc. 475 for (i = 0; i <5 - 1; i++) 476 { 477 for (j = i + 1; j <6; j++) 478 { 479 if (dupeCheck[i] == dupeCheck[j]) 480 { 481 Serial.println("Duplicate codes found. Suggest re-running learn mode"); 482 for(k=0; k<=5; k++) 483 { 484 digitalWrite(dupeFlash[i],HIGH); 485 digitalWrite(dupeFlash[j],HIGH); 486 delay(1000); 487 digitalWrite(dupeFlash[i],LOW); 488 digitalWrite(dupeFlash[j],LOW); 489 delay(1000); 490 } 491 } 492 } 493 } 494 495 remote_code_1 = savedIRCodes[0]; 496 remote_code_2 = savedIRCodes[1]; 497 remote_code_3 = savedIRCodes[2]; 498 remote_code_4 = savedIRCodes[3]; 499 remote_code_5 = savedIRCodes[4]; 500 remote_code_6 = savedIRCodes[5]; 501 delay(1000); 502 Serial.println("Stored codes read."); 503 Serial.println(); 504 } 505 506 507 508 509 510void loop() 511 { 512 // Check if the toggle is on or off. If it is on (in learn mode) 513 // the switchPin is HIGH: 514 learnMode = (digitalRead(switchPin) == HIGH); 515 if (learnMode) 516 { 517 first_iteration = true; 518 Reset(); 519 digitalWrite(statusPin, HIGH); // Turn learn mode LED on: 520 learn_Mode(); 521 Reset(); 522 first_iteration = false; 523 } 524 else 525 { 526 digitalWrite(statusPin, LOW); // Turn learn mode LED off: 527 run_Mode(); 528 first_iteration = false; 529 } 530 531 }
IR Remote repurposing sketch
arduino
1/* 2 3 Toggle 6 LEDs using an IR remote to illustrate 4 how to 5 re-purpose surpulus remotes so they can be 6 used to control almost any device. 7 8 9 This sketch learns the manufacturer's codes for 10 the 1,2,3,4,5,6 and 11 0 buttons on any IR remote 12 when the toggle switch is in the "Learn" or program 13 14 position. These values are saved in the Arduino Nano's 15 EEPROM. When the 16 toggle switch is put in the "Run" mode, 17 these values are used to determine 18 which key is pressed. 19 20 6 associated LEDs are then be toggled on and off 21 by 22 the remote. This is to demonstrate how to learn and 23 ise the codes 24 regardless of the type of IR remote. In 25 addition to LEDs, the outputs can 26 be expanded to turn 27 on or off devices with relays, high-power transistors,etc. 28 29 30 Paul M Dunphy VE1DX 31 32 March 2020 33 34*/ 35 36// Include IR 37 Remote Library developed by Ken Shirriff 38#include <IRremote.h> 39// Give the 40 ability to read/write to the 1024 bytes of EEPROM 41#include <EEPROM.h> 42 43long 44 unsigned int intIRCode; 45long unsigned int savedIRCodes[6]; 46long unsigned int 47 dupeCheck[6]; 48 49// Define pin for the IR sensor 50const int Recv_Pin = 2; 51 52 53// Define pin constants to toggle the LEDs 54const int PinOne = 12; 55const 56 int PinTwo = 11; 57const int PinThree = 10; 58const int PinFour = 9; 59const 60 int PinFive = 8; 61const int PinSix = 7; 62 63// Define pin constants 64 to read and indicate the 65// status of Run/Learn toggle switch. 66const int switchPin 67 = 4; 68const int statusPin = 5; 69 70const unsigned long int repeatKeyPress 71 = 0xFFFFFFFF; 72 73boolean learnMode; // Used to keep track of which 74 // 75 mode we are in as per the toggle switch. 76boolean first_iteration; 77 78// 79 Define integers to remember toggle states of each LED 80int togglestate1; 81int 82 togglestate2; 83int togglestate3; 84int togglestate4; 85int togglestate5; 86int 87 togglestate6; 88 89int current_remote_code; 90 91int remote_code_1; 92int 93 remote_code_2; 94int remote_code_3; 95int remote_code_4; 96int remote_code_5; 97int 98 remote_code_6; 99 100 101// Define IR Receiver and Results Objects 102IRrecv 103 irrecv(Recv_Pin); 104decode_results results; 105 106 107 108 109void EEPROMWritelong(int 110 address, long value) 111 112// Write a 4 byte (32bit) long integer to the EEPROM 113// 114 Since they are 4 bytes long, they are stored at 115// address to address + 3 116 117 { 118 // Decompose a long integer into 4 bytes by using bitshift. 119 // 120 One = Most significant -> Four = Least significant byte 121 byte four = (value 122 & 0xFF); 123 byte three = ((value >> 8) & 0xFF); 124 byte two = ((value 125 >> 16) & 0xFF); 126 byte one = ((value >> 24) & 0xFF); 127 EEPROM.write(address, 128 four); 129 EEPROM.write(address + 1, three); 130 EEPROM.write(address 131 + 2, two); 132 EEPROM.write(address + 3, one); 133 } 134 135 136 137 138long 139 EEPROMReadlong(long address) 140 141// Read a 4 byte (32bit) long integer from the 142 EEPROM. 143// Since they are 4 bytes long, they were stored at 144// address to 145 address + 3 146 { 147 long four = EEPROM.read(address); 148 long three 149 = EEPROM.read(address + 1); 150 long two = EEPROM.read(address + 2); 151 152 long one = EEPROM.read(address + 3); 153 154 //Assemble the bytes into 155 a long integer and return 156 return ((four << 0) & 0xFF) + ((three << 8) & 157 0xFFFF) + 158 ((two << 16) & 0xFFFFFF) + ((one << 24) & repeatKeyPress); 159 160 } 161 162 163 164 165 166 167int Flip_LED(int led, int toggle_state) 168 169 170 { 171 if(toggle_state==0) 172 { 173 digitalWrite(led, HIGH); 174 175 toggle_state=1; 176 } 177 else 178 { 179 digitalWrite(led, 180 LOW); 181 toggle_state=0; 182 } 183 return toggle_state; 184 185 } 186 187 188 189 190 191void Reset() 192 { 193 // Turn all LEDs off and set 194 the toggle 195 // flags to off (0) 196 digitalWrite(PinOne, LOW); 197 digitalWrite(PinTwo, 198 LOW); 199 digitalWrite(PinThree, LOW); 200 digitalWrite(PinFour, LOW); 201 202 digitalWrite(PinFive, LOW); 203 digitalWrite(PinSix, LOW); 204 togglestate1 205 = 0; 206 togglestate2 = 0; 207 togglestate3 = 0; 208 togglestate4 = 0; 209 210 togglestate5 = 0; 211 togglestate6 = 0; 212 } 213 214 215 216 217void guessType() 218 219 { 220 Serial.print("Remote appears to be a "); 221 switch (results.decode_type){ 222 223 case NEC: 224 Serial.println("NEC "); 225 break; 226 case 227 SONY: 228 Serial.println("SONY "); 229 break; 230 case RC5: 231 232 Serial.println("RC5 "); 233 break; 234 case RC6: 235 Serial.println("RC6 236 "); 237 break; 238 case DISH: 239 Serial.println("DISH "); 240 241 break; 242 case SHARP: 243 Serial.println("SHARP "); 244 245 break; 246 case JVC: 247 Serial.println("JVC "); 248 break; 249 250 case SANYO: 251 Serial.println("SANYO "); 252 break; 253 case 254 MITSUBISHI: 255 Serial.println("MITSUBISHI "); 256 break; 257 case 258 SAMSUNG: 259 Serial.println("SAMSUNG "); 260 break; 261 case 262 LG: 263 Serial.println("LG "); 264 break; 265 case WHYNTER: 266 267 Serial.println("WHYNTER "); 268 break; 269 case AIWA_RC_T501: 270 271 Serial.println("AIWA_RC_T501 "); 272 break; 273 case 274 PANASONIC: 275 Serial.println("PANASONIC "); 276 break; 277 278 case DENON: 279 Serial.println("DENON "); 280 break; 281 282 default: 283 case UNKNOWN: 284 Serial.println("UNKNOWN "); 285 286 break; 287 } 288 } 289 290 291 292 293int learnCodeRead(int 294 pinCode) 295 296 { 297 if (irrecv.decode(&results)) 298 { 299 pinCode 300 = results.value; 301 } 302 return pinCode; 303 } 304 305 306 307void 308 Confirm() 309 { 310 int i; 311 312 for(i=0; i<=20; i++) 313 { 314 digitalWrite(statusPin, 315 HIGH); 316 delay(50); 317 digitalWrite(statusPin, LOW); 318 delay(50); 319 320 } 321 digitalWrite(statusPin, HIGH); // Leave "Learn" LED high 322 323 } 324 325 326 327 328 329void learn_Mode() 330 { 331 boolean goodCode; 332 333 int i, j; 334 int location; 335 int pins[6] = {12,11,10,9,8,7}; 336 337 338 // Start listening for each in sequence 339 if (first_iteration) 340 341 { 342 Serial.println(); 343 Serial.println("Entering 344 learn mode"); 345 Serial.println(); 346 } 347 intIRCode = 0; 348 349 location = 0; 350 goodCode = true; 351 j = 0; 352 while ((goodCode=true) 353 and (j<=5)) 354 { 355 for(i=0; i<=25; i++) 356 { 357 digitalWrite(pins[j], 358 HIGH); 359 delay(200); 360 intIRCode = learnCodeRead(intIRCode); 361 362 digitalWrite(pins[j], LOW); 363 delay(200); 364 intIRCode 365 = learnCodeRead(intIRCode); 366 goodCode = ((intIRCode !=repeatKeyPress) 367 and (intIRCode !=0)); 368 if (goodCode) 369 { 370 i=30; 371 // Trick to bail out of loop because 'break' 372 // doesn't 373 work on loops 374 } 375 irrecv.resume(); // Start listening 376 again 377 } 378 goodCode = (intIRCode !=repeatKeyPress and intIRCode 379 !=0); 380 if (goodCode) 381 { 382 if (j==0) 383 { 384 385 guessType(); 386 } 387 Serial.print("Writing 388 to EEPROM Location ");Serial.print(location); 389 Serial.print(" IR 390 code = ");Serial.println(intIRCode,HEX); 391 EEPROMWritelong(location, 392 intIRCode); 393 location = location + 4; 394 j++; 395 396 Confirm(); 397 intIRCode = 0; 398 irrecv.resume(); 399 // Start listening again 400 } 401 402 } 403 Serial.println(); 404 405 Serial.println("Put Arduino back in run mode."); 406 while (digitalRead(switchPin) 407 == HIGH) 408 { 409 digitalWrite(statusPin, HIGH); 410 delay(1000); 411 412 digitalWrite(statusPin, LOW); 413 delay(1000); 414 } 415 416 Serial.println(); 417 Serial.println("Returning to run mode."); 418 419 420 // Probably don't need to be so drastic here, but 421 // 422 This is a "reset" to be sure we get out of learn 423 // mode and restart 424 properly. It's *likely* OK to 425 // remove the following 4 lines. 426 delay(50); 427 428 Serial.flush(); 429 delay(50); 430 asm volatile (" jmp 431 0"); 432 } 433 434 435 436 437 438 439void run_Mode() 440 { 441 if (first_iteration) 442 443 { 444 Serial.println("Entering run mode"); 445 } 446 if 447 (irrecv.decode(&results)) 448 { 449 if (results.value!=repeatKeyPress) 450 { 451 current_remote_code = results.value; 452 Serial.print("Key 453 press detected, IR code = "); 454 Serial.println(current_remote_code,HEX); 455 456 if (current_remote_code == remote_code_1) 457 { 458 togglestate1 459 = Flip_LED(PinOne,togglestate1); 460 } 461 else if (current_remote_code 462 == remote_code_2) { 463 togglestate2 = Flip_LED(PinTwo,togglestate2); 464 465 } 466 else if (current_remote_code == remote_code_3) 467 { 468 togglestate3 = Flip_LED(PinThree,togglestate3); 469 } 470 471 else if (current_remote_code == remote_code_4) { 472 togglestate4 473 = Flip_LED(PinFour,togglestate4); 474 } 475 else 476 if (current_remote_code == remote_code_5) { 477 togglestate5 = Flip_LED(PinFive,togglestate5); 478 479 } 480 else if (current_remote_code == remote_code_6) 481 { 482 togglestate6 = Flip_LED(PinSix,togglestate6); 483 } 484 485 else { 486 Reset(); 487 } 488 } 489 490 delay(500); // Used to get around the rapid string of data 491 492 // if a button is held down. Slows down response time 493 494 // by introducing a lag in the loop. 495 496 irrecv.resume(); // Start listening again 497 } 498 } 499 500 501 502 503 504 505void setup() 506 { 507 first_iteration = true; 508 int i,j,k; 509 510 int location; 511 int dupeFlash[6] = {12,11,10,9,8,7}; // Pin numbers to 512 flash 513 // if duplicates found 514 515 516 Serial.begin(9600); 517 irrecv.enableIRIn(); // Enable the IR Receiver 518 519 520 /* The following section of code should never need to be reset the EEPROM. 521 * 522 However, some new, off "the shelf" NANOs show up with their EEPROMs set 523 * 524 to FFFFFFFFs. This happens to be the code sent by many IR Remotes when 525 * a 526 key is held down. This sketch checks for that code in several places 527 * and 528 it won't work properly if a "key" is assigned a hex FFFFFFFF. To 529 * prevent 530 this gotcha, we check for FFFFFFFFs and if we find one, we set 531 * the 6 key 532 locations to Sony RM-YD104 codes. If this happens, unless you 533 * are using 534 that particular remote, you'll need to run the sketch in "learn" 535 * mode to 536 initialise it. 537 */ 538 539// ============= Begin New Arduino ================== 540 541 542 boolean defaultToSony = false; 543 long unsigned int IRCode = 0; 544 location 545 = 0; 546 for(i=0; i<=5; i++) 547 { 548 IRCode = EEPROMReadlong(location); 549 550 if (IRCode==repeatKeyPress) 551 { 552 defaultToSony 553 = true; 554 } 555 location = location + 4; 556 } 557 558 if (defaultToSony) 559 { 560 Serial.println("HEX FFFFFFFF 561 found in EEPROM memory. Setting codes"); 562 Serial.println("for a Sony 563 RM-YD104 remote. Running 'learn' mode now"); 564 Serial.println("is recommended 565 unless that's the remote you have."); 566 EEPROMWritelong(0, 0x10); 567 568 delay(50); 569 EEPROMWritelong(4, 0x810); 570 delay(50); 571 572 EEPROMWritelong(8, 0x410); 573 delay(50); 574 EEPROMWritelong(12, 575 0xC10); 576 delay(50); 577 EEPROMWritelong(16, 0x210); 578 delay(50); 579 580 EEPROMWritelong(20, 0xA10); 581 delay(50); 582 583 } 584 585 586// ============= End New Arduino ================== 587 588 589 // Set LED pins as outputs 590 pinMode(PinOne, OUTPUT); 591 pinMode(PinTwo, 592 OUTPUT); 593 pinMode(PinThree, OUTPUT); 594 pinMode(PinFour, OUTPUT); 595 596 pinMode(PinFive, OUTPUT); 597 pinMode(PinSix, OUTPUT); 598 599 Reset(); 600 // Start out with them all off 601 602 pinMode(statusPin, OUTPUT); 603 pinMode(switchPin, 604 INPUT); 605 606 //Get codes from last used remote 607 Serial.println(); 608 609 Serial.println("Reading stored IR remote codes . . . "); 610 location 611 = 0; 612 for(j=0; j<=5; j++) 613 { 614 savedIRCodes[j] = EEPROMReadlong(location); 615 616 Serial.print("Reading from EEPROM Location ");Serial.print(location); 617 618 Serial.print(" IR code = ");Serial.println(savedIRCodes[j],HEX); 619 620 location = location + 4; 621 dupeCheck[j]=savedIRCodes[j]; // Save 622 a copy for duplicate checking 623 } 624 625 // Look for consecutive duplicate 626 codes assigned to the 627 // outputs. We don't look for overall duplicates because 628 629 // they are unlikely to happen. Experience has shown that 630 // during 631 programming, the most likely mistake is to press 632 // the same key twice on 633 bacl-to-back LEDs. If duplicates 634 // are found, indicate this by flashing 635 the suspect LEDs. 636 // There are only 6 LEDs, so it only takes 21 comparisons 637 638 // to find any duplicates (6 + 5 + 4 + 3 + 2 + 1 = 21). This 639 // section 640 could be enhanced to look for any duplicates by 641 // sorting the array first, 642 etc. 643 for (i = 0; i <5 - 1; i++) 644 { 645 for (j = i + 1; j 646 <6; j++) 647 { 648 if (dupeCheck[i] == dupeCheck[j]) 649 { 650 651 Serial.println("Duplicate codes found. Suggest re-running learn mode"); 652 653 for(k=0; k<=5; k++) 654 { 655 digitalWrite(dupeFlash[i],HIGH); 656 657 digitalWrite(dupeFlash[j],HIGH); 658 delay(1000); 659 660 digitalWrite(dupeFlash[i],LOW); 661 digitalWrite(dupeFlash[j],LOW); 662 663 delay(1000); 664 } 665 } 666 } 667 668 } 669 670 remote_code_1 = savedIRCodes[0]; 671 remote_code_2 672 = savedIRCodes[1]; 673 remote_code_3 = savedIRCodes[2]; 674 remote_code_4 675 = savedIRCodes[3]; 676 remote_code_5 = savedIRCodes[4]; 677 remote_code_6 678 = savedIRCodes[5]; 679 delay(1000); 680 Serial.println("Stored codes 681 read."); 682 Serial.println(); 683 } 684 685 686 687 688 689void 690 loop() 691 { 692 // Check if the toggle is on or off. If it is on (in learn 693 mode) 694 // the switchPin is HIGH: 695 learnMode = (digitalRead(switchPin) 696 == HIGH); 697 if (learnMode) 698 { 699 first_iteration = true; 700 701 Reset(); 702 digitalWrite(statusPin, HIGH); // Turn learn mode LED 703 on: 704 learn_Mode(); 705 Reset(); 706 first_iteration = false; 707 708 } 709 else 710 { 711 digitalWrite(statusPin, LOW); 712 // Turn learn mode LED off: 713 run_Mode(); 714 first_iteration 715 = false; 716 } 717 718 }
Downloadable files
Breadboard layout with a Nano
Breadboard layout with a Nano
Comments
Only logged in users can leave comments
VE1DX
0 Followers
•0 Projects
Table of contents
Intro
33
0