Fix for ESP32 send Error, removed `USE_SOFT_SEND_PWM` macro

This commit is contained in:
Armin 2021-04-07 18:39:01 +02:00
parent 2f71012a28
commit 35b8c11922
8 changed files with 51 additions and 53 deletions

View File

@ -1,7 +1,7 @@
# IRremote Arduino Library
Available as Arduino library "IRremote"
### [Version 3.1.0](https://github.com/Arduino-IRremote/Arduino-IRremote/archive/master.zip) - work in progress
### [Version 3.1.2](https://github.com/Arduino-IRremote/Arduino-IRremote/archive/master.zip) - work in progress
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
[![Commits since latest](https://img.shields.io/github/commits-since/Arduino-IRremote/Arduino-IRremote/latest)](https://github.com/Arduino-IRremote/Arduino-IRremote/commits/master)
@ -118,10 +118,10 @@ Modify it by commenting them out or in, or change the values if applicable. Or d
| Name | File | Default value | Description |
|-|-|-|-|
| `SEND_PWM_BY_TIMER` | Before `#include <IRremote.h>` | disabled | Disable carrier PWM generation in software and use (restricted) hardware PWM ecxept for ESP32 where both modes are using the flexible `hw_timer_t`. |
| `USE_NO_SEND_PWM` | Before `#include <IRremote.h>` | disabled | Use no carrier PWM, just simulate an active low receiver signal. Overrides `SEND_PWM_BY_TIMER` definition. |
| `USE_OLD_DECODE` | IRremoteInt.h | disabled | Enables the old decoder in order to be version 2.x compatible, where all protocols were MSB first. |
| `EXCLUDE_EXOTIC_PROTOCOLS` | Before `#include <IRremote.h>` | disabled | If activated, BOSEWAVE, MAGIQUEST,WHYNTER and LEGO_PF are excluded in `decode()` and in sending with `IrSender.write()`. Saves up to 900 bytes program space. |
| `MARK_EXCESS_MICROS` | Before `#include <IRremote.h>` | 20 | 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. |
| `USE_NO_SEND_PWM` | Before `#include <IRremote.h>` | disabled | Use no carrier PWM, just simulate an active low receiver signal. |
| `FEEDBACK_LED_IS_ACTIVE_LOW` | Before `#include <IRremote.h>` | disabled | Required on some boards (like my BluePill and my ESP8266 board), where the feedback LED is active low. |
| `DISABLE_LED_FEEDBACK_FOR_RECEIVE` | Before `#include <IRremote.h>` | disabled | This disables the LED feedback code for receive, thus saving around 108 bytes program space and halving the receiver ISR processing time. |
| `IR_INPUT_IS_ACTIVE_HIGH` | Before `#include <IRremote.h>` | disabled | Enable it if you use a RF receiver, which has an active HIGH output signal. |

View File

@ -1,8 +1,11 @@
# Changelog
The latest version may not be released!
## 3.1.1
- Fix for ESP32 send Error, removed `USE_SOFT_SEND_PWM` macro.
## 3.1.0
- USE_SOFT_SEND_PWM is active by default.
- Generation of PWM by software is active by default.
- Removed decode_results results.
- Renamed most irparams_struct values.
- Fixed LG send bug and added unit test.

View File

@ -58,7 +58,7 @@ void setup() {
Serial.print(F("Ready to send IR signals at pin "));
Serial.println(IR_SEND_PIN);
#if defined(USE_SOFT_SEND_PWM) && !defined(ESP32) // for esp32 we use PWM generation by hw_timer_t for each pin
#if !defined(SEND_PWM_BY_TIMER) && !defined(USE_NO_SEND_PWM) && !defined(ESP32) // for esp32 we use PWM generation by ledcWrite() for each pin
/*
* Print internal signal generation info
*/

View File

@ -78,7 +78,7 @@ void setup() {
Serial.print(F("Ready to send IR signals at pin "));
Serial.println(IR_SEND_PIN);
#if defined(USE_SOFT_SEND_PWM) && !defined(ESP32) // for esp32 we use PWM generation by hw_timer_t for each pin
#if !defined(SEND_PWM_BY_TIMER) && !defined(USE_NO_SEND_PWM) && !defined(ESP32) // for esp32 we use PWM generation by ledcWrite() for each pin
/*
* Print internal signal generation info
*/

View File

@ -7,7 +7,7 @@
"type": "git",
"url": "https://github.com/z3t0/Arduino-IRremote.git"
},
"version": "3.1.0",
"version": "3.1.1",
"frameworks": "arduino",
"platforms": "atmelavr",
"authors" :

View File

@ -1,9 +1,9 @@
name=IRremote
version=3.1.0
version=3.1.1
author=shirriff, z3t0 <zetoslab@gmail.com>, ArminJo
maintainer=Armin Joachimsmeyer <armin.arduino@gmail.com>
sentence=Send and receive infrared signals with multiple protocols
paragraph=Currently included protocols: Denon / Sharp, JVC, LG, NEC / Apple, Panasonic / Kaseikyo, RC5, RC6, Samsung, Sony, (Pronto), BoseWave, Lego, Whynter, MagiQuest.<br/><br/><b>New: </b><a href="https://github.com/Arduino-IRremote/Arduino-IRremote#converting-your-program-to-the-31-version">Upgrade instructions</a><br/>Generation of PWM is now done by software by default, thus saving the hardware timer and enabling abitrary output pins. Fixed LG send bug. STM32 and ATtiny88 support added. Removed decode_results results. Renamed most irparams_struct values. The macros FEEDBACK_LED, SYSCLOCK, SENDPIN_ON and SENDPIN_OFF are not longer used / evaluated. Major refactoring of CPU dependent and feedback LED code.<br/>
paragraph=Currently included protocols: Denon / Sharp, JVC, LG, NEC / Apple, Panasonic / Kaseikyo, RC5, RC6, Samsung, Sony, (Pronto), BoseWave, Lego, Whynter, MagiQuest.<br/><br/><b>New: </b><a href="https://github.com/Arduino-IRremote/Arduino-IRremote#converting-your-program-to-the-31-version">Upgrade instructions</a><br/>Fixed ESP send bug.<br/>Generation of PWM is now done by software by default, thus saving the hardware timer and enabling abitrary output pins. Fixed LG send bug. STM32 and ATtiny88 support added. Removed decode_results results. Renamed most irparams_struct values. The macros FEEDBACK_LED, SYSCLOCK, SENDPIN_ON and SENDPIN_OFF are not longer used / evaluated. Major refactoring of CPU dependent and feedback LED code.<br/>
category=Communication
url=https://github.com/Arduino-IRremote/Arduino-IRremote
architectures=avr,megaavr,samd,esp32,mbed,stm32,STM32F1

View File

@ -72,12 +72,13 @@ void IRsend::begin(uint8_t aSendPin, bool aEnableLEDFeedback, uint8_t aLEDFeedba
*/
void IRsend::begin(bool aEnableLEDFeedback, uint8_t aLEDFeedbackPin) {
// must exclude MEGATINYCORE, NRF5, SAMD and ESP32 because they do not use the -flto flag for compile
#if (defined(USE_SOFT_SEND_PWM) || defined(USE_NO_SEND_PWM)) \
#if (!defined(SEND_PWM_BY_TIMER) || defined(USE_NO_SEND_PWM)) \
&& !defined(SUPPRESS_ERROR_MESSAGE_FOR_BEGIN) \
&& !(defined(NRF5) || defined(ARDUINO_ARCH_NRF52840)) && !defined(ARDUINO_ARCH_SAMD) \
&& !defined(ESP32) && !defined(MEGATINYCORE) \
&& !(defined(__STM32F1__) || defined(ARDUINO_ARCH_STM32F1)) && !(defined(STM32F1xx) || defined(ARDUINO_ARCH_STM32))
UsageError("Error: You must use begin(<sendPin>, <EnableLEDFeedback>, <LEDFeedbackPin>) if USE_SOFT_SEND_PWM or USE_NO_SEND_PWM is defined!");
UsageError(
"Error: You must use begin(<sendPin>, <EnableLEDFeedback>, <LEDFeedbackPin>) if SEND_PWM_BY_TIMER is not defined or USE_NO_SEND_PWM is defined!");
#endif
setLEDFeedback(aLEDFeedbackPin, aEnableLEDFeedback);
@ -331,16 +332,16 @@ void IRsend::sendBiphaseData(unsigned int aBiphaseTimeUnit, uint32_t aData, uint
} else {
TRACE_PRINT('0');
#ifdef USE_SOFT_SEND_PWM
(void)tLastBitValue; // to avoid compiler warnings
mark(aBiphaseTimeUnit); // can not eventually delay here, we must call mark to generate the signal
#else
#if defined(SEND_PWM_BY_TIMER) || defined(USE_NO_SEND_PWM)
if (tLastBitValue) {
// Extend the current mark in order to generate a continuous signal without short breaks
delayMicroseconds(aBiphaseTimeUnit);
} else {
mark(aBiphaseTimeUnit);
}
#else
(void) tLastBitValue; // to avoid compiler warnings
mark(aBiphaseTimeUnit); // can not eventually delay here, we must call mark to generate the signal
#endif
space(aBiphaseTimeUnit);
tLastBitValue = 0;
@ -359,7 +360,17 @@ void IRsend::sendBiphaseData(unsigned int aBiphaseTimeUnit, uint32_t aData, uint
void IRsend::mark(unsigned int aMarkMicros) {
setFeedbackLED(true);
#if defined(USE_SOFT_SEND_PWM) && !defined(ESP32) // for esp32 we use PWM generation by hw_timer_t for each pin
#if defined(SEND_PWM_BY_TIMER) || defined(ESP32)
TIMER_ENABLE_SEND_PWM; // Enable timer or ledcWrite() generated PWM output
customDelayMicroseconds(aMarkMicros);
ledOff();
#elif defined(USE_NO_SEND_PWM)
digitalWrite(sendPin, LOW); // Set output to active low.
customDelayMicroseconds(aMarkMicros);
ledOff();
#else
unsigned long start = micros();
unsigned long nextPeriodEnding = start;
unsigned long tMicros;
@ -379,19 +390,7 @@ void IRsend::mark(unsigned int aMarkMicros) {
// digitalToggleFast(IR_TIMING_TEST_PIN); // 3.0 us per call @16MHz
} while (tMicros < nextPeriodEnding); // 3.4 us @16MHz
} while (tMicros - start < aMarkMicros);
#else
# if defined(USE_NO_SEND_PWM)
digitalWrite(sendPin, LOW); // Set output to active low.
# else
TIMER_ENABLE_SEND_PWM; // Enable pin 3 PWM output
# endif // USE_SOFT_SEND_PWM
customDelayMicroseconds(aMarkMicros);
ledOff();
#endif // USE_SOFT_SEND_PWM
# endif
}
/**
@ -400,13 +399,13 @@ void IRsend::mark(unsigned int aMarkMicros) {
* This function may affect the state of feedback LED.
*/
void IRsend::ledOff() {
#if defined(USE_SOFT_SEND_PWM) && !defined(ESP32) // for esp32 we use PWM generation by hw_timer_t for each pin
digitalWrite(sendPin, LOW);
#if defined(SEND_PWM_BY_TIMER) || defined(ESP32)
TIMER_DISABLE_SEND_PWM; // Disable PWM output
#elif defined(USE_NO_SEND_PWM)
digitalWrite(sendPin, HIGH); // Set output to inactive high.
#else
TIMER_DISABLE_SEND_PWM; // Disable PWM output
#endif // defined(USE_NO_SEND_PWM)
digitalWrite(sendPin, LOW);
#endif
setFeedbackLED(false);
}
@ -443,24 +442,22 @@ void IRsend::customDelayMicroseconds(unsigned long aMicroseconds) {
* See my Secrets of Arduino PWM at http://arcfn.com/2009/07/secrets-of-arduino-pwm.html for details.
*/
void IRsend::enableIROut(uint8_t aFrequencyKHz) {
#if defined(USE_SOFT_SEND_PWM) && !defined(ESP32) // for esp32 we use PWM generation by hw_timer_t for each pin
periodTimeMicros = (1000U + aFrequencyKHz / 2) / aFrequencyKHz; // rounded value -> 26 for 38 kHz
periodOnTimeMicros = (((periodTimeMicros * IR_SEND_DUTY_CYCLE) + 50 - (PULSE_CORRECTION_NANOS / 10))/ 100U); // +50 for rounding
#endif
#if defined(USE_NO_SEND_PWM)
(void) aFrequencyKHz;
pinMode(sendPin, OUTPUT);
digitalWrite(sendPin, HIGH); // Set output to inactive high.
#endif
pinMode(sendPin, OUTPUT);
ledOff(); // When not sending, we want it low
#if defined(SEND_PWM_BY_TIMER) && !defined(USE_NO_SEND_PWM)
#if defined(SEND_PWM_BY_TIMER) || defined(ESP32)
# if defined(SEND_PWM_BY_TIMER)
TIMER_DISABLE_RECEIVE_INTR;
# endif
timerConfigForSend(aFrequencyKHz);
#elif defined(USE_NO_SEND_PWM)
(void) aFrequencyKHz;
#else
periodTimeMicros = (1000U + aFrequencyKHz / 2) / aFrequencyKHz; // rounded value -> 26 for 38 kHz
periodOnTimeMicros = (((periodTimeMicros * IR_SEND_DUTY_CYCLE) + 50 - (PULSE_CORRECTION_NANOS / 10)) / 100U); // +50 for rounding
#endif
pinMode(sendPin, OUTPUT);
ledOff(); // When not sending, we want it low/inactive
}
/** @}*/

View File

@ -158,15 +158,13 @@
* Define to use no carrier PWM, just simulate an active low receiver signal.
*/
//#define USE_NO_SEND_PWM
/**
* Define to use carrier PWM generation in software, instead of hardware PWM.
*/
#if !defined(SEND_PWM_BY_TIMER) && !defined(USE_NO_SEND_PWM)
#define USE_SOFT_SEND_PWM
#if defined(SEND_PWM_BY_TIMER) && defined(USE_NO_SEND_PWM)
#undef SEND_PWM_BY_TIMER // USE_NO_SEND_PWM overrides SEND_PWM_BY_TIMER
#warning "SEND_PWM_BY_TIMER and USE_NO_SEND_PWM are both defined -> undefine SEND_PWM_BY_TIMER now!"
#endif
/**
* If USE_SOFT_SEND_PWM, this amount is subtracted from the on-time of the pulses.
* This amount is subtracted from the on-time of the pulses generated for software PWM generation.
* It should be the time used for digitalWrite(sendPin, LOW) and the call to delayMicros()
* Measured value for Nano @16MHz is around 3000, for Bluepill @72MHz is around 700, for Zero 3600
*/