Convenience function isIRReceiverAttachedForTinyReceiver() and 3.party

This commit is contained in:
Armin 2024-02-13 15:46:48 +01:00
parent 7131adf71e
commit 8b9e036889
10 changed files with 215 additions and 39 deletions

View File

@ -58,7 +58,7 @@ PROJECT_LOGO =
# entered, it will be relative to the location where doxygen was started. If # entered, it will be relative to the location where doxygen was started. If
# left blank the current directory will be used. # left blank the current directory will be used.
OUTPUT_DIRECTORY = ..\Arduino-IRremote_gh-pages OUTPUT_DIRECTORY = E:\WORKSPACE_ARDUINO\lib\Arduino-IRremote_gh-pages
# If the CREATE_SUBDIRS tag is set to YES then doxygen will create 4096 sub- # If the CREATE_SUBDIRS tag is set to YES then doxygen will create 4096 sub-
# directories (in 2 levels) under the output directory of each output format and # directories (in 2 levels) under the output directory of each output format and

View File

@ -598,7 +598,9 @@ A simple example can be tested online with [WOKWI](https://wokwi.com/projects/33
#### TinyReceiver + TinySender #### TinyReceiver + TinySender
If **code size** or **timer usage** matters, look at these examples.<br/> If **code size** or **timer usage** matters, look at these examples.<br/>
The **[TinyReceiver](https://github.com/Arduino-IRremote/Arduino-IRremote/blob/master/examples/TinyReceiver/TinyReceiver.ino)** example uses the **TinyIRReceiver** library which can **only receive NEC, Extended NEC, ONKYO and FAST protocols, but does not require any timer**. They use pin change interrupt for on the fly decoding, which is the reason for the restricted protocol choice.<br/> The **[TinyReceiver](https://github.com/Arduino-IRremote/Arduino-IRremote/blob/master/examples/TinyReceiver/TinyReceiver.ino)** example uses the **TinyIRReceiver** library
which can **only receive NEC, Extended NEC, ONKYO and FAST protocols, but does not require any timer**.
They use pin change interrupt for on the fly decoding, which is the reason for the restricted protocol choice.<br/>
TinyReceiver can be tested online with [WOKWI](https://wokwi.com/arduino/projects/339264565653013075). TinyReceiver can be tested online with [WOKWI](https://wokwi.com/arduino/projects/339264565653013075).
The **[TinySender](https://github.com/Arduino-IRremote/Arduino-IRremote/blob/master/examples/TinySender/TinySender.ino)** example uses the **TinyIRSender** library which can **only send NEC, ONKYO and FAST protocols**.<br/> The **[TinySender](https://github.com/Arduino-IRremote/Arduino-IRremote/blob/master/examples/TinySender/TinySender.ino)** example uses the **TinyIRSender** library which can **only send NEC, ONKYO and FAST protocols**.<br/>
@ -718,13 +720,15 @@ These next macros for **TinyIRReceiver** must be defined in your program before
| `NO_LED_FEEDBACK_CODE` | disabled | Disables the feedback LED function. Saves 14 bytes program memory. | | `NO_LED_FEEDBACK_CODE` | disabled | Disables the feedback LED function. Saves 14 bytes program memory. |
| `DISABLE_PARITY_CHECKS` | disabled | Disables the addres and command parity checks. Saves 48 bytes program memory. | | `DISABLE_PARITY_CHECKS` | disabled | Disables the addres and command parity checks. Saves 48 bytes program memory. |
| `USE_EXTENDED_NEC_PROTOCOL` | disabled | Like NEC, but take the 16 bit address as one 16 bit value and not as 8 bit normal and 8 bit inverted value. | | `USE_EXTENDED_NEC_PROTOCOL` | disabled | Like NEC, but take the 16 bit address as one 16 bit value and not as 8 bit normal and 8 bit inverted value. |
| `USE_ONKYO_PROTOCOL` | disabled | Like NEC, but take both the 16 bit address and command each as one 16 bit value and not as 8 bit normal and 8 bit inverted value. | | `USE_ONKYO_PROTOCOL` | disabled | Like NEC, but take the 16 bit address and command each as one 16 bit value and not as 8 bit normal and 8 bit inverted value. |
| `USE_FAST_PROTOCOL` | disabled | Use FAST protocol (no address and 16 bit data, interpreted as 8 bit command and 8 bit inverted command) instead of NEC. | | `USE_FAST_PROTOCOL` | disabled | Use FAST protocol (no address and 16 bit data, interpreted as 8 bit command and 8 bit inverted command) instead of NEC. |
| `ENABLE_NEC2_REPEATS` | disabled | Instead of sending / receiving the NEC special repeat code, send / receive the original frame for repeat. | | `ENABLE_NEC2_REPEATS` | disabled | Instead of sending / receiving the NEC special repeat code, send / receive the original frame for repeat. |
| `USE_CALLBACK_FOR_TINY_RECEIVER` | disabled | Call the fixed function `void handleReceivedTinyIRData()` each time a frame or repeat is received. | | `USE_CALLBACK_FOR_TINY_RECEIVER` | disabled | Call the fixed function `void handleReceivedTinyIRData()` each time a frame or repeat is received. |
The next macro for **IRCommandDispatcher** must be defined in your program before the line `#include <IRCommandDispatcher.hpp>` to take effect. The next macro for **IRCommandDispatcher** must be defined in your program before the line `#include <IRCommandDispatcher.hpp>` to take effect.
| `USE_TINY_IR_RECEIVER` | disabled | Use [TinyReceiver](https://github.com/Arduino-IRremote/Arduino-IRremote#tinyreceiver--tinysender) for receiving IR codes. |
| `IR_COMMAND_HAS_MORE_THAN_8_BIT` | disabled | Enables mapping and dispatching of IR commands consisting of more than 8 bits. Saves up to 160 bytes program memory and 4 bytes RAM + 1 byte RAM per mapping entry. | | `IR_COMMAND_HAS_MORE_THAN_8_BIT` | disabled | Enables mapping and dispatching of IR commands consisting of more than 8 bits. Saves up to 160 bytes program memory and 4 bytes RAM + 1 byte RAM per mapping entry. |
| `BUZZER_PIN` | | If `USE_TINY_IR_RECEIVER` is enabled, the pin to be used for the optional 50 ms buzzer feedback before executing a command. Other IR libraries than Tiny are not compatible with tone() command. |
### Changing include (*.h) files with Arduino IDE ### Changing include (*.h) files with Arduino IDE
First, use *Sketch > Show Sketch Folder (Ctrl+K)*.<br/> First, use *Sketch > Show Sketch Folder (Ctrl+K)*.<br/>

View File

@ -2,6 +2,10 @@
The latest version may not be released! The latest version may not be released!
See also the commit log at github: https://github.com/Arduino-IRremote/Arduino-IRremote/commits/master See also the commit log at github: https://github.com/Arduino-IRremote/Arduino-IRremote/commits/master
# 4.2.2
- Added convenience function isIRReceiverAttachedForTinyReceiver().
- Added Extended NEC Protocol to TinyIR by Butzerb
# 4.2.1 # 4.2.1
- Fix wrong type of tEnableLEDFeedback in IRSend.hpp and IRReceive.hpp. - Fix wrong type of tEnableLEDFeedback in IRSend.hpp and IRReceive.hpp.
- TinyReceiver 2.0 - TinyReceiver 2.0

View File

@ -85,6 +85,7 @@
#define ADC_TEMPERATURE_CHANNEL_MUX 15 #define ADC_TEMPERATURE_CHANNEL_MUX 15
#define ADC_1_1_VOLT_CHANNEL_MUX 12 #define ADC_1_1_VOLT_CHANNEL_MUX 12
#define ADC_GND_CHANNEL_MUX 13 #define ADC_GND_CHANNEL_MUX 13
#define ADC_CHANNEL_MUX_MASK 0x0F
#elif defined(__AVR_ATtiny87__) || defined(__AVR_ATtiny167__) #elif defined(__AVR_ATtiny87__) || defined(__AVR_ATtiny167__)
#define ADC_ISCR_CHANNEL_MUX 3 #define ADC_ISCR_CHANNEL_MUX 3
@ -92,20 +93,25 @@
#define ADC_1_1_VOLT_CHANNEL_MUX 12 #define ADC_1_1_VOLT_CHANNEL_MUX 12
#define ADC_GND_CHANNEL_MUX 14 #define ADC_GND_CHANNEL_MUX 14
#define ADC_VCC_4TH_CHANNEL_MUX 13 #define ADC_VCC_4TH_CHANNEL_MUX 13
#define ADC_CHANNEL_MUX_MASK 0x1F
#elif defined(__AVR_ATmega328P__) #elif defined(__AVR_ATmega328P__)
#define ADC_TEMPERATURE_CHANNEL_MUX 8 #define ADC_TEMPERATURE_CHANNEL_MUX 8
#define ADC_1_1_VOLT_CHANNEL_MUX 14 #define ADC_1_1_VOLT_CHANNEL_MUX 14
#define ADC_GND_CHANNEL_MUX 15 #define ADC_GND_CHANNEL_MUX 15
#define ADC_CHANNEL_MUX_MASK 0x0F
#elif defined(__AVR_ATmega32U4__) #elif defined(__AVR_ATmega32U4__)
#define ADC_TEMPERATURE_CHANNEL_MUX 0x27 #define ADC_TEMPERATURE_CHANNEL_MUX 0x27
#define ADC_1_1_VOLT_CHANNEL_MUX 0x1E #define ADC_1_1_VOLT_CHANNEL_MUX 0x1E
#define ADC_GND_CHANNEL_MUX 0x1F #define ADC_GND_CHANNEL_MUX 0x1F
#define ADC_CHANNEL_MUX_MASK 0x3F
#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) || defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__) || defined(__AVR_ATmega644__) || defined(__AVR_ATmega644A__) || defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644PA__) #elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) || defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__) || defined(__AVR_ATmega644__) || defined(__AVR_ATmega644A__) || defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644PA__)
#define ADC_1_1_VOLT_CHANNEL_MUX 0x1E #define ADC_1_1_VOLT_CHANNEL_MUX 0x1E
#define ADC_GND_CHANNEL_MUX 0x1F #define ADC_GND_CHANNEL_MUX 0x1F
#define ADC_CHANNEL_MUX_MASK 0x1F
#define INTERNAL INTERNAL1V1 #define INTERNAL INTERNAL1V1
#else #else
@ -164,7 +170,10 @@ uint16_t waitAndReadADCChannelWithReferenceAndRestoreADMUXAndReference(uint8_t a
uint16_t readADCChannelWithOversample(uint8_t aADCChannelNumber, uint8_t aOversampleExponent); uint16_t readADCChannelWithOversample(uint8_t aADCChannelNumber, uint8_t aOversampleExponent);
void setADCChannelAndReferenceForNextConversion(uint8_t aADCChannelNumber, uint8_t aReference); void setADCChannelAndReferenceForNextConversion(uint8_t aADCChannelNumber, uint8_t aReference);
uint16_t readADCChannelWithReferenceOversampleFast(uint8_t aADCChannelNumber, uint8_t aReference, uint8_t aOversampleExponent); uint16_t readADCChannelWithReferenceOversampleFast(uint8_t aADCChannelNumber, uint8_t aReference, uint8_t aOversampleExponent);
uint16_t readADCChannelWithReferenceMultiSamples(uint8_t aADCChannelNumber, uint8_t aReference, uint8_t aNumberOfSamples); uint32_t readADCChannelMultiSamples(uint8_t aPrescale, uint16_t aNumberOfSamples);
uint16_t readADCChannelMultiSamplesWithReference(uint8_t aADCChannelNumber, uint8_t aReference, uint8_t aNumberOfSamples);
uint32_t readADCChannelMultiSamplesWithReferenceAndPrescaler(uint8_t aADCChannelNumber, uint8_t aReference, uint8_t aPrescale,
uint16_t aNumberOfSamples);
uint16_t readADCChannelWithReferenceMax(uint8_t aADCChannelNumber, uint8_t aReference, uint16_t aNumberOfSamples); uint16_t readADCChannelWithReferenceMax(uint8_t aADCChannelNumber, uint8_t aReference, uint16_t aNumberOfSamples);
uint16_t readADCChannelWithReferenceMaxMicros(uint8_t aADCChannelNumber, uint8_t aReference, uint16_t aMicrosecondsToAquire); uint16_t readADCChannelWithReferenceMaxMicros(uint8_t aADCChannelNumber, uint8_t aReference, uint16_t aMicrosecondsToAquire);
uint16_t readUntil4ConsecutiveValuesAreEqual(uint8_t aADCChannelNumber, uint8_t aReference, uint8_t aDelay, uint16_t readUntil4ConsecutiveValuesAreEqual(uint8_t aADCChannelNumber, uint8_t aReference, uint8_t aDelay,
@ -192,7 +201,8 @@ float getCPUTemperatureSimple(void);
float getCPUTemperature(void); float getCPUTemperature(void);
float getTemperature(void) __attribute__ ((deprecated ("Renamed to getCPUTemperature()"))); // deprecated float getTemperature(void) __attribute__ ((deprecated ("Renamed to getCPUTemperature()"))); // deprecated
bool isVCCUSBPowered() ; bool isVCCUSBPowered();
bool isVCCUSBPowered(Print *aSerial);
bool isVCCUndervoltageMultipleTimes(); bool isVCCUndervoltageMultipleTimes();
void resetCounterForVCCUndervoltageMultipleTimes(); void resetCounterForVCCUndervoltageMultipleTimes();
bool isVCCUndervoltage(); bool isVCCUndervoltage();

View File

@ -58,7 +58,7 @@ union WordUnionForADCUtils {
* Enable this to see information on each call. * Enable this to see information on each call.
* Since there should be no library which uses Serial, it should only be enabled for development purposes. * Since there should be no library which uses Serial, it should only be enabled for development purposes.
*/ */
#if defined(DEBUG) #if defined(DEBUG) && !defined(LOCAL_DEBUG)
#define LOCAL_DEBUG #define LOCAL_DEBUG
#else #else
//#define LOCAL_DEBUG // This enables debug output only for this file //#define LOCAL_DEBUG // This enables debug output only for this file
@ -161,12 +161,15 @@ uint8_t checkAndWaitForReferenceAndChannelToSwitch(uint8_t aADCChannelNumber, ui
if ((tOldADMUX & MASK_FOR_ADC_REFERENCE) != tNewReference && (aReference == INTERNAL || aReference == INTERNAL2V56)) { if ((tOldADMUX & MASK_FOR_ADC_REFERENCE) != tNewReference && (aReference == INTERNAL || aReference == INTERNAL2V56)) {
#else #else
if ((tOldADMUX & MASK_FOR_ADC_REFERENCE) != tNewReference && aReference == INTERNAL) { if ((tOldADMUX & MASK_FOR_ADC_REFERENCE) != tNewReference && aReference == INTERNAL) {
#endif
#if defined(LOCAL_DEBUG)
Serial.println(F("Switch from DEFAULT to INTERNAL"));
#endif #endif
/* /*
* Switch reference from DEFAULT to INTERNAL * Switch reference from DEFAULT to INTERNAL
*/ */
delayMicroseconds(8000); // experimental value is >= 7600 us for Nano board and 6200 for Uno board delayMicroseconds(8000); // experimental value is >= 7600 us for Nano board and 6200 for Uno board
} else if ((tOldADMUX & 0x0F) != aADCChannelNumber) { } else if ((tOldADMUX & ADC_CHANNEL_MUX_MASK) != aADCChannelNumber) {
if (aADCChannelNumber == ADC_1_1_VOLT_CHANNEL_MUX) { if (aADCChannelNumber == ADC_1_1_VOLT_CHANNEL_MUX) {
/* /*
* Internal 1.1 Volt channel requires <= 200 us for Nano board * Internal 1.1 Volt channel requires <= 200 us for Nano board
@ -249,9 +252,10 @@ uint16_t readADCChannelWithReferenceOversampleFast(uint8_t aADCChannelNumber, ui
/* /*
* Returns sum of all sample values * Returns sum of all sample values
* Conversion time is defined as 0.104 milliseconds for 16 MHz Arduino by ADC_PRESCALE in ADCUtils.h. * Conversion time is defined as 0.104 milliseconds for 16 MHz Arduino by ADC_PRESCALE (=ADC_PRESCALE128) in ADCUtils.h.
* @ param aNumberOfSamples If > 64 an overflow may occur.
*/ */
uint16_t readADCChannelWithReferenceMultiSamples(uint8_t aADCChannelNumber, uint8_t aReference, uint8_t aNumberOfSamples) { uint16_t readADCChannelMultiSamplesWithReference(uint8_t aADCChannelNumber, uint8_t aReference, uint8_t aNumberOfSamples) {
uint16_t tSumValue = 0; uint16_t tSumValue = 0;
ADMUX = aADCChannelNumber | (aReference << SHIFT_VALUE_FOR_REFERENCE); ADMUX = aADCChannelNumber | (aReference << SHIFT_VALUE_FOR_REFERENCE);
@ -275,6 +279,65 @@ uint16_t readADCChannelWithReferenceMultiSamples(uint8_t aADCChannelNumber, uint
return tSumValue; return tSumValue;
} }
/*
* Returns sum of all sample values
* Conversion time is defined as 0.104 milliseconds for 16 MHz Arduino for ADC_PRESCALE128 in ADCUtils.h.
* @ param aPrescale can be one of ADC_PRESCALE2, ADC_PRESCALE4, 8, 16, 32, 64, 128.
* ADC_PRESCALE32 is recommended for excellent linearity and fast readout of 26 microseconds
* @ param aNumberOfSamples If > 16k an overflow may occur.
*/
uint32_t readADCChannelMultiSamplesWithReferenceAndPrescaler(uint8_t aADCChannelNumber, uint8_t aReference, uint8_t aPrescale,
uint16_t aNumberOfSamples) {
uint32_t tSumValue = 0;
ADMUX = aADCChannelNumber | (aReference << SHIFT_VALUE_FOR_REFERENCE);
ADCSRB = 0; // Free running mode. Only active if ADATE is set to 1.
// ADSC-StartConversion ADATE-AutoTriggerEnable ADIF-Reset Interrupt Flag
ADCSRA = (_BV(ADEN) | _BV(ADSC) | _BV(ADATE) | _BV(ADIF) | aPrescale);
for (uint16_t i = 0; i < aNumberOfSamples; i++) {
/*
* wait for free running conversion to finish.
* Do not wait for ADSC here, since ADSC is only low for 1 ADC Clock cycle on free running conversion.
*/
loop_until_bit_is_set(ADCSRA, ADIF);
ADCSRA |= _BV(ADIF); // clear bit to enable recognizing next conversion has finished
// Add value
tSumValue += ADCL | (ADCH << 8); // using WordUnionForADCUtils does not save space here
// tSumValue += (ADCH << 8) | ADCL; // this does NOT work!
}
ADCSRA &= ~_BV(ADATE); // Disable auto-triggering (free running mode)
return tSumValue;
}
/*
* Returns sum of all sample values
* Assumes, that channel and reference are still set to the right values
* @ param aNumberOfSamples If > 16k an overflow may occur.
*/
uint32_t readADCChannelMultiSamples(uint8_t aPrescale, uint16_t aNumberOfSamples) {
uint32_t tSumValue = 0;
ADCSRB = 0; // Free running mode. Only active if ADATE is set to 1.
// ADSC-StartConversion ADATE-AutoTriggerEnable ADIF-Reset Interrupt Flag
ADCSRA = (_BV(ADEN) | _BV(ADSC) | _BV(ADATE) | _BV(ADIF) | aPrescale);
for (uint16_t i = 0; i < aNumberOfSamples; i++) {
/*
* wait for free running conversion to finish.
* Do not wait for ADSC here, since ADSC is only low for 1 ADC Clock cycle on free running conversion.
*/
loop_until_bit_is_set(ADCSRA, ADIF);
ADCSRA |= _BV(ADIF); // clear bit to enable recognizing next conversion has finished
// Add value
tSumValue += ADCL | (ADCH << 8); // using WordUnionForADCUtils does not save space here
// tSumValue += (ADCH << 8) | ADCL; // this does NOT work!
}
ADCSRA &= ~_BV(ADATE); // Disable auto-triggering (free running mode)
return tSumValue;
}
/* /*
* use ADC_PRESCALE32 which gives 26 us conversion time and good linearity * use ADC_PRESCALE32 which gives 26 us conversion time and good linearity
* @return the maximum value of aNumberOfSamples samples. * @return the maximum value of aNumberOfSamples samples.
@ -408,7 +471,7 @@ uint16_t readUntil4ConsecutiveValuesAreEqual(uint8_t aADCChannelNumber, uint8_t
*/ */
float getVCCVoltageSimple(void) { float getVCCVoltageSimple(void) {
// use AVCC with (optional) external capacitor at AREF pin as reference // use AVCC with (optional) external capacitor at AREF pin as reference
float tVCC = readADCChannelWithReferenceMultiSamples(ADC_1_1_VOLT_CHANNEL_MUX, DEFAULT, 4); float tVCC = readADCChannelMultiSamplesWithReference(ADC_1_1_VOLT_CHANNEL_MUX, DEFAULT, 4);
return ((1023 * 1.1 * 4) / tVCC); return ((1023 * 1.1 * 4) / tVCC);
} }
@ -419,7 +482,7 @@ float getVCCVoltageSimple(void) {
*/ */
uint16_t getVCCVoltageMillivoltSimple(void) { uint16_t getVCCVoltageMillivoltSimple(void) {
// use AVCC with external capacitor at AREF pin as reference // use AVCC with external capacitor at AREF pin as reference
uint16_t tVCC = readADCChannelWithReferenceMultiSamples(ADC_1_1_VOLT_CHANNEL_MUX, DEFAULT, 4); uint16_t tVCC = readADCChannelMultiSamplesWithReference(ADC_1_1_VOLT_CHANNEL_MUX, DEFAULT, 4);
return ((1023L * ADC_INTERNAL_REFERENCE_MILLIVOLT * 4) / tVCC); return ((1023L * ADC_INTERNAL_REFERENCE_MILLIVOLT * 4) / tVCC);
} }
@ -459,6 +522,9 @@ uint16_t getVCCVoltageMillivolt(void) {
return ((1023L * ADC_INTERNAL_REFERENCE_MILLIVOLT) / tVCC); return ((1023L * ADC_INTERNAL_REFERENCE_MILLIVOLT) / tVCC);
} }
/*
* Does not set sVCCVoltageMillivolt
*/
uint16_t printVCCVoltageMillivolt(Print *aSerial) { uint16_t printVCCVoltageMillivolt(Print *aSerial) {
aSerial->print(F("VCC=")); aSerial->print(F("VCC="));
uint16_t tVCCVoltageMillivolt = getVCCVoltageMillivolt(); uint16_t tVCCVoltageMillivolt = getVCCVoltageMillivolt();
@ -480,7 +546,7 @@ void readAndPrintVCCVoltageMillivolt(Print *aSerial) {
*/ */
void readVCCVoltageSimple(void) { void readVCCVoltageSimple(void) {
// use AVCC with (optional) external capacitor at AREF pin as reference // use AVCC with (optional) external capacitor at AREF pin as reference
float tVCC = readADCChannelWithReferenceMultiSamples(ADC_1_1_VOLT_CHANNEL_MUX, DEFAULT, 4); float tVCC = readADCChannelMultiSamplesWithReference(ADC_1_1_VOLT_CHANNEL_MUX, DEFAULT, 4);
sVCCVoltage = (1023 * (((float) ADC_INTERNAL_REFERENCE_MILLIVOLT) / 1000) * 4) / tVCC; sVCCVoltage = (1023 * (((float) ADC_INTERNAL_REFERENCE_MILLIVOLT) / 1000) * 4) / tVCC;
} }
@ -491,7 +557,7 @@ void readVCCVoltageSimple(void) {
*/ */
void readVCCVoltageMillivoltSimple(void) { void readVCCVoltageMillivoltSimple(void) {
// use AVCC with external capacitor at AREF pin as reference // use AVCC with external capacitor at AREF pin as reference
uint16_t tVCCVoltageMillivoltRaw = readADCChannelWithReferenceMultiSamples(ADC_1_1_VOLT_CHANNEL_MUX, DEFAULT, 4); uint16_t tVCCVoltageMillivoltRaw = readADCChannelMultiSamplesWithReference(ADC_1_1_VOLT_CHANNEL_MUX, DEFAULT, 4);
sVCCVoltageMillivolt = (1023L * ADC_INTERNAL_REFERENCE_MILLIVOLT * 4) / tVCCVoltageMillivoltRaw; sVCCVoltageMillivolt = (1023L * ADC_INTERNAL_REFERENCE_MILLIVOLT * 4) / tVCCVoltageMillivoltRaw;
} }
@ -548,6 +614,25 @@ bool isVCCUSBPowered() {
&& sVCCVoltageMillivolt < VOLTAGE_USB_POWERED_UPPER_THRESHOLD_MILLIVOLT); && sVCCVoltageMillivolt < VOLTAGE_USB_POWERED_UPPER_THRESHOLD_MILLIVOLT);
} }
/*
* Return true if sVCCVoltageMillivolt is > 4.3 V and < 4.95 V
*/
bool isVCCUSBPowered(Print *aSerial) {
readVCCVoltageMillivolt();
aSerial->print(F("USB powered is "));
bool tReturnValue;
if (VOLTAGE_USB_POWERED_LOWER_THRESHOLD_MILLIVOLT
< sVCCVoltageMillivolt&& sVCCVoltageMillivolt < VOLTAGE_USB_POWERED_UPPER_THRESHOLD_MILLIVOLT) {
tReturnValue = true;
aSerial->print(F("true "));
} else {
tReturnValue = false;
aSerial->print(F("false "));
}
printVCCVoltageMillivolt(aSerial);
return tReturnValue;
}
/* /*
* @ return true only once, when VCC_UNDERVOLTAGE_CHECKS_BEFORE_STOP (6) times voltage too low -> shutdown * @ return true only once, when VCC_UNDERVOLTAGE_CHECKS_BEFORE_STOP (6) times voltage too low -> shutdown
*/ */
@ -685,7 +770,7 @@ float getCPUTemperature(void) {
} }
#else // defined(ADC_UTILS_ARE_AVAILABLE) #else // defined(ADC_UTILS_ARE_AVAILABLE)
// Dummy definition of functions defined in ADCUtils to compile examples without errors // Dummy definition of functions defined in ADCUtils to compile examples for non AVR platforms without errors
/* /*
* Persistent storage for VCC value * Persistent storage for VCC value
*/ */

View File

@ -5,14 +5,14 @@
* *
* To run this example you need to install the "IRremote" or "IRMP" library under "Tools -> Manage Libraries..." or "Ctrl+Shift+I" * To run this example you need to install the "IRremote" or "IRMP" library under "Tools -> Manage Libraries..." or "Ctrl+Shift+I"
* *
* Copyright (C) 2019-2021 Armin Joachimsmeyer * Copyright (C) 2019-2024 Armin Joachimsmeyer
* armin.joachimsmeyer@gmail.com * armin.joachimsmeyer@gmail.com
* *
* This file is part of ServoEasing https://github.com/ArminJo/ServoEasing. * This file is part of ServoEasing https://github.com/ArminJo/ServoEasing.
* This file is part of IRMP https://github.com/IRMP-org/IRMP. * This file is part of IRMP https://github.com/IRMP-org/IRMP.
* This file is part of Arduino-IRremote https://github.com/Arduino-IRremote/Arduino-IRremote. * This file is part of Arduino-IRremote https://github.com/Arduino-IRremote/Arduino-IRremote.
* *
* ServoEasing is free software: you can redistribute it and/or modify * IRCommandDispatcher is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
@ -38,6 +38,22 @@
#define IR_COMMAND_FLAG_REPEATABLE 0x01 // repeat accepted #define IR_COMMAND_FLAG_REPEATABLE 0x01 // repeat accepted
#define IR_COMMAND_FLAG_NON_BLOCKING 0x02 // Non blocking (short) command that can be processed any time and may interrupt other IR commands - used for stop, set direction etc. #define IR_COMMAND_FLAG_NON_BLOCKING 0x02 // Non blocking (short) command that can be processed any time and may interrupt other IR commands - used for stop, set direction etc.
#define IR_COMMAND_FLAG_REPEATABLE_NON_BLOCKING (IR_COMMAND_FLAG_REPEATABLE | IR_COMMAND_FLAG_NON_BLOCKING) #define IR_COMMAND_FLAG_REPEATABLE_NON_BLOCKING (IR_COMMAND_FLAG_REPEATABLE | IR_COMMAND_FLAG_NON_BLOCKING)
#define IR_COMMAND_FLAG_BEEP 0x04 // Do a single short beep before executing command. May not be useful for short or repeating commands.
#define IR_COMMAND_FLAG_BLOCKING_BEEP (IR_COMMAND_FLAG_BLOCKING | IR_COMMAND_FLAG_BEEP)
#if !defined(IS_STOP_REQUESTED)
#define IS_STOP_REQUESTED IRDispatcher.requestToStopReceived
#endif
#if !defined(RETURN_IF_STOP)
#define RETURN_IF_STOP if (IRDispatcher.requestToStopReceived) return
#endif
#if !defined(BREAK_IF_STOP)
#define BREAK_IF_STOP if (IRDispatcher.requestToStopReceived) break
#endif
#if !defined(DELAY_AND_RETURN_IF_STOP)
#define DELAY_AND_RETURN_IF_STOP(aDurationMillis) if (IRDispatcher.delayAndCheckForStop(aDurationMillis)) return
#endif
// Basic mapping structure // Basic mapping structure
struct IRToCommandMappingStruct { struct IRToCommandMappingStruct {
@ -72,13 +88,10 @@ struct IRDataForCommandDispatcherStruct {
#define COMMAND_EMPTY 0xFF // code no command #define COMMAND_EMPTY 0xFF // code no command
#endif #endif
#define RETURN_IF_STOP if (IRDispatcher.requestToStopReceived) return
#define BREAK_IF_STOP if (IRDispatcher.requestToStopReceived) break
#define DELAY_AND_RETURN_IF_STOP(aDurationMillis) if (IRDispatcher.delayAndCheckForStop(aDurationMillis)) return
class IRCommandDispatcher { class IRCommandDispatcher {
public: public:
void init(); void init();
void printIRInfo(Print *aSerial);
bool checkAndRunNonBlockingCommands(); bool checkAndRunNonBlockingCommands();
bool checkAndRunSuspendedBlockingCommands(); bool checkAndRunSuspendedBlockingCommands();
@ -107,7 +120,8 @@ public:
bool justCalledBlockingCommand = false; // Flag that a blocking command was received and called - is set before call of command bool justCalledBlockingCommand = false; // Flag that a blocking command was received and called - is set before call of command
/* /*
* Flag for running blocking commands to terminate. To check, you can use "if (IRDispatcher.requestToStopReceived) return;" (available as macro RETURN_IF_STOP). * Flag for running blocking commands to terminate. To check, you can use "if (IRDispatcher.requestToStopReceived) return;" (available as macro RETURN_IF_STOP).
* Is reset by next IR command received. Can be reset by main loop, if command has stopped. * It is set if a blocking IR command received, which cannot be executed directly. Can be reset by main loop, if command has stopped.
* It is reset before executing a blocking command.
*/ */
volatile bool requestToStopReceived; volatile bool requestToStopReceived;
/* /*

View File

@ -11,14 +11,14 @@
* A blocking command is stored and sets a stop flag for an already running blocking function to terminate. * A blocking command is stored and sets a stop flag for an already running blocking function to terminate.
* The blocking command can in turn be executed by main loop by calling IRDispatcher.checkAndRunSuspendedBlockingCommands(). * The blocking command can in turn be executed by main loop by calling IRDispatcher.checkAndRunSuspendedBlockingCommands().
* *
* Copyright (C) 2019-2022 Armin Joachimsmeyer * Copyright (C) 2019-2024 Armin Joachimsmeyer
* armin.joachimsmeyer@gmail.com * armin.joachimsmeyer@gmail.com
* *
* This file is part of ServoEasing https://github.com/ArminJo/ServoEasing. * This file is part of ServoEasing https://github.com/ArminJo/ServoEasing.
* This file is part of IRMP https://github.com/IRMP-org/IRMP. * This file is part of IRMP https://github.com/IRMP-org/IRMP.
* This file is part of Arduino-IRremote https://github.com/Arduino-IRremote/Arduino-IRremote. * This file is part of Arduino-IRremote https://github.com/Arduino-IRremote/Arduino-IRremote.
* *
* ServoEasing is free software: you can redistribute it and/or modify * IRCommandDispatcher is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
@ -31,6 +31,14 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/gpl.html>. * along with this program. If not, see <http://www.gnu.org/licenses/gpl.html>.
*/ */
/*
* Program behavior is modified by the following macros
* USE_TINY_IR_RECEIVER
* USE_IRMP_LIBRARY
* IR_COMMAND_HAS_MORE_THAN_8_BIT
*/
#ifndef _IR_COMMAND_DISPATCHER_HPP #ifndef _IR_COMMAND_DISPATCHER_HPP
#define _IR_COMMAND_DISPATCHER_HPP #define _IR_COMMAND_DISPATCHER_HPP
@ -38,6 +46,10 @@
#include "IRCommandDispatcher.h" #include "IRCommandDispatcher.h"
#if !defined(STR_HELPER)
#define STR_HELPER(x) #x
#define STR(x) STR_HELPER(x)
#endif
/* /*
* Enable this to see information on each call. * Enable this to see information on each call.
* Since there should be no library which uses Serial, it should only be enabled for development purposes. * Since there should be no library which uses Serial, it should only be enabled for development purposes.
@ -73,6 +85,17 @@ void IRCommandDispatcher::init() {
initPCIInterruptForTinyReceiver(); initPCIInterruptForTinyReceiver();
} }
/*
* @return true, if IR Receiver is attached
*/
void IRCommandDispatcher::printIRInfo(Print *aSerial) {
aSerial->println();
// For available IR commands see IRCommandMapping.h https://github.com/ArminJo/PWMMotorControl/blob/master/examples/SmartCarFollower/IRCommandMapping.h
aSerial->print(F("Listening to IR remote of type "));
aSerial->print(IR_REMOTE_NAME);
aSerial->println(F(" at pin " STR(IR_RECEIVE_PIN)));
}
/* /*
* This is the TinyReceiver callback function, which is called if a complete command was received * This is the TinyReceiver callback function, which is called if a complete command was received
* It checks for right address and then call the dispatcher * It checks for right address and then call the dispatcher
@ -153,11 +176,11 @@ void handleReceivedIRData() {
#endif // elif defined(USE_IRMP_LIBRARY) #endif // elif defined(USE_IRMP_LIBRARY)
/* /*
* The main dispatcher function * The main dispatcher function called by IR-ISR, main loop and checkAndRunSuspendedBlockingCommands()
* Sets flags justCalledRegularIRCommand, executingBlockingCommand * Non blocking commands are executed directly, blocking commands are executed if enabled by parameter and no other command is just running.
* @param aCallBlockingCommandImmediately Run blocking command directly, otherwise set request to stop to true * Otherwise request to stop (requestToStopReceived) is set and command is stored for main loop to be later execute by checkAndRunSuspendedBlockingCommands().
* and store command for main loop to execute by checkAndRunSuspendedBlockingCommands(). * Sets flags justCalledRegularIRCommand, executingBlockingCommand, requestToStopReceived
* Should be false if called by ISR. * @param aCallBlockingCommandImmediately Run blocking command directly, if no other command is just running. Should be false if called by ISR in order not to block ISR.
*/ */
void IRCommandDispatcher::checkAndCallCommand(bool aCallBlockingCommandImmediately) { void IRCommandDispatcher::checkAndCallCommand(bool aCallBlockingCommandImmediately) {
if (IRReceivedData.command == COMMAND_EMPTY) { if (IRReceivedData.command == COMMAND_EMPTY) {
@ -200,21 +223,31 @@ void IRCommandDispatcher::checkAndCallCommand(bool aCallBlockingCommandImmediate
} }
/* /*
* lets start a new turn * Execute commands
*/ */
requestToStopReceived = false;
bool tIsNonBlockingCommand = (IRMapping[i].Flags & IR_COMMAND_FLAG_NON_BLOCKING); bool tIsNonBlockingCommand = (IRMapping[i].Flags & IR_COMMAND_FLAG_NON_BLOCKING);
if (tIsNonBlockingCommand) { if (tIsNonBlockingCommand) {
// short command here, just call // short command here, just call
CD_INFO_PRINT(F("Run non blocking command: ")); CD_INFO_PRINT(F("Run non blocking command: "));
CD_INFO_PRINTLN(tCommandName); CD_INFO_PRINTLN(tCommandName);
#if defined(BUZZER_PIN) && defined(USE_TINY_IR_RECEIVER)
/*
* Do (non blocking) buzzer feedback before command is executed
*/
if(IRMapping[i].Flags & IR_COMMAND_FLAG_BEEP) {
tone(BUZZER_PIN, 2200, 50);
}
#endif
IRMapping[i].CommandToCall(); IRMapping[i].CommandToCall();
} else { } else {
/*
* Blocking command here
*/
if (aCallBlockingCommandImmediately && currentBlockingCommandCalled == COMMAND_EMPTY) { if (aCallBlockingCommandImmediately && currentBlockingCommandCalled == COMMAND_EMPTY) {
/* /*
* here we are called from main loop to execute a command * Here no blocking command was running and we are called from main loop
*/ */
requestToStopReceived = false; // Do not stop the command executed now
justCalledBlockingCommand = true; justCalledBlockingCommand = true;
currentBlockingCommandCalled = IRReceivedData.command; // set lock for recursive calls currentBlockingCommandCalled = IRReceivedData.command; // set lock for recursive calls
lastBlockingCommandCalled = IRReceivedData.command; // set history, can be evaluated by main loop lastBlockingCommandCalled = IRReceivedData.command; // set history, can be evaluated by main loop
@ -224,6 +257,15 @@ void IRCommandDispatcher::checkAndCallCommand(bool aCallBlockingCommandImmediate
CD_INFO_PRINT(F("Run blocking command: ")); CD_INFO_PRINT(F("Run blocking command: "));
CD_INFO_PRINTLN(tCommandName); CD_INFO_PRINTLN(tCommandName);
#if defined(BUZZER_PIN) && defined(USE_TINY_IR_RECEIVER)
/*
* Do (non blocking) buzzer feedback before command is executed
*/
if(IRMapping[i].Flags & IR_COMMAND_FLAG_BEEP) {
tone(BUZZER_PIN, 2200, 50);
}
#endif
IRMapping[i].CommandToCall(); IRMapping[i].CommandToCall();
#if defined(TRACE) #if defined(TRACE)
Serial.println(F("End of blocking command")); Serial.println(F("End of blocking command"));
@ -231,7 +273,9 @@ void IRCommandDispatcher::checkAndCallCommand(bool aCallBlockingCommandImmediate
currentBlockingCommandCalled = COMMAND_EMPTY; currentBlockingCommandCalled = COMMAND_EMPTY;
} else { } else {
/* /*
* Do not run command directly, but set request to stop to true and store command for main loop to execute * Called by ISR or another command still running.
* Do not run command directly, but set request to stop to true and store command
* for main loop to execute by checkAndRunSuspendedBlockingCommands()
*/ */
BlockingCommandToRunNext = IRReceivedData.command; BlockingCommandToRunNext = IRReceivedData.command;
requestToStopReceived = true; // to stop running command requestToStopReceived = true; // to stop running command
@ -256,25 +300,29 @@ bool IRCommandDispatcher::checkAndRunSuspendedBlockingCommands() {
*/ */
if (BlockingCommandToRunNext != COMMAND_EMPTY) { if (BlockingCommandToRunNext != COMMAND_EMPTY) {
CD_INFO_PRINT(F("Take stored command = 0x")); CD_INFO_PRINT(F("Run stored command=0x"));
CD_INFO_PRINTLN(BlockingCommandToRunNext, HEX); CD_INFO_PRINTLN(BlockingCommandToRunNext, HEX);
IRReceivedData.command = BlockingCommandToRunNext; IRReceivedData.command = BlockingCommandToRunNext;
BlockingCommandToRunNext = COMMAND_EMPTY; BlockingCommandToRunNext = COMMAND_EMPTY;
IRReceivedData.isRepeat = false; IRReceivedData.isRepeat = false;
requestToStopReceived = false; // Do not stop the command executed now
checkAndCallCommand(true); checkAndCallCommand(true);
return true; return true;
} }
return false; return false;
} }
/*
* Not used internally
*/
#if defined(IR_COMMAND_HAS_MORE_THAN_8_BIT) #if defined(IR_COMMAND_HAS_MORE_THAN_8_BIT)
void IRCommandDispatcher::setNextBlockingCommand(uint16_t aBlockingCommandToRunNext) void IRCommandDispatcher::setNextBlockingCommand(uint16_t aBlockingCommandToRunNext)
#else #else
void IRCommandDispatcher::setNextBlockingCommand(uint8_t aBlockingCommandToRunNext) void IRCommandDispatcher::setNextBlockingCommand(uint8_t aBlockingCommandToRunNext)
#endif #endif
{ {
CD_INFO_PRINT(F("Set next command to 0x")); CD_INFO_PRINT(F("Set next command to run to 0x"));
CD_INFO_PRINTLN(aBlockingCommandToRunNext, HEX); CD_INFO_PRINTLN(aBlockingCommandToRunNext, HEX);
BlockingCommandToRunNext = aBlockingCommandToRunNext; BlockingCommandToRunNext = aBlockingCommandToRunNext;
requestToStopReceived = true; requestToStopReceived = true;
@ -296,7 +344,6 @@ bool IRCommandDispatcher::delayAndCheckForStop(uint16_t aDelayMillis) {
} }
void IRCommandDispatcher::printIRCommandString(Print *aSerial) { void IRCommandDispatcher::printIRCommandString(Print *aSerial) {
aSerial->print(F("IRCommand="));
for (uint_fast8_t i = 0; i < sizeof(IRMapping) / sizeof(struct IRToCommandMappingStruct); ++i) { for (uint_fast8_t i = 0; i < sizeof(IRMapping) / sizeof(struct IRToCommandMappingStruct); ++i) {
if (IRReceivedData.command == IRMapping[i].IRCode) { if (IRReceivedData.command == IRMapping[i].IRCode) {
aSerial->println(reinterpret_cast<const __FlashStringHelper*>(IRMapping[i].CommandString)); aSerial->println(reinterpret_cast<const __FlashStringHelper*>(IRMapping[i].CommandString));

View File

@ -60,7 +60,7 @@
*/ */
//#define DISABLE_PARITY_CHECKS // Disable parity checks. Saves 48 bytes of program memory. //#define DISABLE_PARITY_CHECKS // Disable parity checks. Saves 48 bytes of program memory.
//#define USE_EXTENDED_NEC_PROTOCOL // Like NEC, but take the 16 bit address as one 16 bit value and not as 8 bit normal and 8 bit inverted value. //#define USE_EXTENDED_NEC_PROTOCOL // Like NEC, but take the 16 bit address as one 16 bit value and not as 8 bit normal and 8 bit inverted value.
//#define USE_ONKYO_PROTOCOL // Like NEC, but take both the 16 bit address and command each as one 16 bit value and not as 8 bit normal and 8 bit inverted value. //#define USE_ONKYO_PROTOCOL // Like NEC, but take the 16 bit address and command each as one 16 bit value and not as 8 bit normal and 8 bit inverted value.
//#define USE_FAST_PROTOCOL // Use FAST protocol (no address and 16 bit data, interpreted as 8 bit command and 8 bit inverted command) instead of NEC / ONKYO. //#define USE_FAST_PROTOCOL // Use FAST protocol (no address and 16 bit data, interpreted as 8 bit command and 8 bit inverted command) instead of NEC / ONKYO.
//#define ENABLE_NEC2_REPEATS // Instead of sending / receiving the NEC special repeat code, send / receive the original frame for repeat. //#define ENABLE_NEC2_REPEATS // Instead of sending / receiving the NEC special repeat code, send / receive the original frame for repeat.
//#define USE_CALLBACK_FOR_TINY_RECEIVER // Call the fixed function "void handleReceivedTinyIRData()" each time a frame or repeat is received. //#define USE_CALLBACK_FOR_TINY_RECEIVER // Call the fixed function "void handleReceivedTinyIRData()" each time a frame or repeat is received.

View File

@ -247,6 +247,7 @@ struct TinyIRReceiverCallbackDataStruct {
}; };
extern volatile TinyIRReceiverCallbackDataStruct TinyIRReceiverData; extern volatile TinyIRReceiverCallbackDataStruct TinyIRReceiverData;
bool isIRReceiverAttachedForTinyReceiver();
bool initPCIInterruptForTinyReceiver(); bool initPCIInterruptForTinyReceiver();
bool enablePCIInterruptForTinyReceiver(); bool enablePCIInterruptForTinyReceiver();
void disablePCIInterruptForTinyReceiver(); void disablePCIInterruptForTinyReceiver();

View File

@ -58,7 +58,7 @@
* - IR_FEEDBACK_LED_PIN The pin number for TinyIRReceiver feedback LED. * - IR_FEEDBACK_LED_PIN The pin number for TinyIRReceiver feedback LED.
* - NO_LED_FEEDBACK_CODE Disables the feedback LED function. Saves 14 bytes program memory. * - NO_LED_FEEDBACK_CODE Disables the feedback LED function. Saves 14 bytes program memory.
* - DISABLE_PARITY_CHECKS Disable parity checks. Saves 48 bytes of program memory. * - DISABLE_PARITY_CHECKS Disable parity checks. Saves 48 bytes of program memory.
* - USE_EXTENDED_NEC_PROTOCOL Like NEC, but take the 16 bit address as one 16 bit value and not as 8 bit normal and 8 bit inverted value. * - USE_EXTENDED_NEC_PROTOCOL Like NEC, but take the 16 bit address as one 16 bit value and not as 8 bit normal and 8 bit inverted value.
* - USE_ONKYO_PROTOCOL Like NEC, but take both the 16 bit address and command each as one 16 bit value and not as 8 bit normal and 8 bit inverted value. * - USE_ONKYO_PROTOCOL Like NEC, but take both the 16 bit address and command each as one 16 bit value and not as 8 bit normal and 8 bit inverted value.
* - USE_FAST_PROTOCOL Use FAST protocol (no address and 16 bit data, interpreted as 8 bit command and 8 bit inverted command) instead of NEC. * - USE_FAST_PROTOCOL Use FAST protocol (no address and 16 bit data, interpreted as 8 bit command and 8 bit inverted command) instead of NEC.
* - ENABLE_NEC2_REPEATS Instead of sending / receiving the NEC special repeat code, send / receive the original frame for repeat. * - ENABLE_NEC2_REPEATS Instead of sending / receiving the NEC special repeat code, send / receive the original frame for repeat.
@ -78,7 +78,7 @@
//#define DISABLE_PARITY_CHECKS // Disable parity checks. Saves 48 bytes of program memory. //#define DISABLE_PARITY_CHECKS // Disable parity checks. Saves 48 bytes of program memory.
//#define USE_EXTENDED_NEC_PROTOCOL // Like NEC, but take the 16 bit address as one 16 bit value and not as 8 bit normal and 8 bit inverted value. //#define USE_EXTENDED_NEC_PROTOCOL // Like NEC, but take the 16 bit address as one 16 bit value and not as 8 bit normal and 8 bit inverted value.
//#define USE_ONKYO_PROTOCOL // Like NEC, but take both the 16 bit address and command each as one 16 bit value and not as 8 bit normal and 8 bit inverted value. //#define USE_ONKYO_PROTOCOL // Like NEC, but take the 16 bit address and command each as one 16 bit value and not as 8 bit normal and 8 bit inverted value.
//#define USE_FAST_PROTOCOL // Use FAST protocol instead of NEC / ONKYO. //#define USE_FAST_PROTOCOL // Use FAST protocol instead of NEC / ONKYO.
//#define ENABLE_NEC2_REPEATS // Instead of sending / receiving the NEC special repeat code, send / receive the original frame for repeat. //#define ENABLE_NEC2_REPEATS // Instead of sending / receiving the NEC special repeat code, send / receive the original frame for repeat.
@ -423,6 +423,17 @@ bool isTinyReceiverIdle() {
return (TinyIRReceiverControl.IRReceiverState == IR_RECEIVER_STATE_WAITING_FOR_START_MARK); return (TinyIRReceiverControl.IRReceiverState == IR_RECEIVER_STATE_WAITING_FOR_START_MARK);
} }
/*
* Checks if IR_RECEIVE_PIN is connected and high
* @return true, if IR Receiver is attached
*/
bool isIRReceiverAttachedForTinyReceiver() {
pinModeFast(IR_RECEIVE_PIN, OUTPUT);
digitalWriteFast(IR_RECEIVE_PIN, LOW); // discharge pin capacity
pinModeFast(IR_RECEIVE_PIN, INPUT);
return digitalRead(IR_RECEIVE_PIN); // use slow digitalRead here, since the pin capacity is not fully charged again if we use digitalReadFast.
}
/** /**
* Sets IR_RECEIVE_PIN mode to INPUT, and if IR_FEEDBACK_LED_PIN is defined, sets feedback LED output mode. * Sets IR_RECEIVE_PIN mode to INPUT, and if IR_FEEDBACK_LED_PIN is defined, sets feedback LED output mode.
* Then call enablePCIInterruptForTinyReceiver() * Then call enablePCIInterruptForTinyReceiver()