# esp32iot **Repository Path**: isletspace/esp32iot ## Basic Information - **Project Name**: esp32iot - **Description**: iot.islet.space 龟缸控制系统(基于MQTT、腾讯云和乐鑫ESP32) - **Primary Language**: C - **License**: GPL-3.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 3 - **Forks**: 0 - **Created**: 2022-01-16 - **Last Updated**: 2025-03-31 ## Categories & Tags **Categories**: Uncategorized **Tags**: ESP32, mqtt ## README # ESP32IOT 本项目是使用 **微信小程序**+**腾讯云**+**乐鑫开发板**+**5V-多路-继电器**+**220V-AC-电器** 的模式对家庭中的硬件进行检测和控制,本项目涉及到 **网络前端**、**服务器后端**、**网络通信** 和 **物联网硬件控制** 方面的相关知识。 **需要实现的功能**: 1. 开发板能够自动连接家庭WiFi(已实现) 2. 开发板能够通过MQTT协议与后台服务器取得联系(已实现) 3. 开发板能够定时自动获取时钟并校准(未实现) 4. 开发板能够根据MQTT协议控制外围电路(已实现) 5. 开发板能够根据已经设置的参数与实时的传感器参数比对,并在一定环境条件内开启/关闭相关电路(已实现) 6. 手机可以通过微信小程序发送MQTT数据至服务器(未实现) **软件开发平台**:Mac **硬件开发IDE**:Arduino # 硬件准备 1. 4路5V红板(光耦/高低电平)继电器 *1 2. DHT11温度模块 *2 3. 加热器 *1 4. ESP32-WROOM-32开发板 *1 其他: 1. 杜邦线 2. 电烙铁 3. 锡丝 4. 松香 5. 面包板 ## 芯片模组比对选型 ESP32-WROOM-32X(此处 `X` 代表不确定) 和 ESP32-WROVER-X(此处 `X` 代表不确定) 在性能上基本一模一样,包括核心数、最大时钟频率、Flash大小、支持的接口类型 和 特殊传感器等等。除了在 PSRAM、工作温度范围、天线、WiFi最高频率 和 模组尺寸上有所区别外。 ESP32-WROVER-X 则具有PSRAM 和 最大的面积(18mm × 31.4mm × 3.3mm)。 ![官方展示的ESP32模组性能参数对比](https://pic.islet.space/2021/12/image-20211228014701607.png) ## 芯片选型 无脑选了ESP32-WROOM-32SE,反正自己用,而且便宜(¥21.5包邮)。 ## 芯片基本信息 ![Arduino所展示的开发板可调参数](https://pic.islet.space/2021/12/image-20211228012555509.png) # Arduino IDE准备 使用 Arduino IDE 进行开发,但开发配置相关的 `.json` 文件 及其安装包都在 `github.com` 上,即使使用了科学上网进行加速,但因为加速器的加速层级可能和IDE拉取资源包所用的数据层级不在同一个上面,无法代理,就白天基本上无法下载,凌晨(正经程序员谁tm熬夜)才有机会下载东西。 > 英文版下的 `首选项` 是 `Preferences` 。 ![修改附加开发板管理网址](https://pic.islet.space/2021/12/image-20211228011905234.png) 然后去 `开发板管理器` 中搜索 `esp32` 进行安装。 ![目录-开发板-开发板管理器](https://pic.islet.space/2021/12/image-20211228012156101.png) ![搜索关键词“esp32”](https://pic.islet.space/2021/12/image-20211228012244049.png) ## 解决github问题 ### 方法一 本来应该用如下链接进行配置的: ```shell https://dl.espressif.com/dl/package_esp32_index.json ``` 自己扒拉了一遍该文件中可能包含的所有资源包(主要是 `github.com` 上的),然后修改了 `.json` 文件,放到自己的桶里,然后放出来使用,还好这个文件里有明确提到要哪些资源不然也没法扒拉。 ```shell https://code.islet.space/espressif/dl/package_esp32_index.json ``` **注意**:Mac系统下可能会因为曾经下载过的缓存文件无法生效(如果自行修改了网站上的 `.json` 文件的话),需要自行清除缓存,打开 `~/Library/ArduinoXX/cache/` 并对应删除该网站的文件夹即可,如 `code.islet.space` 。(这里的 `ArduinoXX` 中的 `XX` 需要自己去看自己的文件夹,应该是受版本控制的) ![修改链接后可以正常下载](https://pic.islet.space/2021/12/image-20211228005455101.png) ### 方法二 自己去github,用浏览器或者下载器下好了以后放到 `用户目录--资源库--程序缓存--指定位置`(如下)。 ``` ~/Library/ArduinoXX/staging/packages/ ``` 这个文件夹也就需要放这么多文件吧。 ![资源库缓存指定位置下的文件](https://pic.islet.space/2021/12/image-20211228012028024.png) 亲测,第二种方法更好用。 ![提示安装成功](https://pic.islet.space/2021/12/image-20211228011814461.png) # Visual Studio Code IDE准备 总的来说,VS Code的IDE配置会比Arduino更为复杂,但是无奈在都是科学上网的情况下,VS Code下载毫无压力,且VS Code使用习惯之后更加方便。 至少前期配置工作来说,VS Code更为友好。 ## Espressif IDF插件安装 首先去插件市场搜索 `Espressif IDF` 插件进行安装,然后点击 `查看` -> `命令面板`。 ![image-20211228182209737](https://pic.islet.space/2021/12/image-20211228182209737.png) 到这里需要输入 `configure esp-idf extension` 以进入该插件的配置页面。 ![image-20211228182314161](https://pic.islet.space/2021/12/image-20211228182314161.png) ## 必要工具安装 然后它就会提示你需要安装几个必要插件,有 Git / Python / CMake 和 Ninja。这些都可以从Espressif的 [官方文档](https://docs.espressif.com/projects/esp-idf/zh_CN/latest/esp32/get-started/index.html) 中获取到安装步骤。 ![image-20211228182508965](https://pic.islet.space/2021/12/image-20211228182508965.png) 下方为四个工具的官方下载链接,前三个都可以通过官方下载软件包进行安装,第四个 Ninja 我安装不成功,是通过 Mac Ports 进行安装的。 GIT : https://git-scm.com/ PYTHON : https://www.python.org/downloads/ CMAKE : https://cmake.org/download/ NINJA : https://github.com/ninja-build/ninja/releases 需要注意的是,CMAKE 和 Ninja 安装完还需要加入到系统环境变量 `PATH` 中去,Windows系统下的系统环境变量添加比较方便,下方为 Mac 系统下 CMake 的系统环境变量添加方法。 ### CMAKE命令行 打开Mac系统下的 CMake GUI,点击 `Tools` --> `How to Install For Command Line Use` ,可以查看到三种将 CMake 添加到命令行中去运行的方法。 ![点击“工具”菜单中的“如何为命令行使用进行安装”](https://pic.islet.space/2021/12/image-20211228183126458.png) ![可以查看到三种安装方法](https://pic.islet.space/2021/12/image-20211228183411724.png) 使用的是第二种方法,向命令行输入 `sudo "/Applications/CMake.app/Contents/bin/cmake-gui" --install` 并输入管理员密码即可。 然后通过 `cmake --version` 可以查看到版本号说明安装成功,但需要注意的是 `whereis cmake` 还是没有用。 ![操作结果](https://pic.islet.space/2021/12/image-20211228183403876.png) ### 工具安装验证 四个必须要安装的软件都已经安装完毕,通过 `--version` 可以查看版本号。 ![安装验证](https://pic.islet.space/2021/12/image-20211228184801497.png) ## 配置继续 四个必要工具安装完毕之后,关闭 `ESP-IDF Setup` 页面,然后重新在 **命令面板** 输入 `configure esp-idf extension` 以进入该插件的配置页面。 ![再次进入配置页面](https://pic.islet.space/2021/12/image-20211228184938407.png) 此处选择 `EXPRESS` 即可,里面会要求选择从哪个服务器下载(自己看情况选择`Github` / `Espressif`)、IDF版本(默认选最新)、IDF放置路径、工具路径、使用的Python3路径 等几个信息,选完了就进入下一界面,会自动下载安装 ESP-IDF。 ![详细配置页面](https://pic.islet.space/2021/12/image-20211228185458736.png) 耐心等待下载完毕即可,我用 `Espressif` 服务器下载不下来,然后该用 `Github` 和 科学上网进行下载的。 ![image-20211228185748221](https://pic.islet.space/2021/12/image-20211228185748221.png) 下载过程页面如下: ![image-20211228190058612](https://pic.islet.space/2021/12/image-20211228190058612.png) ![image-20211228190027057](https://pic.islet.space/2021/12/image-20211228190027057.png) 最后提示的安装成功: ![image-20211228190438498](https://pic.islet.space/2021/12/image-20211228190438498.png) # 示例项目载入 在 **命令面板** 中输入 `show examples projects` 。 ![image-20211228190651117](https://pic.islet.space/2021/12/image-20211228190651117.png) 即可调出 ESP-IDF的示例代码项目列表。 ![image-20211228190738993](https://pic.islet.space/2021/12/image-20211228190738993.png) 选择 `blink` 作为测试代码。 ![image-20211228190839371](https://pic.islet.space/2021/12/image-20211228190839371.png) ## 项目构建 这里可以用命令面板输入 `esp build your project` ,也可以点击GUI下方的 ![image-20211231124940242](https://pic.islet.space/2021/12/image-20211231124940242.png)进行构建。 ![命令面板构建](https://pic.islet.space/2021/12/image-20211228191057987.png) 构建完成后,会生成 `build` 文件夹,下次构建时CMake会查看变动的文件然后只编译变动过的代码。 也可以删除该 `build` 文件夹,使其全部重新构建,会比较费时。 ![build过程](https://pic.islet.space/2021/12/image-20211228191156613.png) 点击下方的闪电按钮![烧录按钮](https://pic.islet.space/2021/12/image-20211231125445685.png)即可烧录,烧录成功提示如下: ![烧录过程](https://pic.islet.space/2021/12/image-20211228221323556.png) # 连接WiFi 下图为使用示例代码更改的项目代码文件内容: ![项目文件内容示例](https://pic.islet.space/2021/12/image-20211228222302314.png) 利用ESP自带的示例代码`station` 进行调试和更改,需要注意以下几点: 1. 不用去更改 `isletSpaceIotMain.c` 中的 `SSID` 和 `PASS` ,只需要在 `sdkconfig` 文件中进行更改即可(如下图)。 2. 所有的 WiFi设置参数 都可以在 `sdkconfig` 文件中进行修改,如需要连接 AP 的 名称和密码,还有自身设备所显示的名称。 3. 修改文件名之后,需要对两个 `CMakeList.txt`文件 和 一个`Makefile` 文件中的项目和文件名进行修改(如下图)。 ![如果修改代码名称需要修改main文件夹下的CMakeList文件](https://pic.islet.space/2021/12/image-20211228222645861.png) ![如果修改项目名称需要修改根目录下的CMakeList](https://pic.islet.space/2021/12/image-20211228222717269.png) ![如果修改项目名称需要修改根目录下的Makefile](https://pic.islet.space/2021/12/image-20211228222733903.png) ## MENUCONFIG MENUCONFIG 或者说 `sdkconfig` ,一个是图形界面的,一个是纯文本形式的。 用menuconfig的话只需要找到下方的齿轮按钮即可。 ![image-20211231130402110](https://pic.islet.space/2021/12/image-20211231130402110.png) 可以找到WiFi相关的配置位置: ![image-20211231130507316](https://pic.islet.space/2021/12/image-20211231130507316.png) 对 `sdkconfig` 文件中的设备名称进行修改。 ![image-20211228223040901](https://pic.islet.space/2021/12/image-20211228223040901.png) 修改完毕后可以在路由器 AP 的后台查看到已经连接的设备的名称,如下。 ![image-20211228223134009](https://pic.islet.space/2021/12/image-20211228223134009.png) # MQTT协议 根据 Espressif 官网的 [ESP-MQTT](https://docs.espressif.com/projects/esp-idf/zh_CN/latest/esp32/api-reference/protocols/mqtt.html) 开发文档可知,MQTT 协议支持以下几种形式: - MQTT over TCP - MQTT over SSL with mbedtls - MQTT over Websocket - MQTT over Websocket Secure. 各MQTT协议形式(与对应SDK里的 [MQTT示例代码](##MQTT相关示例代码))及其所使用的端口号不同: - `protocols/mqtt/tcp`: MQTT over tcp, default port 1883 - `protocols/mqtt/ssl`: MQTT over tcp, default port 8883 - `protocols/mqtt/ssl_psk`: MQTT over tcp using pre-shared keys for authentication, default port 8883 - `protocols/mqtt/ws`: MQTT over Websocket, default port 80 - `protocols/mqtt/wss`: MQTT over Websocket Secure, default port 443 ## MQTT事件结构体 ```c /** * MQTT event configuration structure */ typedef struct { esp_mqtt_event_id_t event_id; /*!< MQTT event type */ esp_mqtt_client_handle_t client; /*!< MQTT client handle for this event */ void *user_context; /*!< User context passed from MQTT client config */ char *data; /*!< Data associated with this event */ int data_len; /*!< Length of the data for this event */ int total_data_len; /*!< Total length of the data (longer data are supplied with multiple events) */ int current_data_offset; /*!< Actual offset for the data associated with this event */ char *topic; /*!< Topic associated with this event */ int topic_len; /*!< Length of the topic for this event associated with this event */ int msg_id; /*!< MQTT messaged id of message */ int session_present; /*!< MQTT session_present flag for connection event */ esp_mqtt_error_codes_t *error_handle; /*!< esp-mqtt error handle including esp-tls errors as well as internal mqtt errors */ bool retain; /*!< Retained flag of the message associated with this event */ } esp_mqtt_event_t; typedef esp_mqtt_event_t *esp_mqtt_event_handle_t; ``` ## MQTT相关示例代码 了解完官方开发文档中的信息,就可以知道MQTT示例代码里的这些文件夹命名含义,以及自己需要打开哪个示例代码了。 ![image-20211228223617579](https://pic.islet.space/2021/12/image-20211228223617579.png) ## MENUCONFIG MENUCONFIG 页面可以看到MQTT的相关配置信息。 ![image-20211229011902429](https://pic.islet.space/2021/12/image-20211229011902429.png) # MQTT服务器开发 自行购买了腾讯云的服务器,然后完成了配置(步骤略),发现自测“主题订阅”不成功。 ![image-20211229033019004](https://pic.islet.space/2021/12/image-20211229033019004.png) 然后刚好发现服务器的 Ubuntu 20 系统使用的防火墙是 `iptables` ,顺利打开 `1883` 端口。 ```shell sudo iptables -A INPUT -p tcp --dport 1883 -j ACCEPT ``` 然后查看打开情况。 ![image-20211229032825212](https://pic.islet.space/2021/12/image-20211229032825212.png) 顺便在服务器页面也打开相关配置。 ![image-20211229032753559](https://pic.islet.space/2021/12/image-20211229032753559.png) 最后自测成功: ![image-20211229032920902](https://pic.islet.space/2021/12/image-20211229032920902.png) ![image-20211229032953396](https://pic.islet.space/2021/12/image-20211229032953396.png) # 小程序开发(未完) 因为个人使用腾讯云注册了自己的域名 islet.space,且小程序也属于腾讯自家产品,为了后续开发的兼容性和便利性,就同步参阅了腾讯云的 [物联网自主品牌小程序开发文档](https://cloud.tencent.com/document/product/1081/47684) 。 ![image-20211227202550338](https://pic.islet.space/2021/12/image-20211227202550338.png) ## 微信开发者工具 微信开发者工具下载页面:https://cloud.tencent.com/document/product/1081/47685 ![image-20211227202759080](https://pic.islet.space/2021/12/image-20211227202759080.png) ![image-20211227203058077](https://pic.islet.space/2021/12/image-20211227203058077.png) ## 后台设置 [物联网开发平台](https://cloud.tencent.com/document/product/1081/34738) # DEBUG ## 烧录和调试过程报错 出现这种情况,可能是所选芯片不正确导致。 ![烧录错误提示](https://pic.islet.space/2021/12/image-20211228214645589.png) ### 解决过程 重新选择了芯片,然后将烧录方法改为 `UART` ,重新烧录即可成功。 ![在插件中选择”扩展设置“](https://pic.islet.space/2021/12/image-20211228215715687.png) ![选择需要调试的设备类型](https://pic.islet.space/2021/12/image-20211228215826153.png) ![选择烧录方式](https://pic.islet.space/2021/12/image-20211228215747432.png) ![烧录成功提示](https://pic.islet.space/2021/12/image-20211228215518196.png) ## 头文件查找错误 这个bug始终没有解决,之后再说吧。。。 ![提示无该文件](https://pic.islet.space/2021/12/image-20211228232022467.png) ## WIFI初始化出错 将WiFi-station的代码搬到 MQTT-TCP中,发现 `wifiStationInit()` 函数初始化错误,报错的行数是 `117` 。 ![wifi初始化函数出错](https://pic.islet.space/2021/12/image-20211229143428551.png) 经检查,发现该函数示例代码的一部分,并未改动,且未添加其他自定义的 `.h` 或 `.c` 文件进行编译,应该不存在人为修改错误。 ![检查函数定义](https://pic.islet.space/2021/12/image-20211229150011594.png) 因为仅修改了本 `isletSpaceIotMain.c` 文件,就在本文件中搜索 `esp_event_loop_create_default` 关键字,发现在 `app_main()` 中也有该语句,初步判断可能是两次调用导致错误,就注释了 `298` 行 和 `299` 行进行重新编译和烧录,问题解决,设备可以正常连接到路由器。 ![注释重复语句](https://pic.islet.space/2021/12/image-20211229150054429.png) ## MQTT服务器连接错误 在设备成功接入WiFi后,发现MQTT客户端无法连接至服务器。给出的错误提示是 `There are no transports valid` ,大致意思即连接不可用。 ![Monitor提示无可用传输](https://pic.islet.space/2021/12/image-20211229150744192.png) 经过检查,发现原来填写在 `sdkconfig` 文件中的 `Broker URL` 链接为 `https://iot.islet.space` ,而实际上,官网给出的配置方式如下: ![查看官方URI定义](https://pic.islet.space/2021/12/image-20211229152435708.png) 打开项目配置菜单,修改为 `mqtt://iot.islet.space` ,并重新 Build 和 Flash。 ![修改URL](https://pic.islet.space/2021/12/image-20211229151252895.png) 可以发现错误已解决,设备已经正常连接至服务器。 ![Monitor提示成功](https://pic.islet.space/2021/12/image-20211229152118764.png) 尝试在对应主题下发布信息进行测试: ![尝试发布信息](https://pic.islet.space/2021/12/image-20211229152036214.png) 通过终端Monitor可以观察到,设备正常接收到数据: ![设备接收成功](https://pic.islet.space/2021/12/image-20211229152141547.png) ## eventHandler未进入 ![image-20211229182911935](https://pic.islet.space/2021/12/image-20211229182911935.png) # 参考 1. [Mac 安装 CMake 配置及环境配置](https://blog.csdn.net/xujiuba/article/details/107234040) 2. [Quick User Guide for the ESP-IDF VS Code Extension](https://www.youtube.com/watch?v=Lc6ausiKvQM) 3. [ESP-IDF 编程指南](https://docs.espressif.com/projects/esp-idf/zh_CN/latest/esp32/get-started/index.html#id2) 4. [ESP-MQTT](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/protocols/mqtt.html)