STM32物联网(封装AT指令进行TCP连接及数据的接收和发送)

文章目录

  • 前言
  • 一、AT指令函数封装
    • 1.向ESP8266发送数据函数
    • 2.设置ESP8266工作模式
    • 3.连接WIFI函数
    • 4.查询IP地址
    • 5.连接TCP服务器
    • 6.发送数据到TCP服务器
    • 7.接收并解析来自TCP服务器的数据
    • 8.关闭TCP服务器
  • 二、代码测试
  • 总结


前言

本篇文章将继续带大家学习STM32物联网,那么在这篇文章中将会封装对应AT指令操作的函数来进行WIFI连接以及TCP的连接。

一、AT指令函数封装

1.向ESP8266发送数据函数

我们需要封装一个函数来给ESP8266发送AT指令。

ESP8266连接到了开发板的串口3,实验直接使用HAL_UART_Transmit来向串口3发送数据即可。

//发送命令给ESP8266
void ESP8266_SendCommand(const char* command)
{
	HAL_UART_Transmit(&huart3, (uint8_t *)command, strlen(command), 10000);
}

2.设置ESP8266工作模式

设置wifi模式的指令:
在这里插入图片描述

直接使用封装好的函数进行连接即可。

ESP8266_SendCommand("AT+CWMODE=3\r\n");

3.连接WIFI函数

连接wifi函数如下:
在这里插入图片描述

//连接wifi
void ESP8266_ConnectWiFi(const char* ssid, const char* pass) 
{
  char cmd[100];
  
  // 发送命令:AT+CWJAP="YourWiFiSSID","YourWiFiPassword"
  sprintf(cmd, "AT+CWJAP=\"%s\",\"%s\"\r\n", ssid, pass);
  ESP8266_SendCommand(cmd);  
}

函数的输入是 Wi-Fi 网络的 SSID 和密码。这些参数是指向 char 数组的指针。ssid 是要连接的 Wi-Fi 网络的 SSID (Service Set Identifier),而 pass 则是该 Wi-Fi 网络的密码。

首先,该函数声明了一个长度为100的字符数组 cmd 用于存储最终发送到 ESP8266 模块的 AT 命令。

使用 sprintf 函数将 Wi-Fi SSID 和密码拼接到一个格式化的字符串中,这个字符串是一个包含了 Wi-Fi SSID 和密码的 AT 命令,格式为 “AT+CWJAP=“SSID”,“PASSWORD”\r\n”,其中 “SSID” 和 “PASSWORD” 部分会被传入的 ssid 和 pass 替换。

最后,将格式化后的 AT 命令通过 ESP8266_SendCommand 函数发送给 ESP8266 模块,使其连接到指定的 Wi-Fi 网络。

4.查询IP地址

查询IP地址指令如下:

在这里插入图片描述

ESP8266_SendCommand("AT+CIFSR\r\n");//查询AP地址

5.连接TCP服务器

下面是连接TCP连接的代码:
在这里插入图片描述

//连接TCP服务器
void ESP8266_ConnectTCPServer(const char* ServerIP, int ServerPort)
{
	// 定义一个缓冲区用于存储命令字符串
	char cmd[100];

	// 发送连接到TCP服务器的命令
	// 例如:AT+CIPSTART="TCP","192.168.1.100",80
	sprintf(cmd, "AT+CIPSTART=\"TCP\",\"%s\",%d\r\n", ServerIP, ServerPort);
	ESP8266_SendCommand(cmd);	
}

函数的输入参数是 ServerIP 和 ServerPort。ServerIP 是要连接的服务器的 IP 地址,以字符串形式传入。ServerPort 是服务器的端口号,以整数形式传入。

首先,函数声明了一个长度为 100 的字符数组 cmd,用于存储最终发送到 ESP8266 模块的 AT 命令。

使用 sprintf 函数将服务器的 IP 地址和端口号拼接到一个格式化的字符串中,形成一个 AT 命令,格式为 “AT+CIPSTART=“TCP”,“ServerIP”,ServerPort\r\n”,其中 “ServerIP” 和 ServerPort 部分会被传入的 ServerIP 和 ServerPort 替换。

最后,将格式化后的 AT 命令通过 ESP8266_SendCommand 函数发送给 ESP8266 模块,以连接到指定的 TCP 服务器。

6.发送数据到TCP服务器

下面是发送数据到TCP服务器的函数:
在这里插入图片描述

//发送数据到TCP服务器
void ESP8266_SendToTCPServer(const char* txData)
{
    // 发送命令:AT+CIPSEND=<length>
    char cmd[100];
    sprintf(cmd, "AT+CIPSEND=%d\r\n", strlen(txData));
    ESP8266_SendCommand(cmd);
    HAL_Delay(100);
    // 发送数据
    ESP8266_SendCommand(txData);	
}

7.接收并解析来自TCP服务器的数据

uint8_t esp8266_rxbuf[RECVBUFSIZE] = {0};//用于保存ESP8266发来的数据

