#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/gpio.h"
#include "esp_log.h"
void IRAM_ATTR button_isr_handler(void* arg);
#define BUTTON_PIN 4 // Button connected to GPIO4
// Global flags for ISR
bool button_event = false; //This becomes true after an interrupt is called, which occurs after a button press or release. When this flag is true, it means we can proceed with the code which allows us to print a falling or rising edge. (JI)
bool fallingEdge = false; //Boolean variable to determine if the edge is falling or rising. Becomes true after an interrupt. (JI)
void app_main() {
// Configuring GPIO as input
gpio_set_direction(BUTTON_PIN, GPIO_MODE_INPUT);
gpio_set_pull_mode(BUTTON_PIN, GPIO_PULLUP_ONLY);
// Setting interrupt on FALLING edge (button press)
gpio_set_intr_type(BUTTON_PIN, GPIO_INTR_ANYEDGE); //Changed NEGEDGE to ANYEDGE, because we want to capture the moment it falls and the moment it rises. (JI)
// Install ISR service (interrupt handling)
gpio_install_isr_service(0);
// Attaching ISR handler to BUTTON_PIN
gpio_isr_handler_add(BUTTON_PIN, button_isr_handler, NULL);
while (1) { //The if statements below can only be accessed after an interrupt is called, which occurs on a button press or release. (JI)
if (button_event) { //Translation: If an interrupt was called (button press or release), proceed with the code below. The interrupt function makes this variable true. (JI)
button_event = false; // Reset flag
//This 'if/else' code block is only reached if an interrupt was called, and the interrupt can only be called on a button press or release. (JI)
if (fallingEdge) { //If this variable is true, then the button was pressed, which means it's falling edge since this an active low circuit. (JI)
printf("Falling Edge\n");
} else {
printf("Rising Edge\n"); //If the variable is false, then it means the button was released and it's a rising edge. (JI)
} //The interrupt runs through its function on button press and button release. (JI)
}
printf("Main loop running...\n"); //This block of code will continuously run if no button is pressed. (JI)
vTaskDelay(pdMS_TO_TICKS(500)); // loop continues running
}
}
// Interrupt Service Routine (ISR)
void IRAM_ATTR button_isr_handler(void* arg) {
int button_state = gpio_get_level(BUTTON_PIN); //This function is called on button press and release to read the value of button_pin and store the value into button_state. (JI)
fallingEdge = (button_state == 0); //If the button is pressed, then button_state becomes true. It feeds a '1' into the 'fallingEdge' variable. The inverse is true on button release. (JI)
button_event = true; //We set this value to true so we can enter the "button_event" if-statement, which is the part of the code which determines if it's a falling or rising edge. (JI)
}