Skip to content

Commit e0c2649

Browse files
authored
Merge pull request Arduino-IRremote#425 from marcmerlin/master
Added ESP32 IR receive support (IRsend not implemented yet).
2 parents 513e104 + 419c948 commit e0c2649

File tree

10 files changed

+74
-8
lines changed

10 files changed

+74
-8
lines changed

Contributors.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,5 +18,6 @@ These are the active contributors of this project that you may contact if there
1818
- [ElectricRCAircraftGuy](https://github.com/electricrcaircraftguy): Active Contributor
1919
- [philipphenkel](https://github.com/philipphenkel): Active Contributor
2020
- [MCUdude](https://github.com/MCUdude): Contributor
21+
- [marcmerlin](https://github.com/marcmerlin): Contributor (ESP32 port)
2122

2223
Note: This list is being updated constantly so please let [z3t0](https://github.com/z3t0) know if you have been missed.

IRremote.cpp

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,17 @@
1818
// Whynter A/C ARC-110WD added by Francesco Meschia
1919
//******************************************************************************
2020

21-
#include <avr/interrupt.h>
22-
2321
// Defining IR_GLOBAL here allows us to declare the instantiation of global variables
2422
#define IR_GLOBAL
2523
# include "IRremote.h"
2624
# include "IRremoteInt.h"
2725
#undef IR_GLOBAL
2826

27+
#ifndef IR_TIMER_USE_ESP32
28+
#include <avr/interrupt.h>
29+
#endif
30+
31+
2932
//+=============================================================================
3033
// The match functions were (apparently) originally MACROs to improve code speed
3134
// (although this would have bloated the code) hence the names being CAPS
@@ -120,7 +123,11 @@ int MATCH_SPACE (int measured_ticks, int desired_us)
120123
// As soon as first MARK arrives:
121124
// Gap width is recorded; Ready is cleared; New logging starts
122125
//
126+
#ifdef IR_TIMER_USE_ESP32
127+
void IRTimer()
128+
#else
123129
ISR (TIMER_INTR_NAME)
130+
#endif
124131
{
125132
TIMER_RESET;
126133

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ Tutorials and more information will be made available on [the official homepage]
2525
- ATmega8535, 16, 32, 164, 324, 644, 1284,
2626
- ATmega64, 128
2727
- ATtiny 84 / 85
28+
- ESP32 (receive only)
2829

2930
We are open to suggestions for adding support to new boards, however we highly recommend you contact your supplier first and ask them to provide support from their side.
3031

@@ -42,6 +43,7 @@ We are open to suggestions for adding support to new boards, however we highly r
4243
| [ATmega8535 ATmega16, ATmega32](https://github.com/MCUdude/MightyCore) | **13** | **1** |
4344
| [ATmega64, ATmega128](https://github.com/MCUdude/MegaCore) | **13** | **1** |
4445
| ATmega1280, ATmega2560 | 5, 6, **9**, 11, 46 | 1, **2**, 3, 4, 5 |
46+
| [ESP32](http://esp32.net/) | N/A (not supported) | **1** |
4547
| [Teensy 1.0](https://www.pjrc.com/teensy/) | **17** | **1** |
4648
| [Teensy 2.0](https://www.pjrc.com/teensy/) | 9, **10**, 14 | 1, 3, **4_HS** |
4749
| [Teensy++ 1.0 / 2.0](https://www.pjrc.com/teensy/) | **1**, 16, 25 | 1, **2**, 3 |

boarddefs.h

Lines changed: 33 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,9 +39,14 @@
3939
# define BLINKLED_ON() (PORTD |= B00000001)
4040
# define BLINKLED_OFF() (PORTD &= B11111110)
4141

42+
// No system LED on ESP32, disable blinking
43+
#elif defined(ESP32)
44+
# define BLINKLED 255
45+
# define BLINKLED_ON() 1
46+
# define BLINKLED_OFF() 1
4247
#else
4348
# define BLINKLED 13
44-
#define BLINKLED_ON() (PORTB |= B00100000)
49+
# define BLINKLED_ON() (PORTB |= B00100000)
4550
# define BLINKLED_OFF() (PORTB &= B11011111)
4651
#endif
4752

@@ -125,15 +130,17 @@
125130

126131
// ATtiny84
127132
#elif defined(__AVR_ATtiny84__)
128-
#define IR_USE_TIMER1 // tx = pin 6
133+
#define IR_USE_TIMER1 // tx = pin 6
129134

130135
//ATtiny85
131136
#elif defined(__AVR_ATtiny85__)
132-
#define IR_USE_TIMER_TINY0 // tx = pin 1
137+
#define IR_USE_TIMER_TINY0 // tx = pin 1
133138

139+
#elif defined(ESP32)
140+
#define IR_TIMER_USE_ESP32
141+
#else
134142
// Arduino Duemilanove, Diecimila, LilyPad, Mini, Fio, Nano, etc
135143
// ATmega48, ATmega88, ATmega168, ATmega328
136-
#else
137144
//#define IR_USE_TIMER1 // tx = pin 9
138145
#define IR_USE_TIMER2 // tx = pin 3
139146

@@ -538,6 +545,28 @@
538545

539546
#define TIMER_PWM_PIN 1 /* ATtiny85 */
540547

548+
//---------------------------------------------------------
549+
// ESP32 (ESP8266 should likely be added here too)
550+
//
551+
552+
// ESP32 has it own timer API and does not use these macros, but to avoid ifdef'ing
553+
// them out in the common code, they are defined to no-op. This allows the code to compile
554+
// (which it wouldn't otherwise) but irsend will not work until ESP32 specific code is written
555+
// for that -- merlin
556+
// As a warning, sending timing specific code from an ESP32 can be challenging if you need 100%
557+
// reliability because the arduino code may be interrupted and cause your sent waveform to be the
558+
// wrong length. This is specifically an issue for neopixels which require 800Khz resolution.
559+
// IR may just work as is with the common code since it's lower frequency, but if not, the other
560+
// way to do this on ESP32 is using the RMT built in driver like in this incomplete library below
561+
// https://github.com/ExploreEmbedded/ESP32_RMT
562+
#elif defined(IR_TIMER_USE_ESP32)
563+
#define TIMER_RESET
564+
#define TIMER_ENABLE_PWM
565+
#define TIMER_DISABLE_PWM Serial.println("IRsend not implemented for ESP32 yet");
566+
#define TIMER_ENABLE_INTR
567+
#define TIMER_DISABLE_INTR
568+
#define TIMER_INTR_NAME
569+
541570
//---------------------------------------------------------
542571
// Unknown Timer
543572
//

changelog.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
## 2.3.3 - 2017/03/31
2+
- Added ESP32 IR receive support [PR #427](https://github.com/z3t0/Arduino-IRremote/pull/425)
3+
14
## 2.2.3 - 2017/03/27
25
- Fix calculation of pause length in LEGO PF protocol [PR #427](https://github.com/z3t0/Arduino-IRremote/pull/427)
36

examples/IRrecvDemo/IRrecvDemo.ino

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,11 @@ decode_results results;
1717
void setup()
1818
{
1919
Serial.begin(9600);
20+
// In case the interrupt driver crashes on setup, give a clue
21+
// to the user what's going on.
22+
Serial.println("Enabling IRin");
2023
irrecv.enableIRIn(); // Start the receiver
24+
Serial.println("Enabled IRin");
2125
}
2226

2327
void loop() {

examples/IRrecvDump/IRrecvDump.ino

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
* You can change this to another available Arduino Pin.
1616
* Your IR receiver should be connected to the pin defined here
1717
*/
18-
int RECV_PIN = 11;
18+
int RECV_PIN = 11;
1919

2020
IRrecv irrecv(RECV_PIN);
2121

irRecv.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
#include "IRremote.h"
22
#include "IRremoteInt.h"
3+
4+
#ifdef IR_TIMER_USE_ESP32
5+
hw_timer_t *timer;
6+
void IRTimer(); // defined in IRremote.cpp
7+
#endif
38

49
//+=============================================================================
510
// Decodes the received IR message
@@ -117,6 +122,17 @@ IRrecv::IRrecv (int recvpin, int blinkpin)
117122
//
118123
void IRrecv::enableIRIn ( )
119124
{
125+
// Interrupt Service Routine - Fires every 50uS
126+
#ifdef ESP32
127+
// ESP32 has a proper API to setup timers, no weird chip macros needed
128+
// simply call the readable API versions :)
129+
// 3 timers, choose #1, 80 divider nanosecond precision, 1 to count up
130+
timer = timerBegin(1, 80, 1);
131+
timerAttachInterrupt(timer, &IRTimer, 1);
132+
// every 50ns, autoreload = true
133+
timerAlarmWrite(timer, 50, true);
134+
timerAlarmEnable(timer);
135+
#else
120136
cli();
121137
// Setup pulse clock timer interrupt
122138
// Prescale /8 (16M/8 = 0.5 microseconds per tick)
@@ -130,6 +146,7 @@ void IRrecv::enableIRIn ( )
130146
TIMER_RESET;
131147

132148
sei(); // enable interrupts
149+
#endif
133150

134151
// Initialize state machine variables
135152
irparams.rcvstate = STATE_IDLE;

irSend.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,8 @@ void IRsend::space (unsigned int time)
5454
//
5555
void IRsend::enableIROut (int khz)
5656
{
57+
// FIXME: implement ESP32 support, see IR_TIMER_USE_ESP32 in boarddefs.h
58+
#ifndef ESP32
5759
// Disable the Timer2 Interrupt (which is used for receiving IR)
5860
TIMER_DISABLE_INTR; //Timer2 Overflow Interrupt
5961

@@ -66,6 +68,7 @@ void IRsend::enableIROut (int khz)
6668
// CS2 = 000: no prescaling
6769
// The top value for the timer. The modulation frequency will be SYSCLOCK / 2 / OCR2A.
6870
TIMER_CONFIG_KHZ(khz);
71+
#endif
6972
}
7073

7174
//+=============================================================================

library.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
"type": "git",
88
"url": "https://github.com/z3t0/Arduino-IRremote.git"
99
},
10-
"version": "2.2.3",
10+
"version": "2.3.3",
1111
"frameworks": "arduino",
1212
"platforms": "atmelavr",
1313
"authors" :

0 commit comments

Comments
 (0)