Skip to content

Commit

Permalink
V4.1.2. Workaround for ESP32 RTOS delay() timing bug influencing the …
Browse files Browse the repository at this point in the history
…mark() function. Closes #1114.
  • Loading branch information
Armin committed Mar 22, 2023
1 parent dfdf835 commit 03b3995
Show file tree
Hide file tree
Showing 5 changed files with 55 additions and 25 deletions.
3 changes: 3 additions & 0 deletions changelog.md
Expand Up @@ -2,6 +2,9 @@
The latest version may not be released!
See also the commit log at github: https://github.com/Arduino-IRremote/Arduino-IRremote/commits/master

## 4.1.2
- Workaround for ESP32 RTOS delay() timing bug influencing the mark() function.

## 4.1.1
- SAMD51 use timer3 if timer5 not available.
- Disabled #define LOCAL_DEBUG in IRReceive.hpp, which was accidently enabled at 4.1.0.
Expand Down
43 changes: 27 additions & 16 deletions examples/AllProtocolsOnLCD/AllProtocolsOnLCD.ino
Expand Up @@ -74,27 +74,34 @@
*/
//#define USE_NO_LCD
//#define USE_SERIAL_LCD
// Definitions for the 1602 LCD
#define LCD_COLUMNS 16
#define LCD_ROWS 2

#if defined(USE_SERIAL_LCD)
#include "LiquidCrystal_I2C.h" // Use an up to date library version, which has the init method
LiquidCrystal_I2C myLCD(0x27, LCD_COLUMNS, LCD_ROWS); // set the LCD address to 0x27 for a 16 chars and 2 line display
#elif !defined(USE_NO_LCD)
#include "LiquidCrystal.h"
#define USE_PARALLEL_LCD
#include "LiquidCrystal.h"
//LiquidCrystal myLCD(4, 5, 6, 7, 8, 9);
LiquidCrystal myLCD(7, 8, 3, 4, 5, 6);
#endif

#if defined(USE_PARALLEL_LCD)
#define DEBUG_BUTTON_PIN 11 // If low, print timing for each received data set
#define AUXILIARY_DEBUG_BUTTON_PIN 12 // Is set to low to enable using of a simple connector for enabling debug
#undef TONE_PIN
#define TONE_PIN 9 // Pin 4 is used by LCD
#else
#define DEBUG_BUTTON_PIN 6
#define DEBUG_BUTTON_PIN 6
#endif
#define AUXILIARY_DEBUG_BUTTON_PIN 12 // Is set to low to enable using of a simple connector for enabling debug

#define MILLIS_BETWEEN_ATTENTION_BEEP 60000 // 60 sec
uint32_t sMillisOfLastReceivedIRFrame = 0;

#if defined(USE_SERIAL_LCD) || defined(USE_PARALLEL_LCD)
#define USE_LCD
// definitions for a 1602 LCD
#define LCD_COLUMNS 16
#define LCD_ROWS 2
# if defined(__AVR__) && defined(ADCSRA) && defined(ADATE)
// For cyclically display of VCC
#include "ADCUtils.hpp"
Expand All @@ -107,14 +114,6 @@ bool ProtocolStringOverwritesVoltage = false;

#endif // defined(USE_SERIAL_LCD) || defined(USE_PARALLEL_LCD)

#if defined(USE_SERIAL_LCD)
LiquidCrystal_I2C myLCD(0x27, LCD_COLUMNS, LCD_ROWS); // set the LCD address to 0x27 for a 16 chars and 2 line display
#endif
#if defined(USE_PARALLEL_LCD)
//LiquidCrystal myLCD(4, 5, 6, 7, 8, 9);
LiquidCrystal myLCD(7, 8, 3, 4, 5, 6);
#endif

