蓝牙与wifi模块

蓝牙

蓝牙模块,又叫做蓝牙串口模块

串口透传技术

透传即透明传送,是指在数据的传输过程中,通过无线的方式这组数据不发生任何形式的改变,仿佛传输过程是透明的一样,同时保证传输的质量,原封不动地到了最终接收者手里。

以太网,蓝牙,Zigbee, GPRS 等模块玩法一样,对嵌入式程序员来说,不需要关心通讯模块内部数据

及协议栈工作原理,只要通过串口编程获得数据即可

接线

串口交叉相连

单片机 蓝牙模块
RX TX
TX RX
VCC VCC
GND GND

Wifi模块ESP-01s

AT指令

AT指令集是从终端设备(Terminal Equipment,TE)或数据终端设备(Data TerminalEquipment,DTE)向终端适配器(Terminal Adapter,TA)或数据电路终端设备(Data CircuitTerminal Equipment,DCE)发送的。

其对所传输的数据包大小有定义:即对于AT指令的发送,除AT两个字符外,最多可以接收1056个字符的长度(包括最后的空字符)。

每个AT命令行中只能包含一条AT指令;对于由终端设备主动向PC端报告的URC指示或者response响应,也要求一行最多有一个,不允许上报的一行中有多条指示或者响应。AT指令以回车作为结尾,响应或上报以回车换行为结尾。

ESP-01s出厂波特率正常是115200, 注意:AT指令,控制类都要加回车,数据传输时不加回车

  • 上电后,通过串口输出一串系统开机信息,购买的部分模块可能电压不稳,导致乱码,以 ready 为 准
1
2
3
4
5
6
7
8
9
################################################ 
arch:ESP8266, 1
compile_time:Ai-Thinker|B&T
wifi_mac:4c75250dAE2F
sdk_version:v3.4-22-g967752e2
firmware_version:2.2.0
compile_time:Jun 30
2021 11:28:20 ready
################################################
  • 上电后发送AT指令测试通信及模块功能是否正常

发送AT

返回OK 就没问题了

  • 通过一下命令配置成9600波特率

AT+UART=9600,8,1,0,0

入网设置

  • 设置工作模式

AT+CWMODE=3 //1. 是station(设备)模式 2.是AP(路由)模式 3.是双模

OK

  • 以设备模式接入家中路由器配置

AT+CWJAP="wifi名字","wifi密码" //指令

WIFI CONNECTED //结果

WIFI GOT IP //结果

这里 连接wifi的时候 只能连接2.4G的wifi 5Gwifi不支持

查询IP地址

AT+CIFSR

1
2
3
4
+CIFSR:APIP,"192.168.4.1"
+CIFSR:APMAC,"a6:e5:7c:1e:c5:96"
+CIFSR:STAIP,"192.168.3.52"
+CIFSR:STAMAC,"a4:e5:7c:1e:c5:96"

连接到 TCP server

开关网络助手,设立TCP服务器

image-20220704165833278

AT+CIPSTART="TCP","192.168.3.19",1234

CONNECT //结果:成功

OK //结果:成功

发送数据

AT+CIPSEND=4 // 设置即将发送数据的长度 (这里是4个字节)

>CLCA // 看到大于号后,输入消息,CLCA,不要带回车

Response :SEND OK //结果:成功

//注意,这种情况下,每次发送前都要先发送AT+CIPSEND=长度 的指令,再发数据!

透传

  • 未设置透传模式 每次发送数据都要进行字符长度设定,如果设置成透传,就有点像蓝牙模块的玩法

在连接到socket服务后

AT+CIPMODE=1 //开启透传模式

Response :OK 返回

AT+CIPSEND //带回车

Response: >

退出透传模式

//在透传发送数据过程中,若识别到单独的⼀包数据 “+++”,则退出透传发送

通过socket控制LED小灯

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
#include <REG52.H>
#include <STDIO.H>
#include<STRING.H>
#define SIZE 16
sfr AUXR = 0x8E;
sbit LED = P3 ^ 7;
sbit LED2 = P3 ^ 6;

