/* * MJD HARDWARE INSTRUCTIONS: * GPIO selector (Adafruit HUZZAH32 dev board) * #21 = SW180 tilt sensor | KY032 obstacle sensor | SW420 Vibration Sensor * * KY032 Sensor (or any other sensor or button that reports a digital signal 0 or 1) * !pinvalue=1 no obstacle | pinvalue=0 yes obstacle * Connect pin 1 (left) of the sensor to DATA * Connect pin 2 (middle) of the sensor to GND * Connect pin 3 (right) of the sensor to VCC */ #include #include #include #include #include "freertos/FreeRTOS.h" #include "freertos/event_groups.h" #include "freertos/task.h" #include "esp_event_loop.h" #include "esp_clk.h" #include "esp_log.h" #include "esp_spi_flash.h" #include "nvs_flash.h" static const char *TAG = "myapp"; /* * GPIO */ #define GPIO_NUM_LED (GPIO_NUM_13) #define GPIO_NUM_SENSOR (GPIO_NUM_21) /* * RTOS */ #define RTOS_TASK_PRIORITY_NORMAL (5) /* * MAIN */ SemaphoreHandle_t xSensorInterruptSemaphore = NULL; void gpio_setup_gpiomux_sensor_to_led() { ESP_LOGI(TAG, "%s: entry", __FUNCTION__); // @special ESP32 GPIO-MUX routes the incoming sensor signal to the on-board LED. // @doc Only the loopback signals 224-228 can be configured to be routed from one input GPIO and directly to another output GPIO. // @special param3=true => invert because for example 1=nothing detected (LED off) and 0=obstance detected on the sensor (LED on). gpio_matrix_in(GPIO_NUM_SENSOR, SIG_IN_FUNC228_IDX, true); gpio_matrix_out(GPIO_NUM_LED, SIG_IN_FUNC228_IDX, false, false); } void gpio_setup_led() { ESP_LOGI(TAG, "%s: entry", __FUNCTION__); gpio_config_t io_conf; io_conf.pin_bit_mask = (1ULL << GPIO_NUM_LED); io_conf.mode = GPIO_MODE_OUTPUT; io_conf.pull_down_en = GPIO_PULLDOWN_DISABLE; io_conf.pull_up_en = GPIO_PULLUP_DISABLE; io_conf.intr_type = GPIO_INTR_DISABLE; gpio_config(&io_conf); } void gpio_setup_sensor() { ESP_LOGI(TAG, "%s: entry", __FUNCTION__); gpio_config_t io_conf; io_conf.pin_bit_mask = (1ULL << GPIO_NUM_SENSOR); io_conf.mode = GPIO_MODE_INPUT; io_conf.pull_up_en = GPIO_PULLUP_ENABLE; io_conf.pull_down_en = GPIO_PULLDOWN_DISABLE; // @okay GPIO_INTR_ANYEDGE @problem GPIO_INTR_POSEDGE GPIO_INTR_NEGEDGE (they both behave the same as ANYEDGE!) io_conf.intr_type = GPIO_INTR_ANYEDGE; ESP_ERROR_CHECK(gpio_config(&io_conf)); } void IRAM_ATTR sensor_isr_handler(void* arg) { xSemaphoreGiveFromISR(xSensorInterruptSemaphore, NULL); } void gpio_semaphore_interrupt_task(void *pvParameter) { ESP_LOGI(TAG, "%s: entry", __FUNCTION__); xSensorInterruptSemaphore = xSemaphoreCreateBinary(); ESP_ERROR_CHECK(gpio_install_isr_service(ESP_INTR_FLAG_LEVEL1)); // @doc ESP_INTR_FLAG_LEVEL1 Accept a Level 1 interrupt vector (lowest priority) ESP_ERROR_CHECK(gpio_isr_handler_add(GPIO_NUM_SENSOR, sensor_isr_handler, NULL)); while (true) { if (xSemaphoreTake(xSensorInterruptSemaphore, portMAX_DELAY) == pdTRUE) { ESP_LOGI(TAG, "***semaphore taken***"); ESP_LOGI(TAG, "*** GPIO#%d (sensor), current value: %d\n", GPIO_NUM_SENSOR, gpio_get_level(GPIO_NUM_SENSOR)); } } } void app_main() { ESP_LOGI(TAG, "%s: entry", __FUNCTION__); gpio_setup_led(); gpio_setup_sensor(); gpio_setup_gpiomux_sensor_to_led(); BaseType_t xReturned; xReturned = xTaskCreate(&gpio_semaphore_interrupt_task, "gpio_semaphore_interrupt_task (name)", 2048, NULL, RTOS_TASK_PRIORITY_NORMAL, NULL); if (xReturned == pdPASS) { ESP_LOGI(TAG, "OK Task has been created, and is running right now"); } }