//空闲中断回调函数
void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)
{
	if(huart->Instance == USART3)
	{		
		printf("%s", esp8266_rxbuf);
		ESP8266_PraseToTCPServer((const char*)esp8266_rxbuf);
		memset(esp8266_rxbuf, 0, sizeof(esp8266_rxbuf));//清空接收到的数据
		HAL_UARTEx_ReceiveToIdle_DMA(&huart3, esp8266_rxbuf, RECVBUFSIZE);
	}
}

//解析ESP8266接收到的TCP数据
void ESP8266_PraseToTCPServer(const char* rxdata)
{
		//检查数据中是否含有IPD
    char *ipdPtr = strstr(rxdata, "IPD");
    if (ipdPtr != NULL)
		{
			// 找到消息内容的起始位置
			char *ptr = strstr(rxdata, ":");
			if (ptr != NULL) 
			{
					char* message = ptr + 1;
					printf("\r\n.....................\r\n");
					printf("recvmsg : %s\r\n", message);
					printf(".....................");
			}
		}			
}

uint8_t esp8266_rxbuf[RECVBUFSIZE] = {0};: 定义了一个长度为 RECVBUFSIZE 的缓冲区 esp8266_rxbuf,用于保存 ESP8266 模块接收到的数据。

void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size): 这是一个空闲中断回调函数。当 UART 接收到足够数量的数据后,会触发空闲中断,进入这个回调函数。在这个回调函数中,首先检查 huart->Instance 是否为 USART3,以确保是与 ESP8266 通信的 UART。然后,通过 printf(“%s”, esp8266_rxbuf); 打印接收到的数据,接着调用 ESP8266_PraseToTCPServer 函数对接收到的数据进行解析,最后通过 memset 清空接收缓冲区,准备接收下一次的数据。

void ESP8266_PraseToTCPServer(const char* rxdata): 这个函数用于解析从 TCP 服务器接收到的数据。首先,通过 strstr 函数检查数据中是否包含 “IPD”,表示接收到了一个 TCP 数据包。如果找到了 “IPD”,则继续寻找 “:”,找到消息内容的起始位置。接着,通过 printf 打印接收到的消息内容。

8.关闭TCP服务器

下面是关闭TCP服务器的AT指令:
在这里插入图片描述

//关闭TCP服务
void ESP8266_CLOSETCP(void)
{
	ESP8266_SendCommand("AT+CIPCLOSE\r\n");
}

二、代码测试

先使用手机开一个热点,这个热点要是2.4GHZ的频段。

让STM32 通过ESP8266连接到手机热点,让电脑也连接到手机热点,让他们处于同一个局域网下。然后就可以让STM32作为客户端和电脑建立TCP连接进行数据之间的通信。
在这里插入图片描述
开启TCP服务器:

在这里插入图片描述
将代码烧录到ESP8266中:
在这里插入图片描述

测试结果表明可以进行正常的数据收发。
在这里插入图片描述

总结

本篇文章就讲解到这里,下篇文章将带大家继续学习。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/405425.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

基于事件触发机制的孤岛微电网二次电压与频率协同控制MATLAB仿真模型

微❤关注“电气仔推送”获得资料&#xff08;专享优惠&#xff09; 本模型质量非常高&#xff0c;运行效果完美。本模型为4机并联孤岛系统&#xff0c;在下垂控制的基础上加入二次控制&#xff0c;二次电压与频率协同控制策略利用事件触发的方法来减少控制器的更新次数。该方法…

2024图像处理分析与信息工程国际学术会议(IACIPIE2024)

2024图像处理分析与信息工程国际学术会议(IACIPIE2024) 会议简介 2024图像处理分析与信息工程国际学术会议&#xff08;IACIPIE2024&#xff09;将在中国长沙举行。 IACIPIE2024是一个年度会议&#xff0c;探讨图像处理分析和信息工程相关领域的发展和影响&#xff0c;旨在介…

树莓派 开启 I2C

sudo raspi-config喜欢或对你有帮助&#xff0c;点个赞吧&#xff0c;自己先点个嘿嘿。 有错误或者疑问还请评论指出。 我的个人网站 点击访问 hongweizhu.com。 END

第十二天-ppt的操作

目录 创建ppt文档 安装 使用 段落的使用 段落添加数据 段落中定义多个段落 自定义段落 ppt插入表表格 PPT插入图片 读取ppt 读取ppt整体对象 ​编辑 获取ppt文本 获取表格内容 创建ppt文档 安装 pip install -i https://pypi.tuna.tsinghua.edu.cn/simple python…

新能源汽车PACK电池包的气密性测试需要用到哪些快速密封连接器

PACK电池包是新能源汽车的重要部件之一&#xff0c;在全部组装完成后需要对其壳体进行气密性测试&#xff0c;以确保壳体的密封性能&#xff0c;避免有雨水、灰尘等外界侵扰拒之门外&#xff0c;从而保证电池的使用寿命不受损害。 新能源汽车PACK电池包 在做气密性测试时需要用…

力扣经典题目解析--旋转图像(字节二面)

题目 原题地址: . - 力扣&#xff08;LeetCode&#xff09; 给定一个 n n 的二维矩阵 matrix 表示一个图像。请你将图像顺时针旋转 90 度。 你必须在 原地 旋转图像&#xff0c;这意味着你需要直接修改输入的二维矩阵。请不要 使用另一个矩阵来旋转图像。 示例 1&#xff1…

