版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Naisu_kun/article/details/80261553
目的
UDP协议是一种比较方便的通讯协议,只要知道IP地址和端口号就可以进行通讯了。对于ESP8266来说UDP通讯功能自然是最基本包含的了。
设置UDP功能
在Arduino for esp8266中使用UDP功能首先需要包含下面两个头文件:
#include <ESP8266WiFi.h> //ESP8266基本网络功能
#include <WiFiUdp.h> //提供UDP相关功能
引用头文件后设置UDP功能只需两步:
WiFiUDP Udp; //建立一个UDP对象
Udp.begin(localUdpPort); //开始监听端口号localUdpPort
//端口号理论上0~65535随便用,但是一般在这里使用1024~49151间的
只要上面两步UDP功能就初始化完毕了,下面就可以进行数据收发了,方便快速。
通过UDP收发数据
接收数据
接收数据方式分两步进行:
1. 首先调用 parsePacket()
检测是否有数据可读取,如果返回值为0 则无数据可用,否则返回接收数据包队列中队首数据的长度;
2. 如果数据有可用就可以调用 read()
方法读取队首数据;
char incomingPacket[255]; // 准备一个缓冲区用于读取数据
int packetSize = Udp.parsePacket(); //获取当前队首数据包长度
//所有收到的数据会以包为单位放进队列
//在调用read()方法前必须先调用此方法
if (packetSize) //如果数据包可用
{
int len = Udp.read(incomingPacket, 255); //读取数据到incomingPacket
}
发送数据
发送数据只要按如下方式进行便可:
Udp.beginPacket(Udp.remoteIP(), Udp.remotePort()); //准备发送,分别填写目标IP和端口号
Udp.write("Hello World"); //发送数据,该方法必须介于beginPacket()和endPacket()之间
Udp.endPacket();
通过UDP通讯控制LED
综合UDP启用、接收、发送功能控制LED点亮熄灭,并回复消息,代码如下:
#include <ESP8266WiFi.h>
#include <WiFiUdp.h>
const char *ssid = "********"; //网络名称
const char *password = "********"; //网络密码
WiFiUDP Udp;
unsigned int localUdpPort = 2333; // 本地端口号
char incomingPacket[537]; // 接收缓冲区
void setup()
{
//以下为基本功能初始化,初始化串口和网络和LED
pinMode(2, OUTPUT);
Serial.begin(115200);
Serial.println();
Serial.printf("Connecting to %s ", ssid);
WiFi.mode(WIFI_STA);
WiFi.setAutoConnect(false);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED)
{
delay(500);
Serial.print(".");
}
Serial.println(" connected");
//以下开启UDP监听并打印输出信息
Udp.begin(localUdpPort);
Serial.printf("Now listening at IP %s, UDP port %d\n", WiFi.localIP().toString().c_str(), localUdpPort);
}
void loop()
{
int packetSize = Udp.parsePacket(); //获取当前队首数据包长度
if (packetSize) // 有数据可用
{
Serial.printf("Received %d bytes from %s, port %d\n", packetSize, Udp.remoteIP().toString().c_str(), Udp.remotePort());
int len = Udp.read(incomingPacket, 536); // 读取数据到incomingPacket
if (len > 0) // 如果正确读取
{
incomingPacket[len] = 0; //末尾补0结束字符串
Serial.printf("UDP packet contents: %s\n", incomingPacket);
if (strcmp(incomingPacket, "Turn off") == 0) // 如果收到Turn off
{
digitalWrite(2, HIGH); // 熄灭LED
Udp.beginPacket(Udp.remoteIP(), Udp.remotePort());
Udp.write("LED has been turn off"); // 回复LED has been turn off
Udp.endPacket();
}
else if (strcmp(incomingPacket, "Turn on") == 0) // 如果收到Turn on
{
digitalWrite(2, LOW); // 点亮LED
Udp.beginPacket(Udp.remoteIP(), Udp.remotePort());
Udp.write("LED has been turn on"); // 回复LED has been turn on
Udp.endPacket();
}
else // 如果非指定消息
{
Udp.beginPacket(Udp.remoteIP(), Udp.remotePort());
Udp.write("Data Error!"); // 回复Data Error!
Udp.endPacket();
}
}
}
}
可以用网络通讯调试工具和串口监视器看到完整的通讯过程:
总结
使用Arduino for esp8266可以非常简单实现UDP通讯过程,更多详细内容可以参考如下:
UDP功能示例:
https://arduino-esp8266.readthedocs.io/en/latest/esp8266wifi/udp-examples.html
UDP功能库说明:
https://arduino-esp8266.readthedocs.io/en/latest/esp8266wifi/udp-class.html
文中所用网络通讯调试工具:
https://packetsender.com/