乐鑫技术交流
直播中

贾虎世

8年用户 1802经验值
私信 关注
[问答]

请问如何才能实现ESP32的2MSPS采样?

板子:ESP-WROOM-32
供电模式与烧录方式:USB
编译软件:VS CODE

本人因为项目需要,接触ESP32已经有2个月了,但是对ESP32的ADC仍然有一些疑问 以及 想反馈一些bug

问题一:
ESP32真的能实现 真;2MSPS采样吗?
Code: Select all
IDFV4.4.2的dma_Read
、Code: Select all
F:ESP-IDFEspressifframeworksesp-idf-v4.4.2componentsdrivertestadc_dma_test下的test_esp32.c
、Code: Select all
F:ESP32idfesp-idf_5esp-idfcomponentsdrivertest_appsi2s_test_appslegacy_i2s_adc_dac
与 Code: Select all
IDFV5的continous_read_main
四个工程我都尝试过了,我的结论是ESP32最多只能支持250KSPS采样。

我曾在乐鑫中文论坛找到过一篇关于实现2MSPS的实例,但其IDF已落后,多数API已无法在IDF4、IDF5中实现。链接如下:
viewtopic.php?f=25&t=8335&sid=ef3ed33a1 ... f3cb8dcc52

说说我为什么得出ESP32只支持250KSPS的结论。
四个工程,在程序的正确性上来说(编译能通过)都能将采样率提高到2MSPS,但实际采样得到的数据却存在重复出现的情况。
例如我将采样率设置为1MSPS,通过测试,采样率的确在1MSPS附近,也能得到近1M个数据,但这些数据中,会有相邻四个数据相同,这不就意味着我得到的数据真实性必须除以4吗?1MSPS/4 = 250KSPS。以下有2个IDF版本得到的相同结果:
(我没找到这个论坛发图的地方,具体的图片可以看我GITHUB发的贴子https://github.com/espressif/esp-idf/issues/10248

且多开通道重复出现的情况也不会消除,并不是跟我曾经想的一样,八个通道分别250KSPS,所以加起来2MSPS.在我看来,ESP32采用I2S去采样ADC,但ADC采样率并没有这么快(在250KSPS附近),导致ESP32多次获取到相同的值(因为ADC未来得及转换)

问题二
ESP32单通道采样时,IDF4.4.2中ad采样数据前后顺序错位,这个问题在我前面发的中文论坛链接里也有提到,原话:
我怀疑单通道AD采样值被i2s模块切成左右声道,输出时前后顺序错位,i2s改为单声道可能就OK了。
这是之前我使用ESP32采样的正弦波波形图,我一度怀疑这是ESP32 ADC内部噪声所致。

根据论坛中的建议,我调换了一些数据的前后顺序,下方是更改后的波形图:
(我没找到这个论坛发图的地方,具体的图片可以看我GITHUB发的贴子https://github.com/espressif/esp-idf/issues/10248

IDF5我还未进行测试,不知是否改善。

结论
我已经在ESP32的ADC采样率上花费了太多时间,但始终无法在ESP32内部ADC高速采样上获得进展,因此发布了这篇帖子。希望碰到过类似问题的朋友给些建议。
如何才能实现ESP32的2MSPS采样。
                                                               

回帖(1)

张娟

2024-6-13 16:31:26
要实现ESP32的2MSPS(每秒200万个采样点)采样,您需要考虑以下几个方面:

1. 选择合适的ADC模块:ESP32有两个ADC模块,分别是ADC1和ADC2。ADC1主要用于测量内部信号,如电池电压、温度传感器等;ADC2主要用于测量外部信号,如模拟输入。对于高速采样,建议使用ADC2。

2. 配置ADC参数:在ESP-IDF中,您需要配置ADC的参数,如分辨率、采样率等。ESP32的ADC分辨率最高可达12位,但采样率会受到ADC转换时间和ESP32主频的限制。

3. 使用DMA(Direct Memory Access):为了实现高速采样,您可以使用DMA来加速数据传输。在ESP-IDF中,您可以使用`adc2_dma_mode_acquire()`和`adc2_dma_mode_release()`函数来启用和禁用DMA模式。

4. 编写采样代码:在您的项目中,您需要编写代码来实现ADC采样。以下是一个简单的示例,演示如何使用ESP-IDF实现ADC采样:

```c
#include "driver/adc.h"
#include "esp_adc_cal.h"

#define ADC_CHANNEL 0
#define ADC_ATTEN   ADC_ATTEN_DB_11
#define ADC_WIDTH   ADC_WIDTH_BIT_12

static esp_adc_cal_characteristics_t *adc_chars;
static const adc_channel_t channel = ADC_CHANNEL;
static const adc_atten_t atten = ADC_ATTEN;
static const adc_bits_width_t width = ADC_WIDTH;

void app_main()
{
    // 初始化ADC
    adc1_config_width(width);
    adc1_config_channel_atten(channel, atten);

    // 校准ADC
    adc_chars = calloc(1, sizeof(esp_adc_cal_characteristics_t));
    esp_adc_cal_value_t val_type = esp_adc_cal_characterize(ADC_UNIT_1, atten, width, 1100, 3300, adc_chars);

    // 开始采样
    while (1) {
        uint32_t adc_reading = adc1_get_raw((adc1_channel_t)channel);
        // 将原始ADC值转换为电压值
        uint32_t voltage = esp_adc_cal_raw_to_voltage(adc_reading, adc_chars);

        // 处理采样数据
        // ...

        vTaskDelay(pdMS_TO_TICKS(1)); // 调整采样间隔以实现2MSPS采样
    }
}
```

5. 优化代码:为了实现2MSPS采样,您可能需要优化您的代码,以减少每次采样之间的延迟。这可能包括减少循环、使用更高效的数据结构等。

6. 考虑硬件限制:ESP32的ADC采样率受到硬件限制,可能无法达到2MSPS。在实际应用中,您可能需要根据硬件性能和需求进行权衡。

总之,要实现ESP32的2MSPS采样,您需要选择合适的ADC模块,配置ADC参数,使用DMA加速数据传输,并编写高效的采样代码。同时,您还需要考虑硬件限制和实际应用需求。
举报

更多回帖

发帖
×
20
完善资料,
赚取积分