Skip to content

Commit ce6f002

Browse files
committed
update README, added interrupts
1 parent 7bbac33 commit ce6f002

File tree

3 files changed

+131
-0
lines changed

3 files changed

+131
-0
lines changed

README.md

+1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
# esp32_basic_code_examples
2+
23
Some basic ESP32 code examples

esp32_interrupts/README.md

+83
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
# ESP32 configuring and handling GPIO interrupts
2+
3+
Web-Links
4+
5+
- [c't Make: ESP32 SPECIAL 2019 page 6](https://shop.heise.de/katalog/make-esp32-special)
6+
- [ESP32-WROOM-32U datasheet](https://www.espressif.com/sites/default/files/documentation/esp32-wroom-32d_esp32-wroom-32u_datasheet_en.pdf)
7+
- [Espressif Programming Guide](<https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/system/intr_alloc.html>)
8+
- [Example: Configuring & Handling ESP32 GPIO Interrupts In Arduino IDE](<https://lastminuteengineers.com/handling-esp32-gpio-interrupts-tutorial/>)
9+
10+
The ESP32 chip features 40 physical GPIO pads. Some GPIO pads cannot be used or do not have the corresponding pin on the chip package(refer to technical reference manual). Each pad can be used as a general purpose I/O or can be connected to an internal peripheral signal. The ESP32-WROOM-32D and ESP32-WROOM-32U have 38 GPIO pins.
11+
12+
- Note that GPIO6-11 are usually used for SPI flash.
13+
- GPIO34-39 can only be set as input mode and do not have software pullup or pulldown functions.
14+
15+
There is also separate “RTC GPIO” support, which functions when GPIOs are routed to the “RTC” low-power and analog subsystem. These pin functions can be used when in deep sleep, when the Ultra Low Power co-processor is running, or when analog functions such as ADC/DAC/etc are in use.
16+
17+
![ESP-WROOM-32U pinout](https://github.com/yz88/esp32_basic_code_examples/blob/master/esp32_interrupts/fritzing/esp32-DevKitC-pinout.png)
18+
19+
The ESP32 offers up to 32 interrupt slots for each of it's two cores. Each interrupt has a certain priority level and can be categorized into two types.
20+
21+
- **Hardware Interrupts** – These occur in response to an external event. For example, GPIO Interrupt(when a key is pressed down) or a Touch Interrupt(when touch is detected)
22+
- **Software Interrupts** – These occur in response to a software instruction. For example, a Simple Timer Interrupt or Watchdog Timer Interrupt(when timer times out)
23+
24+
In ESP32, we can define an interrupt service routine function that will be called when a GPIO pin changes its signal value.
25+
26+
## Attaching Interrupt to a GPIO Pin
27+
28+
In Arduino IDE, we use a function called `attachInterrupt()` to set an interrupt on a pin by pin basis. The recommended syntax looks like below.
29+
30+
```c
31+
attachInterrupt(GPIOPin, ISR, Mode);
32+
```
33+
34+
This function takes three parameters:
35+
36+
- **GPIOPin** – Sets the GPIO pin as an interrupt pin, which tells the ESP32 which pin to monitor.
37+
- **ISR** – Is the name of the function that will be called every time the interrupt is triggered.
38+
- **Mode** – Defines when the interrupt should be triggered. Five constants are predefined as valid values:
39+
40+
| mode | description |
41+
| ------- | ---------------------------------------------------------------------------------- |
42+
| LOW | Triggers interrupt whenever the pin is LOW |
43+
| HIGH | Triggers interrupt whenever the pin is HIGH |
44+
| CHANGE | Triggers interrupt whenever the pin changes value, from HIGH to LOW or LOW to HIGH |
45+
| FALLING | Triggers interrupt when the pin goes from HIGH to LOW |
46+
| RISING | Triggers interrupt when the pin goes from LOW to HIGH |
47+
48+
## Detaching Interrupt from a GPIO Pin
49+
50+
You can optionally call `detachInterrupt()` function when you no longer want ESP32 to monitor a pin. The recommended syntax looks like below.
51+
52+
```c
53+
detachInterrupt(GPIOPin);
54+
```
55+
56+
## Interrupt Service Routine
57+
58+
Interrupt Service Routine is invoked when an interrupt occurs on any GPIO pin. Its syntax looks like below.
59+
60+
```c
61+
void IRAM_ATTR ISR() {
62+
Statements;
63+
}
64+
```
65+
66+
ISRs in ESP32 are special kinds of functions that have some unique rules most other functions do not have.
67+
68+
- The interrupt service routine must have an execution time as short as possible, because it blocks the normal program execution.
69+
- Interrupt service routines should have the IRAM_ATTR attribute, according to the [ESP32 documentation(<https://docs.espressif.com/projects/esp-idf/en/latest/api-guides/general-notes.html#iram-instruction-ram>)]
70+
71+
---
72+
73+
**Note**
74+
75+
**What is IRAM_ATTR?**
76+
77+
By flagging a piece of code with the `IRAM_ATTR` attribute we are declaring that the compiled code will be placed in the Internal RAM (IRAM) of the ESP32.
78+
79+
Otherwise the code is placed in the Flash. And flash on the ESP32 is much slower than internal RAM.
80+
81+
If the code we want to run is an interrupt service routine (ISR), we generally want to execute it as quickly as possible. If we had to ‘wait’ for an ISR to load from flash, things would go horribly wrong.
82+
83+
---

esp32_interrupts/esp32_interrupts.ino

+47
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
/*
2+
ESP-WROOM-32U
3+
Chip is ESP32D0WDQ6 (revision 1)
4+
Features: WiFi, BT, Dual Core, 240MHz, VRef calibration in efuse, Coding Scheme None
5+
MAC: 24:0a:c4:c5:4e:c0
6+
*/
7+
8+
struct Button
9+
{
10+
const uint8_t PIN;
11+
uint32_t numberKeyPresses;
12+
bool pressed;
13+
};
14+
15+
Button button1 = {18, 0, false};
16+
17+
void IRAM_ATTR isr()
18+
{
19+
button1.numberKeyPresses += 1;
20+
button1.pressed = true;
21+
}
22+
23+
void setup()
24+
{
25+
Serial.begin(115200);
26+
pinMode(button1.PIN, INPUT_PULLUP);
27+
attachInterrupt(button1.PIN, isr, FALLING);
28+
}
29+
30+
void loop()
31+
{
32+
if (button1.pressed)
33+
{
34+
Serial.printf("Button 1 has been pressed %u times\n", button1.numberKeyPresses);
35+
button1.pressed = false;
36+
}
37+
38+
// Detach Interrupt after 1 Minute
39+
// check the number of milliseconds that have passed since the program first started using millis() function
40+
static uint32_t lastMillis = 0;
41+
if (millis() - lastMillis > 60000)
42+
{
43+
lastMillis = millis();
44+
detachInterrupt(button1.PIN);
45+
Serial.println("Interrupt Detached!");
46+
}
47+
}

0 commit comments

Comments
 (0)