ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

ESP32 / ESP32-S2 ADC 两点校准组件 adc_tp_calibration 应用指南(esp-iot-solution)

ESP32 / ESP32-S2 ADC 两点校准组件 adc_tp_calibration 应用指南(esp-iot-solution) ESP32 / ESP32-S2 ADC 两点校准组件 adc_tp_calibration 应用指南esp-iot-solution【免费下载链接】esp-iot-solutionEspressif IoT Library. IoT Device Drivers, Documentations and Solutions.项目地址: https://gitcode.com/GitHub_Trending/es/esp-iot-solution导读本文围绕 esp-iot-solution 仓库中的adc_tp_calibration组件展开讲解如何在应用层为 ESP32 与 ESP32-S2 实现 ADC 两点校准从而在不修改 eFuse 的前提下获得更高一致性、可跨衰减档位复用的 ADC 电压换算方案。读完本文你将掌握两种芯片两点校准的数学原理、衰减系数表的使用方法、组件 API 的完整调用流程以及如何借助配套示例在真实硬件上采集并验证校准参数。重要前提当前 ADC 两点校准方案仅适用于ESP32 与 ESP32-S2两款芯片见 idf_component.yml 的targets声明且依赖 ESP-IDF 4.4。一、为什么需要两点校准从 eFuse 出厂校准说起1.1 ESP32 的出厂默认方案与一致性瓶颈ESP32 出厂时ADC 默认采用参考电压法进行校准芯片内部将一段参考电压与 ADC 采样结果对比通过 eFuse 中烧录的参考电压值来推导输入电压。该方案无需外部校准即可工作但不同芯片之间由于工艺偏差同一电压下测量得到的结果可能存在差异。如果用户希望进一步提高 ADC 测量结果的一致性可以将 eFuse 中的校准方案更改为两点校准方法分别在两个已知电压下采集 ADC 原始数据用两点确定一条线性校正曲线从而消除芯片间增益与偏置差异。1.2 ESP32-S2 的两种出厂方案对于 ESP32-S2出厂默认采用的是两点校准法方法一但该方法并未考虑不同 ADC 衰减attenuation下的数据进行校准。衰减档位不同时ADC 的增益特性会发生变化方法一无法覆盖这些差异。如果用户希望使用不同衰减下的数据进行校准可以将 eFuse 中的校准方案更改为两点校准方法方法二——该方法分别在四种衰减档位下各取一个校准点精度更高、覆盖更全面。1.3 eFuse 修改的不可逆风险无论是 ESP32 还是 ESP32-S2上述两种出厂方案的切换都需要用户使用espefuse 工具修改 eFuse 中的校准方案并输入相应校准数据。这个操作必须格外谨慎原因在于eFuse 数据具有不可逆性一旦烧录了错误的校准数据将无法再次修改或恢复烧录错误可能导致 ADC 校准数据永久错误造成不必要的损失。正是为了避免上述 eFuse 写入风险adc_tp_calibration组件提供了一种在应用层完成两点校准的替代方案具备以下特点支持在应用层填入校准参数用户可自行将校准数据存储到 NVS、SD 卡等存储介质中支持 ESP32 使用两点校准方案、ESP32-S2 使用两点校准方案方法二且不影响现有 ESP-IDF 自带的校准方案两者可并行共存。二、ESP32 两点校准原理与数学推导2.1 校准点的选取ESP32 两点校准需要分别向ADC1 通道与ADC2 通道施加稳定的150 mV与850 mV电压然后使用 ADC 获取原始数据接口读取当前电压下的稳定原始数据Input VoltageADC1 (ATTEN0)ADC2 (ATTEN0)150 mVA1A2850 mVB1B2注意获取 150 mV 与 850 mV 下的 ADC 原始数据时需要配置 ADC 驱动的衰减为ADC_ATTEN_DB_0。两组原始数据A 与 B只在此衰减档位下采集但最终换算公式可以通过衰减系数外推到其他档位。2.2 线性校正公式ESP32 ADC 两点校准的计算公式为y (coeff_a * x coeff_around) / coeff_scale coeff_b其中各项含义如下coeff_a增益系数即(850-150) * atten_scale[atten] (B-A)/2] / (B-A)coeff_b偏置系数即850 - [(850-150)*B (B-A)/2] / (B-A) atten_offset[atten]coeff_scale固定缩放因子65536coeff_around四舍五入项取coeff_scale / 2即 32768。公式中(B-A)/2与coeff_around的作用是引入四舍五入避免整数除法带来的截断误差。2.3 衰减系数表ADC1 / ADC2不同衰减档位对应的atten_scale与atten_offset在源码中已固化为查找表见 adc_tp_calibration.c组件初始化时会依据adc_unit自动选择 ADC1 或 ADC2 对应的一组系数ADC1系数ATTEN0ATTEN_2_5ATTEN_6ATTEN_12atten_scale6550486975120389224310atten_offset012754ADC2系数ATTEN0ATTEN_2_5ATTEN_6ATTEN_12atten_scale6546786861120416224708atten_offset092666从源码结构看这两组表是 ESP32 硬件特性的标定结果atten_scale反映不同衰减下 ADC 增益的变化atten_offset用于补偿衰减带来的零偏。也就是说虽然原始数据只在ATTEN0下采集但通过这两个系数即可换算到其他衰减档位下的电压值这正是“两点校准 系数外推”方案的核心价值。三、ESP32-S2 两点校准方法二原理3.1 校准点的选取ESP32-S2 两点校准方法二需要在不同衰减档位下分别采集校准数据向 ADC1 与 ADC2 通道依次施加600 mV、800 mV、1000 mV 与 2000 mV的稳定电压每个电压点对应一个衰减档位。以 ADC1 为例Input VoltageATTENADC1 Raw Value600 mVATTEN_0High[ATTEN_0]800 mVATTEN_2_5High[ATTEN_2_5]1000 mVATTEN_6High[ATTEN_6]2000 mVATTEN_12High[ATTEN_12]注意方法二的校准点选取需要分别在对应的衰减与标定电压下获取稳定的 ADC 原始数据以确保校准的准确性。其中High[atten]用于存储不同衰减与标定电压下的 ADC 原始数据。3.2 线性校正公式ESP32-S2 方法二的计算公式为y (x * coeff_a / (coeff_ascaling / coeff_bscaling) coeff_b) / coeff_bscaling其中coeff_acoeff_ascaling * v_high[atten] / High[atten]coeff_b固定为0coeff_ascaling65536coeff_bscaling1024。每个衰减档位的标定电压v_high为衰减档位ATTEN0ATTEN_2_5ATTEN_6ATTEN_12v_high60080010002000对照 adc_tp_calibration.c 的源码实现v_high[] {600, 800, 1000, 2000}与coeff_a_scaling 65536、coeff_b_scaling 1024一一对应。由于每个衰减档位都在其满量程附近的标定点上单独计算coeff_a方法二在不同衰减下的精度比 ESP32 的“单点采样 系数外推”更高。四、组件 API 参考adc_tp_calibration组件的公开接口定义在 include/adc_tp_calibration.h共包含一个配置结构体与三个函数。4.1 校准配置结构体adc_tp_cali_config_t该结构体保存校准所需的原始 ADC 值不同芯片字段不同通过CONFIG_IDF_TARGET_ESP32/CONFIG_IDF_TARGET_ESP32S2宏区分字段ESP32ESP32-S2adc_unitADC 单元ADC_UNIT_1或ADC_UNIT_2同左adc_raw_value_150mv_atten0150 mV、ATTEN0 下的原始值—adc_raw_value_850mv_atten0850 mV、ATTEN0 下的原始值—adc_raw_value_600mv_atten0—600 mV、ATTEN0 下的原始值adc_raw_value_800mv_atten2_5—800 mV、ATTEN_2_5 下的原始值adc_raw_value_1000mv_atten6—1000 mV、ATTEN_6 下的原始值adc_raw_value_2000mv_atten12—2000 mV、ATTEN_12 下的原始值4.2 核心函数adc_tp_cali_handle_t adc_tp_cali_create(adc_tp_cali_config_t *config, adc_atten_t atten)根据配置与目标衰减档位创建校准句柄。内部会校验config非空、adc_unit合法并依据芯片类型预计算coeff_a、coeff_b失败时返回NULL。esp_err_t adc_tp_cali_delete(adc_tp_cali_handle_t *adc_tp_cali_handle)释放校准句柄内存句柄置空句柄为空时直接返回ESP_OK。esp_err_t adc_tp_cali_raw_to_voltage(adc_tp_cali_handle_t adc_tp_cali_handle, int raw_value, int *voltage)将 ADC 原始值换算为**毫伏mV**电压结果写入voltage参数为空指针时返回ESP_ERR_INVALID_ARG。从实现看adc_tp_cali_raw_to_voltage的核心计算逻辑与第二、三节的数学公式完全一致见 adc_tp_calibration.c且整个过程为纯整数运算不依赖浮点适合在资源受限的嵌入式环境运行。五、在项目中集成与使用组件5.1 添加组件依赖推荐使用 ESP-IDF 组件管理器添加依赖在 CMake 构建阶段会自动下载idf.py add-dependency espressif/adc_tp_calibration*也可以手动创建idf_component.yml声明依赖可参考组件自身的 idf_component.yml。组件要求idf 4.4并依赖cmake_utilities。5.2 使用步骤与完整代码示例组件 README见 README.md给出了四个标准步骤。务必注意校准方案与 ADC 衰减设置密切相关组件创建时传入的atten必须与 ADC 驱动中配置的衰减档位保持一致。// Step1: 初始化校准参数 #if CONFIG_IDF_TARGET_ESP32 adc_tp_cali_config_t tp_cali_config { .adc_unit ADC_UNIT_1, .adc_raw_value_150mv_atten0 323, .adc_raw_value_850mv_atten0 3300, }; #elif CONFIG_IDF_TARGET_ESP32S2 adc_tp_cali_config_t tp_cali_config { .adc_unit ADC_UNIT_1, .adc_raw_value_600mv_atten0 5895, .adc_raw_value_800mv_atten2_5 5786, .adc_raw_value_1000mv_atten6 5820, .adc_raw_value_2000mv_atten12 6287, }; #endif // Step2: 初始化两点 ADC 校准atten 必须与 ADC 驱动一致 adc_tp_cali_handle_t adc_tp_cali adc_tp_cali_create(tp_cali_config, ADC_ATTEN_DB_0); // Step3: 初始化 ADC 驱动并获取原始 ADC 数据此处省略具体驱动代码 // ... // Step4: 校准 ADC 数据raw_value 来自 ADC 驱动voltage 单位为 mV adc_tp_cali_raw_to_voltage(adc_tp_cali, raw_value, voltage);重要提醒示例中的校准数据323/3300、5895/5786/5820/6287仅用于演示不是通用值。真实数据必须由用户在硬件上按照文档描述的校准流程手动采集得到具体采集方法见第六节并建议将标定结果持久化存储到 NVS、SD 卡等介质避免每次上电重复校准。5.3 测试用例对 API 的验证组件自带单元测试见 test_apps/main/test_adc_tp_calibration.c以 Unity 框架编写为 ESP32 与 ESP32-S2 各提供一个test_adc_tp_cali_raw_to_voltage用例测试中同时兼容 IDF 5.0 的adc1_config_width/adc1_config_channel_atten旧接口与 IDF 5.0 的adc_oneshot新接口每次创建校准句柄后连续采样 100 次TEST_SAMPLE_COUNT逐次调用adc_tp_cali_raw_to_voltage打印原始值与电压值通过setUp/tearDown对比MALLOC_CAP_8BIT/MALLOC_CAP_32BIT堆水位检测内存泄漏保证adc_tp_cali_create/adc_tp_cali_delete配对使用无泄漏。该测试同时印证了组件“不影响 ESP-IDF 自带校准方案”的设计测试运行过程中 ESP-IDF 的标准校准如 Line Fitting仍正常工作两者互不干扰。六、实战在真实硬件上采集校准参数配套示例详解校准参数必须来自真实硬件测量。仓库在 examples/utilities/adc_tp_calibration 提供了一整套标定示例可自动引导用户完成参数采集并验证两点校准效果。6.1 准备工作一块ESP32 或 ESP32-S2开发板一台可调电源校准以可调电源输出的稳定电压为基准示例默认对ADC1 与 ADC2 同时校准——如果你的项目只使用其中一个单元可以只校准对应单元采集校准数据时建议在 ADC 引脚外接100 nF 滤波电容并配合软件滤波以获得稳定的 ADC 读数见 README.md。6.2 工程配置menuconfig运行idf.py menuconfig进入Example Configuration菜单配置引脚与采样参数详见 Kconfig.projbuildESP32 芯片ADC1 通道 0~7ADC2 通道 0~9ESP32 ADC Configuration --- (6) ADC1 Channel Number (9) ADC2 Channel NumberESP32-S2 芯片ADC1/ADC2 通道均为 0~9在ESP32S2 ADC Configuration菜单中配置相同的两项。通道选择没有限制任意合法通道均可。通用采样参数Example Configuration --- (50) Number of times to read ADC // 每个电压点的读取次数范围 20~100 (30) ADC Error Tolerance Range (mV) // 电压误差容忍范围范围 1~30Number of times to read ADC为避免校准时电压波动影响数据质量建议配置较大的读取次数。示例会把所有 ADC 读数排序后取中间 10 个值的平均值见 示例主程序 的calculate_middle_average以剔除离群值ADC Error Tolerance Range示例会额外使用 IDF 默认校准方案验证输入电压的有效性防止用户在错误电压下采集数据。由于默认校准本身存在一定偏差需要配置该容差范围来判定当前电压是否达标。6.3 构建、烧录与运行idf.py build flash monitormonitor中的PORT请替换为开发板实际串口号按Ctrl-]退出串口监视器。运行过程中示例会按日志提示逐步施加电压完成当前电压点的校准后系统自动切换到下一个校准点并打印所需电压直至全部电压点采集完毕。例如 ESP32 下日志会依次提示I (295) ADC_TP_CALIBRATION: Memory allocated successfully. Please input 150mV to ADC1 channel 6 I (305) ADC_TP_CALIBRATION: ADC1 channel 6 Measuring 150mV - Progress: 1/50, raw: 340, voltage: 155 mV ...校准完成后日志输出可直接用于填充配置结构体的参数此处数据为该示例硬件实测非通用值I (33065) ADC_TP_CALIBRATION: ESP32 ADC TP Calibration Success, adc1_raw_value_150mv_atten0: 335, adc1_raw_value_850mv_atten0: 3312 I (33075) ADC_TP_CALIBRATION: ESP32 ADC TP Calibration Success, adc2_raw_value_150mv_atten0: 480, adc2_raw_value_850mv_atten0: 3451随后示例进入验证循环同时用 IDF 默认校准与两点校准读取电压可观察到两点校准后 ADC1 与 ADC2 的一致性良好I (33095) ADC_TP_CALIBRATION: ADC1 channel 6 with 0dB attenuation raw: 3311, voltage: 849 mV I (33205) ADC_TP_CALIBRATION: ADC2 channel 9 with 0dB attenuation raw: 3454, voltage: 850 mV I (33505) ADC_TP_CALIBRATION: ADC1 channel 6 with 0dB attenuation raw: 3312, voltage: 849 mV I (33605) ADC_TP_CALIBRATION: ADC2 channel 9 with 0dB attenuation raw: 3453, voltage: 850 mV6.4 示例内部实现要点adc_driver.c 封装了基于adc_oneshot的驱动与 IDF 标准校准优先 Curve Fitting其次 Line Fitting用于在采集校准点时校验输入电压是否在容差范围内采集阶段通过adc_driver_read_calibrated_value同时拿到原始值与 IDF 校准电压只有abs(cali - target_voltage) CONFIG_ADC_ERROR_TOLERANCE_RANGE的样本才被计入有效数据见 示例主程序最后为 ADC1、ADC2 分别构造adc_tp_cali_config_t、调用adc_tp_cali_create创建校准句柄并在循环中与两点校准电压交替输出对比直观展示校准效果。七、使用注意事项与最佳实践衰减档位必须一致adc_tp_cali_create传入的atten必须与 ADC 驱动配置的衰减一致否则换算结果会使用错误的系数表产生系统性偏差。校准数据不可跨设备复用两点校准参数与具体芯片相关必须在目标设备上重新采集数据可存入 NVS、SD 卡等介质但更换芯片后需要重新标定。采集数据时保证电压稳定建议外接 100 nF 滤波电容并在采集时进行多次采样与软件滤波如示例中的“排序取中段均值”以提高校准点原始数据的可信度。区分芯片与方案ESP32 使用“ATTEN0 两点采样 系数外推”方案ESP32-S2 使用方法二必须在每个衰减档位对应的标定电压下分别采样两者校准点数与配置结构体字段均不同。无需触碰 eFuse应用层校准不会修改 eFuse因此不存在不可逆烧录风险同时与 ESP-IDF 自带校准并行共存可在需要时随时切换或对比。资源开销校准句柄仅保存少量整型系数coeff_a、coeff_b等运行时换算为纯整数运算测试用例也验证了创建/删除过程无内存泄漏可放心在长期运行的产品中使用。结语adc_tp_calibration组件为 ESP32 与 ESP32-S2 提供了一条零 eFuse 风险、精度可控、可持久化存储的 ADC 两点校准路径ESP32 侧通过 150 mV/850 mV 两点采样配合衰减系数表实现跨档位外推ESP32-S2 侧通过方法二在每个衰减档位独立标定两者都能显著提升 ADC 测量一致性。结合仓库自带的标定示例与单元测试开发者可以在真实硬件上快速完成校准参数采集、验证与固化将其无缝集成到自己的测量应用中。延伸阅读组件源码与头文件见 adc_tp_calibration.c 与 adc_tp_calibration.h完整标定示例见 examples/utilities/adc_tp_calibration自动化测试见 test_adc_tp_calibration.c。【免费下载链接】esp-iot-solutionEspressif IoT Library. IoT Device Drivers, Documentations and Solutions.项目地址: https://gitcode.com/GitHub_Trending/es/esp-iot-solution创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表