Arduino-IRremote/examples/SendAndReceive/SendAndReceive.ino

162 lines
6.6 KiB
C++

/*
* SendAndReceive.cpp
*
* Demonstrates sending IR codes and receiving it simultaneously
*
* This file is part of Arduino-IRremote https://github.com/Arduino-IRremote/Arduino-IRremote.
*
************************************************************************************
* MIT License
*
* Copyright (c) 2021-2023 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 <Arduino.h>
// select only NEC and the universal decoder for pulse distance protocols
#define DECODE_NEC // Includes Apple and Onkyo
#define DECODE_DISTANCE_WIDTH // In case NEC is not received correctly. Universal decoder for pulse distance width protocols
//#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 NO_LED_FEEDBACK_CODE // saves 92 bytes program memory
//#define RECORD_GAP_MICROS 12000 // Default is 5000. Activate it for some LG air conditioner protocols
//#define SEND_PWM_BY_TIMER // Disable carrier PWM generation in software and use (restricted) hardware PWM.
//#define USE_NO_SEND_PWM // Use no carrier PWM, just simulate an active low receiver signal. Overrides SEND_PWM_BY_TIMER definition
//#define DEBUG // Activate this for lots of lovely debug output from the decoders.
#include "PinDefinitionsAndMore.h" // Define macros for input and output pin etc.
#include <IRremote.hpp>
#define DELAY_AFTER_SEND 2000
#define DELAY_AFTER_LOOP 5000
void setup() {
Serial.begin(115200);
#if defined(__AVR_ATmega32U4__) || defined(SERIAL_PORT_USBVIRTUAL) || defined(SERIAL_USB) /*stm32duino*/|| defined(USBCON) /*STM32_stm32*/|| defined(SERIALUSB_PID) || defined(ARDUINO_attiny3217)
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!
#endif
// Just to know which program is running on my Arduino
Serial.println(F("START " __FILE__ " from " __DATE__ "\r\nUsing library version " VERSION_IRREMOTE));
// 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)));
IrSender.begin(); // Start with IR_SEND_PIN as send pin and enable feedback LED at default feedback LED pin
Serial.println(F("Send IR signals at pin " STR(IR_SEND_PIN)));
#if FLASHEND >= 0x3FFF // For 16k flash or more, like ATtiny1604
// For esp32 we use PWM generation by ledcWrite() for each pin.
# if !defined(SEND_PWM_BY_TIMER) && !defined(USE_NO_SEND_PWM) && !defined(ESP32)
/*
* Print internal software PWM generation info
*/
IrSender.enableIROut(38); // Call it with 38 kHz to initialize the values printed below
Serial.print(F("Send signal mark duration is "));
Serial.print(IrSender.periodOnTimeMicros);
Serial.print(F(" us, pulse correction is "));
Serial.print(IrSender.getPulseCorrectionNanos());
Serial.print(F(" ns, total period is "));
Serial.print(IrSender.periodTimeMicros);
Serial.println(F(" us"));
# endif
// 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"));
#endif
}
uint16_t sAddress = 0x0102;
uint8_t sCommand = 0x34;
uint8_t sRepeats = 1;
/*
* Send NEC IR protocol
*/
void send_ir_data() {
Serial.print(F("Sending: 0x"));
Serial.print(sAddress, HEX);
Serial.print(sCommand, HEX);
Serial.println(sRepeats, HEX);
Serial.flush(); // To avoid disturbing the software PWM generation by serial output interrupts
// clip repeats at 4
if (sRepeats > 4) {
sRepeats = 4;
}
// Results for the first loop to: Protocol=NEC Address=0x102 Command=0x34 Raw-Data=0xCB340102 (32 bits)
IrSender.sendNEC(sAddress, sCommand, sRepeats);
}
void receive_ir_data() {
if (IrReceiver.decode()) {
Serial.print(F("Decoded protocol: "));
Serial.print(getProtocolString(IrReceiver.decodedIRData.protocol));
Serial.print(F(", decoded raw data: "));
#if (__INT_WIDTH__ < 32)
Serial.print(IrReceiver.decodedIRData.decodedRawData, HEX);
#else
PrintULL::print(&Serial, IrReceiver.decodedIRData.decodedRawData, HEX);
#endif
Serial.print(F(", decoded address: "));
Serial.print(IrReceiver.decodedIRData.address, HEX);
Serial.print(F(", decoded command: "));
Serial.println(IrReceiver.decodedIRData.command, HEX);
IrReceiver.resume();
}
}
void loop() {
/*
* Print loop values
*/
Serial.println();
Serial.print(F("address=0x"));
Serial.print(sAddress, HEX);
Serial.print(F(" command=0x"));
Serial.print(sCommand, HEX);
Serial.print(F(" repeats="));
Serial.println(sRepeats);
Serial.flush();
send_ir_data();
IrReceiver.restartAfterSend(); // Is a NOP if sending does not require a timer.
// wait for the receiver state machine to detect the end of a protocol
delay((RECORD_GAP_MICROS / 1000) + 5);
receive_ir_data();
// Prepare data for next loop
sAddress += 0x0101;
sCommand += 0x11;
sRepeats++;
delay(100); // Loop delay
}