void printIRResultOnLCD();
size_t printByteHexOnLCD(uint16_t aHexByteValue);
void printSpacesOnLCD(uint_fast8_t aNumberOfSpacesToPrint);
Expand Down Expand Up @@ -186,7 +185,7 @@ void setup() {
myLCD.backlight();
#endif
#if defined(USE_PARALLEL_LCD)
myLCD.begin(LCD_COLUMNS, LCD_ROWS);
myLCD.begin(LCD_COLUMNS, LCD_ROWS); // This also clears display
#endif

#if defined(USE_LCD)
Expand Down Expand Up @@ -261,14 +260,26 @@ void loop() {
IrReceiver.resume();
} // if (IrReceiver.decode())

/*
* Check for attention every 10 minute, after the current measurement was finished
*/
if (millis() - sMillisOfLastReceivedIRFrame >= MILLIS_BETWEEN_ATTENTION_BEEP) {
sMillisOfLastReceivedIRFrame = millis();
IrReceiver.stop();
tone(TONE_PIN, 2200);
delay(50);
noTone(TONE_PIN);
IrReceiver.startWithTicksToAdd(50 * (MICROS_IN_ONE_MILLI / MICROS_PER_TICK));
}

#if defined(USE_LCD) && defined(ADC_UTILS_ARE_AVAILABLE)
//Periodically print VCC
if (!ProtocolStringOverwritesVoltage && millis() - sMillisOfLastVoltagePrint > MILLIS_BETWEEN_VOLTAGE_PRINT) {
/*
* Periodically print VCC
*/
sMillisOfLastVoltagePrint = millis();
sVCCMillivolt = getVCCVoltageMillivoltSimple();
sVCCMillivolt = getVCCVoltageMillivoltSimple();
char tVoltageString[5];
dtostrf(sVCCMillivolt / 1000.0, 4, 2, tVoltageString);
myLCD.setCursor(LCD_VOLTAGE_START_INDEX - 1, 0);
Expand Down
2 changes: 1 addition & 1 deletion library.json
Expand Up @@ -7,7 +7,7 @@
"type": "git",
"url": "https://github.com/z3t0/Arduino-IRremote.git"
},
"version": "4.1.1",
"version": "4.1.2",
"frameworks": "arduino",
"platforms": ["atmelavr", "atmelmegaavr", "atmelsam", "espressif8266", "espressif32", "ststm32"],
"authors" :
Expand Down
2 changes: 1 addition & 1 deletion library.properties
@@ -1,5 +1,5 @@
name=IRremote
version=4.1.1
version=4.1.2
author=shirriff, z3t0, ArminJo
maintainer=Armin Joachimsmeyer <armin.arduino@gmail.com>
sentence=Send and receive infrared signals with multiple protocols
Expand Down
30 changes: 23 additions & 7 deletions src/IRSend.hpp
Expand Up @@ -683,6 +683,14 @@ void IRsend::sendPulseDistanceWidthFromArray(PulseDistanceWidthProtocolConstants
void IRsend::sendPulseDistanceWidth(PulseDistanceWidthProtocolConstants *aProtocolConstants, IRRawDataType aData,
uint_fast8_t aNumberOfBits, int_fast8_t aNumberOfRepeats) {

#if defined(LOCAL_DEBUG)
Serial.print(F("Data=0x"));
Serial.print(aData, HEX);
Serial.print(F(" #="));
Serial.println(aNumberOfBits);
Serial.flush();
#endif

if (aNumberOfRepeats < 0) {
if (aProtocolConstants->SpecialSendRepeatFunction != NULL) {
aProtocolConstants->SpecialSendRepeatFunction();
Expand Down Expand Up @@ -823,10 +831,10 @@ void IRsend::sendPulseDistanceWidthData(uint16_t aOneMarkMicros, uint16_t aOneSp
uint16_t aZeroSpaceMicros, IRRawDataType aData, uint_fast8_t aNumberOfBits, uint8_t aFlags) {

#if defined(LOCAL_DEBUG)
// Even printing this short messages (at 115200) disturbs the send timing :-(
// Serial.print(aData, HEX);
// Serial.print('|');
// Serial.println(aNumberOfBits);
Serial.print(aData, HEX);
Serial.print('|');
Serial.println(aNumberOfBits);
Serial.flush();
#endif

// For MSBFirst, send data from MSB to LSB until mask bit is shifted out
Expand Down Expand Up @@ -1129,9 +1137,17 @@ void IRsend::customDelayMicroseconds(unsigned long aMicroseconds) {
#if defined(ESP32) || defined(ESP8266)
// from https://github.com/crankyoldgit/IRremoteESP8266/blob/00b27cc7ea2e7ac1e48e91740723c805a38728e0/src/IRsend.cpp#L123
// Invoke a delay(), where possible, to avoid triggering the WDT.
delay(aMicroseconds / 1000UL); // Delay for as many whole milliseconds as we can.
// Delay the remaining sub-millisecond.
delayMicroseconds(static_cast<uint16_t>(aMicroseconds % 1000UL));
// see https://github.com/Arduino-IRremote/Arduino-IRremote/issues/1114 for the reason of checking for > 20000 ( 20000 is just a best guess :-))
if (aMicroseconds > 20000) {
delay(aMicroseconds / 1000UL); // Delay for as many whole milliseconds as we can.
// Delay the remaining sub-millisecond.
delayMicroseconds(static_cast<uint16_t>(aMicroseconds % 1000UL));
} else {
unsigned long start = micros();
// overflow invariant comparison :-)
while (micros() - start < aMicroseconds) {
}
}
#else

# if defined(__AVR__)
Expand Down

0 comments on commit 03b3995

Please sign in to comment.