/* * ReceiveDemo.cpp * * Demonstrates receiving IR codes with the IRremote library and the use of the Arduino tone() function with this library. * Long press of one IR button (receiving of multiple repeats for one command) is detected. * If debug button is pressed (pin connected to ground) a long output is generated, which may disturb detecting of repeats. * * This file is part of Arduino-IRremote https://github.com/Arduino-IRremote/Arduino-IRremote. * ************************************************************************************ * MIT License * * Copyright (c) 2020-2024 Armin Joachimsmeyer * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is furnished * to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * ************************************************************************************ */ #include /* * Specify which protocol(s) should be used for decoding. * If no protocol is defined, all protocols (except Bang&Olufsen) are active. * This must be done before the #include */ //#define DECODE_DENON // Includes Sharp //#define DECODE_JVC //#define DECODE_KASEIKYO //#define DECODE_PANASONIC // alias for DECODE_KASEIKYO //#define DECODE_LG //#define DECODE_ONKYO // Decodes only Onkyo and not NEC or Apple //#define DECODE_NEC // Includes Apple and Onkyo //#define DECODE_SAMSUNG //#define DECODE_SONY //#define DECODE_RC5 //#define DECODE_RC6 //#define DECODE_BOSEWAVE //#define DECODE_LEGO_PF //#define DECODE_MAGIQUEST //#define DECODE_WHYNTER //#define DECODE_FAST //#define DECODE_DISTANCE_WIDTH // Universal decoder for pulse distance width protocols //#define DECODE_HASH // special decoder for all protocols //#define DECODE_BEO // This protocol must always be enabled manually, i.e. it is NOT enabled if no protocol is defined. It prevents decoding of SONY! // etc. see IRremote.hpp // //#define NO_LED_FEEDBACK_CODE // saves 92 bytes program memory //#define EXCLUDE_UNIVERSAL_PROTOCOLS // Saves up to 1000 bytes program memory. //#define EXCLUDE_EXOTIC_PROTOCOLS // saves around 650 bytes program memory if all other protocols are active #define IR_REMOTE_DISABLE_RECEIVE_COMPLETE_CALLBACK // saves 32 bytes program memory // MARK_EXCESS_MICROS is subtracted from all marks and added to all spaces before decoding, // to compensate for the signal forming of different IR receiver modules. See also IRremote.hpp line 142. //#define MARK_EXCESS_MICROS 20 // Adapt it to your IR receiver module. 40 is taken for the cheap VS1838 module her, since we have high intensity. #if defined(DECODE_BEO) #define RECORD_GAP_MICROS 16000 // always get the complete frame in the receive buffer, but this prevents decoding of SONY! #endif //#define RECORD_GAP_MICROS 12000 // Default is 8000. Activate it for some LG air conditioner protocols //#define DEBUG // Activate this for lots of lovely debug output from the decoders. #include #define STR_HELPER(x) #x #define STR(x) STR_HELPER(x) #define IR_RECEIVE_PIN P0_11 // #define IR_SEND_PIN 3 // #define TONE_PIN P0_4 void handleOverflow(); bool detectLongPress(uint16_t aLongPressDurationMillis); void setup() { Serial.begin(9600); while (!Serial) ; // Wait for Serial to become available. Is optimized away for some cores. // Just to know which program is running on my Arduino Serial.println(F("START " __FILE__ " from " __DATE__ "\r\nUsing library version " VERSION_IRREMOTE)); // In case the interrupt driver crashes on setup, give a clue // to the user what's going on. Serial.println(F("Enabling IRin...")); // Start the receiver and if not 3. parameter specified, take LED_BUILTIN pin from the internal boards definition as default feedback LED IrReceiver.begin(IR_RECEIVE_PIN, ENABLE_LED_FEEDBACK); Serial.print(F("Ready to receive IR signals of protocols: ")); printActiveIRProtocols(&Serial); Serial.println(F("at pin " STR(IR_RECEIVE_PIN))); Serial.print(F("FeedbackLED at pin ")); Serial.println(LED_BUILTIN); // Works also for ESP32: static const uint8_t LED_BUILTIN = 8; #define LED_BUILTIN LED_BUILTIN // infos for receive Serial.print(RECORD_GAP_MICROS); Serial.println(F(" us is the (minimum) gap, after which the start of a new IR packet is assumed")); Serial.print(MARK_EXCESS_MICROS); Serial.println(F(" us are subtracted from all marks and added to all spaces for decoding")); } void loop() { /* * Check if received data is available and if yes, try to decode it. * Decoded result is in the IrReceiver.decodedIRData structure. * * E.g. command is in IrReceiver.decodedIRData.command * address is in command is in IrReceiver.decodedIRData.address * and up to 32 bit raw data in IrReceiver.decodedIRData.decodedRawData */ if (IrReceiver.decode()) { Serial.println(); if (IrReceiver.decodedIRData.flags & IRDATA_FLAGS_WAS_OVERFLOW) { handleOverflow(); } else { /* * No overflow here. * Stop receiver, print short info and send usage and start receiver again */ if (IrReceiver.decodedIRData.protocol == UNKNOWN) { // We have debug enabled or an unknown protocol, print extended info if (IrReceiver.decodedIRData.protocol == UNKNOWN) { Serial.println(F("Received noise or an unknown (or not yet enabled) protocol")); } IrReceiver.printIRResultRawFormatted(&Serial, true); } if (IrReceiver.decodedIRData.protocol != UNKNOWN) { /* * The info output for a successful receive */ IrReceiver.printIRResultShort(&Serial); IrReceiver.printIRSendUsage(&Serial); } } /* * !!!Important!!! Enable receiving of the next value, because receiving * has stopped after the end of the current received data packet. * Do it here, to preserve raw data for printing with printIRResultRawFormatted() */ IrReceiver.resume(); /* * Finally check the received data and perform actions according to the received address and commands */ if (IrReceiver.decodedIRData.address == 0) { if (IrReceiver.decodedIRData.command == 0x10) { // do something } else if (IrReceiver.decodedIRData.command == 0x11) { // do something else } } // Check if repeats of the IR command was sent for more than 1000 ms if (detectLongPress(1000)) { Serial.print(F("Command 0x")); Serial.print(IrReceiver.decodedIRData.command, HEX); Serial.println(F(" was repeated for more than 2 seconds")); } } // if (IrReceiver.decode()) /* * Your code here * For all users of the FastLed library, use this code for strip.show() to improve receiving performance (which is still not 100%): * if (IrReceiver.isIdle()) { * strip.show(); * } */ } void handleOverflow() { Serial.println(F("Overflow detected")); Serial.println(F("Try to increase the \"RAW_BUFFER_LENGTH\" value of " STR(RAW_BUFFER_LENGTH) " in " __FILE__)); // see also https://github.com/Arduino-IRremote/Arduino-IRremote#compile-options--macros-for-this-library IrReceiver.stopTimer(); // tone(TONE_PIN, 1100, 10); // delay(50); // tone(TONE_PIN, 1100, 10); delay(50); IrReceiver.restartTimer(); } unsigned long sMillisOfFirstReceive; bool sLongPressJustDetected; /** * True once we received the consecutive repeats for more than aLongPressDurationMillis milliseconds. * The first frame, which is no repeat, is NOT counted for the duration! * @return true once after the repeated IR command was received for longer than aLongPressDurationMillis milliseconds, false otherwise. */ bool detectLongPress(uint16_t aLongPressDurationMillis) { if (!sLongPressJustDetected && (IrReceiver.decodedIRData.flags & IRDATA_FLAGS_IS_REPEAT)) { /* * Here the repeat flag is set (which implies, that command is the same as the previous one) */ if (millis() - aLongPressDurationMillis > sMillisOfFirstReceive) { sLongPressJustDetected = true; // Long press here } } else { // No repeat here sMillisOfFirstReceive = millis(); sLongPressJustDetected = false; } return sLongPressJustDetected; // No long press here }