IRrecvDumpV2.ino 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262
  1. /*
  2. * IRremoteESP8266: IRrecvDumpV2 - dump details of IR codes with IRrecv
  3. * An IR detector/demodulator must be connected to the input kRecvPin.
  4. *
  5. * Copyright 2009 Ken Shirriff, http://arcfn.com
  6. * Copyright 2017 David Conran
  7. *
  8. * Example circuit diagram:
  9. * https://github.com/markszabo/IRremoteESP8266/wiki#ir-receiving
  10. *
  11. * Changes:
  12. * Version 0.4 July, 2018
  13. * - Minor improvements and more A/C unit support.
  14. * Version 0.3 November, 2017
  15. * - Support for A/C decoding for some protcols.
  16. * Version 0.2 April, 2017
  17. * - Decode from a copy of the data so we can start capturing faster thus
  18. * reduce the likelihood of miscaptures.
  19. * Based on Ken Shirriff's IrsendDemo Version 0.1 July, 2009,
  20. */
  21. #ifndef UNIT_TEST
  22. #include <Arduino.h>
  23. #endif
  24. #include <IRrecv.h>
  25. #include <IRremoteESP8266.h>
  26. #include <IRutils.h>
  27. // The following are only needed for extended decoding of A/C Messages
  28. #include <ir_Coolix.h>
  29. #include <ir_Daikin.h>
  30. #include <ir_Fujitsu.h>
  31. #include <ir_Gree.h>
  32. #include <ir_Haier.h>
  33. #include <ir_Hitachi.h>
  34. #include <ir_Kelvinator.h>
  35. #include <ir_Midea.h>
  36. #include <ir_Mitsubishi.h>
  37. #include <ir_Panasonic.h>
  38. #include <ir_Samsung.h>
  39. #include <ir_Toshiba.h>
  40. // ==================== start of TUNEABLE PARAMETERS ====================
  41. // An IR detector/demodulator is connected to GPIO pin 14
  42. // e.g. D5 on a NodeMCU board.
  43. const uint16_t kRecvPin = 14;
  44. // The Serial connection baud rate.
  45. // i.e. Status message will be sent to the PC at this baud rate.
  46. // Try to avoid slow speeds like 9600, as you will miss messages and
  47. // cause other problems. 115200 (or faster) is recommended.
  48. // NOTE: Make sure you set your Serial Monitor to the same speed.
  49. const uint32_t kBaudRate = 115200;
  50. // As this program is a special purpose capture/decoder, let us use a larger
  51. // than normal buffer so we can handle Air Conditioner remote codes.
  52. const uint16_t kCaptureBufferSize = 1024;
  53. // kTimeout is the Nr. of milli-Seconds of no-more-data before we consider a
  54. // message ended.
  55. // This parameter is an interesting trade-off. The longer the timeout, the more
  56. // complex a message it can capture. e.g. Some device protocols will send
  57. // multiple message packets in quick succession, like Air Conditioner remotes.
  58. // Air Coniditioner protocols often have a considerable gap (20-40+ms) between
  59. // packets.
  60. // The downside of a large timeout value is a lot of less complex protocols
  61. // send multiple messages when the remote's button is held down. The gap between
  62. // them is often also around 20+ms. This can result in the raw data be 2-3+
  63. // times larger than needed as it has captured 2-3+ messages in a single
  64. // capture. Setting a low timeout value can resolve this.
  65. // So, choosing the best kTimeout value for your use particular case is
  66. // quite nuanced. Good luck and happy hunting.
  67. // NOTE: Don't exceed kMaxTimeoutMs. Typically 130ms.
  68. #if DECODE_AC
  69. // Some A/C units have gaps in their protocols of ~40ms. e.g. Kelvinator
  70. // A value this large may swallow repeats of some protocols
  71. const uint8_t kTimeout = 50;
  72. #else // DECODE_AC
  73. // Suits most messages, while not swallowing many repeats.
  74. const uint8_t kTimeout = 15;
  75. #endif // DECODE_AC
  76. // Alternatives:
  77. // const uint8_t kTimeout = 90;
  78. // Suits messages with big gaps like XMP-1 & some aircon units, but can
  79. // accidentally swallow repeated messages in the rawData[] output.
  80. //
  81. // const uint8_t kTimeout = kMaxTimeoutMs;
  82. // This will set it to our currently allowed maximum.
  83. // Values this high are problematic because it is roughly the typical boundary
  84. // where most messages repeat.
  85. // e.g. It will stop decoding a message and start sending it to serial at
  86. // precisely the time when the next message is likely to be transmitted,
  87. // and may miss it.
  88. // Set the smallest sized "UNKNOWN" message packets we actually care about.
  89. // This value helps reduce the false-positive detection rate of IR background
  90. // noise as real messages. The chances of background IR noise getting detected
  91. // as a message increases with the length of the kTimeout value. (See above)
  92. // The downside of setting this message too large is you can miss some valid
  93. // short messages for protocols that this library doesn't yet decode.
  94. //
  95. // Set higher if you get lots of random short UNKNOWN messages when nothing
  96. // should be sending a message.
  97. // Set lower if you are sure your setup is working, but it doesn't see messages
  98. // from your device. (e.g. Other IR remotes work.)
  99. // NOTE: Set this value very high to effectively turn off UNKNOWN detection.
  100. const uint16_t kMinUnknownSize = 12;
  101. // ==================== end of TUNEABLE PARAMETERS ====================
  102. // Use turn on the save buffer feature for more complete capture coverage.
  103. IRrecv irrecv(kRecvPin, kCaptureBufferSize, kTimeout, true);
  104. decode_results results; // Somewhere to store the results
  105. // Display the human readable state of an A/C message if we can.
  106. void dumpACInfo(decode_results *results) {
  107. String description = "";
  108. #if DECODE_DAIKIN
  109. if (results->decode_type == DAIKIN) {
  110. IRDaikinESP ac(0);
  111. ac.setRaw(results->state);
  112. description = ac.toString();
  113. }
  114. #endif // DECODE_DAIKIN
  115. #if DECODE_FUJITSU_AC
  116. if (results->decode_type == FUJITSU_AC) {
  117. IRFujitsuAC ac(0);
  118. ac.setRaw(results->state, results->bits / 8);
  119. description = ac.toString();
  120. }
  121. #endif // DECODE_FUJITSU_AC
  122. #if DECODE_KELVINATOR
  123. if (results->decode_type == KELVINATOR) {
  124. IRKelvinatorAC ac(0);
  125. ac.setRaw(results->state);
  126. description = ac.toString();
  127. }
  128. #endif // DECODE_KELVINATOR
  129. #if DECODE_MITSUBISHI_AC
  130. if (results->decode_type == MITSUBISHI_AC) {
  131. IRMitsubishiAC ac(0);
  132. ac.setRaw(results->state);
  133. description = ac.toString();
  134. }
  135. #endif // DECODE_MITSUBISHI_AC
  136. #if DECODE_TOSHIBA_AC
  137. if (results->decode_type == TOSHIBA_AC) {
  138. IRToshibaAC ac(0);
  139. ac.setRaw(results->state);
  140. description = ac.toString();
  141. }
  142. #endif // DECODE_TOSHIBA_AC
  143. #if DECODE_GREE
  144. if (results->decode_type == GREE) {
  145. IRGreeAC ac(0);
  146. ac.setRaw(results->state);
  147. description = ac.toString();
  148. }
  149. #endif // DECODE_GREE
  150. #if DECODE_MIDEA
  151. if (results->decode_type == MIDEA) {
  152. IRMideaAC ac(0);
  153. ac.setRaw(results->value); // Midea uses value instead of state.
  154. description = ac.toString();
  155. }
  156. #endif // DECODE_MIDEA
  157. #if DECODE_HAIER_AC
  158. if (results->decode_type == HAIER_AC) {
  159. IRHaierAC ac(0);
  160. ac.setRaw(results->state);
  161. description = ac.toString();
  162. }
  163. #endif // DECODE_HAIER_AC
  164. #if DECODE_HAIER_AC_YRW02
  165. if (results->decode_type == HAIER_AC_YRW02) {
  166. IRHaierACYRW02 ac(0);
  167. ac.setRaw(results->state);
  168. description = ac.toString();
  169. }
  170. #endif // DECODE_HAIER_AC_YRW02
  171. #if DECODE_SAMSUNG_AC
  172. if (results->decode_type == SAMSUNG_AC) {
  173. IRSamsungAc ac(0);
  174. ac.setRaw(results->state);
  175. description = ac.toString();
  176. }
  177. #endif // DECODE_SAMSUNG_AC
  178. #if DECODE_COOLIX
  179. if (results->decode_type == COOLIX) {
  180. IRCoolixAC ac(0);
  181. ac.setRaw(results->value); // Coolix uses value instead of state.
  182. description = ac.toString();
  183. }
  184. #endif // DECODE_COOLIX
  185. #if DECODE_PANASONIC_AC
  186. if (results->decode_type == PANASONIC_AC &&
  187. results->bits > kPanasonicAcShortBits) {
  188. IRPanasonicAc ac(0);
  189. ac.setRaw(results->state);
  190. description = ac.toString();
  191. }
  192. #endif // DECODE_PANASONIC_AC
  193. #if DECODE_HITACHI_AC
  194. if (results->decode_type == HITACHI_AC) {
  195. IRHitachiAc ac(0);
  196. ac.setRaw(results->state);
  197. description = ac.toString();
  198. }
  199. #endif // DECODE_HITACHI_AC
  200. // If we got a human-readable description of the message, display it.
  201. if (description != "") Serial.println("Mesg Desc.: " + description);
  202. }
  203. // The section of code run only once at start-up.
  204. void setup() {
  205. Serial.begin(kBaudRate, SERIAL_8N1, SERIAL_TX_ONLY);
  206. while (!Serial) // Wait for the serial connection to be establised.
  207. delay(50);
  208. Serial.println();
  209. Serial.print("IRrecvDumpV2 is now running and waiting for IR input on Pin ");
  210. Serial.println(kRecvPin);
  211. #if DECODE_HASH
  212. // Ignore messages with less than minimum on or off pulses.
  213. irrecv.setUnknownThreshold(kMinUnknownSize);
  214. #endif // DECODE_HASH
  215. irrecv.enableIRIn(); // Start the receiver
  216. }
  217. // The repeating section of the code
  218. //
  219. void loop() {
  220. // Check if the IR code has been received.
  221. if (irrecv.decode(&results)) {
  222. // Display a crude timestamp.
  223. uint32_t now = millis();
  224. Serial.printf("Timestamp : %06u.%03u\n", now / 1000, now % 1000);
  225. if (results.overflow)
  226. Serial.printf(
  227. "WARNING: IR code is too big for buffer (>= %d). "
  228. "This result shouldn't be trusted until this is resolved. "
  229. "Edit & increase kCaptureBufferSize.\n",
  230. kCaptureBufferSize);
  231. // Display the basic output of what we found.
  232. Serial.print(resultToHumanReadableBasic(&results));
  233. dumpACInfo(&results); // Display any extra A/C info if we have it.
  234. yield(); // Feed the WDT as the text output can take a while to print.
  235. // Display the library version the message was captured with.
  236. Serial.print("Library : v");
  237. Serial.println(_IRREMOTEESP8266_VERSION_);
  238. Serial.println();
  239. // Output RAW timing info of the result.
  240. Serial.println(resultToTimingInfo(&results));
  241. yield(); // Feed the WDT (again)
  242. // Output the results as source code
  243. Serial.println(resultToSourceCode(&results));
  244. Serial.println(""); // Blank line between entries
  245. yield(); // Feed the WDT (again)
  246. }
  247. }