Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow disabling the use of delay() calls. #450

Merged
merged 2 commits into from
May 7, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions src/IRremoteESP8266.h
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,12 @@
#define DECODE_AC false // We don't need that infrastructure.
#endif

// Use millisecond 'delay()' calls where we can to avoid tripping the WDT.
// Note: If you plan to send IR messages in the callbacks of the AsyncWebserver
// library, you need to set ALLOW_DELAY_CALLS to false.
// Ref: https://github.com/markszabo/IRremoteESP8266/issues/430
#define ALLOW_DELAY_CALLS true

/*
* Always add to the end of the list and should never remove entries
* or change order. Projects may save the type number for later usage
Expand Down
21 changes: 19 additions & 2 deletions src/IRsend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -117,13 +117,14 @@ void IRsend::enableIROut(uint32_t freq, uint8_t duty) {
offTimePeriod = period - onTimePeriod;
}

#if ALLOW_DELAY_CALLS
// An ESP8266 RTOS watch-dog timer friendly version of delayMicroseconds().
// Args:
// usec: Nr. of uSeconds to delay for.
void IRsend::_delayMicroseconds(uint32_t usec) {
// delayMicroseconds is only accurate to 16383us.
// delayMicroseconds() is only accurate to 16383us.
// Ref: https://www.arduino.cc/en/Reference/delayMicroseconds
if (usec <= 16383) {
if (usec <= MAX_ACCURATE_USEC_DELAY) {
#ifndef UNIT_TEST
delayMicroseconds(usec);
#endif
Expand All @@ -136,6 +137,22 @@ void IRsend::_delayMicroseconds(uint32_t usec) {
#endif
}
}
#else // ALLOW_DELAY_CALLS
// A version of delayMicroseconds() that handles large values and does NOT use
// the watch-dog friendly delay() calls where appropriate.
// Args:
// usec: Nr. of uSeconds to delay for.
//
// NOTE: Use this only if you know what you are doing as it may cause the WDT
// to reset the ESP8266.
void IRsend::_delayMicroseconds(uint32_t usec) {
for (; usec > MAX_ACCURATE_USEC_DELAY; usec -= MAX_ACCURATE_USEC_DELAY)
#ifndef UNIT_TEST
delayMicroseconds(MAX_ACCURATE_USEC_DELAY);
delayMicroseconds(static_cast<uint16_t>(usec));
#endif // UNIT_TEST
}
#endif // ALLOW_DELAY_CALLS

// Modulate the IR LED for the given period (usec) and at the duty cycle set.
//
Expand Down
3 changes: 3 additions & 0 deletions src/IRsend.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@
#define PERIOD_OFFSET -3
#define DUTY_DEFAULT 50
#define DUTY_MAX 100 // Percentage
// delayMicroseconds() is only accurate to 16383us.
// Ref: https://www.arduino.cc/en/Reference/delayMicroseconds
#define MAX_ACCURATE_USEC_DELAY 16383U

// Classes
class IRsend {
Expand Down