第六篇 串口(应用篇)- WIFI模块和4G模块

目录

一、WIFI模块(ESP-01S)

1、关于模块的基本信息

2、AT指令

1)了解概念

2)ESP-01S的常用AT指令

3、编程实现

1)将ESP-01S配置成客户端Client

📓如何调试该程序?—白盒测试

2)将ESP-01S配置成服务器Server

二、4G无线通讯模块(EC03-DNC)

1、关于模块的基本信息

2、EC01-DNC的常用AT指令

3、花生壳内网穿透

4、编程实现

三、总结


一、WIFI模块(ESP-01S

1、关于模块的基本信息

        ESP-01s其核心处理器是ESP8266,该系列是安信可科技有限公司开发的一系列基于乐鑫ESP8266的低功耗UART-WIFI芯片模组,可以方便地进行二次开发,接入云端服务,实现手机3/4G全球随时随地的控制,加速产品原型设计。

✒️ESP8266 系列模组出厂使用的 AT 固件,默认波特率为 115200

✒️ESP-01s工作AP(路由)模式下,默认的端口为333

✒️查询模块的MAC地址到安信可官网查询真伪

2、AT指令

1)了解概念

✒️终端设备(或数据终端设备)发送到终端适配器(或数据电路终端设备)

✒️除AT两个字符,最多可以接收1056个字符(含最后的空字符)

✒️每个AT命令行只能有一条AT指令,响应的终端也只允许一个(一对一)

✒️指令以回车结尾,响应以回车换行结尾(区分大小写)

2)ESP-01S的常用AT指令

指令       作用ESP-01S响应
AT+RST重启模块ready
AT+UART=9600,8,1,0,0配置串口OK/ERROR
AT+CWMODE=1 设备(station)模式OK/ERROR
=2 路由(AP)模式OK/ERROR
=3 双模OK/ERROR
AT+CWJAP=”wifi名”,”密码”设备模式下连接WiFi

WIFI CONNECTED/FAIL

WIFI GOT IP

AT+CIFSR查询获取到的IP信息IP信息
AT+CIPSTART=”TCP”,”client ip”,port连接服务器OK

AT+CIPMODE=1

AT+CIPSEND

开启透传模式数据传输

(退出发送+++)

OK/ERROR
AT+CIPMUX=1多连接(AP模式下)OK/ERROR
AT+CIPSEND=通道,字节数发送数据SEND OK
AT+CIPSERVER=1TCP连接,默认端口333OK/ERROR

3、编程实现

1)将ESP-01S配置成客户端Client

#include "reg52.h"
#include <intrins.h>
#include <string.h>

#define MAXSIZE 12

sfr AUXR = 0x8E;
sbit led1 = P3^6;
sbit led2 = P3^7;
char cmd[MAXSIZE];

void uartInit(void){
	AUXR = 0x01;
	SCON |= 0x01<<6;
	SCON &= ~(0x01<<7);
	TMOD |= 0x01<<5;
	TMOD &= ~(0x01<<4);
	TR1 = 1;
	TH1 = 0xFD;
	TL1 = 0xFD;
	REN = 1;
	EA = 1;
	ES = 1;
}

/*********AT指令********/
code char WIFI_Connect[] = "AT+CWJAP=\"wifi_name\",\"wifi_password\"\r\n";		//连接WIFI
char Server_Connect[] = "AT+CIPSTART=\"TCP\",\"172.17.52.195\",8888\r\n";		//连接服务器
char Tou_Chuang[] = "AT+CIPMODE=1\r\n";			//透传模式
char Data_Transmit[] = "AT+CIPSEND\r\n";	//数据开始传输

/*****指令响应标志位********/
int ready_flag = 0;				//模块上电启动完成标志位
int respond_ok_flag = 0;	
int wifi_connect_flag = 0;

/*******发送指令函数*******/
void send_ATCMD(char *cmd){
	while(*cmd != '\0'){
		SBUF = *cmd;
		while(!TI);
		TI = 0;
		cmd++;
	}
}

/*****软件延时1s(心跳包用)*********/
void Delay1000ms(){
	unsigned char i, j, k;
	_nop_();
	i = 8;
	j = 1;
	k = 243;
	do{
		do{
			while (--k);
		} while (--j);
	} while (--i);
}

