Closed 3w3rt0n closed 2 weeks ago
v5.3
Windows
Command line with Make
CMD
The adc_monitor interrupt is not being generated.
With a threshold of 1500, interruption does not occur.
Continuous ADC reading works but threshold interrupt is not generated
The code is based on the continuous reading example and with the modifications indicated in the documentation: Example Continuous Read Analog to Digital Converter (ADC) Continuous Mode Driver - Monitor
#include <string.h> #include <stdio.h> #include "sdkconfig.h" #include "esp_log.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "freertos/semphr.h" #include "esp_adc/adc_continuous.h" #include "esp_adc/adc_monitor.h" #define EXAMPLE_ADC_UNIT ADC_UNIT_1 #define _EXAMPLE_ADC_UNIT_STR(unit) #unit #define EXAMPLE_ADC_UNIT_STR(unit) _EXAMPLE_ADC_UNIT_STR(unit) #define EXAMPLE_ADC_CONV_MODE ADC_CONV_SINGLE_UNIT_1 #define EXAMPLE_ADC_ATTEN ADC_ATTEN_DB_0 #define EXAMPLE_ADC_BIT_WIDTH SOC_ADC_DIGI_MAX_BITWIDTH #if CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2 #define EXAMPLE_ADC_OUTPUT_TYPE ADC_DIGI_OUTPUT_FORMAT_TYPE1 #define EXAMPLE_ADC_GET_CHANNEL(p_data) ((p_data)->type1.channel) #define EXAMPLE_ADC_GET_DATA(p_data) ((p_data)->type1.data) #else #define EXAMPLE_ADC_OUTPUT_TYPE ADC_DIGI_OUTPUT_FORMAT_TYPE2 #define EXAMPLE_ADC_GET_CHANNEL(p_data) ((p_data)->type2.channel) #define EXAMPLE_ADC_GET_DATA(p_data) ((p_data)->type2.data) #endif #define EXAMPLE_READ_LEN 256 static adc_channel_t channel[1] = {ADC_CHANNEL_5}; static TaskHandle_t s_task_handle; static const char *TAG = "EXAMPLE"; static bool threshold = false; static bool IRAM_ATTR monitor_event(adc_monitor_handle_t monitor_handle, const adc_monitor_evt_data_t *event_data, void *user_data){ threshold = true; return true; } static bool IRAM_ATTR s_conv_done_cb(adc_continuous_handle_t handle, const adc_continuous_evt_data_t *edata, void *user_data) { BaseType_t mustYield = pdFALSE; vTaskNotifyGiveFromISR(s_task_handle, &mustYield); return (mustYield == pdTRUE); } void app_main(void) { esp_err_t ret; uint32_t ret_num = 0; uint8_t result[EXAMPLE_READ_LEN] = {0}; memset(result, 0xcc, EXAMPLE_READ_LEN); s_task_handle = xTaskGetCurrentTaskHandle(); adc_continuous_handle_t handle = NULL; adc_continuous_handle_cfg_t adc_config = { .max_store_buf_size = 1024, .conv_frame_size = 256, }; ESP_ERROR_CHECK(adc_continuous_new_handle(&adc_config, &handle)); adc_continuous_config_t dig_cfg = { .sample_freq_hz = 20 * 1000, .conv_mode = EXAMPLE_ADC_CONV_MODE, .format = EXAMPLE_ADC_OUTPUT_TYPE, }; adc_digi_pattern_config_t adc_pattern[SOC_ADC_PATT_LEN_MAX] = {0}; dig_cfg.pattern_num = 1; adc_pattern[0].atten = EXAMPLE_ADC_ATTEN; adc_pattern[0].channel = channel[0] & 0x7; adc_pattern[0].unit = EXAMPLE_ADC_UNIT; adc_pattern[0].bit_width = EXAMPLE_ADC_BIT_WIDTH; ESP_LOGI(TAG, "adc_pattern[%d].atten is :%"PRIx8, 0, adc_pattern[0].atten); ESP_LOGI(TAG, "adc_pattern[%d].channel is :%"PRIx8, 0, adc_pattern[0].channel); ESP_LOGI(TAG, "adc_pattern[%d].unit is :%"PRIx8, 0, adc_pattern[0].unit); dig_cfg.adc_pattern = adc_pattern; ESP_ERROR_CHECK(adc_continuous_config(handle, &dig_cfg)); adc_continuous_evt_cbs_t cbs = { .on_conv_done = s_conv_done_cb, }; ESP_ERROR_CHECK(adc_continuous_register_event_callbacks(handle, &cbs, NULL)); //START ADC_MONITOR adc_monitor_handle_t monitor_handle; adc_monitor_config_t monitor_config = { .adc_unit = ADC_UNIT_1, .channel = ADC_CHANNEL_5, .h_threshold = 1500, .l_threshold = 1000, }; adc_monitor_evt_cbs_t cbs_monitor = { .on_over_high_thresh = monitor_event, .on_below_low_thresh = monitor_event, }; ESP_ERROR_CHECK(adc_new_continuous_monitor(handle, &monitor_config, &monitor_handle)); ESP_ERROR_CHECK(adc_continuous_monitor_register_event_callbacks(monitor_handle, &cbs_monitor, NULL)); ESP_ERROR_CHECK(adc_continuous_monitor_enable(monitor_handle)); //END ADC_MONITOR ESP_ERROR_CHECK(adc_continuous_start(handle)); while (1) { ulTaskNotifyTake(pdTRUE, portMAX_DELAY); char unit[] = EXAMPLE_ADC_UNIT_STR(EXAMPLE_ADC_UNIT); while (1) { ret = adc_continuous_read(handle, result, EXAMPLE_READ_LEN, &ret_num, 0); if(threshold){ ESP_LOGI(TAG, ":: Threshold\n"); threshold = false; } if (ret == ESP_OK) { ESP_LOGI("TASK", "ret is %x, ret_num is %"PRIu32" bytes", ret, ret_num); for (int i = 0; i < ret_num; i += SOC_ADC_DIGI_RESULT_BYTES) { adc_digi_output_data_t *p = (adc_digi_output_data_t*)&result[i]; uint32_t chan_num = EXAMPLE_ADC_GET_CHANNEL(p); uint32_t data = EXAMPLE_ADC_GET_DATA(p); if (chan_num < SOC_ADC_CHANNEL_NUM(EXAMPLE_ADC_UNIT)) { ESP_LOGI(TAG, "Unit: %s, Channel: %"PRIu32", Value: %d", unit, chan_num, (int)data); } else { ESP_LOGW(TAG, "Invalid data [%s_%"PRIu32"_%"PRIx32"]", unit, chan_num, data); } } vTaskDelay(10); } else if (ret == ESP_ERR_TIMEOUT) { //We try to read `EXAMPLE_READ_LEN` until API returns timeout, which means there's no available data break; } } } // ESP_ERROR_CHECK(adc_continuous_stop(handle)); //ESP_ERROR_CHECK(adc_continuous_deinit(handle)); }
The code does not present any errors or warnings during build or execution.
No response
Same issue as https://github.com/espressif/esp-idf/issues/14769
The fix is on the way.
After applying the fix it resolved FIX
The serial print has a delay in this code, the threshold occurs exactly when I change the value of the potentiometer.
Thanks @suda-morris and I'm waiting for the merge into the official version, expected correction?
Answers checklist.
IDF version.
v5.3
Operating System used.
Windows
How did you build your project?
Command line with Make
If you are using Windows, please specify command line type.
CMD
What is the expected behavior?
The adc_monitor interrupt is not being generated.
With a threshold of 1500, interruption does not occur.
What is the actual behavior?
Continuous ADC reading works but threshold interrupt is not generated
Steps to reproduce.
The code is based on the continuous reading example and with the modifications indicated in the documentation: Example Continuous Read Analog to Digital Converter (ADC) Continuous Mode Driver - Monitor
Build or installation Logs.
More Information.
No response