Issue with ESP-ADC Continuous Conversion - Abort() Exception

temuko
Posts: 8
Joined: Sun Oct 15, 2023 10:55 am
Location: Europe, Spain

Issue with ESP-ADC Continuous Conversion - Abort() Exception

Postby temuko » Sun Dec 03, 2023 9:35 pm

Hello everyone,

I'm new to ESP development and currently working on a project where I need to read values from the ADC and send them via UART. I've encountered an issue with ADC conversion, and although I've tried to adapt examples from esp-idf, I'm unsure where the error might be in my code.
  1. #include <string.h>
  2. #include <stdio.h>
  3. #include "esp_log.h"
  4. #include "freertos/FreeRTOS.h"
  5. #include "freertos/task.h"
  6. #include "freertos/semphr.h"
  7. #include "esp_adc/adc_continuous.h"
  8. #include "adc_reader.h"  // Debes definir adc_reader.h con las estructuras y funciones necesarias.
  9. #include "sdkconfig.h"
  10.  
  11. #define ADC_UNIT                    ADC_UNIT_1
  12. #define _ADC_UNIT_STR(unit)         #unit
  13. #define ADC_UNIT_STR(unit)          _ADC_UNIT_STR(unit)
  14. #define ADC_CONV_MODE               ADC_CONV_SINGLE_UNIT_1
  15. #define ADC_ATTEN                   ADC_ATTEN_DB_0
  16. #define ADC_BIT_WIDTH               SOC_ADC_DIGI_MAX_BITWIDTH
  17.  
  18. #define ADC_OUTPUT_TYPE             ADC_DIGI_OUTPUT_FORMAT_TYPE1
  19. #define ADC_GET_CHANNEL(p_data)     ((p_data)->type1.channel)
  20. #define ADC_GET_DATA(p_data)        ((p_data)->type1.data)
  21.  
  22. // prueba git
  23.  
  24. #define READ_LEN                    256
  25.  
  26. static adc_channel_t channel[1] = {ADC_CHANNEL_0};
  27.  
  28. static const char *TAG = "ADC_READ";
  29.  
  30. static TaskHandle_t s_task_handle;
  31. static adc_continuous_handle_t handle = NULL;
  32.  
  33.  
  34. static bool IRAM_ATTR s_conv_done_cb(adc_continuous_handle_t handle, const adc_continuous_evt_data_t *edata, void *user_data)
  35. {
  36.     BaseType_t mustYield = pdFALSE;
  37.    
  38.     // Notify that ADC continuous driver has done enough number of conversions
  39.     if (s_task_handle != NULL) {
  40.         vTaskNotifyGiveFromISR(s_task_handle, &mustYield);
  41.     }
  42.  
  43.     ESP_LOGI(TAG, "ADC Conversion done");
  44.    
  45.     return (mustYield == pdTRUE);
  46. }
  47.  
  48.  
  49.  
  50. void adc_reader_init(void)
  51. {
  52.  
  53.     adc_continuous_handle_t handle_init = NULL;
  54.     uint8_t channel_num = 1;
  55.     adc_continuous_handle_cfg_t adc_config = {
  56.         .max_store_buf_size = 1024,
  57.         .conv_frame_size = READ_LEN,
  58.     };
  59.     ESP_ERROR_CHECK(adc_continuous_new_handle(&adc_config, &handle_init));
  60.  
  61.     adc_continuous_config_t dig_cfg = {
  62.         .sample_freq_hz = 20*1000,
  63.         .conv_mode = ADC_CONV_MODE,
  64.         .format = ADC_OUTPUT_TYPE,
  65.     };
  66.  
  67.     adc_digi_pattern_config_t adc_pattern[SOC_ADC_PATT_LEN_MAX] = {0};
  68.     dig_cfg.pattern_num = channel_num;
  69.     for (int i = 0; i < channel_num; i++) {
  70.         adc_pattern[i].atten = ADC_ATTEN;
  71.         adc_pattern[i].channel = channel[i] & 0x7;
  72.         adc_pattern[i].unit = ADC_UNIT;
  73.         adc_pattern[i].bit_width = ADC_BIT_WIDTH;
  74.  
  75.         ESP_LOGI(TAG, "adc_pattern[%d].atten is :%"PRIx8, i, adc_pattern[i].atten);
  76.         ESP_LOGI(TAG, "adc_pattern[%d].channel is :%"PRIx8, i, adc_pattern[i].channel);
  77.         ESP_LOGI(TAG, "adc_pattern[%d].unit is :%"PRIx8, i, adc_pattern[i].unit);
  78.     }
  79.     dig_cfg.adc_pattern = adc_pattern;
  80.     ESP_ERROR_CHECK(adc_continuous_config(handle_init, &dig_cfg));
  81.     ESP_LOGI(TAG, "ADC Reader Initialized");
  82.     handle = handle_init;
  83.  
  84. }
  85.  
  86. uint32_t adc_reader_read(void)
  87. {
  88.     esp_err_t ret;
  89.     uint32_t ret_num = 0;
  90.     uint8_t result[READ_LEN] = {0};
  91.     memset(result, 0xcc, READ_LEN);
  92.  
  93.     s_task_handle = xTaskGetCurrentTaskHandle();
  94.     adc_continuous_evt_cbs_t cbs = {
  95.         .on_conv_done = s_conv_done_cb,
  96.     };
  97.     ESP_ERROR_CHECK(adc_continuous_register_event_callbacks(handle, &cbs, NULL));
  98.     ESP_LOGI(TAG, "Starting ADC conversion");
  99.     ESP_ERROR_CHECK(adc_continuous_start(handle));
  100.     ESP_LOGI(TAG, "ADC started");
  101.  
  102.     ulTaskNotifyTake(pdTRUE, portMAX_DELAY);
  103.     ESP_LOGI(TAG, "ulTaskNotify");  
  104.     char unit[] = ADC_UNIT_STR(ADC_UNIT);
  105.     ret = adc_continuous_read(handle, result, READ_LEN, &ret_num, 0);
  106.     ESP_LOGI(TAG, "read_data");
  107.     if (ret == ESP_OK) {
  108.         ESP_LOGI("TASK", "ret is %x, ret_num is %"PRIu32" bytes", ret, ret_num);
  109.         for (int i = 0; i < ret_num; i += SOC_ADC_DIGI_RESULT_BYTES) {
  110.                 adc_digi_output_data_t *p = (void*)&result[i];
  111.                 uint32_t chan_num = ADC_GET_CHANNEL(p);
  112.                 uint32_t data = ADC_GET_DATA(p);
  113.                 /* Check the channel number validation, the data is invalid if the channel num exceed the maximum channel */
  114.                 if (chan_num < SOC_ADC_CHANNEL_NUM(ADC_UNIT)) {
  115.                     //ESP_LOGI(TAG, "Unit: %s, Channel: %"PRIu32", Value: %"PRIx32, unit, chan_num, data);
  116.                     return data;
  117.                 } else {
  118.                     //ESP_LOGW(TAG, "Invalid data [%s_%"PRIu32"_%"PRIx32"]", unit, chan_num, data);
  119.                 }
  120.                 }
  121.                 /**
  122.                  * Because printing is slow, so every time you call `ulTaskNotifyTake`, it will immediately return.
  123.                  * To avoid a task watchdog timeout, add a delay here. When you replace the way you process the data,
  124.                  * usually you don't need this delay (as this task will block for a while).
  125.                  */
  126.                 vTaskDelay(1);
  127.             } else if (ret == ESP_ERR_TIMEOUT) {
  128.                 //We try to read `READ_LEN` until API returns timeout, which means there's no available data
  129.                 return 0;
  130.             }
  131.     return 0;
  132.     //ESP_ERROR_CHECK(adc_continuous_stop(handle));
  133.     //ESP_ERROR_CHECK(adc_continuous_deinit(handle));
  134. }