/*****软件延时150ms(闪烁灯用)*******/
void Delay150ms(){
	unsigned char i, j, k;
	_nop_();
	i = 2;
	j = 13;
	k = 237;
	do{
		do{
			while (--k);
		} while (--j);
	} while (--i);
}

/**********指示灯**********/
void ledBlink(int num,int cnt){	//cnt:闪烁次数
	int i;												//num:1 or 2
	led1 = 1;
	led2 = 1;
	for(i=0;i<=cnt;i++){
		if(num == 1){
			led2 = 1;
			led1 = ~led1;
		}else{
			led1 = 1;
			led2 = ~led2;
		}
		Delay150ms();
	}
}
void main(void){
	uartInit();			//串口初始化
	
	/*****等待模块上电初始化完成后连接WIFI,响应ready****/
	while(!ready_flag);
	send_ATCMD("AT\r\n");  //发送AT确认模块已经启动再发送连接wifi指令
	while(!respond_ok_flag);
	respond_ok_flag = 0;
	send_ATCMD(WIFI_Connect);
	ledBlink(1,8);
	
	/*****等待WIFI连接完成后连接服务器,响应WIFI GOT IP、OK***/
	while(!wifi_connect_flag);
	while(!respond_ok_flag);
	respond_ok_flag = 0;
	send_ATCMD(Server_Connect);
	ledBlink(2,8);
	
	/****等待连接服务器成功后开启透传模式,响应OK*****/
	while(!respond_ok_flag);
	respond_ok_flag = 0;
	send_ATCMD(Tou_Chuang);
	ledBlink(1,8);
	
	/****等待透传模式开启后发送传输数据指令,响应OK****/
	while(!respond_ok_flag);
	respond_ok_flag = 0;
	send_ATCMD(Data_Transmit);
	ledBlink(2,8);

	/****每隔1s发送心跳包到服务器*****/
	while(1){
		send_ATCMD("I am alive!\r\n");
		Delay1000ms();
		led2 = 1;
	}
}

/*******串口中断处理**************/
/*******处理模块响应**************/
void interruptHandle() interrupt 4{
	static char tmp;		//静态变量,只初始化1次
	static char i;
	if(RI){
		RI = 0;		//接收中断位软件清0
		tmp = SBUF;
	/********过滤出响应的首个关键字符,将其置于数组首位置**********/
		if(tmp == 'r'||tmp == 'W' || tmp == 'O'){
			i = 0;
		}
		cmd[i++] = tmp;		//放置响应的关键词:ready、WIFI GOT IP、OK
		
		/***********捕捉响应ready******************/
		if(cmd[0] == 'r' && cmd[4] == 'y'){
			ready_flag = 1;
			memset(cmd,'\0',sizeof(cmd));
		}
		
		/***********捕捉响应WIFI GOT IP**************/
		if(cmd[0] == 'W' && cmd[5] == 'G'){
			wifi_connect_flag = 1;
			memset(cmd,'\0',sizeof(cmd));
		}

		/***********捕捉响应OK******************/
		if(cmd[0] == 'O' && cmd[1] == 'K'){
			respond_ok_flag = 1;
			memset(cmd,'\0',sizeof(cmd));
		}

		/*********判断数组越界********/
		if(i == MAXSIZE) i = 0;
	}
}

📓如何调试该程序?—白盒测试

        如果单片机和ESP-01S直接交互数据,我们无法清楚看到和判断程序运行状况,很难进行调试。所以,我们需要先通过将单片机发送的指令传到电脑,再由我们手动通过电脑发送给ESP-01S,同样,ESP-01S响应的数据先传给电脑,以便我们观察调试代码。具体需要以下接线:

2)将ESP-01S配置成服务器Server

#include "reg52.h"
#include <intrins.h>
#include <string.h>

#define MAXSIZE 12

sfr AUXR = 0x8E;
sbit led1 = P3^6;
sbit led2 = P3^7;
char cmd[MAXSIZE];

/*******串口初始化******/
void uartInit(void){
	AUXR = 0x01;
	SCON |= 0x01<<6;
	SCON &= ~(0x01<<7);
	TMOD |= 0x01<<5;
	TMOD &= ~(0x01<<4);
	TR1 = 1;
	TH1 = 0xFD;
	TL1 = 0xFD;
	REN = 1;
	EA = 1;
	ES = 1;
}

