/* Mainly based on IRrecvDumpV2 from IRremoteESP8266 Slightly changed to run with OMOTE hardware. */ /* * 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 * * Example circuit diagram: * https://github.com/crankyoldgit/IRremoteESP8266/wiki#ir-receiving * * 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, */ //#include #include #include #include #include #include #include #include "infrared_receiver_hal_esp32.h" uint8_t IR_RX_GPIO = 15; // IR receiver input uint8_t IR_VCC_GPIO = 25; // IR receiver power bool irReceiverEnabled = false; tAnnounceNewIRmessage_cb thisAnnounceNewIRmessage_cb = NULL; void set_announceNewIRmessage_cb_HAL(tAnnounceNewIRmessage_cb pAnnounceNewIRmessage_cb) { thisAnnounceNewIRmessage_cb = pAnnounceNewIRmessage_cb; } // 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; // 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(IR_RX_GPIO, kCaptureBufferSize, kTimeout, true); decode_results results; // Somewhere to store the results // This section of code runs only once at start-up. void start_infraredReceiver_HAL() { pinMode(IR_RX_GPIO, INPUT); pinMode(IR_VCC_GPIO, OUTPUT); digitalWrite(IR_VCC_GPIO, HIGH); // Turn on IR receiver // 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", IR_RX_GPIO); #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 shutdown_infraredReceiver_HAL() { irrecv.disableIRIn(); digitalWrite(IR_VCC_GPIO, LOW); // IR Receiver off } // The repeating section of the code void infraredReceiver_loop_HAL() { // Check if the IR code has been received. if (irrecv.decode(&results)) { // 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 String message = ""; message += typeToString((&results)->decode_type, (&results)->repeat); message += " "; message += resultToHexidecimal(&results); if (thisAnnounceNewIRmessage_cb != NULL) { thisAnnounceNewIRmessage_cb(std::string(message.c_str())); } yield(); // Feed the WDT (again) // if message repeats infinitely, you can try one of these two workarounds. Don't know why this is needed. // irrecv.resume(); // another workaround could be: // irrecv.disableIRIn(); // irrecv.enableIRIn(); } } bool get_irReceiverEnabled_HAL() { return irReceiverEnabled; } void set_irReceiverEnabled_HAL(bool aIrReceiverEnabled) { irReceiverEnabled = aIrReceiverEnabled; }