My code compiles and runs, but I encounter an abort() exception. I've reviewed the code and ADC configurations, but haven't identified the issue. I'm also attaching the exception backtrace for further reference.
  1. V (1689) intr_alloc: esp_intr_alloc_intrstatus (cpu 0): checking args
  2. V (1689) intr_alloc: esp_intr_alloc_intrstatus (cpu 0): Args okay. Resulting flags 0x40E
  3. D (1699) intr_alloc: Connected src 32 to int 17 (cpu 0)
  4. I (1699) ADC_READ: adc_pattern[0].atten is :0
  5. I (1709) ADC_READ: adc_pattern[0].channel is :0
  6. I (1709) ADC_READ: adc_pattern[0].unit is :0
  7. I (1719) gpio: GPIO[36]| InputEn: 0| OutputEn: 0| OpenDrain: 0| Pullup: 0| Pulldown: 0| Intr:0
  8. I (1729) ADC_READ: ADC Reader Initialized
  9. I (1729) ADC_READ: Starting ADC conversion
  10.  
  11. abort() was called at PC 0x40082cc7 on core 0
  12.  
  13.  
  14. Backtrace: 0x40081852:0x3ffb07e0 0x40086781:0x3ffb0800 0x4008bc76:0x3ffb0820 0x40082cc7:0x3ffb0890 0x40082e05:0x3ffb08c0 0x40082e7e:0x3ffb08e0 0x400e174a:0x3ffb0910 0x400e48b9:0x3ffb0c30 0x400ec0f9:0x3ffb0c60 0x4008bb29:0x3ffb0c90 0x40083295:0x3ffb0ce0 0x400846c9:0x3ffb0d10 0x40084720:0x3ffb0d50 0x40082ab9:0x3ffb0d70 0x4008489b:0x3ffb53a0 0x400d230f:0x3ffb53c0 0x4008780e:0x3ffb53e0 0x40088d61:0x3ffb5400
  15.  
  16.  
  17.  
  18.  
  19. ELF file SHA256: dc14c757f9a86e5f
  20.  
  21. Rebooting...
  22. ets Jul 29 2019 12:21:46
