diff --git a/SampleSrc/IRRecv.ino b/SampleSrc/IRRecv.ino index 2a65cb6..f0bebff 100644 --- a/SampleSrc/IRRecv.ino +++ b/SampleSrc/IRRecv.ino @@ -1,102 +1,182 @@ /* - * IRremoteESP8266: IRrecvDump - dump details of IR codes with IRrecv + * IRremoteESP8266: IRrecvDumpV2 - dump details of IR codes with IRrecv + * An IR detector/demodulator must be connected to the input kRecvPin. + * * Copyright 2009 Ken Shirriff, http://arcfn.com + * Copyright 2017-2019 David Conran * - ***** DEPRECATED - DO NOT USE ***** - * Unless you know what you are doing, you should be using the - * IRrecvDumpV2.ino sketch/example instead for capturing & decoding IR messages. - * In almost ALL ways it is BETTER, FASTER, and MORE DETAILED. + * Example circuit diagram: + * https://github.com/crankyoldgit/IRremoteESP8266/wiki#ir-receiving * - * This code is left only for legacy reasons, and as another simple example of - * how to use the IRremoteESP8266 library. - * - * As of November 2017 it will no longer be updated or supported. - * You have been warned. - ***** DEPRECATED - DO NOT USE ***** - * - * An IR detector/demodulator must be connected to the input RECV_PIN. - * Version 0.2 Oct 2017 + * Changes: + * Version 1.2 October, 2020 + * - Enable easy setting of the decoding tolerance value. + * Version 1.0 October, 2019 + * - Internationalisation (i18n) support. + * - Stop displaying the legacy raw timing info. + * Version 0.5 June, 2019 + * - Move A/C description to IRac.cpp. + * Version 0.4 July, 2018 + * - Minor improvements and more A/C unit support. + * Version 0.3 November, 2017 + * - Support for A/C decoding for some protocols. + * Version 0.2 April, 2017 + * - Decode from a copy of the data so we can start capturing faster thus + * reduce the likelihood of miscaptures. * Based on Ken Shirriff's IrsendDemo Version 0.1 July, 2009, - * JVC and Panasonic protocol added by Kristian Lauszus - * (Thanks to zenwheel and other people at the original blog post) - * LG added by Darryl Smith (based on the JVC protocol) */ #include -#include +#include #include +#include +#include +#include #include -// an IR detector/demodulator is connected to GPIO pin 2 -uint16_t RECV_PIN = 2; +// ==================== start of TUNEABLE PARAMETERS ==================== +// An IR detector/demodulator is connected to GPIO pin 14 +// e.g. D5 on a NodeMCU board. +// Note: GPIO 16 won't work on the ESP8266 as it does not have interrupts. +// Note: GPIO 14 won't work on the ESP32-C3 as it causes the board to reboot. +#ifdef ARDUINO_ESP32C3_DEV +const uint16_t kRecvPin = 10; // 14 on a ESP32-C3 causes a boot loop. +#else // ARDUINO_ESP32C3_DEV +const uint16_t kRecvPin = 14; +#endif // ARDUINO_ESP32C3_DEV -IRrecv irrecv(RECV_PIN); +// The Serial connection baud rate. +// i.e. Status message will be sent to the PC at this baud rate. +// Try to avoid slow speeds like 9600, as you will miss messages and +// cause other problems. 115200 (or faster) is recommended. +// NOTE: Make sure you set your Serial Monitor to the same speed. +const uint32_t kBaudRate = 115200; -decode_results results; +// As this program is a special purpose capture/decoder, let us use a larger +// than normal buffer so we can handle Air Conditioner remote codes. +const uint16_t kCaptureBufferSize = 1024; +// kTimeout is the Nr. of milli-Seconds of no-more-data before we consider a +// message ended. +// This parameter is an interesting trade-off. The longer the timeout, the more +// complex a message it can capture. e.g. Some device protocols will send +// multiple message packets in quick succession, like Air Conditioner remotes. +// Air Coniditioner protocols often have a considerable gap (20-40+ms) between +// packets. +// The downside of a large timeout value is a lot of less complex protocols +// send multiple messages when the remote's button is held down. The gap between +// them is often also around 20+ms. This can result in the raw data be 2-3+ +// times larger than needed as it has captured 2-3+ messages in a single +// capture. Setting a low timeout value can resolve this. +// So, choosing the best kTimeout value for your use particular case is +// quite nuanced. Good luck and happy hunting. +// NOTE: Don't exceed kMaxTimeoutMs. Typically 130ms. +#if DECODE_AC +// Some A/C units have gaps in their protocols of ~40ms. e.g. Kelvinator +// A value this large may swallow repeats of some protocols +const uint8_t kTimeout = 50; +#else // DECODE_AC +// Suits most messages, while not swallowing many repeats. +const uint8_t kTimeout = 15; +#endif // DECODE_AC +// Alternatives: +// const uint8_t kTimeout = 90; +// Suits messages with big gaps like XMP-1 & some aircon units, but can +// accidentally swallow repeated messages in the rawData[] output. +// +// const uint8_t kTimeout = kMaxTimeoutMs; +// This will set it to our currently allowed maximum. +// Values this high are problematic because it is roughly the typical boundary +// where most messages repeat. +// e.g. It will stop decoding a message and start sending it to serial at +// precisely the time when the next message is likely to be transmitted, +// and may miss it. + +// Set the smallest sized "UNKNOWN" message packets we actually care about. +// This value helps reduce the false-positive detection rate of IR background +// noise as real messages. The chances of background IR noise getting detected +// as a message increases with the length of the kTimeout value. (See above) +// The downside of setting this message too large is you can miss some valid +// short messages for protocols that this library doesn't yet decode. +// +// Set higher if you get lots of random short UNKNOWN messages when nothing +// should be sending a message. +// Set lower if you are sure your setup is working, but it doesn't see messages +// from your device. (e.g. Other IR remotes work.) +// NOTE: Set this value very high to effectively turn off UNKNOWN detection. +const uint16_t kMinUnknownSize = 12; + +// How much percentage lee way do we give to incoming signals in order to match +// it? +// e.g. +/- 25% (default) to an expected value of 500 would mean matching a +// value between 375 & 625 inclusive. +// Note: Default is 25(%). Going to a value >= 50(%) will cause some protocols +// to no longer match correctly. In normal situations you probably do not +// need to adjust this value. Typically that's when the library detects +// your remote's message some of the time, but not all of the time. +const uint8_t kTolerancePercentage = kTolerance; // kTolerance is normally 25% + +// Legacy (No longer supported!) +// +// Change to `true` if you miss/need the old "Raw Timing[]" display. +#define LEGACY_TIMING_INFO false +// ==================== end of TUNEABLE PARAMETERS ==================== + +// Use turn on the save buffer feature for more complete capture coverage. +IRrecv irrecv(kRecvPin, kCaptureBufferSize, kTimeout, true); +decode_results results; // Somewhere to store the results + +// This section of code runs only once at start-up. void setup() { - Serial.begin(115200); +#if defined(ESP8266) + Serial.begin(kBaudRate, SERIAL_8N1, SERIAL_TX_ONLY); +#else // ESP8266 + Serial.begin(kBaudRate, SERIAL_8N1); +#endif // ESP8266 + while (!Serial) // Wait for the serial connection to be establised. + delay(50); + // Perform a low level sanity checks that the compiler performs bit field + // packing as we expect and Endianness is as we expect. + assert(irutils::lowLevelSanityCheck() == 0); + + Serial.printf("\n" D_STR_IRRECVDUMP_STARTUP "\n", kRecvPin); +#if DECODE_HASH + // Ignore messages with less than minimum on or off pulses. + irrecv.setUnknownThreshold(kMinUnknownSize); +#endif // DECODE_HASH + irrecv.setTolerance(kTolerancePercentage); // Override the default tolerance. irrecv.enableIRIn(); // Start the receiver } -void dump(decode_results *results) { - // Dumps out the decode_results structure. - // Call this after IRrecv::decode() - uint16_t count = results->rawlen; - if (results->decode_type == UNKNOWN) { - Serial.print("Unknown encoding: "); - } else if (results->decode_type == NEC) { - Serial.print("Decoded NEC: "); - } else if (results->decode_type == SONY) { - Serial.print("Decoded SONY: "); - } else if (results->decode_type == RC5) { - Serial.print("Decoded RC5: "); - } else if (results->decode_type == RC5X) { - Serial.print("Decoded RC5X: "); - } else if (results->decode_type == RC6) { - Serial.print("Decoded RC6: "); - } else if (results->decode_type == RCMM) { - Serial.print("Decoded RCMM: "); - } else if (results->decode_type == PANASONIC) { - Serial.print("Decoded PANASONIC - Address: "); - Serial.print(results->address, HEX); - Serial.print(" Value: "); - } else if (results->decode_type == LG) { - Serial.print("Decoded LG: "); - } else if (results->decode_type == JVC) { - Serial.print("Decoded JVC: "); - } else if (results->decode_type == AIWA_RC_T501) { - Serial.print("Decoded AIWA RC T501: "); - } else if (results->decode_type == WHYNTER) { - Serial.print("Decoded Whynter: "); - } else if (results->decode_type == NIKAI) { - Serial.print("Decoded Nikai: "); - } - serialPrintUint64(results->value, 16); - Serial.print(" ("); - Serial.print(results->bits, DEC); - Serial.println(" bits)"); - Serial.print("Raw ("); - Serial.print(count, DEC); - Serial.print("): {"); - - for (uint16_t i = 1; i < count; i++) { - if (i % 100 == 0) - yield(); // Preemptive yield every 100th entry to feed the WDT. - if (i & 1) { - Serial.print(results->rawbuf[i] * kRawTick, DEC); - } else { - Serial.print(", "); - Serial.print((uint32_t) results->rawbuf[i] * kRawTick, DEC); - } - } - Serial.println("};"); -} - +// The repeating section of the code void loop() { + // Check if the IR code has been received. if (irrecv.decode(&results)) { - dump(&results); - Serial.println("DEPRECATED: Please use IRrecvDumpV2.ino instead!"); - irrecv.resume(); // Receive the next value + // Display a crude timestamp. + uint32_t now = millis(); + Serial.printf(D_STR_TIMESTAMP " : %06u.%03u\n", now / 1000, now % 1000); + // Check if we got an IR message that was to big for our capture buffer. + if (results.overflow) + Serial.printf(D_WARN_BUFFERFULL "\n", kCaptureBufferSize); + // Display the library version the message was captured with. + Serial.println(D_STR_LIBRARY " : v" _IRREMOTEESP8266_VERSION_STR "\n"); + // Display the tolerance percentage if it has been change from the default. + if (kTolerancePercentage != kTolerance) + Serial.printf(D_STR_TOLERANCE " : %d%%\n", kTolerancePercentage); + // Display the basic output of what we found. + Serial.print(resultToHumanReadableBasic(&results)); + // Display any extra A/C info if we have it. + String description = IRAcUtils::resultAcToString(&results); + if (description.length()) Serial.println(D_STR_MESGDESC ": " + description); + yield(); // Feed the WDT as the text output can take a while to print. +#if LEGACY_TIMING_INFO + // Output legacy RAW timing info of the result. + Serial.println(resultToTimingInfo(&results)); + yield(); // Feed the WDT (again) +#endif // LEGACY_TIMING_INFO + // Output the results as source code + Serial.println(resultToSourceCode(&results)); + Serial.println(); // Blank line between entries + yield(); // Feed the WDT (again) } }