Advertisement
w0lfiesmith

Arduino IR Prank Project

Sep 20th, 2013
3,156
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 6.20 KB | None | 0 0
  1. /*
  2.  * IRprank: record and play back 10 IR signals 8
  3.  * An IR detector/demodulator must be connected to the input RECV_PIN.
  4.  * An IR LED must be connected to the output PWM pin 3.
  5.  * A button must be connected to the input BUTTON_PIN; this is the
  6.  * send button.
  7.  * A visible LED can be connected to STATUS_PIN to provide status.
  8.  *
  9.  * The logic is:
  10.  * If the button is pressed, send the IR code.
  11.  * If an IR code is received, record it.
  12.  *
  13.  * Version 0.11 September, 2009
  14.  * Copyright 2009 Ken Shirriff
  15.  * http://arcfn.com
  16.  * Modified by James Bruce, http://www.makeuseof.com/tag/author/jbruce
  17.  */
  18.  
  19. #include <IRremote.h>
  20.  
  21. int RECV_PIN = 11;
  22. int BUTTON_PIN = 6;
  23. int STATUS_PIN = 13;
  24.  
  25. IRrecv irrecv(RECV_PIN);
  26. IRsend irsend;
  27.  
  28. decode_results results;
  29.  
  30. void setup()
  31. {
  32.   Serial.begin(9600);
  33.   irrecv.enableIRIn(); // Start the receiver
  34.   pinMode(BUTTON_PIN, INPUT);
  35.   pinMode(STATUS_PIN, OUTPUT);
  36. }
  37.  
  38. // Storage for the recorded code
  39. int codeType = -1; // The type of code
  40. unsigned long codeValue; // The code value if not raw
  41. unsigned int rawCodes[RAWBUF]; // The durations if raw
  42. int codeLen; // The length of the code
  43. int toggle = 0; // The RC5/6 toggle state
  44.  
  45. /* Modifications for IR prank */
  46. int codeTypes[10];
  47. unsigned long codeValues[10];
  48. int codeLens[10];
  49. int currentSignalIndex = 0;
  50. int maxStoredSignals = 10;
  51. boolean canRecordMore = true; // false when maximum signals is received, must reset to change the signal pattern
  52. boolean playingBack = false; // used to toggle playback mode via button presses
  53.  
  54. // Stores the code for later playback
  55. // Most of this code is just logging
  56. void storeCode(decode_results *results) {
  57.   codeType = results->decode_type;
  58.   int count = results->rawlen;
  59.   if (codeType == UNKNOWN) {
  60.     Serial.println("Received unknown code, saving as raw");
  61.     codeLen = results->rawlen - 1;
  62.     // To store raw codes:
  63.     // Drop first value (gap)
  64.     // Convert from ticks to microseconds
  65.     // Tweak marks shorter, and spaces longer to cancel out IR receiver distortion
  66.     for (int i = 1; i <= codeLen; i++) {
  67.       if (i % 2) {
  68.         // Mark
  69.         rawCodes[i - 1] = results->rawbuf[i]*USECPERTICK - MARK_EXCESS;
  70.         Serial.print(" m");
  71.       }
  72.       else {
  73.         // Space
  74.         rawCodes[i - 1] = results->rawbuf[i]*USECPERTICK + MARK_EXCESS;
  75.         Serial.print(" s");
  76.       }
  77.       Serial.print(rawCodes[i - 1], DEC);
  78.     }
  79.     Serial.println("");
  80.   }
  81.   else {
  82.     if (codeType == NEC) {
  83.       Serial.print("Received NEC: ");
  84.       if (results->value == REPEAT) {
  85.         // Don't record a NEC repeat value as that's useless.
  86.         Serial.println("repeat; ignoring.");
  87.         return;
  88.       }
  89.     }
  90.     else if (codeType == SONY) {
  91.       Serial.print("Received SONY: ");
  92.     }
  93.     else if (codeType == RC5) {
  94.       Serial.print("Received RC5: ");
  95.     }
  96.     else if (codeType == RC6) {
  97.       Serial.print("Received RC6: ");
  98.     }
  99.     else {
  100.       Serial.print("Unexpected codeType ");
  101.       Serial.print(codeType, DEC);
  102.       Serial.println("");
  103.     }
  104.     Serial.println(results->value, HEX);
  105.     codeValue = results->value;
  106.     codeLen = results->bits;
  107.   }
  108.  
  109.   /* Store in the array of values */
  110.   codeLens[currentSignalIndex] = codeLen;
  111.   codeValues[currentSignalIndex] = codeValue;
  112.   codeTypes[currentSignalIndex] = codeType;
  113.   currentSignalIndex++;
  114. }
  115.  
  116. void sendCode(int repeat) {
  117.   if (codeType == NEC) {
  118.     if (repeat) {
  119.       irsend.sendNEC(REPEAT, codeLen);
  120.       Serial.println("Sent NEC repeat");
  121.     }
  122.     else {
  123.       irsend.sendNEC(codeValue, codeLen);
  124.       Serial.print("Sent NEC ");
  125.       Serial.println(codeValue, HEX);
  126.     }
  127.   }
  128.   else if (codeType == SONY) {
  129.     irsend.sendSony(codeValue, codeLen);
  130.     Serial.print("Sent Sony ");
  131.     Serial.println(codeValue, HEX);
  132.   }
  133.   else if (codeType == RC5 || codeType == RC6) {
  134.     if (!repeat) {
  135.       // Flip the toggle bit for a new button press
  136.       toggle = 1 - toggle;
  137.     }
  138.     // Put the toggle bit into the code to send
  139.     codeValue = codeValue & ~(1 << (codeLen - 1));
  140.     codeValue = codeValue | (toggle << (codeLen - 1));
  141.     if (codeType == RC5) {
  142.       Serial.print("Sent RC5 ");
  143.       Serial.println(codeValue, HEX);
  144.       irsend.sendRC5(codeValue, codeLen);
  145.     }
  146.     else {
  147.       irsend.sendRC6(codeValue, codeLen);
  148.       Serial.print("Sent RC6 ");
  149.       Serial.println(codeValue, HEX);
  150.     }
  151.   }
  152.   else if (codeType == UNKNOWN /* i.e. raw */) {
  153.     // Assume 38 KHz
  154.     irsend.sendRaw(rawCodes, codeLen, 38);
  155.     Serial.println("Sent raw");
  156.   }
  157. }
  158.  
  159. int lastButtonState;
  160.  
  161. void loop() {
  162.   // If button pressed, send the code.
  163.   int buttonState = digitalRead(BUTTON_PIN);
  164.  
  165.   if (lastButtonState == HIGH && buttonState == LOW) {
  166.     Serial.println("Toggling playback mode");
  167.    
  168.     //Toggle whichever mode is currently on
  169.     playingBack = !playingBack;
  170.     currentSignalIndex = 0; // reset to first signal reagrd,ess of mode
  171.   }
  172.  
  173.   if(playingBack){
  174.      if(currentSignalIndex == maxStoredSignals){
  175.         currentSignalIndex = 0; //reset index upon reaching maximum
  176.      }
  177.      
  178.      codeType = codeTypes[currentSignalIndex];
  179.      codeLen = codeLens[currentSignalIndex];
  180.      codeValue = codeValues[currentSignalIndex];
  181.      Serial.print("Sending single at index ");
  182.      Serial.println(currentSignalIndex);
  183.      sendCode(false);
  184.     digitalWrite(STATUS_PIN, HIGH);
  185.     //sendCode(lastButtonState == buttonState); // repeats are difficult to deal with when you have multiple signals, let's just default to 1 repeat
  186.    
  187.     digitalWrite(STATUS_PIN, LOW);
  188.     delay(1000); // Wait a bit between retransmissions
  189.     currentSignalIndex++;
  190.   }
  191.   else{
  192.     //switched to inert mode, listen or wait
  193.     if (irrecv.decode(&results) && canRecordMore) {
  194.       digitalWrite(STATUS_PIN, HIGH);
  195.       storeCode(&results);
  196.       if(currentSignalIndex == maxStoredSignals){
  197.         Serial.println("Stored as many as we can, waiting for playback trigger");
  198.         canRecordMore = false; // Reset arduino to allow for more signals to be recorded  
  199.       }
  200.       else{
  201.         irrecv.resume(); // resume receiver
  202.         digitalWrite(STATUS_PIN, LOW);
  203.       }
  204.     }
  205.   }
  206.  
  207.  
  208.   lastButtonState = buttonState;
  209. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement