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

ESP8266学习

一,连接Wifi

1.Esp8266连接手机热点

AT

AT+RST
AT+CWMODE=1
AT+CWJAP="ESP8266","123456789"

手机查看连接信息

2.Esp8266连接手机热点进入透传模式

AT

AT+RST
AT+CWMODE=1
AT+CWJAP="ESP8266","123456789"

AT+CIPMUX=0
AT+CIPSTART="TCP","192.168.10.7",8080
AT+CIPMODE=1    //透传模式
AT+CIPSEND
AT+RESTORE

需要先发送 “+++” 来退出透传模式,之后才能进行 AT 指令的交互。

不加回车换行

AT+SAVETRANSLINK=1,"192.168.10.7",8080,"TCP",100        保存,上电后自动配置

AT+SAVETRANSLINK=1,"服务器IP",端口,"TCP"  // 保存透传配置(1 表示使能上电自动连接和自动进入透传模式。即模块在上电之后,会按照后续设定的参数自动连接目标服务器,并自动进入透传模式;如果设置为 0,则不会自动进行连接和进入透传,需要手动发送相关指令来操作。)100 表示模块上电后自动连接服务器时的超时时间

解释:

  1. AT:测试模块是否正常响应,正常会返回 "OK"
  2. AT+RST:重启模块,恢复初始状态
  3. AT+CWMODE=1:STA(站点)模式,模块作为客户端连接外部 WiFi(如路由器)AT+CWMODE=2:AP(接入点)模式,模块自身创建 WiFi 热点供其他设备连接AT+CWMODE=3:混合模式,同时具备 STA 和 AP 功能(既能连外部 WiFi,又能自建热点)
  4. AT+CWJAP="ESP8266","123456789":连接名为 "ESP8266"、密码 "123456789" 的 WiFi
  5. AT+CIPSTART="TCP","192.168.10.7",8080:建立 TCP 连接到 IP 为 192.168.10.7、端口 8080 的服务器
  6. AT+CIPMUX=0:设置为单连接模式(同一时间只保持一个连接)
  7. AT+CIPMODE=1:开启透传模式(串口数据直接通过 TCP 发送,无需额外指令)
  8. AT+CIPSEND:进入透传发送状态(此时可直接发送数据)
  9. AT+RESTORE:恢复模块出厂设置(清除所有配置)

二,两个ESP8266通信

1.一个配置服务器

  • AT+RST:用于复位 ESP8266 模块。
  • AT+CWMODE=2:设置模块的工作模式为 AP(接入点)模式,此时模块可作为热点,让其他设备连接。
  • AT+CWSAP="ESP8266","12345678",5,3:配置 AP 模式下的参数,设置热点名称为 “ESP8266”,密码为 “12345678”,信道为 5,加密方式为 WPA PSK。
  • AT+CIPMUX=1:将模块设置为多连接模式,支持同时与多个客户端建立连接。
  • AT+CIPSERVER=1,8080:建立服务器,端口为 8080,这样模块可监听来自客户端的连接请求。
  • AT+CIFSR:用于查询模块的 IP 地址等网络相关信息。

AT+CIPSEND=<连接ID>,<数据长度>

2.另一个单片机作为客户端

  • AT
  • AT+RST
  • AT+CWMODE=1
  • AT+CWJAP="ESP8266","123456789"
  • AT+CIPMUX=0
  • AT+CIPSTART="TCP","192.168.10.7",8080
  • AT+CIPMODE=1    //透传模式
  • AT+CIPSEND
  • AT+RESTORE

需要先发送 “+++” 来退出透传模式,之后才能进行 AT 指令的交互。

这样两个ESP8266就可以相互通信

程序:

服务器

一个程序是创建服务器,检测信息,是否连接,和获取的数据信息

这个程序,功能不完善,能简单获取设备号,和显示客户端发来的消息

