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.
Code: Untitled.c Select all
#include <string.h>
#include <stdio.h>
#include "esp_log.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/semphr.h"
#include "esp_adc/adc_continuous.h"
#include "adc_reader.h" // Debes definir adc_reader.h con las estructuras y funciones necesarias.
#include "sdkconfig.h"
#define ADC_UNIT ADC_UNIT_1
#define _ADC_UNIT_STR(unit) #unit
#define ADC_UNIT_STR(unit) _ADC_UNIT_STR(unit)
#define ADC_CONV_MODE ADC_CONV_SINGLE_UNIT_1
#define ADC_ATTEN ADC_ATTEN_DB_0
#define ADC_BIT_WIDTH SOC_ADC_DIGI_MAX_BITWIDTH
#define ADC_OUTPUT_TYPE ADC_DIGI_OUTPUT_FORMAT_TYPE1
#define ADC_GET_CHANNEL(p_data) ((p_data)->type1.channel)
#define ADC_GET_DATA(p_data) ((p_data)->type1.data)
// prueba git
#define READ_LEN 256
static adc_channel_t channel[1] = {ADC_CHANNEL_0};
static const char *TAG = "ADC_READ";
static TaskHandle_t s_task_handle;
static adc_continuous_handle_t handle = NULL;
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;
// Notify that ADC continuous driver has done enough number of conversions
if (s_task_handle != NULL) {
vTaskNotifyGiveFromISR(s_task_handle, &mustYield);
}
ESP_LOGI(TAG, "ADC Conversion done");
return (mustYield == pdTRUE);
}
void adc_reader_init(void)
{
adc_continuous_handle_t handle_init = NULL;
uint8_t channel_num = 1;
adc_continuous_handle_cfg_t adc_config = {
.max_store_buf_size = 1024,
.conv_frame_size = READ_LEN,
};
ESP_ERROR_CHECK(adc_continuous_new_handle(&adc_config, &handle_init));
adc_continuous_config_t dig_cfg = {
.sample_freq_hz = 20*1000,
.conv_mode = ADC_CONV_MODE,
.format = ADC_OUTPUT_TYPE,
};
adc_digi_pattern_config_t adc_pattern[SOC_ADC_PATT_LEN_MAX] = {0};
dig_cfg.pattern_num = channel_num;
for (int i = 0; i < channel_num; i++) {
adc_pattern[i].atten = ADC_ATTEN;
adc_pattern[i].channel = channel[i] & 0x7;
adc_pattern[i].unit = ADC_UNIT;
adc_pattern[i].bit_width = ADC_BIT_WIDTH;
ESP_LOGI(TAG, "adc_pattern[%d].atten is :%"PRIx8, i, adc_pattern[i].atten);
ESP_LOGI(TAG, "adc_pattern[%d].channel is :%"PRIx8, i, adc_pattern[i].channel);
ESP_LOGI(TAG, "adc_pattern[%d].unit is :%"PRIx8, i, adc_pattern[i].unit);
}
dig_cfg.adc_pattern = adc_pattern;
ESP_ERROR_CHECK(adc_continuous_config(handle_init, &dig_cfg));
ESP_LOGI(TAG, "ADC Reader Initialized");
handle = handle_init;
}
uint32_t adc_reader_read(void)
{
esp_err_t ret;
uint32_t ret_num = 0;
uint8_t result[READ_LEN] = {0};
memset(result, 0xcc, READ_LEN);
s_task_handle = xTaskGetCurrentTaskHandle();
adc_continuous_evt_cbs_t cbs = {
.on_conv_done = s_conv_done_cb,
};
ESP_ERROR_CHECK(adc_continuous_register_event_callbacks(handle, &cbs, NULL));
ESP_LOGI(TAG, "Starting ADC conversion");
ESP_ERROR_CHECK(adc_continuous_start(handle));
ESP_LOGI(TAG, "ADC started");
ulTaskNotifyTake(pdTRUE, portMAX_DELAY);
ESP_LOGI(TAG, "ulTaskNotify");
char unit[] = ADC_UNIT_STR(ADC_UNIT);
ret = adc_continuous_read(handle, result, READ_LEN, &ret_num, 0);
ESP_LOGI(TAG, "read_data");
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 = (void*)&result[i];
uint32_t chan_num = ADC_GET_CHANNEL(p);
uint32_t data = ADC_GET_DATA(p);
/* Check the channel number validation, the data is invalid if the channel num exceed the maximum channel */
if (chan_num < SOC_ADC_CHANNEL_NUM(ADC_UNIT)) {
//ESP_LOGI(TAG, "Unit: %s, Channel: %"PRIu32", Value: %"PRIx32, unit, chan_num, data);
return data;
} else {
//ESP_LOGW(TAG, "Invalid data [%s_%"PRIu32"_%"PRIx32"]", unit, chan_num, data);
}
}
/**
* Because printing is slow, so every time you call `ulTaskNotifyTake`, it will immediately return.
* To avoid a task watchdog timeout, add a delay here. When you replace the way you process the data,
* usually you don't need this delay (as this task will block for a while).
*/
vTaskDelay(1);
} else if (ret == ESP_ERR_TIMEOUT) {
//We try to read `READ_LEN` until API returns timeout, which means there's no available data
return 0;
}
return 0;
//ESP_ERROR_CHECK(adc_continuous_stop(handle));
//ESP_ERROR_CHECK(adc_continuous_deinit(handle));
}Code: Untitled.txt Select all
V (1689) intr_alloc: esp_intr_alloc_intrstatus (cpu 0): checking args
V (1689) intr_alloc: esp_intr_alloc_intrstatus (cpu 0): Args okay. Resulting flags 0x40E
D (1699) intr_alloc: Connected src 32 to int 17 (cpu 0)
I (1699) ADC_READ: adc_pattern[0].atten is :0
I (1709) ADC_READ: adc_pattern[0].channel is :0
I (1709) ADC_READ: adc_pattern[0].unit is :0
I (1719) gpio: GPIO[36]| InputEn: 0| OutputEn: 0| OpenDrain: 0| Pullup: 0| Pulldown: 0| Intr:0
I (1729) ADC_READ: ADC Reader Initialized
I (1729) ADC_READ: Starting ADC conversion
abort() was called at PC 0x40082cc7 on core 0
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
ELF file SHA256: dc14c757f9a86e5f
Rebooting...
ets Jul 29 2019 12:21:46I appreciate any help or guidance you can provide!
Thanks
