ESP32 总是高引脚拧紧模拟测量

物联网 传感器 硬件 ESP32 微控制器
2021-06-24 09:07:38

TL;DR当尝试使用我的 ESP32 的某些引脚读取模拟信号时,结果发现这些引脚具有非零电压,从而扰乱了测量。为什么?

我给自己买了一个 Olimex ESP32-POE-ISO(见规格)来灌溉我的花园。我在 GPIO0-5 上连接了一些猎人阀,计划是将 3 个湿度/温度传感器 ( Truebner SMT50 ) 连接到模块另一侧的引脚上(参见引脚分配)。

然而,我最终拔掉了我的头发。在某些引脚(例如 GPIO14/ADC2_CH6、GPIO32/ADC1_CH4、GPIO33/ADC1_CH5、GPI35/ADC1_CH7)上,我得到了正确的读数。我已经尝试了这些引脚上 3 个传感器中每一个的两个特性(湿度和温度),我得到的值看起来很合理。所以我排除了有缺陷的传感器。

我也尝试过 GPIO13/ADC2_CH4、GPIO15/ADC2_CH3、GPI36/ADC1_CH0、GPIO0/ADC2_CH1 和 GPIO2/ADC2_CH2,但我总是得到很高的数字(2400-3400 之间的 12 位原始值,对应于电压 1.9V - 2.7V)。事实上,在断开传感器并用万用表测量后,我可以发现这些引脚确实有这样的电压(针对 GND 引脚测量),而“好”引脚没有。

初始化代码如下所示(channel.channel.adc1_id...adc2_id包含类似ADC1_CHANNEL_0, ... 的):

void SensorService::init() {
    ESP_LOGI(TAG, "Initializing sensor service");

    adc1_config_width(ADC_WIDTH_BIT_12);
    sensorToChannel = getChannelMapping();
    for( const auto& [ idx, channel ] : sensorToChannel) {
        switch (channel.unit) {
            case ADC_UNIT_1:
                adc1_config_channel_atten(channel.channel.adc1_id, ADC_ATTEN_11db);
                break;
            case ADC_UNIT_2:
                adc2_config_channel_atten(channel.channel.adc2_id, ADC_ATTEN_11db);
                break;
            default:
                ESP_LOGW(TAG, "Invalid ADC unit requested");
                break;
        };
    }
}

像这样读取原始值:

std::optional<unsigned int> SensorService::getRawValue(unsigned int sensorIdx) {
    ESP_LOGV(TAG, "Getting raw value for sensor %d", sensorIdx);

    if (!this->isValidSensorIdx(sensorIdx)) {
        ESP_LOGW(TAG, "Requested non-existing sensor");
        return std::nullopt;
    }

    TargetChannel target = sensorToChannel.at(sensorIdx);
    switch (target.unit) {
        case ADC_UNIT_1:
            return std::make_optional(adc1_get_raw(target.channel.adc1_id));
        case ADC_UNIT_2:
            int value;
            adc2_get_raw(target.channel.adc2_id, ADC_WIDTH_BIT_12, &value);
            return std::make_optional(value);
        default:
            ESP_LOGW(TAG, "Invalid ADC unit requested");
            return std::nullopt;
    }
}

这对某些别针非常有效,但对其他别针则不然。

我还尝试了一些我可以在文档中找到的东西来明确地将引脚设置为INPUT低电平。但这并没有改变任何事情。

    for (auto const& [ sensorIdx, pin ] : sensorPins) {
        gpio_pad_select_gpio(pin);
        gpio_set_direction(pin, GPIO_MODE_INPUT);
        gpio_set_level(pin, 0);
    }

我正在通过以太网/POE 为电路板供电和连接。我没有(有意)在代码中的任何地方激活 WIFI、RTC、霍尔传感器。不使用 SD 卡或闪存进行数据存储。这些值将仅通过 HTTP/以太网轮询。

所以,我在这里的实际问题是,为什么有些引脚(例如 GPI36,明确记录为仅输入引脚)具有非零电压,而其他引脚则没有?我错过了什么?

2个回答

看起来板上的几个引脚上有上拉。

如果您查看原理图,您将在 UEXT 部分看到:

在此处输入图片说明

GPIO16、GPI36、GPIO13和GPIO5上有上拉。这解释了您在 GPI36 和 GPIO13 上看到的结果。

GPIO0 还有一个上拉(在 ESP-WROOM-32 MODULE 部分)。GPIO15 和 GPIO2 在 SD/MMC 卡部分各有一个。

这里和那里还有很多引体向上。看起来板上浮动的引脚不多。另请参阅原理图底部的注释部分,了解与引导相关的其他上拉/下拉信息。

请注意,SMT50 电压输出的输出电阻为 10 kOhm(请参阅SMT50 数据表 因此,如果上拉电阻为 3.3V,那么您将始终获得过高的电压电平。很高兴了解上拉,因为我计划从一个ESP32灌溉控制项目和SMT50开始,我会选择没有上拉的引脚。