我一直在尝试使用 Vedat Oner 的第一版教科书(课程要求)来学习 ESP32,并且自发布以来,新版本似乎已经打破了所有其他依赖性。在 ESP-IDF 架构中将 VSCode 与 PlatformIO 结合使用。开发板是 Freenove ESP32-WROVER。
我从教科书中逐字复制了以下示例代码,但我将 DHT11_PIN 从 17 更改为 34,因为我的开发板没有可用的引脚 17(作者使用的是不同的型号)。
#include <stdio.h>
#include <freertos/FreeRTOS.h>
#include <freertos/task.h>
#include "dht.h"
#include "driver/gpio.h"
// defines
#define DHT11_PIN 34
#define BUZZER_PIN 18
#define BUZZER_PIN_SEL (1ULL << BUZZER_PIN)
#define HUM_THRESHOLD 800
#define TEMP_THRESHOLD 250
// globals
static int16_t temperature;
static bool temp_alarm = false;
static int16_t humidity;
static bool hum_alarm =false;
// initialize hardware
static void init_hw(void) {
gpio_config_t io_conf;
io_conf.mode = GPIO_MODE_OUTPUT;
io_conf.pin_bit_mask = BUZZER_PIN_SEL;
io_conf.intr_type = GPIO_INTR_DISABLE;
io_conf.pull_down_en = 0;
io_conf.pull_up_en = 0;
gpio_config(&io_conf);
}
// generates alarm beep
static void beep(void *arg) {
int cnt = 2 * (int)arg;
bool state = true;
for (int i = 0; i < cnt; ++i, state = !state) {
gpio_set_level(BUZZER_PIN, state);
vTaskDelay(100 / portTICK_PERIOD_MS);
}
vTaskDelete(NULL);
}
// checks for humidity and temp alarms
static void check_alarm(void) {
bool is_alarm = temperature >= TEMP_THRESHOLD;
bool run_beep = is_alarm && !temp_alarm;
temp_alarm = is_alarm;
if (run_beep) {
xTaskCreate(beep, "beep", configMINIMAL_STACK_SIZE, (void *)3, 5, NULL);
return;
}
is_alarm = humidity >= HUM_THRESHOLD;
run_beep = is_alarm && !hum_alarm;
hum_alarm = is_alarm;
if (run_beep) {
xTaskCreate(beep, "beep", configMINIMAL_STACK_SIZE, (void *)2, 5, NULL);
}
}
void app_main() {
init_hw();
while (1) {
if (dht_read_data(DHT_TYPE_DHT11, (gpio_num_t)DHT11_PIN, &humidity, &temperature) == ESP_OK) {
printf("Humidity: %d%% Temp: %dC\n", humidity / 10, temperature / 10); check_alarm();
}
else {
printf("Could not read data from sensor\n");
}
vTaskDelay(2000 / portTICK_PERIOD_MS);
}
}
DHT11 示例使用 dht.c,但第 94 行和 119 行的函数
ets_delay_us()
似乎已在某个更新中被删除。我尝试了建议的修复方法,将其替换为 esp_rom_delay_us()
并进行了编译,但是当我将其上传到 ESP32 并进行监控时,它崩溃了:控制台开始吐出无穷无尽的乱码,如下所示:
ELF file SHA256: 840611cd9
Rebooting...
ets Jul 29 2019 12:21:46
rst:0xc (SW_CPU_RESET),boot:0x1b (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:2
load:0x3fff0030,len:7176
load:0x40078000,len:15564
ho 0 tail 12 room 4
load:0x40080400,len:4
load:0x40080404,len:3904
entry 0x40080638
␛[0;32mI (31) boot: ESP-IDF 5.3.1 2nd stage bootloader␛[0m
␛[0;32mI (31) boot: compile time Nov 5 2024 22:19:16␛[0m
␛[0;32mI (31) boot: Multicore bootloader␛[0m
␛[0;32mI (35) boot: chip revision: v3.1␛[0m
␛[0;32mI (39) boot.esp32: SPI Speed : 40MHz␛[0m
␛[0;32mI (44) boot.esp32: SPI Mode : DIO␛[0m
␛[0;32mI (48) boot.esp32: SPI Flash Size : 4MB␛[0m
␛[0;32mI (53) boot: Enabling RNG early entropy source...␛[0m
␛[0;32mI (58) boot: Partition Table:␛[0m
␛[0;32mI (62) boot: ## Label Usage Type ST Offset Length␛[0m
␛[0;32mI (69) boot: 0 nvs WiFi data 01 02 00009000 00006000␛[0m
␛[0;32mI (76) boot: 1 phy_init RF data 01 01 0000f000 00001000␛[0m
␛[0;32mI (84) boot: 2 factory factory app 00 00 00010000 00100000␛[0m
␛[0;32mI (91) boot: End of partition table␛[0m
␛[0;32mI (96) esp_image: segment 0: paddr=00010020 vaddr=3f400020 size=09d4ch ( 40268) map␛[0m
␛[0;32mI (118) esp_image: segment 1: paddr=00019d74 vaddr=3ffb0000 size=02368h ( 9064) load␛[0m
␛[0;32mI (122) esp_image: segment 2: paddr=0001c0e4 vaddr=40080000 size=03f34h ( 16180) load␛[0m
␛[0;32mI (130) esp_image: segment 3: paddr=00020020 vaddr=400d0020 size=14cb8h ( 85176) map␛[0m
␛[0;32mI (161) esp_image: segment 4: paddr=00034ce0 vaddr=40083f34 size=08af0h ( 35568) load␛[0m
␛[0;32mI (182) boot: Loaded app from partition at offset 0x10000␛[0m
␛[0;32mI (182) boot: Disabling RNG early entropy source...␛[0m
␛[0;32mI (194) cpu_start: Multicore app␛[0m
␛[0;32mI (202) cpu_start: Pro cpu start user code␛[0m
␛[0;32mI (202) cpu_start: cpu freq: 160000000 Hz␛[0m
␛[0;32mI (202) app_init: Application information:␛[0m
␛[0;32mI (205) app_init: Project name: DHT11_demo␛[0m
␛[0;32mI (210) app_init: App version: 1␛[0m
␛[0;32mI (215) app_init: Compile time: Nov 5 2024 22:17:47␛[0m
␛[0;32mI (221) app_init: ELF file SHA256: 840611cd9...␛[0m
␛[0;32mI (226) app_init: ESP-IDF: 5.3.1␛[0m
␛[0;32mI (231) efuse_init: Min chip rev: v0.0␛[0m
␛[0;32mI (236) efuse_init: Max chip rev: v3.99 ␛[0m
␛[0;32mI (240) efuse_init: Chip rev: v3.1␛[0m
␛[0;32mI (246) heap_init: Initializing. RAM available for dynamic allocation:␛[0m
␛[0;32mI (253) heap_init: At 3FFAE6E0 len 00001920 (6 KiB): DRAM␛[0m
␛[0;32mI (259) heap_init: At 3FFB2C30 len 0002D3D0 (180 KiB): DRAM␛[0m
␛[0;32mI (265) heap_init: At 3FFE0440 len 00003AE0 (14 KiB): D/IRAM␛[0m
␛[0;32mI (271) heap_init: At 3FFE4350 len 0001BCB0 (111 KiB): D/IRAM␛[0m
␛[0;32mI (278) heap_init: At 4008CA24 len 000135DC (77 KiB): IRAM␛[0m
␛[0;32mI (285) spi_flash: detected chip: generic␛[0m
␛[0;32mI (288) spi_flash: flash io: dio␛[0m
␛[0;32mI (293) main_task: Started on CPU0␛[0m
␛[0;32mI (303) main_task: Calling app_main()␛[0m
␛[0;32mI (303) gpio: GPIO[18]| InputEn: 0| OutputEn: 1| OpenDrain: 0| Pullup: 0| Pulldown: 0| Intr:0 ␛[0m
␛[0;31mE (303) gpio: io_num=34 can only be input␛[0m
␛[0;31mE (313) gpio: gpio_set_level(239): GPIO output gpio_num error␛[0m
abort() was called at PC 0x40082867 on core 0
Backtrace: 0x40082122:0x3ffb3970 0x4008559d:0x3ffb3990 0x4008b2fd:0x3ffb39b0 0x40082867:0x3ffb3a20 0x400829a5:0x3ffb3a50 0x40082a1e:0x3ffb3a70 0x400d8f2e:0x3ffb3aa0 0x400d8561:0x3ffb3dc0 0x400e4c51:0x3ffb3df0 0x4008b1b1:0x3ffb3e20 0x400d1ece:0x3ffb3e70 0x400d0fc9:0x3ffb3ea0 0x400d1171:0x3ffb3ed0 0x400d0f38:0x3ffb3f00 0x400e4470:0x3ffb3f20 0x40085e01:0x3ffb3f50
我不知道这意味着什么,我尝试使用吹风机将传感器的温度提高到阈值以上,但蜂鸣器没有响起。
这些消息不是胡言乱语。它们包含有关启动过程以及程序崩溃原因的宝贵信息。您分享的其中有一行解释了问题:
␛[0;31mE (303) gpio: io_num=34 can only be input␛[0m
某些 GPIO 引脚有限制。 GPIO34、35、36 和 39 均为仅输入。您选择了 GPIO34。您使用的库需要同时进行输入和输出,这会导致您看到的失败。
选择一个不同的引脚,一个不是捆绑引脚(它决定 CPU 如何启动,该 CPU 上的 GPIO0 和 GPIO12),另一个不是仅输入的引脚。
这里有一个有用的指南,介绍哪些引脚可用的用途。 CPU 型号(在本例中为 vanilla ESP32)很重要,具体的主板并不重要。