2021-01-04 09:54:10 +08:00
/*
* IRDispatcherDemo . cpp
*
2021-10-24 18:38:35 +08:00
* Receives NEC IR commands and maps them to different actions by means of a mapping array .
2021-01-04 09:54:10 +08:00
*
* Copyright ( C ) 2020 - 2021 Armin Joachimsmeyer
* armin . joachimsmeyer @ gmail . com
*
2022-08-17 16:54:56 +08:00
* This file is part of IRMP https : //github.com/IRMP-org/IRMP.
2021-03-03 02:59:41 +08:00
* This file is part of Arduino - IRremote https : //github.com/Arduino-IRremote/Arduino-IRremote.
2021-01-04 09:54:10 +08:00
*
* IRMP is free software : you can redistribute it and / or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation , either version 3 of the License , or
* ( at your option ) any later version .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License
2022-04-05 10:47:32 +08:00
* along with this program . If not , see < http : //www.gnu.org/licenses/gpl.html>.
2021-01-04 09:54:10 +08:00
*
*/
# include <Arduino.h>
/*
2021-10-24 18:38:35 +08:00
* Choose the library to be used for IR receiving
2021-01-04 09:54:10 +08:00
*/
2021-12-08 07:44:48 +08:00
# define USE_TINY_IR_RECEIVER // Recommended, but only for NEC protocol!!! If disabled and IRMP_INPUT_PIN is defined, the IRMP library is used for decoding
2022-03-30 17:55:04 +08:00
//#define TINY_RECEIVER_USE_ARDUINO_ATTACH_INTERRUPT // costs 112 bytes program memory + 4 bytes RAM
2021-10-24 18:38:35 +08:00
2022-08-28 02:22:58 +08:00
# include "PinDefinitionsAndMore.h" // Define macros for input and output pin etc.
2021-10-24 18:38:35 +08:00
// Some kind of auto detect library if USE_TINY_IR_RECEIVER is deactivated
# if !defined(USE_TINY_IR_RECEIVER)
# if defined(IR_RECEIVE_PIN)
# define USE_TINY_IR_RECEIVER
# elif !defined(USE_IRMP_LIBRARY) && defined(IRMP_INPUT_PIN)
# define USE_IRMP_LIBRARY
2021-01-04 09:54:10 +08:00
# else
2021-10-24 18:38:35 +08:00
# error No IR library selected
2021-01-04 09:54:10 +08:00
# endif
2021-10-24 18:38:35 +08:00
# endif
2021-01-04 09:54:10 +08:00
2021-12-08 21:14:04 +08:00
//#define NO_LED_FEEDBACK_CODE // You can set it here, before the include of IRCommandDispatcher below
2021-01-04 09:54:10 +08:00
2022-07-30 16:26:04 +08:00
# if defined(USE_TINY_IR_RECEIVER)
//#define NO_LED_FEEDBACK_CODE // Activate this if you want to suppress LED feedback or if you do not have a LED. This saves 14 bytes code and 2 clock cycles per interrupt.
/*
* Set sensible receive pin for different CPU ' s
*/
# if defined(__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__) || defined(__AVR_ATtiny87__) || defined(__AVR_ATtiny167__)
# include "ATtinySerialOut.hpp" // Available as Arduino library "ATtinySerialOut"
# if defined(ARDUINO_AVR_DIGISPARKPRO)
# define IR_INPUT_PIN 9 // PA3 - on Digispark board labeled as pin 9
# else
# define IR_INPUT_PIN 0 // PCINT0
# endif
# elif defined(__AVR_ATtiny1616__) || defined(__AVR_ATtiny3216__) || defined(__AVR_ATtiny3217__)
# define IR_INPUT_PIN 10
# elif (defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__))
# define IR_INPUT_PIN 21 // INT0
# elif defined(ESP8266)
# define IR_INPUT_PIN 14 // D5
# elif defined(ESP32)
# define IR_INPUT_PIN 15
# elif defined(ARDUINO_ARCH_MBED) && defined(ARDUINO_ARCH_MBED_NANO)
# define IR_INPUT_PIN 3 // GPIO15 Use pin 3 since pin 2|GPIO25 is connected to LED on Pi pico
# elif defined(ARDUINO_ARCH_RP2040) // Pi Pico with arduino-pico core https://github.com/earlephilhower/arduino-pico
# define IR_INPUT_PIN 15 // to be compatible with the Arduino Nano RP2040 Connect (pin3)
# else
# define IR_INPUT_PIN 2 // INT0
# endif
2021-10-24 18:38:35 +08:00
# elif defined(USE_IRMP_LIBRARY)
2022-03-30 17:55:04 +08:00
/*
* IRMP version
*/
2022-07-30 16:26:04 +08:00
# define IR_INPUT_PIN 2
2022-03-30 17:55:04 +08:00
# define IRMP_USE_COMPLETE_CALLBACK 1 // Enable callback functionality. It is required if IRMP library is used.
2021-03-09 04:38:06 +08:00
# if defined(ALTERNATIVE_IR_FEEDBACK_LED_PIN)
# define FEEDBACK_LED_PIN ALTERNATIVE_IR_FEEDBACK_LED_PIN
2021-01-04 09:54:10 +08:00
# endif
2022-03-30 17:55:04 +08:00
//#define IRMP_ENABLE_PIN_CHANGE_INTERRUPT // Enable interrupt functionality (not for all protocols) - requires around 376 additional bytes of program memory
2021-01-04 09:54:10 +08:00
2022-03-30 17:55:04 +08:00
# define IRMP_PROTOCOL_NAMES 1 // Enable protocol number mapping to protocol strings - requires some program memory. Must before #include <irmp*>
2021-01-04 09:54:10 +08:00
2021-10-24 18:38:35 +08:00
# define IRMP_SUPPORT_NEC_PROTOCOL 1 // this enables only one protocol
//#define IRMP_SUPPORT_KASEIKYO_PROTOCOL 1
2021-01-04 09:54:10 +08:00
2022-03-30 17:55:04 +08:00
# if defined(ALTERNATIVE_IR_FEEDBACK_LED_PIN)
2021-03-09 04:38:06 +08:00
# define IRMP_FEEDBACK_LED_PIN ALTERNATIVE_IR_FEEDBACK_LED_PIN
2021-01-04 09:54:10 +08:00
# endif
/*
* After setting the definitions we can include the code and compile it .
*/
2021-09-09 21:53:50 +08:00
# include <irmp.hpp>
2021-01-04 09:54:10 +08:00
void handleReceivedIRData ( ) ;
2021-10-24 18:38:35 +08:00
void irmp_tone ( uint8_t _pin , unsigned int frequency , unsigned long duration ) ;
# endif // #if defined(USE_IRMP_LIBRARY)
2021-01-04 09:54:10 +08:00
bool doBlink = false ;
uint16_t sBlinkDelay = 200 ;
2021-10-24 18:38:35 +08:00
void doPrintMenu ( ) ;
2021-01-04 09:54:10 +08:00
void doLedOn ( ) ;
void doLedOff ( ) ;
void doIncreaseBlinkFrequency ( ) ;
void doDecreaseBlinkFrequency ( ) ;
void doStop ( ) ;
2021-10-24 18:38:35 +08:00
void doResetBlinkFrequency ( ) ;
2021-01-04 09:54:10 +08:00
void doLedBlinkStart ( ) ;
void doLedBlink20times ( ) ;
void doTone1800 ( ) ;
void doTone2200 ( ) ;
/*
* Set definitions and include IRCommandDispatcher library after the declaration of all commands to map
*/
# define INFO // to see some informative output
# include "IRCommandDispatcher.h" // Only for required declarations, the library itself is included below after the definitions of the commands
2021-09-09 21:53:50 +08:00
# include "IRCommandMapping.h" // must be included before IRCommandDispatcher.hpp to define IR_ADDRESS and IRMapping and string "unknown".
# include "IRCommandDispatcher.hpp"
2021-01-04 09:54:10 +08:00
2021-10-24 18:38:35 +08:00
/*
* Helper macro for getting a macro definition as string
*/
# define STR_HELPER(x) #x
# define STR(x) STR_HELPER(x)
2021-01-04 09:54:10 +08:00
2021-10-24 18:38:35 +08:00
void setup ( ) {
2021-01-04 09:54:10 +08:00
pinMode ( LED_BUILTIN , OUTPUT ) ;
Serial . begin ( 115200 ) ;
2022-04-05 10:47:32 +08:00
# if defined(__AVR_ATmega32U4__) || defined(SERIAL_PORT_USBVIRTUAL) || defined(SERIAL_USB) /*stm32duino*/ || defined(USBCON) /*STM32_stm32*/ || defined(SERIALUSB_PID) || defined(ARDUINO_attiny3217)
2021-04-08 07:51:03 +08:00
delay ( 4000 ) ; // To be able to connect Serial monitor after reset or power up and before first print out. Do not wait for an attached Serial Monitor!
2021-01-04 09:54:10 +08:00
# endif
# if defined(ESP8266)
Serial . println ( ) ; // to separate it from the internal boot output
# endif
// Just to know which program is running on my Arduino
2021-10-24 18:38:35 +08:00
# if defined(USE_TINY_IR_RECEIVER)
Serial . println ( F ( " START " __FILE__ " from " __DATE__ " \r \n Using TinyIRReceiver " ) ) ;
# elif defined(USE_IRREMOTE_LIBRARY)
Serial . println ( F ( " START " __FILE__ " from " __DATE__ " \r \n Using IRremote library version " VERSION_IRREMOTE ) ) ;
# elif defined(USE_IRMP_LIBRARY)
Serial . println ( F ( " START " __FILE__ " from " __DATE__ " \r \n Using IRMP library version " VERSION_IRMP ) ) ;
2021-01-04 09:54:10 +08:00
# endif
2021-10-24 18:38:35 +08:00
# if !defined(ESP8266) && !defined(NRF5)
// play feedback tone before setup, since it kills the IR timer settings
2022-05-19 07:47:10 +08:00
tone ( TONE_PIN , 1000 , 50 ) ;
2021-01-04 09:54:10 +08:00
delay ( 50 ) ;
# endif
IRDispatcher . init ( ) ; // This just calls irmp_init()
2021-10-24 18:38:35 +08:00
# if defined(USE_TINY_IR_RECEIVER)
2021-01-04 09:54:10 +08:00
Serial . println ( F ( " Ready to receive NEC IR signals at pin " STR ( IR_INPUT_PIN ) ) ) ;
# else
2021-10-24 18:38:35 +08:00
irmp_register_complete_callback_function ( & handleReceivedIRData ) ; // fixed function in IRCommandDispatcher.hpp
2021-01-04 09:54:10 +08:00
Serial . print ( F ( " Ready to receive IR signals of protocols: " ) ) ;
irmp_print_active_protocols ( & Serial ) ;
Serial . println ( F ( " at pin " STR ( IRMP_INPUT_PIN ) ) ) ;
2022-03-30 17:55:04 +08:00
# if defined(ALTERNATIVE_IR_FEEDBACK_LED_PIN)
2021-03-09 04:38:06 +08:00
irmp_irsnd_LEDFeedback ( true ) ; // Enable receive signal feedback at ALTERNATIVE_IR_FEEDBACK_LED_PIN
2021-10-24 18:38:35 +08:00
Serial . println ( F ( " IR feedback pin is " STR ( ALTERNATIVE_IR_FEEDBACK_LED_PIN ) ) ) ;
2021-01-04 09:54:10 +08:00
# endif
# endif
Serial . print ( F ( " Listening to commands of IR remote of type " ) ) ;
Serial . println ( IR_REMOTE_NAME ) ;
2021-10-24 18:38:35 +08:00
doPrintMenu ( ) ;
2021-01-04 09:54:10 +08:00
}
2021-10-24 18:38:35 +08:00
void loop ( ) {
IRDispatcher . checkAndRunSuspendedBlockingCommands ( ) ;
if ( doBlink ) {
2021-01-04 09:54:10 +08:00
digitalWrite ( LED_BUILTIN , HIGH ) ;
2022-01-27 01:36:50 +08:00
DELAY_AND_RETURN_IF_STOP ( sBlinkDelay ) ;
2021-01-04 09:54:10 +08:00
digitalWrite ( LED_BUILTIN , LOW ) ;
2022-01-27 01:36:50 +08:00
DELAY_AND_RETURN_IF_STOP ( sBlinkDelay ) ;
2021-01-04 09:54:10 +08:00
}
if ( millis ( ) - IRDispatcher . IRReceivedData . MillisOfLastCode > 120000 )
{
2021-10-24 18:38:35 +08:00
//Short beep as remainder, if we did not receive any command in the last 2 minutes
2021-01-04 09:54:10 +08:00
IRDispatcher . IRReceivedData . MillisOfLastCode + = 120000 ;
doTone1800 ( ) ;
}
2021-10-24 18:38:35 +08:00
// delay(10);
2021-01-04 09:54:10 +08:00
}
2021-10-24 18:38:35 +08:00
void doPrintMenu ( ) {
Serial . println ( ) ;
Serial . println ( F ( " Press 1 for tone 1800 Hz " ) ) ;
Serial . println ( F ( " Press 2 for tone 2200 Hz " ) ) ;
Serial . println ( F ( " Press 3 for this Menu " ) ) ;
Serial . println ( F ( " Press 0 for LED blink 20 times " ) ) ;
Serial . println ( F ( " Press UP for LED on " ) ) ;
Serial . println ( F ( " Press DOWN for LED off " ) ) ;
Serial . println ( F ( " Press OK for LED blink start " ) ) ;
Serial . println ( F ( " Press RIGHT for LED increase blink frequency " ) ) ;
Serial . println ( F ( " Press LEFT for LED decrease blink frequency " ) ) ;
Serial . println ( F ( " Press STAR for reset blink frequency " ) ) ;
Serial . println ( F ( " Press HASH for stop " ) ) ;
Serial . println ( ) ;
}
2021-01-04 09:54:10 +08:00
/*
* Here the actions that are matched to IR keys
*/
2021-10-24 18:38:35 +08:00
void doLedOn ( ) {
2021-01-04 09:54:10 +08:00
digitalWrite ( LED_BUILTIN , HIGH ) ;
doBlink = false ;
}
2021-10-24 18:38:35 +08:00
void doLedOff ( ) {
2021-01-04 09:54:10 +08:00
digitalWrite ( LED_BUILTIN , LOW ) ;
doBlink = false ;
}
2021-10-24 18:38:35 +08:00
void doIncreaseBlinkFrequency ( ) {
doBlink = true ;
if ( sBlinkDelay > 5 ) {
2021-01-04 09:54:10 +08:00
sBlinkDelay - = sBlinkDelay / 4 ;
}
}
2021-10-24 18:38:35 +08:00
void doDecreaseBlinkFrequency ( ) {
doBlink = true ;
2021-01-04 09:54:10 +08:00
sBlinkDelay + = sBlinkDelay / 4 ;
}
2021-10-24 18:38:35 +08:00
void doStop ( ) {
2021-01-04 09:54:10 +08:00
doBlink = false ;
}
2021-10-24 18:38:35 +08:00
void doResetBlinkFrequency ( ) {
2021-01-04 09:54:10 +08:00
sBlinkDelay = 200 ;
digitalWrite ( LED_BUILTIN , LOW ) ;
}
2021-10-24 18:38:35 +08:00
void doLedBlinkStart ( ) {
2021-01-04 09:54:10 +08:00
doBlink = true ;
}
2021-10-24 18:38:35 +08:00
/*
* This is a blocking function and checks periodically for stop
*/
void doLedBlink20times ( ) {
for ( int i = 0 ; i < 20 ; + + i ) {
2021-01-04 09:54:10 +08:00
digitalWrite ( LED_BUILTIN , HIGH ) ;
2022-01-27 01:36:50 +08:00
DELAY_AND_RETURN_IF_STOP ( 200 ) ;
2021-01-04 09:54:10 +08:00
digitalWrite ( LED_BUILTIN , LOW ) ;
2022-01-27 01:36:50 +08:00
DELAY_AND_RETURN_IF_STOP ( 200 ) ;
2021-01-04 09:54:10 +08:00
}
}
2021-10-24 18:38:35 +08:00
void doTone1800 ( ) {
# if defined(USE_IRMP_LIBRARY) && !defined(IRMP_ENABLE_PIN_CHANGE_INTERRUPT)
2021-01-04 09:54:10 +08:00
irmp_tone ( TONE_PIN , 1800 , 200 ) ;
2021-10-24 18:38:35 +08:00
# else
# if !defined(ESP8266) && !defined(NRF5) // tone() stops timer 1 for ESP8266
tone ( TONE_PIN , 1800 , 200 ) ;
# endif
2021-01-04 09:54:10 +08:00
# endif
}
2021-10-24 18:38:35 +08:00
void doTone2200 ( ) {
# if defined(USE_IRMP_LIBRARY) && !defined(IRMP_ENABLE_PIN_CHANGE_INTERRUPT)
2021-01-04 09:54:10 +08:00
// use IRMP compatible function for tone()
irmp_tone ( TONE_PIN , 2200 , 50 ) ;
2021-10-24 18:38:35 +08:00
# else
# if !defined(ESP8266) && !defined(NRF5) // tone() stops timer 1 for ESP8266
tone ( TONE_PIN , 2200 , 50 ) ;
# endif
# endif
2021-01-04 09:54:10 +08:00
}
2021-10-24 18:38:35 +08:00
# if defined(USE_IRMP_LIBRARY)
2021-01-04 09:54:10 +08:00
/*
2021-10-24 18:38:35 +08:00
* Convenience IRMP compatible wrapper function for Arduino tone ( ) if IRMP_ENABLE_PIN_CHANGE_INTERRUPT is NOT activated
* It currently disables the receiving of repeats
2021-01-04 09:54:10 +08:00
*/
2021-10-24 18:38:35 +08:00
void irmp_tone ( uint8_t _pin , unsigned int frequency , unsigned long duration ) {
# if defined(__AVR__) && !defined(IRMP_ENABLE_PIN_CHANGE_INTERRUPT)
2021-01-04 09:54:10 +08:00
storeIRTimer ( ) ;
tone ( _pin , frequency , 0 ) ;
2021-10-24 18:38:35 +08:00
if ( duration = = 0 ) {
2021-01-04 09:54:10 +08:00
duration = 100 ;
}
delay ( duration ) ;
noTone ( _pin ) ;
restoreIRTimer ( ) ;
# elif defined(ESP8266)
2021-10-24 18:38:35 +08:00
// tone() stops timer 1
2021-01-04 09:54:10 +08:00
( void ) _pin ;
( void ) frequency ;
( void ) duration ;
# else
tone ( _pin , frequency , duration ) ;
# endif
}
2021-10-24 18:38:35 +08:00
# endif // #if defined(USE_IRMP_LIBRARY)