/*********AT指令********/
char AP_MODE[] = "AT+CWMODE=2\r\n";			//路由模式
char MUL_CONNECT[] = "AT+CIPMUX=1\r\n";		//多连接模式
char TCP_SERVER[]  = "AT+CIPSERVER=1\r\n";		//TCP服务器
char DATA_TRANSMIT[] = "AT+CIPSEND=0,12\r\n";		//

/*****指令响应标志位********/
int ready_flag = 0;						//模块上电启动完成标志位
int respond_ok_flag = 0;			//模块响应OK标志位
int client_connect_flag = 0;	//客服端接入标志位


/*******发送指令函数*******/
void sendCommand(char *cmd){
	while(*cmd != '\0'){
		SBUF = *cmd;
		while(!TI);
		TI = 0;
		cmd++;
	}
}

/*****软件延时1s(心跳包用)*********/
void Delay1000ms(){
	unsigned char i, j, k;
	_nop_();
	i = 8;
	j = 1;
	k = 243;
	do{
		do{
			while (--k);
		} while (--j);
	} while (--i);
}


/*****软件延时150ms(闪烁灯用)*******/
void Delay150ms(){
	unsigned char i, j, k;
	_nop_();
	i = 2;
	j = 13;
	k = 237;
	do{
		do{
			while (--k);
		} while (--j);
	} while (--i);
}

/**********LED闪烁**********/
void ledBlink(int num,int cnt){	//cnt:闪烁次数
	int i;												//num:1 or 2
	led1 = 1;
	led2 = 1;
	for(i=0;i<=cnt;i++){
		if(num == 1){
			led2 = 1;
			led1 = ~led1;
		}
		if(num == 2){
			led1 = 1;
			led2 = ~led2;
		}
		Delay150ms();
	}
}
void main(void){
	uartInit();			//串口初始化
	/********配置成AP模式*********/
	while(!ready_flag);
	sendCommand("AT\r\n");
	while(!respond_ok_flag);
	respond_ok_flag = 0;
	sendCommand(AP_MODE);
	
	/********使能多连接***********/
	while(!respond_ok_flag);
	respond_ok_flag = 0;
	sendCommand(MUL_CONNECT);
	
	/******** TCP服务器 ***********/
	while(!respond_ok_flag);
	respond_ok_flag = 0;
	sendCommand(TCP_SERVER);
	
	/****每隔1秒ESP_01S给客户端发送心跳包*****/
	while(!respond_ok_flag);
	respond_ok_flag = 0;
	while(!client_connect_flag);
	client_connect_flag = 0;
	while(1){
		sendCommand(DATA_TRANSMIT);
		Delay1000ms();				
		sendCommand("I am alive\r\n");
		Delay1000ms();
	}
}

/*******串口中断处理**************/
/*******处理模块响应**************/
void interruptHandle() interrupt 4{
	static char tmp;		//静态变量,只初始化1次
	static char i;
	if(RI){
		RI = 0;		//接收中断位软件清0
		tmp = SBUF;
		
		/********过滤出响应的首个关键字符,将其置于数组首位置**********/
		if(tmp == 'r'||tmp == 'O' || tmp == ','  || tmp == ':'){
			i = 0;
		}
		cmd[i++] = tmp;		//放置响应的关键词:ready、OK
		
		/***********捕捉响应ready******************/
		if(cmd[0] == 'r' && cmd[4] == 'y'){
			ready_flag = 1;
			memset(cmd,'\0',sizeof(cmd));
		}
		
		/***********捕捉响应OK******************/
		if(cmd[0] == 'O' && cmd[1] == 'K'){
			respond_ok_flag = 1;
			memset(cmd,'\0',sizeof(cmd));
		}
		
		/****捕获客户端接入响应:0,CONNECT***/
		if(cmd[0] == ',' && cmd[1] == 'C'){
			client_connect_flag = 1;
			if(client_connect_flag){		//每次有客户端接入时led2闪烁8次后熄灭
				ledBlink(2,8);
				led2 = 1;
		}
			memset(cmd,'\0',sizeof(cmd));
}
		/****处理客服端发送过来的数据*******/
		if(cmd[0] == ':' && cmd[1] == 'o' && cmd[2] == 'p'){
			ledBlink(1,8);
			memset(cmd,'\0',sizeof(cmd));
		}
		if(cmd[0] == ':' && cmd[1] == 'c' && cmd[2] == 'l'){
			led1 = 1;
			memset(cmd,'\0',sizeof(cmd));
		}
		/*********判断数组越界********/
		if(i > MAXSIZE){
			i = 0;
		}
	}
}

