This commit is contained in:
Armin 2023-12-31 23:53:49 +01:00
parent 1008347e33
commit 1144c99122
28 changed files with 152 additions and 84 deletions

View File

@ -24,6 +24,10 @@ Available as [Arduino library "IRremote"](https://www.arduinolibraries.info/libr
   
[![Button Contribute](https://img.shields.io/badge/Contribute-752a61?style=for-the-badge&logoColor=white&logo=GitHub)](https://github.com/Arduino-IRremote/Arduino-IRremote/blob/master/Contributing.md)
#### If you find this program useful, please give it a star.
🌎 [Google Translate](https://translate.google.com/translate?sl=en&u=https://github.com/Arduino-IRremote/Arduino-IRremote)
</div>
# Overview
@ -861,7 +865,8 @@ The IR signal is sampled at a **50 &micro;s interval**. For a constant 525 &micr
And believe me, if you send a 525 &micro;s signal, your receiver will output something between around 400 and 700 &micro;s!<br/>
Therefore **we decode by default with a +/- 25% margin** using the formulas [here](https://github.com/Arduino-IRremote/Arduino-IRremote/blob/master/src/IRremoteInt.h#L376-L399).<br/>
E.g. for the NEC protocol with its 560 &micro;s unit length, we have TICKS_LOW = 8.358 and TICKS_HIGH = 15.0. This means, we accept any value between 8 ticks / 400 &micro;s and 15 ticks / 750 &micro;s (inclusive) as a mark or as a zero space. For a one space we have TICKS_LOW = 25.07 and TICKS_HIGH = 45.0.<br/>
And since the receivers generated marks are longer or shorter than the spaces, we have introduced the [`MARK_EXCESS_MICROS` value](https://github.com/Arduino-IRremote/Arduino-IRremote#compile-options--macros-for-this-library)
And since the receivers generated marks are longer or shorter than the spaces,
we have introduced the [`MARK_EXCESS_MICROS`](https://github.com/Arduino-IRremote/Arduino-IRremote#compile-options--macros-for-this-library) macro
to compensate for this receiver (and signal strength as well as ambient light dependent :disappointed: ) specific deviation.<br/>
Welcome to the world of **real world signal processing**.

View File

@ -112,6 +112,43 @@
#error "No temperature channel definitions specified for this AVR CPU"
#endif
/*
* Thresholds for OVER and UNDER voltage and detection of kind of power supply (USB or Li-ion)
*
* Default values are suitable for Li-ion batteries.
* We normally have voltage drop at the connectors, so the battery voltage is assumed slightly higher, than the Arduino VCC.
* But keep in mind that the ultrasonic distance module HC-SR04 may not work reliable below 3.7 volt.
*/
#if !defined(LI_ION_VCC_UNDERVOLTAGE_THRESHOLD_MILLIVOLT)
#define LI_ION_VCC_UNDERVOLTAGE_THRESHOLD_MILLIVOLT 3400 // Do not stress your battery and we require some power for standby
#endif
#if !defined(LI_ION_VCC_EMERGENCY_UNDERVOLTAGE_THRESHOLD_MILLIVOLT)
#define LI_ION_VCC_EMERGENCY_UNDERVOLTAGE_THRESHOLD_MILLIVOLT 3000 // Many Li-ions are specified down to 3.0 volt
#endif
#if !defined(VCC_UNDERVOLTAGE_THRESHOLD_MILLIVOLT)
#define VCC_UNDERVOLTAGE_THRESHOLD_MILLIVOLT LI_ION_VCC_UNDERVOLTAGE_THRESHOLD_MILLIVOLT
#endif
#if !defined(VCC_EMERGENCY_UNDERVOLTAGE_THRESHOLD_MILLIVOLT)
#define VCC_EMERGENCY_UNDERVOLTAGE_THRESHOLD_MILLIVOLT LI_ION_VCC_EMERGENCY_UNDERVOLTAGE_THRESHOLD_MILLIVOLT
#endif
#if !defined(VCC_OVERVOLTAGE_THRESHOLD_MILLIVOLT)
#define VCC_OVERVOLTAGE_THRESHOLD_MILLIVOLT 5250 // + 5 % operation voltage
#endif
#if !defined(VCC_EMERGENCY_OVERVOLTAGE_THRESHOLD_MILLIVOLT)
#define VCC_EMERGENCY_OVERVOLTAGE_THRESHOLD_MILLIVOLT 5500 // +10 %. Max recommended operation voltage
#endif
#if !defined(VCC_CHECK_PERIOD_MILLIS)
#define VCC_CHECK_PERIOD_MILLIS 10000L // 10 seconds period of VCC checks
#endif
#if !defined(VCC_UNDERVOLTAGE_CHECKS_BEFORE_STOP)
#define VCC_UNDERVOLTAGE_CHECKS_BEFORE_STOP 6 // Shutdown after 6 times (60 seconds) VCC below VCC_UNDERVOLTAGE_THRESHOLD_MILLIVOLT or 1 time below VCC_EMERGENCY_UNDERVOLTAGE_THRESHOLD_MILLIVOLT
#endif
#if !defined(VOLTAGE_USB_LOWER_THRESHOLD_MILLIVOLT)
#define VOLTAGE_USB_LOWER_THRESHOLD_MILLIVOLT 4300
#endif
extern long sLastVCCCheckMillis;
extern uint8_t sVCCTooLowCounter;
@ -150,11 +187,13 @@ float getCPUTemperatureSimple(void);
float getCPUTemperature(void);
float getTemperature(void) __attribute__ ((deprecated ("Renamed to getCPUTemperature()"))); // deprecated
bool isVCCTooLowMultipleTimes();
void resetVCCTooLowMultipleTimes();
bool isVCCTooLow();
bool isVCCTooHigh();
bool isVCCTooHighSimple();
bool isVCCUSBPowered() ;
bool isVCCUndervoltageMultipleTimes();
void resetCounterForVCCUndervoltageMultipleTimes();
bool isVCCUndervoltage();
bool isVCCEmergencyUndervoltage();
bool isVCCOvervoltage();
bool isVCCOvervoltageSimple();
#endif // defined(__AVR__) ...

View File

@ -481,7 +481,7 @@ void readAndPrintVCCVoltageMillivolt(Print *aSerial) {
void readVCCVoltageSimple(void) {
// use AVCC with (optional) external capacitor at AREF pin as reference
float tVCC = readADCChannelWithReferenceMultiSamples(ADC_1_1_VOLT_CHANNEL_MUX, DEFAULT, 4);
sVCCVoltage = (1023 * 1.1 * 4) / tVCC;
sVCCVoltage = (1023 * (((float) ADC_INTERNAL_REFERENCE_MILLIVOLT) / 1000) * 4) / tVCC;
}
/*
@ -540,33 +540,17 @@ uint16_t getVoltageMillivoltWith_1_1VoltReference(uint8_t aADCChannelForVoltageM
}
/*
* Default values are suitable for Li-ion batteries.
* We normally have voltage drop at the connectors, so the battery voltage is assumed slightly higher, than the Arduino VCC.
* But keep in mind that the ultrasonic distance module HC-SR04 may not work reliable below 3.7 volt.
* Return true if sVCCVoltageMillivolt is > 4.3 V
*/
#if !defined(VCC_STOP_THRESHOLD_MILLIVOLT)
#define VCC_STOP_THRESHOLD_MILLIVOLT 3400 // Do not stress your battery and we require some power for standby
#endif
#if !defined(VCC_EMERGENCY_STOP_MILLIVOLT)
#define VCC_EMERGENCY_STOP_MILLIVOLT 3000 // Many Li-ions are specified down to 3.0 volt
#endif
#if !defined(VCC_TOO_HIGH_STOP_MILLIVOLT)
#define VCC_TOO_HIGH_STOP_MILLIVOLT 5250 // + 5 % operation voltage
#endif
#if !defined(VCC_TOO_HIGH_EMERGENCY_STOP_MILLIVOLT)
#define VCC_TOO_HIGH_EMERGENCY_STOP_MILLIVOLT 5500 // +10 %. Max recommended operation voltage
#endif
#if !defined(VCC_CHECK_PERIOD_MILLIS)
#define VCC_CHECK_PERIOD_MILLIS 10000 // Period of VCC checks
#endif
#if !defined(VCC_CHECKS_TOO_LOW_BEFORE_STOP)
#define VCC_CHECKS_TOO_LOW_BEFORE_STOP 6 // Shutdown after 6 times (60 seconds) VCC below VCC_STOP_THRESHOLD_MILLIVOLT or 1 time below VCC_EMERGENCY_STOP_MILLIVOLT
#endif
bool isVCCUSBPowered() {
readVCCVoltageMillivolt();
return (sVCCVoltageMillivolt > VOLTAGE_USB_LOWER_THRESHOLD_MILLIVOLT);
}
/*
* @ return true only once, when VCC_CHECKS_TOO_LOW_BEFORE_STOP (6) times voltage too low -> shutdown
* @ return true only once, when VCC_UNDERVOLTAGE_CHECKS_BEFORE_STOP (6) times voltage too low -> shutdown
*/
bool isVCCTooLowMultipleTimes() {
bool isVCCUndervoltageMultipleTimes() {
/*
* Check VCC every VCC_CHECK_PERIOD_MILLIS (10) seconds
*/
@ -580,33 +564,35 @@ bool isVCCTooLowMultipleTimes() {
readVCCVoltageMillivolt();
# endif
if (sVCCTooLowCounter < VCC_CHECKS_TOO_LOW_BEFORE_STOP) {
if (sVCCTooLowCounter < VCC_UNDERVOLTAGE_CHECKS_BEFORE_STOP) {
/*
* Do not check again if shutdown has happened
*/
if (sVCCVoltageMillivolt > VCC_STOP_THRESHOLD_MILLIVOLT) {
if (sVCCVoltageMillivolt > VCC_UNDERVOLTAGE_THRESHOLD_MILLIVOLT) {
sVCCTooLowCounter = 0; // reset counter
} else {
/*
* Voltage too low, wait VCC_CHECKS_TOO_LOW_BEFORE_STOP (6) times and then shut down.
* Voltage too low, wait VCC_UNDERVOLTAGE_CHECKS_BEFORE_STOP (6) times and then shut down.
*/
if (sVCCVoltageMillivolt < VCC_EMERGENCY_STOP_MILLIVOLT) {
if (sVCCVoltageMillivolt < VCC_EMERGENCY_UNDERVOLTAGE_THRESHOLD_MILLIVOLT) {
// emergency shutdown
sVCCTooLowCounter = VCC_CHECKS_TOO_LOW_BEFORE_STOP;
sVCCTooLowCounter = VCC_UNDERVOLTAGE_CHECKS_BEFORE_STOP;
# if defined(INFO)
Serial.println(F("Voltage < " STR(VCC_EMERGENCY_STOP_MILLIVOLT) " mV detected -> emergency shutdown"));
Serial.println(
F(
"Voltage < " STR(VCC_EMERGENCY_UNDERVOLTAGE_THRESHOLD_MILLIVOLT) " mV detected -> emergency shutdown"));
# endif
} else {
sVCCTooLowCounter++;
# if defined(INFO)
Serial.print(F("Voltage < " STR(VCC_STOP_THRESHOLD_MILLIVOLT) " mV detected: "));
Serial.print(VCC_CHECKS_TOO_LOW_BEFORE_STOP - sVCCTooLowCounter);
Serial.print(F("Voltage < " STR(VCC_UNDERVOLTAGE_THRESHOLD_MILLIVOLT) " mV detected: "));
Serial.print(VCC_UNDERVOLTAGE_CHECKS_BEFORE_STOP - sVCCTooLowCounter);
Serial.println(F(" tries left"));
# endif
}
if (sVCCTooLowCounter == VCC_CHECKS_TOO_LOW_BEFORE_STOP) {
if (sVCCTooLowCounter == VCC_UNDERVOLTAGE_CHECKS_BEFORE_STOP) {
/*
* 6 times voltage too low -> shutdown
* 6 times voltage too low -> return signal for shutdown etc.
*/
return true;
}
@ -616,14 +602,24 @@ bool isVCCTooLowMultipleTimes() {
return false;
}
/*
* Return true if VCC_EMERGENCY_STOP_MILLIVOLT (3 V) reached
* Return true if VCC_EMERGENCY_UNDERVOLTAGE_THRESHOLD_MILLIVOLT (3 V) reached
*/
bool isVCCTooLow() {
return (sVCCVoltageMillivolt < VCC_EMERGENCY_STOP_MILLIVOLT);
bool isVCCUndervoltage() {
readVCCVoltageMillivolt();
return (sVCCVoltageMillivolt < VCC_UNDERVOLTAGE_THRESHOLD_MILLIVOLT);
}
void resetVCCTooLowMultipleTimes() {
/*
* Return true if VCC_EMERGENCY_UNDERVOLTAGE_THRESHOLD_MILLIVOLT (3 V) reached
*/
bool isVCCEmergencyUndervoltage() {
readVCCVoltageMillivolt();
return (sVCCVoltageMillivolt < VCC_EMERGENCY_UNDERVOLTAGE_THRESHOLD_MILLIVOLT);
}
void resetCounterForVCCUndervoltageMultipleTimes() {
sVCCTooLowCounter = 0;
}
@ -636,13 +632,13 @@ void resetVCCTooLowMultipleTimes() {
* Raw reading of 1.1 V is 204 at 5.5 V (+10 %).
* @return true if 5 % overvoltage reached
*/
bool isVCCTooHigh() {
bool isVCCOvervoltage() {
readVCCVoltageMillivolt();
return (sVCCVoltageMillivolt > VCC_TOO_HIGH_STOP_MILLIVOLT);
return (sVCCVoltageMillivolt > VCC_OVERVOLTAGE_THRESHOLD_MILLIVOLT);
}
bool isVCCTooHighSimple() {
bool isVCCOvervoltageSimple() {
readVCCVoltageMillivoltSimple();
return (sVCCVoltageMillivolt > VCC_TOO_HIGH_STOP_MILLIVOLT);
return (sVCCVoltageMillivolt > VCC_OVERVOLTAGE_THRESHOLD_MILLIVOLT);
}
/*

View File

@ -322,7 +322,7 @@ void noTone(uint8_t aPinNumber){
#define SEND_PWM_BY_TIMER // We do not have pin restrictions for this CPU's, so lets use the hardware PWM for send carrier signal generation
#else
# if defined(SEND_PWM_BY_TIMER)
#undef IR_SEND_PIN // SendPin is determined by timer! This avoids warning in IRTimer.hpp
#undef IR_SEND_PIN // SendPin is determined by timer! This avoids warnings in IRremote.hpp and IRTimer.hpp
# endif
#endif

View File

@ -322,7 +322,7 @@ void noTone(uint8_t aPinNumber){
#define SEND_PWM_BY_TIMER // We do not have pin restrictions for this CPU's, so lets use the hardware PWM for send carrier signal generation
#else
# if defined(SEND_PWM_BY_TIMER)
#undef IR_SEND_PIN // SendPin is determined by timer! This avoids warning in IRTimer.hpp
#undef IR_SEND_PIN // SendPin is determined by timer! This avoids warnings in IRremote.hpp and IRTimer.hpp
# endif
#endif

View File

@ -322,7 +322,7 @@ void noTone(uint8_t aPinNumber){
#define SEND_PWM_BY_TIMER // We do not have pin restrictions for this CPU's, so lets use the hardware PWM for send carrier signal generation
#else
# if defined(SEND_PWM_BY_TIMER)
#undef IR_SEND_PIN // SendPin is determined by timer! This avoids warning in IRTimer.hpp
#undef IR_SEND_PIN // SendPin is determined by timer! This avoids warnings in IRremote.hpp and IRTimer.hpp
# endif
#endif

View File

@ -322,7 +322,7 @@ void noTone(uint8_t aPinNumber){
#define SEND_PWM_BY_TIMER // We do not have pin restrictions for this CPU's, so lets use the hardware PWM for send carrier signal generation
#else
# if defined(SEND_PWM_BY_TIMER)
#undef IR_SEND_PIN // SendPin is determined by timer! This avoids warning in IRTimer.hpp
#undef IR_SEND_PIN // SendPin is determined by timer! This avoids warnings in IRremote.hpp and IRTimer.hpp
# endif
#endif

View File

@ -322,7 +322,7 @@ void noTone(uint8_t aPinNumber){
#define SEND_PWM_BY_TIMER // We do not have pin restrictions for this CPU's, so lets use the hardware PWM for send carrier signal generation
#else
# if defined(SEND_PWM_BY_TIMER)
#undef IR_SEND_PIN // SendPin is determined by timer! This avoids warning in IRTimer.hpp
#undef IR_SEND_PIN // SendPin is determined by timer! This avoids warnings in IRremote.hpp and IRTimer.hpp
# endif
#endif

View File

@ -322,7 +322,7 @@ void noTone(uint8_t aPinNumber){
#define SEND_PWM_BY_TIMER // We do not have pin restrictions for this CPU's, so lets use the hardware PWM for send carrier signal generation
#else
# if defined(SEND_PWM_BY_TIMER)
#undef IR_SEND_PIN // SendPin is determined by timer! This avoids warning in IRTimer.hpp
#undef IR_SEND_PIN // SendPin is determined by timer! This avoids warnings in IRremote.hpp and IRTimer.hpp
# endif
#endif

View File

@ -322,7 +322,7 @@ void noTone(uint8_t aPinNumber){
#define SEND_PWM_BY_TIMER // We do not have pin restrictions for this CPU's, so lets use the hardware PWM for send carrier signal generation
#else
# if defined(SEND_PWM_BY_TIMER)
#undef IR_SEND_PIN // SendPin is determined by timer! This avoids warning in IRTimer.hpp
#undef IR_SEND_PIN // SendPin is determined by timer! This avoids warnings in IRremote.hpp and IRTimer.hpp
# endif
#endif

View File

@ -322,7 +322,7 @@ void noTone(uint8_t aPinNumber){
#define SEND_PWM_BY_TIMER // We do not have pin restrictions for this CPU's, so lets use the hardware PWM for send carrier signal generation
#else
# if defined(SEND_PWM_BY_TIMER)
#undef IR_SEND_PIN // SendPin is determined by timer! This avoids warning in IRTimer.hpp
#undef IR_SEND_PIN // SendPin is determined by timer! This avoids warnings in IRremote.hpp and IRTimer.hpp
# endif
#endif

View File

@ -322,7 +322,7 @@ void noTone(uint8_t aPinNumber){
#define SEND_PWM_BY_TIMER // We do not have pin restrictions for this CPU's, so lets use the hardware PWM for send carrier signal generation
#else
# if defined(SEND_PWM_BY_TIMER)
#undef IR_SEND_PIN // SendPin is determined by timer! This avoids warning in IRTimer.hpp
#undef IR_SEND_PIN // SendPin is determined by timer! This avoids warnings in IRremote.hpp and IRTimer.hpp
# endif
#endif

View File

@ -322,7 +322,7 @@ void noTone(uint8_t aPinNumber){
#define SEND_PWM_BY_TIMER // We do not have pin restrictions for this CPU's, so lets use the hardware PWM for send carrier signal generation
#else
# if defined(SEND_PWM_BY_TIMER)
#undef IR_SEND_PIN // SendPin is determined by timer! This avoids warning in IRTimer.hpp
#undef IR_SEND_PIN // SendPin is determined by timer! This avoids warnings in IRremote.hpp and IRTimer.hpp
# endif
#endif

View File

@ -322,7 +322,7 @@ void noTone(uint8_t aPinNumber){
#define SEND_PWM_BY_TIMER // We do not have pin restrictions for this CPU's, so lets use the hardware PWM for send carrier signal generation
#else
# if defined(SEND_PWM_BY_TIMER)
#undef IR_SEND_PIN // SendPin is determined by timer! This avoids warning in IRTimer.hpp
#undef IR_SEND_PIN // SendPin is determined by timer! This avoids warnings in IRremote.hpp and IRTimer.hpp
# endif
#endif

View File

@ -322,7 +322,7 @@ void noTone(uint8_t aPinNumber){
#define SEND_PWM_BY_TIMER // We do not have pin restrictions for this CPU's, so lets use the hardware PWM for send carrier signal generation
#else
# if defined(SEND_PWM_BY_TIMER)
#undef IR_SEND_PIN // SendPin is determined by timer! This avoids warning in IRTimer.hpp
#undef IR_SEND_PIN // SendPin is determined by timer! This avoids warnings in IRremote.hpp and IRTimer.hpp
# endif
#endif

View File

@ -322,7 +322,7 @@ void noTone(uint8_t aPinNumber){
#define SEND_PWM_BY_TIMER // We do not have pin restrictions for this CPU's, so lets use the hardware PWM for send carrier signal generation
#else
# if defined(SEND_PWM_BY_TIMER)
#undef IR_SEND_PIN // SendPin is determined by timer! This avoids warning in IRTimer.hpp
#undef IR_SEND_PIN // SendPin is determined by timer! This avoids warnings in IRremote.hpp and IRTimer.hpp
# endif
#endif

View File

@ -322,7 +322,7 @@ void noTone(uint8_t aPinNumber){
#define SEND_PWM_BY_TIMER // We do not have pin restrictions for this CPU's, so lets use the hardware PWM for send carrier signal generation
#else
# if defined(SEND_PWM_BY_TIMER)
#undef IR_SEND_PIN // SendPin is determined by timer! This avoids warning in IRTimer.hpp
#undef IR_SEND_PIN // SendPin is determined by timer! This avoids warnings in IRremote.hpp and IRTimer.hpp
# endif
#endif

View File

@ -322,7 +322,7 @@ void noTone(uint8_t aPinNumber){
#define SEND_PWM_BY_TIMER // We do not have pin restrictions for this CPU's, so lets use the hardware PWM for send carrier signal generation
#else
# if defined(SEND_PWM_BY_TIMER)
#undef IR_SEND_PIN // SendPin is determined by timer! This avoids warning in IRTimer.hpp
#undef IR_SEND_PIN // SendPin is determined by timer! This avoids warnings in IRremote.hpp and IRTimer.hpp
# endif
#endif

View File

@ -322,7 +322,7 @@ void noTone(uint8_t aPinNumber){
#define SEND_PWM_BY_TIMER // We do not have pin restrictions for this CPU's, so lets use the hardware PWM for send carrier signal generation
#else
# if defined(SEND_PWM_BY_TIMER)
#undef IR_SEND_PIN // SendPin is determined by timer! This avoids warning in IRTimer.hpp
#undef IR_SEND_PIN // SendPin is determined by timer! This avoids warnings in IRremote.hpp and IRTimer.hpp
# endif
#endif

View File

@ -322,7 +322,7 @@ void noTone(uint8_t aPinNumber){
#define SEND_PWM_BY_TIMER // We do not have pin restrictions for this CPU's, so lets use the hardware PWM for send carrier signal generation
#else
# if defined(SEND_PWM_BY_TIMER)
#undef IR_SEND_PIN // SendPin is determined by timer! This avoids warning in IRTimer.hpp
#undef IR_SEND_PIN // SendPin is determined by timer! This avoids warnings in IRremote.hpp and IRTimer.hpp
# endif
#endif

View File

@ -322,7 +322,7 @@ void noTone(uint8_t aPinNumber){
#define SEND_PWM_BY_TIMER // We do not have pin restrictions for this CPU's, so lets use the hardware PWM for send carrier signal generation
#else
# if defined(SEND_PWM_BY_TIMER)
#undef IR_SEND_PIN // SendPin is determined by timer! This avoids warning in IRTimer.hpp
#undef IR_SEND_PIN // SendPin is determined by timer! This avoids warnings in IRremote.hpp and IRTimer.hpp
# endif
#endif

View File

@ -322,7 +322,7 @@ void noTone(uint8_t aPinNumber){
#define SEND_PWM_BY_TIMER // We do not have pin restrictions for this CPU's, so lets use the hardware PWM for send carrier signal generation
#else
# if defined(SEND_PWM_BY_TIMER)
#undef IR_SEND_PIN // SendPin is determined by timer! This avoids warning in IRTimer.hpp
#undef IR_SEND_PIN // SendPin is determined by timer! This avoids warnings in IRremote.hpp and IRTimer.hpp
# endif
#endif

View File

@ -322,7 +322,7 @@ void noTone(uint8_t aPinNumber){
#define SEND_PWM_BY_TIMER // We do not have pin restrictions for this CPU's, so lets use the hardware PWM for send carrier signal generation
#else
# if defined(SEND_PWM_BY_TIMER)
#undef IR_SEND_PIN // SendPin is determined by timer! This avoids warning in IRTimer.hpp
#undef IR_SEND_PIN // SendPin is determined by timer! This avoids warnings in IRremote.hpp and IRTimer.hpp
# endif
#endif

View File

@ -322,7 +322,7 @@ void noTone(uint8_t aPinNumber){
#define SEND_PWM_BY_TIMER // We do not have pin restrictions for this CPU's, so lets use the hardware PWM for send carrier signal generation
#else
# if defined(SEND_PWM_BY_TIMER)
#undef IR_SEND_PIN // SendPin is determined by timer! This avoids warning in IRTimer.hpp
#undef IR_SEND_PIN // SendPin is determined by timer! This avoids warnings in IRremote.hpp and IRTimer.hpp
# endif
#endif

View File

@ -322,7 +322,7 @@ void noTone(uint8_t aPinNumber){
#define SEND_PWM_BY_TIMER // We do not have pin restrictions for this CPU's, so lets use the hardware PWM for send carrier signal generation
#else
# if defined(SEND_PWM_BY_TIMER)
#undef IR_SEND_PIN // SendPin is determined by timer! This avoids warning in IRTimer.hpp
#undef IR_SEND_PIN // SendPin is determined by timer! This avoids warnings in IRremote.hpp and IRTimer.hpp
# endif
#endif

View File

@ -192,7 +192,7 @@
#if (defined(ESP32) || defined(ARDUINO_ARCH_RP2040) || defined(PARTICLE)) || defined(ARDUINO_ARCH_MBED)
# if !defined(SEND_PWM_BY_TIMER)
#define SEND_PWM_BY_TIMER // the best and default method for ESP32 etc.
#warning INFO: For ESP32, RP2040, mbed and particle boards SEND_PWM_BY_TIMER is enabled by default. If this is not intended, deactivate the line in IRremote.hpp over this warning message in file IRremote.hpp.
#warning INFO: For ESP32, RP2040, mbed and particle boards SEND_PWM_BY_TIMER is enabled by default, since we have the resources and timing is more exact than the software generated one. If this is not intended, deactivate the line in IRremote.hpp over this warning message in file IRremote.hpp.
# endif
#else
# if defined(SEND_PWM_BY_TIMER)

View File

@ -417,7 +417,7 @@ public:
IRsend();
/*
* IR_SEND_PIN is defined
* IR_SEND_PIN is defined or fixed by timer, value of IR_SEND_PIN is then "DeterminedByTimer"
*/
#if defined(IR_SEND_PIN)
void begin();

View File

@ -52,12 +52,13 @@ void enableSendPWMByTimer();
void disableSendPWMByTimer();
void timerConfigForSend(uint16_t aFrequencyKHz);
#if defined(SEND_PWM_BY_TIMER) && ( (defined(ESP32) || defined(ARDUINO_ARCH_RP2040) || defined(PARTICLE)) || defined(ARDUINO_ARCH_MBED) )
#define SEND_PWM_DOES_NOT_USE_RECEIVE_TIMER // Receive timer and send generation are independent, so it is recommended to always define SEND_PWM_BY_TIMER
// SEND_PWM_BY_TIMER is defined in IRremote.hpp line 195.
#if defined(SEND_PWM_BY_TIMER) && ( (defined(ESP32) || defined(ARDUINO_ARCH_RP2040) || defined(PARTICLE)) || defined(ARDUINO_ARCH_MBED) )
#define SEND_PWM_DOES_NOT_USE_RECEIVE_TIMER // Receive timer and send generation timer are independent here.
#endif
#if defined(IR_SEND_PIN) && defined(SEND_PWM_BY_TIMER) && !defined(SEND_PWM_DOES_NOT_USE_RECEIVE_TIMER) // For e.g ESP32 IR_SEND_PIN definition is useful
#undef IR_SEND_PIN // avoid warning below, user warning is done at IRremote.hpp
#if defined(IR_SEND_PIN) && defined(SEND_PWM_BY_TIMER) && !defined(SEND_PWM_DOES_NOT_USE_RECEIVE_TIMER) // For ESP32 etc. IR_SEND_PIN definition is useful
#undef IR_SEND_PIN // To avoid "warning: "IR_SEND_PIN" redefined". The user warning is done at IRremote.hpp line 202.
#endif
// Macros for enabling timers for development
@ -1434,8 +1435,7 @@ void timerConfigForReceive() {
// the ledc functions behave like hardware timers for us :-), so we do not require our own soft PWM generation code.
hw_timer_t *s50usTimer = NULL; // set by timerConfigForReceive()
# if !defined(SEND_AND_RECEIVE_TIMER_LEDC_CHANNEL)
# if ESP_ARDUINO_VERSION < ESP_ARDUINO_VERSION_VAL(3, 0, 0) && !defined(SEND_AND_RECEIVE_TIMER_LEDC_CHANNEL)
#define SEND_AND_RECEIVE_TIMER_LEDC_CHANNEL 0 // The channel used for PWM 0 to 7 are high speed PWM channels
# endif
@ -1481,24 +1481,52 @@ void timerConfigForReceive() {
// every 50 us, autoreload = true
}
# if !defined(IR_SEND_PIN)
uint8_t sLastSendPin = 0; // To detach before attach, if already attached
# endif
# if defined(SEND_PWM_BY_TIMER)
void enableSendPWMByTimer() {
# if ESP_ARDUINO_VERSION < ESP_ARDUINO_VERSION_VAL(3, 0, 0)
ledcWrite(SEND_AND_RECEIVE_TIMER_LEDC_CHANNEL, (IR_SEND_DUTY_CYCLE_PERCENT * 256) / 100); // * 256 since we have 8 bit resolution
# else
ledcWrite(IrSender.sendPin, (IR_SEND_DUTY_CYCLE_PERCENT * 256) / 100); // New API
# endif
}
void disableSendPWMByTimer() {
# if ESP_ARDUINO_VERSION < ESP_ARDUINO_VERSION_VAL(3, 0, 0)
ledcWrite(SEND_AND_RECEIVE_TIMER_LEDC_CHANNEL, 0);
# else
ledcWrite(IrSender.sendPin, 0); // New API
# endif
}
/*
* timerConfigForSend() is used exclusively by IRsend::enableIROut()
* ledcWrite since ESP 2.0.2 does not work if pin mode is set. Disable receive interrupt if it uses the same resource
* timerConfigForSend() is used exclusively by IRsend::enableIROut() (or enableHighFrequencyIROut())
* ledcWrite since ESP 2.0.2 does not work if pin mode is set.
*/
void timerConfigForSend(uint16_t aFrequencyKHz) {
# if ESP_ARDUINO_VERSION < ESP_ARDUINO_VERSION_VAL(3, 0, 0)
ledcSetup(SEND_AND_RECEIVE_TIMER_LEDC_CHANNEL, aFrequencyKHz * 1000, 8); // 8 bit PWM resolution
# if defined(IR_SEND_PIN)
ledcAttachPin(IR_SEND_PIN, SEND_AND_RECEIVE_TIMER_LEDC_CHANNEL); // bind pin to channel
# else
ledcAttachPin(IrSender.sendPin, SEND_AND_RECEIVE_TIMER_LEDC_CHANNEL); // bind pin to channel
# if defined(IR_SEND_PIN)
ledcAttachPin(IR_SEND_PIN, SEND_AND_RECEIVE_TIMER_LEDC_CHANNEL); // attach pin to channel
# else
if(sLastSendPin != 0 && sLastSendPin != IrSender.sendPin){
ledcDetachPin(IrSender.sendPin); // detach pin before new attaching see #1194
}
ledcAttachPin(IrSender.sendPin, SEND_AND_RECEIVE_TIMER_LEDC_CHANNEL); // attach pin to channel
sLastSendPin = IrSender.sendPin;
# endif
# else // New API here
# if defined(IR_SEND_PIN)
ledcAttach(IR_SEND_PIN, aFrequencyKHz * 1000, 8); // New API
# else
if(sLastSendPin != 0 && sLastSendPin != IrSender.sendPin){
ledcDetach(IrSender.sendPin); // detach pin before new attaching see #1194
}
ledcAttach(IrSender.sendPin, aFrequencyKHz * 1000, 8); // New API
sLastSendPin = IrSender.sendPin;
# endif
# endif
}
# endif // defined(SEND_PWM_BY_TIMER)