I'm usinig the ESP32 WROOVER-E and the last esp-idf version. I would greatly appreciate any advice or insights from the community. If anyone has experienced a similar issue with ADC operations or has recommendations for troubleshooting, your input would be invaluable.

I appreciate any help or guidance you can provide!
Thanks :)

ESP_Sprite
Posts: 9708
Joined: Thu Nov 26, 2015 4:08 am

Re: Issue with ESP-ADC Continuous Conversion - Abort() Exception

Postby ESP_Sprite » Mon Dec 04, 2023 1:38 am

Can you decode that backtrace? In esp-idf, the easiest way is to use 'idf.py monitor' as your serial terminal, it'll automatically decode it.

temuko
Posts: 8
Joined: Sun Oct 15, 2023 10:55 am
Location: Europe, Spain

Re: Issue with ESP-ADC Continuous Conversion - Abort() Exception

Postby temuko » Wed Dec 06, 2023 1:00 pm

Thank you. This is what appears with the decoded backtrace:

Code: Select all

Backtrace: 0x4008182a:0x3ffb07e0 0x40086709:0x3ffb0800 0x4008bbfe:0x3ffb0820 0x40082c9f:0x3ffb0890 0x40082ddd:0x3ffb08c0 0x40082e56:0x3ffb08e0 0x400ddb7a:0x3ffb0910 0x400e0ce9:0x3ffb0c30 0x400e8529:0x3ffb0c60 0x4008bab1:0x3ffb0c90 0x40083271:0x3ffb0ce0 0x40084651:0x3ffb0d10 0x400846a8:0x3ffb0d50 0x40082a91:0x3ffb0d70 0x40084823:0x3ffb52c0 0x400d21ab:0x3ffb52e0 0x40087796:0x3ffb5300 0x40088ce9:0x3ffb5320
0x4008182a: panic_abort at /home/xae/esp/esp-idf/components/esp_system/panic.c:452

