当前位置: 首页 > news >正文

第五十二章 ESP32S3 UDP 实验

        对于 lwIP 的 Socket 的使用方式,它与文件操作非常相似。在文件操作中,首先打开文件,然后进行读/写操作,最后关闭文件。在TCP/IP网络通信中,也存在着相同的操作流程,但所使用的接口不再是文件描述符或 FILE*,而是被称为 Socket 的描述符。通过 Socket,可以进行读、写、打开和关闭操作来进行网络数据的传输。此外,还有一些辅助函数,如查询域名/IP 地址和设置 Socket 功能等。在本章中,我们将使用 Socket 编程接口来实现 UDP 实验。
本章分为如下几个部分:
52.1 Socket 编程 UDP 连接流程
52.2 硬件设计
52.3 软件设计
52.4 下载验证

52.1 Socket 编程 UDP 连接流程

        在实现 UDP协议之前,用户需要按照以下步骤配置结构体 sockaddr_in的成员变量,以便建
立 UDP 连接:
①:配置 ESP32-S3 设备连接网络(必须的,因为 WiFi 是无线通信,所以需搭建通信桥梁)。
②:将 sin_family 设置为 AF_INET,表示使用 IPv4 网络协议。
③:设置 sin_port 为所需的端口号,例如 8080。
④:设置 sin_addr.s_addr 为本地 IP 地址。
⑤:调用函数 Socket 创建 Socket 连接。请注意,该函数的第二个参数指定连接类型。
SOCK_STREAM 表示 TCP 连接,而 SOCK_DGRAM 表示 UDP 连接。
⑥:调用函数 bind 将本地服务器地址与 Socket 进行绑定。
⑦:调用适当的收发函数来接收或发送数据。
通过遵循这些步骤,用户可以成功地配置并建立 UDP 连接,以实现数据的发送和接收。

52.2 硬件设计

1. 例程功能
本章实验功能简介:
本实验主要通过 Socket 编程接口实现了一个 UDP 服务器。这个服务器具有以下功能:
①:可以通过按键发送 UDP 广播数据给其他 UDP 客户端。
②:能够接收其他 UDP 客户端发送的广播数据。
③:实时将接收到的数据显示在 LCD 屏幕上。
通过这个实验,可深入了解 UDP 协议的工作原理,并掌握如何使用 Socket 编程接口来实现UDP通信。这对于开发基于UDP的网络应用程序非常有用,例如实时通信、多播应用等。

2. 硬件资源
1) LED 灯
LED-IO1
2) XL9555
IIC_INT-IO0(需在 P5 连接 IO0)
IIC_SDA-IO41
IIC_SCL-IO42
3) SPILCD
CS-IO21
SCK-IO12
SDA-IO11
DC-IO40(在 P5 端口,使用跳线帽将 IO_SET 和 LCD_DC 相连)
PWR- IO1_3(XL9555)
RST- IO1_2(XL9555)
4) ESP32-S3 内部 WiFi

3. 原理图
本章实验使用的 WiFi 为 ESP32-S3 的片上资源,因此并没有相应的连接原理图。

52.3 软件设计

52.3.1 程序流程图
本实验的程序流程图:

图 52.3.1.1 程序流程图

52.3.2 程序解析

        在本章节中,主要关注两个文件: lwip_demo.c 和 lwip_demo.h。 lwip_demo.h 文件主要定义了发送标志位并声明了 lwip_demo 函数,这部分相对简单,所以暂不详细解释。主要关注点是lwip_demo.c 文件中的函数。在 lwip_demo 函数中,我们配置了相关的 UDP 参数,并创建了一个名为 lwip_send_thread 的发送数据线程。这个线程通过调用 scokec 函数来发送数据到服务器。接下来,将分别详细解释 lwip_demo 函数和 lwip_send_thread 任务。

