ARTICLE DETAIL

资讯详情

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

ESP32 OpenThread CoAP Greenhouse 实战:同一 Mesh 网络上 Plain CoAP 遥测与 CoAPS 安全控制的双传输设计

ESP32 OpenThread CoAP Greenhouse 实战:同一 Mesh 网络上 Plain CoAP 遥测与 CoAPS 安全控制的双传输设计 ESP32 OpenThread CoAP Greenhouse 实战同一 Mesh 网络上 Plain CoAP 遥测与 CoAPS 安全控制的双传输设计【免费下载链接】arduino-esp32Arduino core for the ESP32 family of SoCs项目地址: https://gitcode.com/GitHub_Trending/ar/arduino-esp32本文基于 arduino-esp32 仓库中的 OpenThread 原生 API 示例CoAP_Greenhouse示例总览讲解一个典型的 IoT 双传输架构开放遥测走明文 CoAP5683NON 可靠级经认证的执行器命令走 CoAPS/DTLS5684CON 可靠级两套协议运行在同一对 Thread Mesh 节点上。读完后你将掌握Thread Leader/Commissioner 与 Joiner 的双板组网流程、OThreadCoAPServer与OThreadCoAPSecureServer双服务器共存方式、CoAPS 的 sdkconfig/menuconfig 开启方法以及 PSK 密钥在客户端与服务端之间的匹配细节。双传输架构为什么遥测和执行器要分开该示例模拟一个温室场景只读环境数据温度、光照对网络内任意节点开放而可写控制命令灌溉阀门、通风风扇必须通过 DTLS 认证通道下发。这种开放遥测 认证执行器的拆分是物联网网关的常见安全模型。仓库用一对 sketch 完整演示了多个资源、CON 与 NON 的可靠性差异以及同一对 Mesh 节点上的双传输共存Sketch角色greenhouse_serverLeader 网关Leader Commissioner 明文 CoAP 服务器 CoAPS 服务器greenhouse_clientJoiner 控制器Joiner 明文 NON 轮询遥测 CoAPS CON 控制命令原始文档中的架构示意图如下ASCII 图┌─────────────────────────────────────┐ greenhouse_client │ PlainClient (5683) │ │ NON GET greenhouse/temp │ │ NON GET greenhouse/light │ │ SecureClient (5684) │ │ CON PUT valve/water │ │ CON PUT fan/speed │ └─────────────────┬───────────────────┘ │ Thread mesh ┌──────────────────────▼──────────────────────────┐ greenhouse_server │ OThreadCoAPServer — telemetry (read) │ │ OThreadCoAPSecureServer — actuators (write) │ └─────────────────────────────────────────────────┘从源码结构看客户端通过OThread.getLeaderRloc()直接取 Leader 的 RLOC16 作为服务器地址greenhouse_client.ino 中serverIp OThread.getLeaderRloc();无需额外的 mDNS 解析因为服务器就是组网时先烧录的那块板子。资源清单端口、方法与可靠性示例共注册 4 个 URI 资源明文与加密传输各有分工路径传输方法客户端可靠性用途greenhouse/tempPlain 5683GETNON温度°Cgreenhouse/lightPlain 5683GETNON光照强度luxvalve/waterCoAPS 5684PUTCON灌溉 0–100 %fan/speedCoAPS 5684PUTCON通风 0–100 %端口约定与 OThreadCoAP.h 中的宏定义一致OT_COAP_DEFAULT_PORT 5683明文、OT_COAP_SECURE_DEFAULT_PORT 5684CoAPS。响应码使用头文件中的OT_COAP_RESP_*常量如 205/204/405PUT 成功时服务端回204 Changed方法不匹配回405 Method Not Allowed见 greenhouse_server.ino 中resp.setCode(OT_COAP_RESP_METHOD_NA)的处理。服务端组网、Commissioner 与双服务器启动服务端 sketch 位于 greenhouse_server.ino文件头部声明了全部可调参数常量含义PSKDCommissioner 接受的 Joiner 密钥值J01NMEJOINER_WINDOW_SECaddJoiner()窗口有效期默认 600 秒CHANNEL802.15.4 信道默认 15PAN_ID16 位 PAN ID默认0xBEE5NETKEY128 位网络密钥硬编码的演示值COAP_PSK16 字节 CoAPS 预共享密钥必须与客户端一致COAP_PSK_IDPSK 身份字符串默认esp-coap-demosetup()的启动链条源码 greenhouse_server.ino#L158-L227组建网络DataSet ds; ds.initNew();后设置网络名ESP_OT_CoAP_Greenhouse、信道、PAN ID、网络密钥依次OThread.commitDataSet(ds)→OThread.networkInterfaceUp()→OThread.start()再轮询OThread.otGetDeviceRole() OT_ROLE_CHILD确认附着30 秒超时超时则OThread.stop()后 2 秒重试。启动 CommissionerOThread.startCommissioner()成功后调用OThread.addJoiner(PSKD, JOINER_WINDOW_SEC)串口输出Commissioner ready (PSKd J01NME)。这是客户端能够入网的前提——必须先烧录服务端并等到该提示。注册明文资源OThreadCoAPServer.on(greenhouse/temp, OT_COAP_METHOD_GET, onGreenhouseTemp, s_state)等两条然后OThreadCoAPServer.begin()。条件注册 CoAPS 资源只有OThreadCoAP::secureApiEnabled()为 true即固件编译时开启了OPENTHREAD_CONFIG_COAP_SECURE_API_ENABLE才执行OThreadCoAPSecureServer.setPSK(...)、注册valve/water与fan/speed并begin()否则打印CoAPS is not enabled in this build仅保留明文遥测。这保证了同一份代码在未开启 CoAPS 的固件上也能降级运行。资源处理函数遵循 OThreadCoAP.h 中OThreadCoAPHandler回调约定检查req.method()是否匹配不匹配则回405PUT 处理函数用parsePercent()校验 payload 在 0–100 范围内越界回400 Bad Requestpayload 为0-100合法则更新状态并回204 Changed。每个请求还会由logRequestKind()打印[CON]或[NON]标记与对端 IPv6 地址便于在串口确认客户端使用的可靠性等级。loop()中模拟环境漂移温度每次random(-5,6)/10.0f随机游走并按fanSpeed/200降温风扇开得越大降温越多钳制在 18–32 °C光照在 2000–20000 lux 间随机游走。注意状态是纯内存的static GreenhouseState s_state服务端重启后阀门/风扇状态丢失这也是故障排查表中服务端重启后需复位客户端重新入网一行的根源。客户端Joiner 入网与 8 秒/24 秒双周期控制客户端 sketch 位于 greenhouse_client.ino关键常量与自动化阈值常量含义PSKD必须与服务端 Commissioner 一致的J01NMECHANNEL_HINT802.15.4 信道提示默认 15JOIN_TIMEOUT_MSstartJoiner()内部等待 Commissioner 的最长时间60000 msTELEMETRY_MS明文 NON 轮询周期默认 8000 msCONTROL_MSCoAPS 控制循环周期默认 24000 msTEMP_FAN_ON_C温度超过 26.0 °C 时风扇设为 75%否则 15%LIGHT_VALVE_LUX光照低于 8000 lux 时阀门设为 60%否则 10%COAP_PSK/COAP_PSK_ID16 字节 PSK 与身份串必须与服务端完全一致入网流程joinNetwork()源码OThread.setChannel(CHANNEL_HINT)→networkInterfaceUp()→OThread.startJoiner(PSKD, JOIN_TIMEOUT_MS)返回非OT_ERROR_NONE即Joiner failed: N→OThread.start()后等待附着。客户端只在setup()里入网失败则OThread.stop()后 3 秒重试如果它先于服务端 Commissioner 启动而开机需要手动复位。loop()是两个周期叠加// 每 8 s明文 NON 遥测 PlainClient.setConfirmable(false); int code PlainClient.GET(serverIp, greenhouse/temp); // 0 时 OThreadCoAP::errorToString(code) lastTempC PlainClient.getString().toFloat(); // 每 24 s自动化 CoAPS CON PUT前提首次遥测成功后 lastTempC 0 SecureClient.connect(serverIp); // DTLS 握手失败打印 DTLS connect failed. SecureClient.setConfirmable(true); sendSecurePut(fan/speed, fanSpeed); // temp 26 C - 75% sendSecurePut(valve/water, valveOpen); // light 8000 - 60% SecureClient.disconnect();对应源码中pollTelemetry()greenhouse_client.ino#L97-L116与runControlLoop()greenhouse_client.ino#L130-L151。几个值得注意的实现细节控制前门控loop()中if (lastTempC 0.0f OThreadCoAP::secureApiEnabled())才执行控制循环所以前 24 秒看不到控制输出是设计行为——它在等待第一次成功的 NON 遥测lastTempC初始为 0.0f。DTLS 会话生命周期每个控制周期connect()→ 两次PUT→disconnect()即每 24 秒重新握手一次而不是保持长连接。这与 OThreadCoAPSecureClient 的约束呼应每设备仅支持一个活动 CoAPS 客户端会话且同一设备上不能同时运行OThreadCoAPSecureClient::connect()与OThreadCoAPSecureServer——本示例因此把 CoAPS 服务器放在服务端板、CoAPS 客户端放在客户端板。超时配置明文客户端PlainClient.setTimeout(3000)安全客户端SecureClient.setConnectTimeout(10000)DTLS 握手与setTimeout(5000)请求等待CoAPS 下仅限制 sketch 等待线上重传走栈默认值见头文件对setTimeout的注释 OThreadCoAP.h#L681-L687。运行步骤与演示凭据运行前提来自总览 README启用 CoAPS 构建选项见下文启用 CoAPS一节若只跑明文遥测可跳过。先烧录greenhouse_server等待串口出现Commissioner ready以及明文5683/CoAPS5684两条监听提示。在第二块板烧录 greenhouse_client。两块板均用 115200 波特率打开串口监视器客户端每 8 秒轮询遥测并在首次遥测成功后每 24 秒发送 CON 控制命令。两块 sketch 的 CI 配置也印证了各自需要的配置项greenhouse_server/ci.yml 声明了CONFIG_OPENTHREAD_ENABLEDy、CONFIG_SOC_IEEE802154_SUPPORTEDy、CONFIG_OPENTHREAD_COMMISSIONERy。必需的 IDF 特性sdkconfig特性用途CONFIG_OPENTHREAD_ENABLEDy编入 OpenThread 协议栈CONFIG_SOC_IEEE802154_SUPPORTEDySoC 具备 802.15.4 射频CONFIG_OPENTHREAD_COMMISSIONERygreenhouse_server使用CONFIG_OPENTHREAD_JOINERygreenhouse_client使用OPENTHREAD_CONFIG_COAP_SECURE_API_ENABLE15684 端口 CoAPS 执行器MBEDTLS_KEY_EXCHANGE_PSK_ENABLEDPSK 密码套件共享演示凭据参数值网络名ESP_OT_CoAP_Greenhouse信道15PAN ID0xBEE5Thread Joiner PSKdJ01NMECoAPS PSK idesp-coap-demo明文 CoAP 遥测5683在不开任何 CoAPS 构建标志的情况下即可工作执行器 PUT 命令则必须开启。运行期可用OThreadCoAP::secureApiEnabled()判断当前固件是否包含 CoAPSOThreadCoAP.h#L162-L166 注释明确其返回OPENTHREAD_CONFIG_COAP_SECURE_API_ENABLE的编译状态。支持的目标两个 sketch 均声明支持见 greenhouse_server/README.mdSoCThread状态ESP32-H2是支持ESP32-C6是支持ESP32-C5是支持启用 CoAPS以 ESP-IDF 组件方式构建 Arduino标准 Arduino IDE 构建的固件可能不含 CoAPS 安全 API。如需 5684 端口上的 CoAPS 执行器需要把 sketch 当作ESP-IDF 工程Arduino 作为 component构建再在 menuconfig 中开启特性。可参考仓库文档 docs/esp-idf_component.rstArduino as an ESP-IDF component。操作流程把 sketch 拷入工程main/目录.ino改名.cpp执行idf.py set-target soc然后idf.py menuconfig。需要开启的选项menuconfig 路径设置Component config → OpenThreadOpenThreadComponent config → OpenThread → Thread Core FeaturesEnable Commissionergreenhouse_serverComponent config → OpenThread → Thread Core FeaturesEnable Joinergreenhouse_clientComponent config → mbedTLS → TLS Key Exchange MethodsEnable pre-shared-key ciphersuitesComponent config → mbedTLS → TLS Key Exchange MethodsEnable PSK based ciphersuite modesComponent config → OpenThread → Thread Extensioned FeaturesUse a header file defined by customer关键点CoAPS API 标志OPENTHREAD_CONFIG_COAP_SECURE_API_ENABLE不是menuconfig 里的直接开关。使用自定义 OpenThread 头文件时在其中定义#define OPENTHREAD_CONFIG_COAP_SECURE_API_ENABLE 1把该头文件路径填到Thread Extensioned Features → OpenThread Custom Header Config保存后执行idf.py build flash monitor。预期串口输出服务端CoAPS 可用时 CoAP Greenhouse — server Forming Thread network... Waiting for attach.. Attached as Leader. Starting Commissioner... Commissioner ready (PSKd J01NME) Starting CoAP servers... Ready. Plain CoAP on port 5683: GET greenhouse/temp, greenhouse/light CoAPS on port 5684: PUT valve/water, fan/speed (PSK id esp-coap-demo) Mesh-local: fdde:ad00:beef:0:.... [NON] GET greenhouse/temp from fdde:ad00:beef:0:.... [CoAPS CON] PUT fan/speed from fdde:ad00:beef:0:.... Fan - 75% Valve - 60%客户端 CoAP Greenhouse — client Joining Thread network (Joiner)... Commissioning with PSKd J01NME... Waiting for attach.. Attached as Child. Greenhouse server: fdde:ad00:beef:0:0:ff:fe00:0 Ready. Polling telemetry and running control loop. [plain NON] temp24.3 C [plain NON] light11500 lux Control: temp24.3 fan15% light11500 valve10% [CoAPS CON] PUT fan/speed15 - 2.04 Changed [CoAPS CON] PUT valve/water10 - 2.04 Changed若固件未含 CoAPS两端都会打印CoAPS is not enabled in this build服务端遥测继续、客户端跳过安全控制若入网失败客户端会打印Joiner failed: 7并每 3 秒重试。故障排查启动顺序是第一位的排查项先烧录 greenhouse_server等Commissioner ready与两条监听提示后再烧录/复位 greenhouse_client若客户端在 Commissioner 激活前开机需复位。症状可能原因客户端Join failed先烧录 greenhouse_server并等待 Commissioner ready之后复位客户端CoAPS is not enabled in this build固件缺少 CoAPS。按上文启用 CoAPS以 ESP-IDF 组件方式重新构建明文 5683 遥测不受影响明文 GET 正常、CoAPS PUT 失败CoAPS 构建标志缺失或 PSK 不匹配——5683 遥测可以在无安全构建下工作两者应分开判断客户端跳过控制输出等待首次成功的 NON 遥测lastTempC必须非零客户端入网后服务端复位复位客户端重新入网服务端状态存于内存重启即丢失服务端CoAPS server start failed构建已启用 CoAPS 但OThreadCoAPSecureServer.begin()失败PSK、端口或附着问题服务端Plain CoAP server start failedOpenThread 未附着CON PUT ... failed: Timeout服务端 CoAPS 未运行或节点已脱离 Mesh相关示例CoAP Secure仅 CoAPS 的最小演示secure_server / secure_client。Native CoAP 示例总览所有原生 CoAP 演示与端口约定还列出了setPort()、useDefaultCoapRetransmit()、joinMulticastGroup()等本示例未展示的高级选项。OThreadCoAP.hOThreadCoAPClient/OThreadCoAPServerClass/OThreadCoAPSecureClient/OThreadCoAPSecureServerClass的完整 API 与约束单例服务器、单 CoAPS 会话、错误码OT_COAP_ERROR_*等。以上示例代码与文档均以 Apache License 2.0 发布。【免费下载链接】arduino-esp32Arduino core for the ESP32 family of SoCs项目地址: https://gitcode.com/GitHub_Trending/ar/arduino-esp32创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表