news 2026/4/22 1:57:29

避坑指南:在OpenHarmony上为ESP32配置ADC读取YL-69湿度,解决Wi-Fi占用问题

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
避坑指南:在OpenHarmony上为ESP32配置ADC读取YL-69湿度,解决Wi-Fi占用问题

ESP32与OpenHarmony实战:突破ADC2与Wi-Fi冲突的土壤湿度监测方案

当你在OpenHarmony系统上为ESP32配置YL-69土壤湿度传感器时,是否遇到过这样的报错信息:"ADC2 used by Wi-Fi"?这个看似简单的提示背后,隐藏着ESP32芯片架构设计上的一个重要特性。本文将带你深入理解ADC资源分配机制,并提供三种可落地的解决方案。

1. 问题根源:ESP32的ADC资源分配机制

ESP32芯片内置两个ADC模块(ADC1和ADC2),每个ADC有多个通道。但这两个ADC在设计上有着关键区别:

  • ADC1:8个通道(GPIO32-39),可自由使用
  • ADC2:10个通道(GPIO0,2,4,12-15,25-27),与Wi-Fi共用

当Wi-Fi功能启用时,系统会自动占用ADC2的所有通道。这就是为什么在原始代码中尝试使用ADC2_CHANNEL_2时会收到冲突提示。

// 问题代码示例 esp_err_t r = adc2_get_raw(ADC2_TEST_CHANNEL, ADC_WIDTH_12Bit, &read_raw); if (r == ESP_ERR_TIMEOUT) { printf("ADC2 used by Wi-Fi.\n"); // 这里会触发错误 }

2. 解决方案一:改用ADC1通道

最直接的解决方法是更换到ADC1通道。以下是具体实施步骤:

  1. 硬件调整:将YL-69传感器的输出线从GPIO2(ADC2_CHANNEL_2)改接到GPIO36(ADC1_CHANNEL_0)

  2. 代码修改

// 修改后的ADC初始化 void adc_Init() { adc1_config_width(ADC_WIDTH_BIT_12); adc1_config_channel_atten(ADC1_CHANNEL_0, ADC_ATTEN_DB_0); } // 读取数据 int read_soil_moisture() { return adc1_get_raw(ADC1_CHANNEL_0); }
  1. 注意事项
    • ADC1的输入电压范围:0-1.1V(当atten=0时)
    • GPIO36是仅输入引脚,不能用作输出
    • 建议增加电压分压电路保护ADC输入

3. 解决方案二:调整Wi-Fi初始化顺序

如果必须使用ADC2通道,可以通过控制初始化顺序来暂时规避冲突:

// 先初始化ADC2并读取数据 void read_before_wifi() { adc2_config_channel_atten(ADC2_CHANNEL_2, ADC_ATTEN_DB_0); int raw_value; adc2_get_raw(ADC2_CHANNEL_2, ADC_WIDTH_BIT_12, &raw_value); // 存储读数或立即处理 } // 然后在适当的时候再初始化Wi-Fi void init_wifi_later() { // Wi-Fi初始化代码 }

适用场景

  • 只需要开机时单次读取传感器值
  • 可以接受在Wi-Fi启用后无法继续读取ADC2

限制

  • 不能实现实时连续监测
  • Wi-Fi启用后仍会丢失ADC2功能

4. 解决方案三:软件模拟切换方案

对于需要同时使用Wi-Fi和ADC2的高级场景,可以采用时间分片技术:

  1. 设计思路

    • 创建两个独立任务:Wi-Fi任务和传感器任务
    • 使用信号量控制资源访问
    • 在读取传感器时临时关闭Wi-Fi
  2. 实现代码

#include "esp_wifi.h" SemaphoreHandle_t adc_mutex; void sensor_task(void *pvParameters) { while(1) { xSemaphoreTake(adc_mutex, portMAX_DELAY); // 临时禁用Wi-Fi esp_wifi_stop(); // 读取ADC2 int raw_val; adc2_get_raw(ADC2_CHANNEL_2, ADC_WIDTH_BIT_12, &raw_val); // 重启Wi-Fi esp_wifi_start(); xSemaphoreGive(adc_mutex); vTaskDelay(pdMS_TO_TICKS(1000)); // 1秒间隔 } } void wifi_task(void *pvParameters) { // 正常的Wi-Fi操作 } void app_main() { adc_mutex = xSemaphoreCreateMutex(); // 初始化Wi-Fi esp_wifi_init(); esp_wifi_start(); // 创建任务 xTaskCreate(sensor_task, "sensor", 4096, NULL, 5, NULL); xTaskCreate(wifi_task, "wifi", 4096, NULL, 5, NULL); }

性能影响

  • 每次切换会导致Wi-Fi短暂断开(约100-200ms)
  • 不适合高频率采集(建议间隔≥1秒)
  • 会增加系统功耗

5. 方案对比与选型建议

方案复杂度实时性Wi-Fi影响适用场景
改用ADC1★☆☆大多数常规应用
调整顺序★★☆只需开机单次读取
软件切换★★★短暂断开必须使用ADC2的实时系统

在实际项目中,我遇到过一个智慧农业案例,需要每5分钟上报一次土壤数据。最初尝试方案三导致网络不稳定,最终改用方案一(ADC1)并增加缓存机制完美解决了问题。这也印证了KISS原则(Keep It Simple, Stupid)在嵌入式开发中的重要性。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/22 1:57:04

LangChain构建聊天机器人-聊天记录保存

一、核心技术知识点梳理 1、什么是“存储系统”?内存和外部存储的区别?(聊天记录存哪里) (1)存储系统:就是“保存数据的地方”,比如我们电脑的“文件夹”(本地存储&…

作者头像 李华
网站建设 2026/4/22 1:46:37

Transformer中跳过连接的作用与优化实践

1. 跳过连接在Transformer模型中的作用机制跳过连接(Skip Connection)最早出现在残差网络(ResNet)中,用于解决深度神经网络中的梯度消失问题。当这项技术被引入Transformer架构时,它带来了三个关键改进&…

作者头像 李华
网站建设 2026/4/22 1:38:58

虚拟助手如何重塑儿童人机交互与未来市场

1. 虚拟助手的崛起:从新奇玩具到家庭必需品1999年夏天,我拥有了人生第一部手机——Sagem RC 922。这部只能存储100个联系人、带着外置天线的设备,在诺基亚席卷市场的时代显得如此简陋。但正是这个只能打电话、发短信的"砖头"&#…

作者头像 李华