如何使用ChatGPT创建一份优质简历

目录 第一步&#xff1a;明确目标和重点 第二步&#xff1a;与ChatGPT建立对话 第三步&#xff1a;整理生成的内容 第四步&#xff1a;注重行文风格 第五步&#xff1a;强调成就和量化结果 第六步&#xff1a;个性化和定制 第七步&#xff1a;反复修改和完善 总结 在现…

接口自动化如何处理用例依赖?

情况一 获取token 需要在所有接口用例前执行的用例&#xff0c;如登录接口获取到token。 这种情况不适合将这个获取token的方法写到任何一个测试用例文件里&#xff0c;应该写成fixture&#xff0c;并写入conftest文件&#xff0c;供全局使用。 如图&#xff0c;fixture获取到…

浅拷贝导致的bug

错误代码&#xff1a; //初始化formTableData的值 const formTableData ref({saleOrderTime:,saleOrderDetails:[] });const showModal async (item) > {//调接口获取后端返回的数据let data (await api.searchSaleOrderById({saleOrderId:item.id})).dataconsole.log(&…

open3d 连接两个点云

连接两个点云 一、连接两个点云二、代码三、结果1.coloud1点云2.cloud2点云3.cloud1 和 colud2 合并4.生成连接字段&#xff08;拼接颜色&#xff09; 四、相关链接五、问题与解决方案1.问题2.解决方案 一、连接两个点云 看代码吧。。。 二、代码 import numpy as np import…

1TB! 台湾最新倾斜摄影3DTiles数据分享

之前的文章分享了546GB香港倾斜摄影3DTiles数据&#xff0c;主要是验证倾斜模型3DTiles转换工具的生产效率和数据显示效率&#xff0c;结果对比可以看出无论是数据生产速度以及成果数据显示效率上&#xff0c;都优于其他两种技术路线。最近使用倾斜模型3DTiles工具生产了台湾地…

Zookeeper简介及选举机制

1.概述 Zookeeper是一个开源的&#xff0c;分布式的&#xff0c;为分布式框架&#xff08;如下图中的Hadoop和Hive&#xff09;提供协调服务的Apache项目。 工作机制&#xff1a;基于观察者设计模式的分布式服务管理框架&#xff0c;负责存储和管理数据&#xff0c;接受观察者…

查看navicat保存的数据库连接密码

背景 经常使用navicat的朋友可能会碰到忘记数据库连接密码的情况&#xff0c;自然会想到navicat连接配置中就保存了密码。 个人经验&#xff0c;按以下步骤可查看密码明文 本人在mac上使用的navicat版本 1&#xff0c;导出connection_local.ncx 点击OK导出保存为connection_l…

文件上传失败原因汇总(个人情况总结)

1.后端配置application里有服务限制大小 # Spring spring:servlet:multipart:max-file-size: 500MBmax-request-size: 500MB 2.如果你用了dubbo&#xff0c;要调整生产者和消费者超时时间以及payload大小&#xff0c;最好是dubbo自增策略&#xff0c;防止用了dubbo的服务端口冲…

项目优化-

前言 用户浏览菜品&#xff0c;添加购物车&#xff0c;下单等操作最终都会反映成一个sql&#xff0c;操作数据库。 但是当前系统只部署了一台数据库&#xff0c;读和写所有压力都由一台数据库承担&#xff0c;压力大&#xff1b;如果数据库服务器磁盘损坏则数据丢失&#xff0…

Flutter(一):安装和环境配置、创建Flutter项目

安装和环境配置、创建Flutter项目 Flutter 下载方式1方式2 Flutter 环境配置配置国内镜像站点解压 Flutter将 flutter 添加到系统环境变量中运行 flutter doctor来验证安装 Android Studio下载插件创建项目安装 Android SDK 工具在模拟器上运行 Flutter 下载 方式1 全版本&…

谈谈六西格玛(6σ)

什么是六西格玛&#xff08;6σ&#xff09;&#xff1f; 六西格玛&#xff08;6σ&#xff09;是一种管理方法和质量改进体系&#xff0c;旨在减少组织过程中的变异性&#xff0c;提高业务绩效&#xff0c;并实现客户满意度的持续提升。它由美国Motorola公司在20世纪80年代发…

liunx文件权限和内核

liunx文件权限和内核 liunx内核liunx权限liunx用户用户的切换liunx文件权限属性liunx文件默认权限liunx文件权限的粘滞位 liunx内核 liunx内核模拟图 在liunx中内核可以想象成一堆软件。由于内核过于复杂&#xff0c;我们并不想直接操作内核。因为内核1. 内核过于复杂&#x…

超级抽象的前端2

vue3的调用方法失败的原因 function validateConfirm(rule, value, callback) {if (value ! form.password) {callback(new Error(两次输入的密码不一致))} else {callback()}function showAgreement() {dialogVisible.value true}function submitForm() {// 这里是提交表单的…

ROS1查看版本

目录 方法一方法二 方法一 rosversion -d方法二