code char LJWL[] = "AT+CWJAP=\"liuxu\",\"liuxu123121\"\r\n"; //入网指令
code char LJFWQ[] = "AT+CIPSTART=\"TCP\",\"192.168.3.19\",1234\r\n";//连接服务器
code char TCMS[] = "AT+CIPMODE=1\r\n"; //透传指令
code char FSSJ[] = "AT+CIPSEND\r\n"; //数据传输开始指令
code char RESET[] = "AT+RST\r\n"; //重启模块指令
char AT_OK_Flag = 0; //OK返回值的标志位
char AT_Connect_Net_Flag = 0;//WIFI GOT IP返回值的标志位

void Delay1000ms() //@11.0592MHz
{
unsigned char i, j, k;
i = 8;
j = 1;
k = 243;
do
{
do
{
while (--k)
;
} while (--j);
} while (--i);
}
void UartInit(void) // 9600bps@11.0592MHz
{
AUXR = 0x01;
SCON = 0x50; //配置串口工作方式1,REN使能接收
TMOD &= 0xF0;
TMOD |= 0x20; //定时器1工作方式位8位自动重装
TH1 = 0xFD;
TL1 = 0xFD; // 9600波特率的初值
TR1 = 1; //启动定时器
EA = 1; //开启总中断
ES = 1; //开启串口中断
}
void sendByte(char data_msg)
{
SBUF = data_msg;
while (!TI)
;
TI = 0;
}
void SendString(char *str)
{
while (*str != '\0')
{
sendByte(*str);
str++;
}
}
char buffer[16];
void main()
{
LED = 1;
LED2 = 1;
UartInit();
Delay1000ms();
SendString(LJWL);
while (!AT_Connect_Net_Flag);
while (!AT_OK_Flag);
AT_OK_Flag = 0;

SendString(LJFWQ);
while (!AT_OK_Flag);
AT_OK_Flag = 0;

SendString(TCMS);
while (!AT_OK_Flag);
AT_OK_Flag = 0;

SendString(FSSJ);
while (!AT_OK_Flag);

if (AT_Connect_Net_Flag){
LED = 0;
}
if (AT_OK_Flag){
LED2 = 0;
}
while (1)
{
{
SendString("xiaoliutongxue NB\r\n");
Delay1000ms();
}
}
}
void UART_Hander() interrupt 4
{
static int i = 0; //静态变量,被初始化一次
char tmp;
if (RI) //中断处理函数中,对于接收中断的响应
{
RI = 0; //清除接收中断标志位
tmp = SBUF;
if (tmp == 'W' || tmp == 'O' || tmp == 'L' || tmp == 'F')
{
i = 0;
}
buffer[i++] = tmp; //入网成功的判断依据WIFI GOT IP
if (buffer[0] == 'W' && buffer[5] == 'G')
{
AT_Connect_Net_Flag = 1;
memset(buffer, '\0', SIZE);
} //连接服务器等OK返回值指令的判断
if (buffer[0] == 'O' && buffer[1] == 'K')
{
AT_OK_Flag = 1;
memset(buffer, '\0', SIZE);
} //联网失败出现FAIL字样捕获
if (buffer[0] == 'F' && buffer[1] == 'A')
{
for (i = 0; i < 5; i++)
{
LED = 0;
Delay1000ms();
LED = 1;
Delay1000ms();
}
SendString(RESET);
memset(buffer, '\0', SIZE);
} //灯控指令
if (buffer[0] == 'L' && buffer[2] == '1')
{
LED = 0; //点亮D5
memset(buffer, '\0', SIZE);
}
if (buffer[0] == 'L' && buffer[2] == '0')
{
LED = 1; //熄灭D5
memset(buffer, '\0', SIZE);
}
if (i == SIZE)
i = 0;
}
}

代码重点:

当捕获到

WIFI GOT IP

证明 联网成功 联网标志改为1

当捕获到OK

证明指令执行成功 指令执行标志位 改为1

当捕获到 F

证明指令执行错误 小灯闪烁5次 重启模块

ESP01模块作为路由器

USB转TTL插入电脑,TX--RX RX-TX VCC-3.3V GDN-GND

查询IP地址:AT+CIFSR

//1 配置成双模

AT+CWMODE=2

Response :OK

//2 使能多链接

AT+CIPMUX=1

Response :OK

//3 建立TCPServer

AT+CIPSERVER=1 // default port = 333

Response :OK


到这里 socket 服务器已经打开 连接地址为 espIP地址 端口 333

向客户端发送信息

//4 发送数据

AT+CIPSEND=0,4 // 发送4个字节在连接0通道上

>abcd //输入数据,不带回车

Response :SEND OK

//• 接收数据