#include "stm32f10x.h"
#include "OLED.h"
#include "Delay.h"
#include "usart.h"
#include "string.h"
#include "EXTI_KEY.h"extern const unsigned char BMP1[];
//extern const unsigned char BMP2[];#define BUFFER_SIZE 100  //缓冲区大小
char receiveBuffer[BUFFER_SIZE];  // 缓冲区
//uint16_t dht11[BUFFER_SIZE];  //
uint8_t receiveIndex = 0,copyreceive=0;  // 接收索引
uint16_t receivedChar=0;char server_ok=0,show=0;
char i=0,kehu=0,clear=0;void ESP8266_SendAT(char *p,char*q)
{USART_SendString(USART1,p);while((receiveBuffer[copyreceive-3]!=*q)&&(receiveBuffer[copyreceive-2]!=*(q+1)));memset(receiveBuffer,32,BUFFER_SIZE);
}void ESP8266_Init() 
{ESP8266_SendAT("AT\r\n", "OK");          // 测试模块ESP8266_SendAT("AT+CWMODE=2\r\n", "OK"); // 设为AP模式(手机/设备可连)ESP8266_SendAT("AT+CWSAP=\"ESP8266\",\"12345678\",5,3\r\n", "OK"); // AP名:ESP8266,密码:12345678ESP8266_SendAT("AT+CIPMUX=1\r\n", "OK"); // 多连接模式ESP8266_SendAT("AT+CIPSERVER=1,8080\r\n", "OK"); // 启动服务器,端口8080
}int main()
{char *customer;static uint8_t last_state = 0xFF; //记录上次状态// 硬件初始化EXTI_PE_Configuration();  // 中断按键配置OLED_Init();              // OLED初始化USART1_Config();          // 串口1配置(连ESP8266)ESP8266_Init();           // 初始化ESP8266服务器OLED_Clear();OLED_ShowString(1, 1, "Server Ready");  // 显示服务器就绪while(1){//模式1 显示客户端连接状态if(show == 1){OLED_ShowString(1,1,"Wait Connect");customer=receiveBuffer+2;if(strncmp(customer,"CONNECT",7)==0){uint8_t current_customer = *(customer-2) - '0';if(last_state!=current_customer){OLED_Clear();OLED_ShowString(1, 1, "Connected");switch(current_customer) {case 0:OLED_ShowString(2,1,"one customer");break;case 1:OLED_ShowString(2,1,"two customer");break;case 2:OLED_ShowString(2,1,"three customer");break;case 3:OLED_ShowString(2,1,"four customer");break;default:OLED_ShowString(2,1,"unknown");break;}OLED_ShowString(3,1,"status: on");last_state=current_customer;}show = 0;}}//显示客户端发送的数据if(show == 2){OLED_Clear();OLED_ShowString(1,1,"Wait Data");customer=receiveBuffer;if(strncmp(customer,"+IPD,",5)==0){OLED_ShowString(2,1,"Data:");OLED_ShowString(2,6,receiveBuffer+9); //+IPD,0,4:}show=0;}	}
}void USART1_IRQHandler(void)
{if (USART_GetITStatus(USART1, USART_IT_RXNE)!= RESET) {receivedChar = USART_ReceiveData(USART1);if (receivedChar!= '\n' && receiveIndex < BUFFER_SIZE - 1) {receiveBuffer[receiveIndex++] = receivedChar;} else {receiveBuffer[receiveIndex] = '\0';copyreceive=receiveIndex;receiveIndex = 0; }show =kehu;}
}
void EXTI0_IRQHandler(void)
{	static int mode=0;if(EXTI_GetITStatus(EXTI_Line0) != RESET) {mode = (mode >= 2) ? 1 : mode + 1;  // 模式1/2切换// 发1字节数据到服务器连接(ID=0)USART_SendString(USART1, "AT+CIPSEND=0,1\r\n");Delay_ms(100);USART_SendData(USART1, mode);  // 发模式值(1/2)Delay_ms(100);kehu = mode;  // 标记当前模式}  EXTI_ClearITPendingBit(EXTI_Line0);     
}

客户端

连接服务器,检测服务器发来的消息,为’1‘的话,发送数据

#include "stm32f10x.h"
#include "OLED.h"
#include "Delay.h"
#include "usart.h"
#include "string.h"
#include "dht11.h"extern const unsigned char BMP1[];
//extern const unsigned char BMP2[];
u8 temp;
u8 humi;
u8 tempp;
u8 humip;
#define BUFFER_SIZE 100  
char receiveBuffer[BUFFER_SIZE];  
uint8_t receiveIndex = 0,copyreceive=0; uint16_t instruction=0;char i=0,ready=0,show=0;
void ESP8266_AT(char *p,char*q)
{USART_SendString(USART1,p);while((receiveBuffer[copyreceive-3]!=*q)&&(receiveBuffer[copyreceive-2]!=*(q+1)));memset(receiveBuffer,32,BUFFER_SIZE);
}
void ESP8266_Init(void)
{USART_SendString(USART1, "+++");  // 发送退出指令Delay_ms(500);USART_SendString(USART1, "+++");Delay_ms(500);USART_SendString(USART1, "+++");OLED_ShowString(1,1,"ESP_Init");Delay_ms(500);ESP8266_AT("AT\r\n","OK");ESP8266_AT("AT+CWMODE=1\r\n","OK");ESP8266_AT("AT+CWJAP=\"ESP8266\",\"12345678\"\r\n","OK");ESP8266_AT("AT+CIPMUX=0\r\n","OK");ESP8266_AT("AT+CIPMODE=1\r\n","OK");ESP8266_AT("AT+CIPSTART=\"TCP\",\"192.168.4.1\",8080\r\n","OK");ESP8266_AT("AT+CIPSEND\r\n","OK");OLED_ShowString(4,1,"ESP_Init ok");Delay_s(1);
}int main()
{char tx[10];OLED_Init();USART1_Config();DHT11_Init();ESP8266_Init();ready=1;OLED_Clear();OLED_ShowString(1,1,"wait server");OLED_ShowString(2,1,"temp:");OLED_ShowString(3,1,"humi:");while(1){DHT11_Read_Data(&temp,&tempp,&humi,&humip);OLED_ShowNum(2,6,temp,2);OLED_ShowNum(3,6,humi,2);OLED_ShowString(2,8,".");OLED_ShowString(3,8,".");OLED_ShowNum(2,9,tempp,1);OLED_ShowNum(3,9,humip,1);if(show==1){OLED_ShowNum(4,1,instruction,2);show=0;}if(instruction==49){tx[0]='T';tx[1]=(temp/10)+'0';tx[2]=(temp%10)+'0';tx[3]='.';tx[4]=(tempp%10)+'0';tx[5]='\0';USART_SendString(USART1,tx);Delay_ms(500);tx[0] = 'H';                  tx[1] = (humi / 10) + '0';   tx[2] = (humi % 10) + '0';    tx[3] = '.';                  tx[4] = (humip % 10) + '0';   tx[5] = '\0';                 USART_SendString(USART1, tx);Delay_ms(500);  // 保持与温度发送相同的间隔}}}void USART1_IRQHandler(void)
{if (USART_GetITStatus(USART1, USART_IT_RXNE)!= RESET) {char receivedChar = USART_ReceiveData(USART1);if(ready==0){if (receivedChar!= '\n' && receiveIndex < BUFFER_SIZE - 1) {receiveBuffer[receiveIndex++] = receivedChar;} else {receiveBuffer[receiveIndex] = '\0';  copyreceive=receiveIndex;receiveIndex = 0;  }}if(ready==1){instruction=receivedChar;show=1;}}
}

三:MQTT连接

1.通信

无线通信                                                                                  通信协议

WIFI                                                                                           MQTT

NBIOT                                                                                        coap

GPRS                                                                                          HTTP

Lora

MQTT要保证实时连接

2.传输层协议

TCP和UDP的对比

对比维度

TCP

UDP

连接方式

面向连接(三次握手)

无连接

传输可靠性

可靠(不丢、有序)

不可靠(可能丢、乱序)

速度

较慢(多步骤确认)

快(无额外步骤)

资源开销

适用场景

需可靠(下载、聊天)

需快速(直播、游戏)

3.涉及的C 语言知识

Strlen函数和Sizeof函数:

相同点:字符数组的长度

不同点:是否包含结束标志’\0’

Strlen 不包含结束标志‘\0‘

Sizeof 包含结束标志’\0’

Memcpy

void *memcpy(void *str1,const void *str2,size_t n)

从存储区str2复制n个字节到存储区str1中

将一个内存数据复制到另一块中,即用于复制源空间的数据到目的空间

Memset 

void *memset(void *str, int c, size_t n) 

将已开辟内存空间 str 的首 n 个字节的值设置为指定的值 c

常用于初始化某个内存空间

Sprintf  头文件   stdio.h

Sprint函数数据打印到数组容器中

4.onenet平台

围绕设备→平台(上报事件) ” 和 “平台→设备(下发指令)

 设备数据上报平台

设备事件上报请求($sys/{pid}/{device-name}/thing/event/post 、发布权限)

  • 谁用:设备(比如传感器、智能终端 )
  • 干啥用:设备主动把自身的 “事件” 发给平台。
    举个例子:
    • 温湿度传感器检测到 “温度超限”,就通过向这个主题 发布(Publish) 消息,把 {"event":"temp_over","data":{"temp":35}}(意思是 “温度超限事件,当前温度 35℃” )这类数据上报给平台,让平台知道 “设备那边出状况了”。
    • 简单说就是 设备主动 “喊” 平台:我这有情况,你看看

设备事件上报响应($sys/{pid}/{device-name}/thing/event/post/reply 、订阅权限)

  • 谁用:还是设备(因为要接收平台回复 )
  • 干啥用:设备订阅这个主题,等平台回应。
    接着上面的例子:
    • 平台收到传感器 “温度超限” 事件后,可能回复 {"code":200,"msg":"已收到,将触发降温策略"}(意思是 “收到事件,会处理” )。
    • 设备因为订阅了这个主题,就能收到平台的 响应(Reply),知道 “平台接收到事件,下一步要干啥” 。
    • 简单说就是 设备等平台 “回话”,确认消息有没有处理、下一步咋做

设备接收平台下发命令

1. 设备属性设置请求($sys/{pid}/{device-name}/thing/property/set 、订阅权限 )

核心作用:平台→设备 “发指令” 的通道,让平台能远程要求设备修改自身属性(比如开关 LED、调整传感器采集频率 )。

  • 谁用:设备端(如单片机 + ESP8266 )需要 订阅(Subscribe) 这个主题,才能收到平台的指令。
  • 场景举例:
    平台想控制设备 “打开 LED”,就会往 $sys/{pid}/{device-name}/thing/property/set 主题发一条消息,内容可能是:

  • 设备因为订阅了这个主题,就能收到这条消息,知道 “平台要我改 LED 状态为开” 。
  • 通俗理解:平台通过这个主题 “远程喊话设备”:“你把某个属性改成 XX ,赶紧执行!”

2. 设备属性设置响应($sys/{pid}/{device-name}/thing/property/set_reply 、发布权限 )

核心作用:设备→平台 “回反馈” 的通道,让设备能告诉平台 “指令执行结果咋样了”(成功 / 失败、具体状态 )。

谁用:设备端执行完平台指令后,需要 发布(Publish) 消息到这个主题,回复平台。

场景举例:

设备收到 “打开 LED” 指令后,成功点亮了 LED ,就往 $sys/{pid}/{device-name}/thing/property/set_reply 发消息:

  • 平台收到后,就知道 “设备收到指令了,而且执行成功,LED 确实开了” 。
  • 通俗理解:设备通过这个主题 “回喊平台”:“你让我改的属性,我改完了!结果是 XX ,你看看对不对~”

设备数据上报平台

设备事件上报请求($sys/{pid}/{device-name}/thing/event/post 、发布权限)

  • 谁用:设备(比如传感器、智能终端 )
  • 干啥用:设备主动把自身的 “事件” 发给平台。
    举个例子:
    • 温湿度传感器检测到 “温度超限”,就通过向这个主题 发布(Publish) 消息,把 {"event":"temp_over","data":{"temp":35}}(意思是 “温度超限事件,当前温度 35℃” )这类数据上报给平台,让平台知道 “设备那边出状况了”。
    • 简单说就是 设备主动 “喊” 平台:我这有情况,你看看

设备事件上报响应($sys/{pid}/{device-name}/thing/event/post/reply 、订阅权限)

  • 谁用:还是设备(因为要接收平台回复 )
  • 干啥用:设备订阅这个主题,等平台回应。
    接着上面的例子:
    • 平台收到传感器 “温度超限” 事件后,可能回复 {"code":200,"msg":"已收到,将触发降温策略"}(意思是 “收到事件,会处理” )。
    • 设备因为订阅了这个主题,就能收到平台的 响应(Reply),知道 “平台接收到事件,下一步要干啥” 。
    • 简单说就是 设备等平台 “回话”,确认消息有没有处理、下一步咋做

设备接收平台下发命令

1. 设备属性设置请求($sys/{pid}/{device-name}/thing/property/set 、订阅权限 )

核心作用:平台→设备 “发指令” 的通道,让平台能远程要求设备修改自身属性(比如开关 LED、调整传感器采集频率 )。

  • 谁用:设备端(如单片机 + ESP8266 )需要 订阅(Subscribe) 这个主题,才能收到平台的指令。
  • 场景举例:
    平台想控制设备 “打开 LED”,就会往 $sys/{pid}/{device-name}/thing/property/set 主题发一条消息,内容可能是:

  • 设备因为订阅了这个主题,就能收到这条消息,知道 “平台要我改 LED 状态为开” 。
  • 通俗理解:平台通过这个主题 “远程喊话设备”:“你把某个属性改成 XX ,赶紧执行!”

2. 设备属性设置响应($sys/{pid}/{device-name}/thing/property/set_reply 、发布权限 )

核心作用:设备→平台 “回反馈” 的通道,让设备能告诉平台 “指令执行结果咋样了”(成功 / 失败、具体状态 )。

谁用:设备端执行完平台指令后,需要 发布(Publish) 消息到这个主题,回复平台。

场景举例:

设备收到 “打开 LED” 指令后,成功点亮了 LED ,就往 $sys/{pid}/{device-name}/thing/property/set_reply 发消息:

  • 平台收到后,就知道 “设备收到指令了,而且执行成功,LED 确实开了” 。
  • 通俗理解:设备通过这个主题 “回喊平台”:“你让我改的属性,我改完了!结果是 XX ,你看看对不对~”

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

相关文章:

  • 嵌入式开发学习———Linux环境下网络编程学习(六)
  • 驾驭 Glide 的引擎:深度解析 Module 与集成之道
  • 音视频学习(五十六):单RTP包模式和FU-A分片模式
  • ESP32开发WSL_VSCODE环境搭建
  • *解决 Visual Studio 编译时的字符编码问题
  • 41_基于深度学习的小麦病害检测识别系统(yolo11、yolov8、yolov5+UI界面+Python项目源码+模型+标注好的数据集)
  • 服务器(Linux)新账户搭建Pytorch深度学习环境
  • Linux(从入门到精通)
  • Wisdom SSH 核心功能定位与 sudo 权限配置指南
  • 四层Nginx代理日志配置
  • 2024年Engineering SCI2区,面向工程管理的无人机巡检路径与调度,深度解析+性能实测
  • Vue 2 中的 v-model和Vue3中的v-model
  • 设计模式:原型模式(Prototype Pattern)
  • 使用 HandlerMethodReturnValueHandler 在SpringBoot项目 实现 RESTful API 返回值自动封装,简化开发
  • 数据结构青铜到王者第三话---ArrayList与顺序表(2)
  • 零知开源——基于STM32F103RBT6和ADXL335实现SG90舵机姿态控制系统
  • three.js+WebGL踩坑经验合集(9.1):polygonOffsetUnits工作原理大揭秘
  • 【数据结构】LeetCode160.相交链表 138.随即链表复制 牛客——链表回文问题
  • [SC]SystemC动态进程概述及案例
  • LinkedIn 自动消息发送工具
  • 网络编程——TCP、UDP
  • 人工智能(AI)与网络安全
  • 【Linux】协议的本质
  • 一键脚本:自动安装 Nginx + Certbot + HTTPS(Let‘s Encrypt)
  • QT-QSS样式表
  • 面试:计算机网络
  • 《输赢》电视剧总结学习
  • 数据结构:红黑树(Red-Black Tree)
  • 电商秒杀场景下,深挖JVM内存泄漏与多线程死锁的解决方案
  • Python3.14安装包下载与保姆级图文安装教程!!