/* 需要自己设置远程IP地址 */
#define IP_ADDR   "192.168.1.2"#define LWIP_DEMO_RX_BUFSIZE         200    /* 最大接收数据长度 */
#define LWIP_DEMO_PORT               8080   /* 连接的本地端口号 */
#define LWIP_SEND_THREAD_PRIO       ( tskIDLE_PRIORITY + 3 ) /* 发送数据线程优先级 *//* 接收数据缓冲区 */
uint8_t g_lwip_demo_recvbuf[LWIP_DEMO_RX_BUFSIZE]; 
/* 发送数据内容 */
char g_lwip_demo_sendbuf[] = "I am ESP32 S3.\r\n";
/* 数据发送标志位 */
uint8_t g_lwip_send_flag;
static struct sockaddr_in dest_addr;            /* 远端地址 */
struct sockaddr_in g_local_info;
socklen_t g_sock_fd;                            /* 定义一个Socket接口 */
static void lwip_send_thread(void *arg);
extern QueueHandle_t g_display_queue;           /* 显示消息队列句柄 *//*** @brief       发送数据线程* @param       无* @retval      无*/
void lwip_data_send(void)
{xTaskCreate(lwip_send_thread, "lwip_send_thread", 4096, NULL, LWIP_SEND_THREAD_PRIO, NULL);
}/*** @brief       lwip_demo实验入口* @param       无* @retval      无*/
void lwip_demo(void)
{char *tbuf;lwip_data_send();                                           /* 创建发送数据线程 *//* 远端参数设置 */dest_addr.sin_addr.s_addr = inet_addr(IP_ADDR);             /* 目标地址 */dest_addr.sin_family = AF_INET;dest_addr.sin_port = htons(LWIP_DEMO_PORT);                 /* 目标端口 */g_local_info.sin_family = AF_INET;                          /* IPv4地址 */g_local_info.sin_port = htons(LWIP_DEMO_PORT);              /* 设置端口号 */g_local_info.sin_addr.s_addr = htons(INADDR_ANY);           /* 设置本地IP地址 */g_sock_fd = socket(AF_INET, SOCK_DGRAM, 0);                 /* 建立一个新的socket连接 */tbuf = malloc(200);                                         /* 申请内存 */sprintf((char *)tbuf, "Port:%d", LWIP_DEMO_PORT);           /* 客户端端口号 */spilcd_show_string(0, 170, 200, 16, 16, tbuf, MAGENTA);/* 建立绑定 */bind(g_sock_fd, (struct sockaddr *)&g_local_info, sizeof(g_local_info));while (1){memset(g_lwip_demo_recvbuf, 0, sizeof(g_lwip_demo_recvbuf));int rcvDataSize = recv(g_sock_fd, (void *)g_lwip_demo_recvbuf, sizeof(g_lwip_demo_recvbuf), 0);if (rcvDataSize > 0){printf("%s\r\n", g_lwip_demo_recvbuf);}}
}/*** @brief       发送数据线程函数* @param       pvParameters : 传入参数(未用到)* @retval      无*/
void lwip_send_thread(void *pvParameters)
{pvParameters = pvParameters;while (1){if ((g_lwip_send_flag & LWIP_SEND_DATA) == LWIP_SEND_DATA)      /* 有数据要发送 */{// printf("send\r\n");sendto(g_sock_fd,                                           /* scoket */(char *)g_lwip_demo_sendbuf,                          /* 发送的数据 */sizeof(g_lwip_demo_sendbuf), 0,                       /* 发送的数据大小 */(struct sockaddr *)&dest_addr,                        /* 接收端地址信息 */ sizeof(dest_addr));                                   /* 接收端地址信息大小 */g_lwip_send_flag &= ~LWIP_SEND_DATA;}vTaskDelay(100);}
}

        在源码中, lwip_demo函数通过 lwip_data_send创建了发送数据的线程 lwip_send_thread,并配置了 Socket 的 UDP 协议。该线程在发送前会检查标志位,有效时则通过 sendto 发送数据并重置标志位。同时,需设置目标 IP 地址以确保数据正确发送。此外,主函数的循环中不断通过recv 接收数据并使用串口输出接收的数据。

52.4 下载验证

        实验前需要在程序中,将相关配置修改为自己的配置,具体下面两点:

  • Wifi账号和密码:首先需要设置好能够连接的网络账号(将宏DEFAULT_SSID修改为自己的账号,将宏DEFAULT_PWD修改为自己的密码);
  • 电脑IP地址:设置自己电脑的远程IP地址(修改宏IP_ADDR为自己电脑IP地址,方法是在Windows的命令提示符中输入ipconfig,就会看到电脑IP地址)。

        然后,使用电脑作为终端,确保它与 ESP32-S3 设备处于同一网络段内。当 ESP32-S3 设备成功连接到网络时,它的 LCD 显示屏上会显示相应的内容:

图 52.4.1 设备连接到网络时 LCD 显示的信息

        打开网络调试助手,然后配置网络参数,如 UDP 协议、端口号、目标主机设置等,设置内容如下图所示,在确保网络连接正常后,通过按下开发板上的 KEY0 按键来发送数据(存在数组g_lwip_demo_sendbuf[] = "I am ESP32 S3.\r\n";)至网络调试助手。
当网络调试助手接收到开发板发送的字符串时,它会在显示区域展示这个信息。此外,用户还可以在调试助手的发送区域输入要发送的数据,然后点击发送键("I am a computer."),将数据发送至ESP32-S3 设备。此时, ESP32-S3 的串口将打印接收到的数据,具体操作和输出如下图所示。

图 52.4.3 接收网络调试助手的数据

http://www.dtcms.com/a/456848.html

相关文章:

  • [鹤城杯 2021]Misc2
  • 山东省旅游网站建设网络设计是干什么的工作
  • 基于 ZYNQ ARM+FPGA+AI YOLOV4 的电网悬垂绝缘子缺陷检测系统的研究
  • 开源 C++ QT QML 开发(十二)通讯--TCP客户端
  • 【密码学实战】openHiTLS pkeyutl命令行:公钥实用工具(加解密、密钥交换)
  • 做标书有什么好的网站吗网站改版不收录
  • JDK17和JDK8的 G1
  • win10安装conda环境
  • TDengine 浮点数新编码 BSS 用户手册
  • mybatis call存储过程,out的参数怎么返回
  • 今日八股——JVM篇
  • 【论文阅读】REACT: SYNERGIZING REASONING AND ACTING IN LANGUAGE MODELS
  • 沈阳做网站比较好的公司做网站需要会的软件
  • ubuntu22.04安装gvm管理go
  • 基于单片机的智能点滴输液速度与液位控制系统设计
  • 嵌入式开发学习日志38——stm32之看门狗
  • golang面经——内存相关模块
  • 成都政务网站建设怎样做视频网站
  • 架构设计常画哪些图
  • 自然语言处理分享系列-词向量空间中的高效表示估计(一)
  • RNN的注意力机制:原理与实现(代码示例)
  • Flutter bottomNavigationBar 底部导航栏
  • 做男装去哪个网站好的网站开发工具有哪些
  • 【Spring 3】深入剖析 Spring 的 Prototype Scope:何时以及如何使用非单例 Bean
  • asp.net+mvc+网站开发wordpress 手机端页面
  • 【开题答辩全过程】以 爱篮球app为例,包含答辩的问题和答案
  • 深入理解跨域问题与解决方案
  • 从零搭建 RAG 智能问答系统1:基于 LlamaIndex 与 Chainlit实现最简单的聊天助手
  • Redis核心通用命令解析
  • 后端(JavaWeb)学习笔记(CLASS 1):maven