+IPD, 0, n: xxxxxxxxxx //+IPD是固定字符串 0是通道,n是数据长度,xxx是数据

//断开连接

AT+CIPCLOSE=0

Response :0, CLOSED OK

image-20220704223056856
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
// ESP-01s工作在路由模式,查询路由器IP地址192.168.4.1,使用的服务器默认端口号333
// ESP-01s收到收到数据op/cl给上官一号,实现D6led的亮/灭
#include "reg52.h"
#include "intrins.h"
#include <string.h>
#define SIZE 12
sfr AUXR = 0x8E;
sbit D5 = P3 ^ 7;
sbit D6 = P3 ^ 6;
char buffer[SIZE]; // 1 工作在路由模式
char LYMO[] = "AT+CWMODE=2\r\n"; // 2 使能多链接
char DLJ[] = "AT+CIPMUX=1\r\n"; // 3 建立TCPServer
char JLFW[] = "AT+CIPSERVER=1\r\n"; // default port = 333
//发送数据
char FSSJ[] = "AT+CIPSEND=0,5\r\n";
char AT_OK_Flag = 0; // OK返回值的标志位
char AT_Connect_Net_Flag = 0; // WIFI GOT IP返回值的标志位
char Client_Connect_Flag = 0;
void UartInit(void) // 9600bps@11.0592MHz
{
AUXR = 0x01;
SCON = 0x50; //配置串口工作方式1,REN使能接收
TMOD &= 0xF0;
TMOD |= 0x20; //定时器1工作方式位8位自动重装
TH1 = 0xFD;
TL1 = 0xFD; // 9600波特率的初值
TR1 = 1; //启动定时器
EA = 1; //开启总中断
ES = 1; //开启串口中断
}
void Delay1000ms() //@11.0592MHz
{
unsigned char i, j, k;
_nop_();
i = 8;
j = 1;
k = 243;
do
{
do
{
while (--k)
;
} while (--j);
} while (--i);
}
void sendByte(char data_msg)
{
SBUF = data_msg;
while (!TI)
;
TI = 0;
}
void sendString(char *str)
{
while (*str != '\0')
{
sendByte(*str);
str++;
}
}
void main()
{
int mark = 0;
D5 = D6 = 1; //灭状态灯 //配置C51串口的通信方式
UartInit();
Delay1000ms(); //给espwifi模块上电时间
sendString(LYMO);
while (!AT_OK_Flag)
;
AT_OK_Flag = 0;
sendString(DLJ);
while (!AT_OK_Flag)
;
AT_OK_Flag = 0;
sendString(JLFW);
while (!Client_Connect_Flag)
;
AT_OK_Flag = 0;
if (Client_Connect_Flag)
{
D5 = 0; //点亮D5,代表有客户端接入
D6 = 0;
}
while (1)
{ // 4 发送数据
sendString(FSSJ);
Delay1000ms();
Delay1000ms();
sendString("Hello");
Delay1000ms();
Delay1000ms();
}
}
void Uart_Handler() interrupt 4
{
static int i = 0; //静态变量,被初始化一次
char tmp;
if (RI) //中断处理函数中,对于接收中断的响应
{
RI = 0; //清除接收中断标志位
tmp = SBUF;
if (tmp == 'W' || tmp == 'O' || tmp == 'L' || tmp == '0' || tmp == ':')
{
i = 0;
}
buffer[i++] = tmp; //入网成功的判断依据WIFI GOT IP
if (buffer[0] == 'W' && buffer[5] == 'G')
{
AT_Connect_Net_Flag = 1;
memset(buffer, '\0', SIZE);
} //连接服务器等OK返回值指令的判断
if (buffer[0] == 'O' && buffer[1] == 'K')
{
AT_OK_Flag = 1;
memset(buffer, '\0', SIZE);
}
if (buffer[0] == '0' && buffer[2] == 'C')
{
Client_Connect_Flag = 1;
memset(buffer, '\0', SIZE);
} //灯控指令

if (buffer[0] == ':' && buffer[1] == 'o' && buffer[2] == 'p')
{
D5 = 0; //点亮D5
memset(buffer, '\0', SIZE);
}
if (buffer[0] == ':' && buffer[1] == 'c' && buffer[2] == 'l')
{
D5 = 1; //熄灭D5
memset(buffer, '\0', SIZE);
}
if (i == 12)
i = 0;
}
}