二、4G无线通讯模块(EC03-DNC

1、关于模块的基本信息

        EC03-DNC是亿佰特公司推出的 LTE CAT1 数传模块产品, 该产品软件功能完善, 覆盖绝大多数常规应用场景, EC03-DNC 是为实现串口设备与网络服务,通过网络相互传输数据而开发的产品 , 该产品是一款带分集接收功能 的LTE-FDD/LTE-TDD 无线通信数传模块, 支持 LTE-FDD , LTE-TDD 网络数据连接, 用户只需通过简单的设置, 即可实现串口到网络服务器的双向数据透明传输。

✒️基于串口AT指令的开发方式

✒️有两种工作模式,默认是透传模式,通过其他方式进入AT指令模式

✒️模块正常工作状态,红灯常亮,黄灯闪烁(SIM卡)

✒️默认出厂波特率115200

✒️进入AT指令模式:发送+++(不换行)后3秒内发送任意AT指令(换行)

2、EC01-DNC的常用AT指令

配置步骤

指令

作用

成功-模块响应

(1)使用前查看

AT+CREG

查询是否注册到网络

+OK=1

AT+CPIN

查询SIM状态

+OK=1

AT+ICCID

查询SIM信息

+OK=SIM卡卡号

AT+CSQ

查询信号值

+OK=信号值

(2)模块基本配置

AT+UART=9600,NONE

查询/设置串口参数

+OK

AT+HEARTMOD

AT+HEARTMOD=NET/UART

查询/设置心跳包模式

+OK=NET(网络心跳)

+OK=UART(串口心跳)

AT+HEARTINFO

AT+HEARTINFO=<内容>

查询/设置心跳包内容

+OK=<内容>

AT+HEARTM

AT+HEARTM=<time>

查询/设置心跳包时间

+OK=<time>

(3)退出AT模式

进入透传模式

AT+EXAT

退出AT模式

+OK

(4)连接服务器

AT+SOCK=TCPC,IP,PORT

连接socket服务器

+OK

AT+LINKSTA

查询连接状态

+OK=Connect

注:这里只列出下面的demo所需要的配置指令

3、花生壳内网穿透

        前面通过ESP-01S模块实现客户端接入点亮LED灯,主要是在同一局域网内(内网)实现的。而4G模块可以实现公网(外网)服务器的访问,这里通过花生壳软件将内部的TCP服务器地址(例如:192.168.136.1:8888)映射到公网(例如:103.46.128.53:50014),再通过4G模块访问花生壳映射的公网地址(103.46.128.53:50014)从而接入内网的TCP服务器。

(使用内网搭建起TCP服务器)

(花生壳软件内网穿透) 

(内网穿透成功后,获得对应的公网IP和端口号) 

(验证服务器) 

 ✒️接下来要做到就是让EC03-DNC模块访问花生壳映射出来的公网地址(例如:103.46.54.106:21910),从而连接上TCP服务器,并通过服务器传过来的指令控制单片机的LED。首先配置好EC03-DNC(修改波特率、心跳包、连接TCP服务器—通过公网,配置完成后模块重启会自动连接),最后再实现控制单片机LED。

(4G模块接入服务器) 

4、编程实现

#include "reg52.h"
#include <intrins.h>
#include <string.h>

#define MAXSIZE 12

sfr AUXR = 0x8E;
sbit led1 = P3^6;
sbit led2 = P3^7;
char cmd[MAXSIZE];

void uartInit(void){
	AUXR = 0x01;
	SCON |= 0x01<<6;
	SCON &= ~(0x01<<7);
	TMOD |= 0x01<<5;
	TMOD &= ~(0x01<<4);
	TR1 = 1;
	TH1 = 0xFD;
	TL1 = 0xFD;
	REN = 1;
	EA = 1;
	ES = 1;
}


/*****软件延时150ms(闪烁灯用)*******/
void Delay150ms(){
	unsigned char i, j, k;
	_nop_();
	i = 2;
	j = 13;
	k = 237;
	do{
		do{
			while (--k);
		} while (--j);
	} while (--i);
}

/**********指示灯**********/
void ledBlink(int num,int cnt){	//cnt:闪烁次数
	int i;												//num:1 or 2
	led1 = 1;
	led2 = 1;
	for(i=0;i<=cnt;i++){
		if(num == 1){
			led2 = 1;
			led1 = ~led1;
		}else{
			led1 = 1;
			led2 = ~led2;
		}
		Delay150ms();
	}
}
void main(void){
	uartInit();			//串口初始化
	while(1);
}
/**Led1 blink**/
/**Led2 blink**/
/*******串口中断处理**************/

void interruptHandle() interrupt 4{
	static char tmp;		//静态变量,只初始化1次
	static char i;
	if(RI){
		RI = 0;		//接收中断位软件清0
		tmp = SBUF;
	/********过滤出响应的首个关键字符,将其置于数组首位置**********/
		if(tmp == 'L'){
			i = 0;
		}
		cmd[i++] = tmp;		
		if(cmd[0] == 'L' && cmd[3] == '1'){
			ledBlink(1,8);
			led1 = 1;
			memset(cmd,'\0',sizeof(cmd));
		}
		if(cmd[0] == 'L' && cmd[3] == '2'){
			ledBlink(2,8);
			led2 = 1;
			memset(cmd,'\0',sizeof(cmd));
		}
		/*********判断数组越界********/
		if(i > MAXSIZE){
			i = 0;
		}
	}
}

 (配置好模块后,通过修改上篇wifi模块代码,即可实现网络点灯)

三、总结

         对于51来讲,ESP-01S(wifi模块)和EC01-DNC(4G模块)都是基于单片机串口通讯,都是串口设备与网络服务器为了实现相互传输数据而开发的产品。但是wifi模块和4G模块应用场景不同,wifi模块主要与接入同一局域网的服务器或者客户端通讯,而4G模块可以实现对公网服务器的访问

说明:由于笔者水平有限,文中不可避免有所错漏,敬请读者斧正  

  • 7
    点赞
  • 59
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 6
    评论
2022 / 01/ 30: 新版esptool 刷micropython固件指令不是 esptool.py cmd... 而是 esptool cmd... 即可;另外rshell 在 >= python 3.10 的时候出错解决方法可以查看:  已于2022年发布的: 第二章:修复rshell在python3.10出错 免费内容: https://edu.csdn.net/course/detail/29666 micropython语法和python3一样,编写起来非常方便。如果你快速入门单片机玩物联网而且像轻松实现各种功能,那绝力推荐使用micropython。方便易懂易学。 同时如果你懂C语音,也可以用C写好函数并编译进micropython固件里然后进入micropython调用(非必须)。 能通过WIFI联网(2.1章),也能通过sim卡使用2G/3G/4G/5G联网(4.5章)。 为实现语音控制,本教程会教大家使用tensorflow利用神经网络训练自己的语音模型并应用。为实现通过网页控制,本教程会教大家linux(debian10 nginx->uwsgi->python3->postgresql)网站前后台入门。为记录单片机传输过来的数据, 本教程会教大家入门数据库。  本教程会通过通俗易懂的比喻来讲解各种原理与思路,并手把手编写程序来实现各项功能。 本教程micropython版本是 2019年6月发布的1.11; 更多内容请看视频列表。  学习这门课程之前你需要至少掌握: 1: python3基础(变量, 循环, 函数, 常用库, 常用方法)。 本视频使用到的零件与淘宝上大致价格:     1: 超声波传感器(3)     2: MAX9814麦克风放大模块(8)     3: DHT22(15)     4: LED(0.1)     5: 8路5V低电平触发继电器(12)     6: HX1838红外接收模块(2)     7:红外发射管(0.1),HX1838红外接收板(1)     other: 电表, 排线, 面包板(2)*2,ESP32(28)  

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

AF_INET6

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值