0x40086709: esp_system_abort at /home/xae/esp/esp-idf/components/esp_system/port/esp_system_chip.c:84

0x4008bbfe: abort at /home/xae/esp/esp-idf/components/newlib/abort.c:38

0x40082c9f: lock_acquire_generic at /home/xae/esp/esp-idf/components/newlib/locks.c:130

0x40082ddd: _lock_acquire_recursive at /home/xae/esp/esp-idf/components/newlib/locks.c:158

0x40082e56: __retarget_lock_acquire_recursive at /home/xae/esp/esp-idf/components/newlib/locks.c:314

0x400ddb7a: _vfprintf_r at /builds/idf/crosstool-NG/.build/xtensa-esp32-elf/src/newlib/newlib/libc/stdio/vfprintf.c:849 (discriminator 2)

0x400e0ce9: vprintf at /builds/idf/crosstool-NG/.build/xtensa-esp32-elf/src/newlib/newlib/libc/stdio/vprintf.c:34 (discriminator 5)

0x400e8529: esp_log_writev at /home/xae/esp/esp-idf/components/log/log.c:200

0x4008bab1: esp_log_write at /home/xae/esp/esp-idf/components/log/log.c:210

0x40083271: s_conv_done_cb at /home/xae/tfg_codes/ecg_source_code/main/adc_reader.c:43 (discriminator 13)

0x40084651: s_adc_dma_intr at /home/xae/esp/esp-idf/components/esp_adc/adc_continuous.c:310

0x400846a8: adc_dma_intr_handler at /home/xae/esp/esp-idf/components/esp_adc/adc_continuous.c:278

0x40082a91: _xt_lowint1 at /home/xae/esp/esp-idf/components/freertos/FreeRTOS-Kernel/portable/xtensa/xtensa_vectors.S:1236

0x40084823: xt_utils_wait_for_intr at /home/xae/esp/esp-idf/components/xtensa/include/xt_utils.h:81
 (inlined by) esp_cpu_wait_for_intr at /home/xae/esp/esp-idf/components/esp_hw_support/cpu.c:111

0x400d21ab: esp_vApplicationIdleHook at /home/xae/esp/esp-idf/components/esp_system/freertos_hooks.c:59

0x40087796: prvIdleTask at /home/xae/esp/esp-idf/components/freertos/FreeRTOS-Kernel/tasks.c:4327 (discriminator 1)

0x40088ce9: vPortTaskWrapper at /home/xae/esp/esp-idf/components/freertos/FreeRTOS-Kernel/portable/xtensa/port.c:162





ELF file SHA256: b3e6b852ac5caad2

ESP_Sprite
Posts: 9708
Joined: Thu Nov 26, 2015 4:08 am

Re: Issue with ESP-ADC Continuous Conversion - Abort() Exception

Postby ESP_Sprite » Thu Dec 07, 2023 1:04 am

Thank you. You seem to be doing some kind of log command in s_conv_done_cb. That callback is done in interrupt context, and there are not that many API calls that are allowed to be done in such a context; calling the standard log functions (or anything that uses the printf family) is not one of them. That is causing the abort. You can try to use ESP_EARLY_LOG() instead; that is allowed to be called form interrupt context.

temuko
Posts: 8
Joined: Sun Oct 15, 2023 10:55 am
Location: Europe, Spain

Re: Issue with ESP-ADC Continuous Conversion - Abort() Exception

Postby temuko » Fri Dec 08, 2023 9:56 pm

Thank you!

I've resolved the issue. I encountered additional problems because I wasn't stopping the ADC after the first reading, which led to errors afterward. The ESP_LOGI was another issue when I attempted to debug the initial one.

Appreciate the assistance!

Who is online

Users browsing this forum: Google [Bot], Majestic-12 [Bot] and 131 guests