You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

184 lines
4.9KB

  1. /*
  2. * IRrecord: record and play back IR signals as a minimal
  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. */
  17. #include <IRremote.h>
  18. int RECV_PIN = 11;
  19. int BUTTON_PIN = 12;
  20. int STATUS_PIN = 13;
  21. IRrecv irrecv(RECV_PIN);
  22. IRsend irsend;
  23. decode_results results;
  24. void setup()
  25. {
  26. Serial.begin(9600);
  27. irrecv.enableIRIn(); // Start the receiver
  28. pinMode(BUTTON_PIN, INPUT);
  29. pinMode(STATUS_PIN, OUTPUT);
  30. }
  31. // Storage for the recorded code
  32. int codeType = -1; // The type of code
  33. unsigned long codeValue; // The code value if not raw
  34. unsigned int rawCodes[RAWBUF]; // The durations if raw
  35. int codeLen; // The length of the code
  36. int toggle = 0; // The RC5/6 toggle state
  37. // Stores the code for later playback
  38. // Most of this code is just logging
  39. void storeCode(decode_results *results) {
  40. codeType = results->decode_type;
  41. //int count = results->rawlen;
  42. if (codeType == UNKNOWN) {
  43. Serial.println("Received unknown code, saving as raw");
  44. codeLen = results->rawlen - 1;
  45. // To store raw codes:
  46. // Drop first value (gap)
  47. // Convert from ticks to microseconds
  48. // Tweak marks shorter, and spaces longer to cancel out IR receiver distortion
  49. for (int i = 1; i <= codeLen; i++) {
  50. if (i % 2) {
  51. // Mark
  52. rawCodes[i - 1] = results->rawbuf[i]*USECPERTICK - MARK_EXCESS;
  53. Serial.print(" m");
  54. }
  55. else {
  56. // Space
  57. rawCodes[i - 1] = results->rawbuf[i]*USECPERTICK + MARK_EXCESS;
  58. Serial.print(" s");
  59. }
  60. Serial.print(rawCodes[i - 1], DEC);
  61. }
  62. Serial.println("");
  63. }
  64. else {
  65. if (codeType == NEC) {
  66. Serial.print("Received NEC: ");
  67. if (results->value == REPEAT) {
  68. // Don't record a NEC repeat value as that's useless.
  69. Serial.println("repeat; ignoring.");
  70. return;
  71. }
  72. }
  73. else if (codeType == SONY) {
  74. Serial.print("Received SONY: ");
  75. }
  76. else if (codeType == PANASONIC) {
  77. Serial.print("Received PANASONIC: ");
  78. }
  79. else if (codeType == JVC) {
  80. Serial.print("Received JVC: ");
  81. }
  82. else if (codeType == RC5) {
  83. Serial.print("Received RC5: ");
  84. }
  85. else if (codeType == RC6) {
  86. Serial.print("Received RC6: ");
  87. }
  88. else {
  89. Serial.print("Unexpected codeType ");
  90. Serial.print(codeType, DEC);
  91. Serial.println("");
  92. }
  93. Serial.println(results->value, HEX);
  94. codeValue = results->value;
  95. codeLen = results->bits;
  96. }
  97. }
  98. void sendCode(int repeat) {
  99. if (codeType == NEC) {
  100. if (repeat) {
  101. irsend.sendNEC(REPEAT, codeLen);
  102. Serial.println("Sent NEC repeat");
  103. }
  104. else {
  105. irsend.sendNEC(codeValue, codeLen);
  106. Serial.print("Sent NEC ");
  107. Serial.println(codeValue, HEX);
  108. }
  109. }
  110. else if (codeType == SONY) {
  111. irsend.sendSony(codeValue, codeLen);
  112. Serial.print("Sent Sony ");
  113. Serial.println(codeValue, HEX);
  114. }
  115. else if (codeType == PANASONIC) {
  116. irsend.sendPanasonic(codeValue, codeLen);
  117. Serial.print("Sent Panasonic");
  118. Serial.println(codeValue, HEX);
  119. }
  120. else if (codeType == JVC) {
  121. irsend.sendJVC(codeValue, codeLen, false);
  122. Serial.print("Sent JVC");
  123. Serial.println(codeValue, HEX);
  124. }
  125. else if (codeType == RC5 || codeType == RC6) {
  126. if (!repeat) {
  127. // Flip the toggle bit for a new button press
  128. toggle = 1 - toggle;
  129. }
  130. // Put the toggle bit into the code to send
  131. codeValue = codeValue & ~(1 << (codeLen - 1));
  132. codeValue = codeValue | (toggle << (codeLen - 1));
  133. if (codeType == RC5) {
  134. Serial.print("Sent RC5 ");
  135. Serial.println(codeValue, HEX);
  136. irsend.sendRC5(codeValue, codeLen);
  137. }
  138. else {
  139. irsend.sendRC6(codeValue, codeLen);
  140. Serial.print("Sent RC6 ");
  141. Serial.println(codeValue, HEX);
  142. }
  143. }
  144. else if (codeType == UNKNOWN /* i.e. raw */) {
  145. // Assume 38 KHz
  146. irsend.sendRaw(rawCodes, codeLen, 38);
  147. Serial.println("Sent raw");
  148. }
  149. }
  150. int lastButtonState;
  151. void loop() {
  152. // If button pressed, send the code.
  153. int buttonState = digitalRead(BUTTON_PIN);
  154. if (lastButtonState == HIGH && buttonState == LOW) {
  155. Serial.println("Released");
  156. irrecv.enableIRIn(); // Re-enable receiver
  157. }
  158. if (buttonState) {
  159. Serial.println("Pressed, sending");
  160. digitalWrite(STATUS_PIN, HIGH);
  161. sendCode(lastButtonState == buttonState);
  162. digitalWrite(STATUS_PIN, LOW);
  163. delay(50); // Wait a bit between retransmissions
  164. }
  165. else if (irrecv.decode(&results)) {
  166. digitalWrite(STATUS_PIN, HIGH);
  167. storeCode(&results);
  168. irrecv.resume(); // resume receiver
  169. digitalWrite(STATUS_PIN, LOW);
  170. }
  171. lastButtonState = buttonState;
  172. }