前言
最近我在研究 COAP 协议,在尝试使用 COAP 协议找了到了一个能在ESP32上用的coap-simple库,虽然库并不完善关于loop处理的部分应该是没写完,但是对于第一次接触COAP的朋友来说更容易理解,方便学习,需要的朋友可以去下面下载:
https://github.com/hirotakaster/CoAP-simple-library
我之前使用 IOT PI 的 COAP 能和 PC node coap 通讯,但是因为 coap-simple 库不完善,正常的无法与 node coap 通讯,只能和同样使用这个库设备通讯,这次就来尝试 ESP32 之间的 M2M 通讯。
获取库
使用 arduino IDE 就能下载到这个库:
如果没有看到这个库,可以去首选项添加一下附加开发板管理器网址:
https://github.com/espressif/arduino-esp32/releases/download/1.0.5/package_esp32_index.json
具体使用可以参考的我 arduino 超详细的开发入门指导 或者直接通过我上面发的 GitHub 网址下载。
代码解析
以下代码为了方便讲解,可能经过了调换了顺序或者裁剪。
这个 demo 是客户端、服务端一体的,只需要注册对应的回调函数就行。
初始化部分
这部分包括了设备初始化,协议初始化等部分,重点在服务器/客户端的回调函数部分。和 SDDC 官方demo类似,在这注册回调函数之后,通过对应的端点找到对应的回调函数。
#include <WiFi.h>
#include <WiFiUdp.h>
#include <coap-simple.h>
void setup() {
Serial.begin(115200);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
// LED State
pinMode(9, OUTPUT);
digitalWrite(9, HIGH);
LEDSTATE = true;
// 添加服务器url端点.
// 可以添加多个端点url.
// coap.server(callback_switch, "switch");
// coap.server(callback_env, "env/temp");
// coap.server(callback_env, "env/humidity");
Serial.println("Setup Callback Light");
// 其实就是注册服务器处理回调函数
// 将处理函数指针与url添加到 uri.add 中
coap.server(callback_light, "light");
// 注册客户端响应的回调函数。
// this endpoint is single callback.
Serial.println("Setup Response Callback");
// 很上面一样,其实就是把回调函数指针注册到resp里
coap.response(callback_response);
// 使用默认端口5683 启动 coap server/client
coap.start();
}
void loop() {
// 作为客户端时向coap服务器发送GET或PUT coap请求.
// 可以发送给另外一个 ESP32
// msgid = coap.put(IPAddress(192, 168, 128, 101), 5683, "light", "0");
// msgid = coap.get(IPAddress(192, 168, 128, 101), 5683, "light");
delay(1000);
coap.loop();
}
回调函数
// CoAP 服务器端点 URL ,对客户端发过来的命令进行处理并且回应
void callback_light(CoapPacket &packet, IPAddress ip, int port)
{
// 这是一个模拟控灯的回调函数,通过接收的命令
Serial.println("[Light] ON/OFF");
Serial.println(packet.messageid);
// 发送响应
char p[packet.payloadlen + 1];
memcpy(p, packet.payload, packet.payloadlen);
p[packet.payloadlen] = NULL;
String message(p);
if (message.equals("0"))
LEDSTATE = false;
else if(message.equals("1"))
LEDSTATE = true;
if (LEDSTATE) {
digitalWrite(9,