ESP8266_10---------AP_UDP_Server

写在前面:

上一篇ESP8266_09---------------AP_UDP_Client介绍了ESP8266设置为AP模式,作为Client,以UDP的方式与野火串口模拟出的server进行通信。

本篇ESP8266要作为server端,与野火串口模拟出的client进行通信。

大致流程:


一、相关的API:

1.设置 WiFi 的工作模式:

bool wifi_set_opmode (uint8 opmode)
//opmode:
//0x01: Station 模式;
//0x02:SoftAP 模式;
//0x03:Station+SoftAP 模式
//返回值:true:成功;false:失败;

2.设置 WiFi SoftAP 模式,并保存到 flash:

bool wifi_softap_set_config(struct softap_config *config)
/*
参数结构体如下:
struct softap_config 
{
    uint8 ssid[32];//WiFi名称
    uint8 password[64]; //密码
    uint8 ssid_len; //WiFi名长度
    uint8 channel; //通道号1 ~ 13
    AUTH_MODE authmode;//加密方,softAP模式不支持AUTH_WEP加密方式。
    uint8 ssid_hidden; //是否隐藏 WiFi,默认为 0 不隐藏网络
    uint8 max_connection; //最大连接设备数,最大设备数为 4
    uint16 beacon_interval;//信标间隔时间,支持 100-60000ms(信标间隔时间即 
                              SSID 广播包发送的间距),默认为 100ms
}
返回值:true:成功;false:失败;
注意:使用此函数前必须设置 ESP8266 为 AP 模式;此函数其实是在内核中
完成的,不会调用立即生效;注意配置的 WiFi 密码不少于 8 位!!!
*/

3.查询 WiFi Station 模式或者 AP 模式的 IP 地址,确认模式是否配置成功:

bool wifi_get_ip_info(uint8 if_index, struct ip_info *info)
/*
uint8 if_index:选择是查询 AP 模式的还是 Station 模式的,0x00:Station 模
                式;0x01:AP 模式,我们也可以使用宏,在 SDK 包内定义了两个宏:
#define STATION_IF 0x00
#define SOFTAP_IF 0x01
struct ip_info *info:用于存储获取到的 IP 信息结构体;
返回值:true:成;false:失败。
*/

4.  创建 UDP 通讯 :

sin8 espconn_create(struct espconn *espconn)
/*
参数:struct espconn *espconn 为对应网络连接的结构体,UDP 连接和
TCP 连接共用这一个结构体。
struct espconn {
enum espconn_type type;
//连接类型,可以是 UDP 和 TCP
enum espconn_state state;
//连接状态
union {
esp_tcp *tcp;
esp_udp *udp;
} proto;
//一个共用体,包含了一个 tcp 连接参数结构体和 udp
//连接参数结构体
espconn_recv_callback recv_callback; //接收成功的回调函数
espconn_sent_callback sent_callback; //发送成功的回调函数
uint8 link_cnt;
//连接数量
void *reverse;
//指针变量,可用来存储相关需要的数据
};
返回值:0:成功,其他:失败,返回对应的错误码
ESPCONN_ ARG:未找到参数 espconn 对应的 UDP 连接
ESPCONN_MEM:空间不足
ESPCONN_ ISCONN:连接已经建立
注意:定义的网络结构体必须是全局变量。
例:struct espconn ESPConnect_Struct; //定义网络连接结构体,全局变量
esp_udp udp_Struct;
ESPConnect_Struct.type=ESPCONN_UDP;
ESPConnect_Struct.proto.udp=(esp_udp*)os_malloc(sizeof(esp_udp));
ESPConnect_Struct.proto.udp->local_port=9999;
ESPConnect_Struct.sent_callback=ESP8266_UDP_Sen d_Cb;
ESPConnect_Struct.recv_callback=ESP8266_UDP_Receive_Cb;
espconn_create(&ESPConnect_Struct);
*/

5.  通过无线网络发送数据:

sint8 espconn_send(struct espconn *espconn,uint8 *psent,uint16 length)
/*
struct espconn *espconn:远端网络信息结构体,
uint8 *psent:需要发送的数据内容;
uint16 length:需要发送的数据长度。
例:
espconn_send(&ESPConnect_Struct,"Hello!",os_strlen("Hello!"));
*/

6.  查询某个 TCP 连接或者 UDP 传输的远端信息,此函数一般在接收成功的回调函数中调用。

sint8 espconn_get_connection_info(struct espconn *espconn, remot_info
**pcon_info,uint8 typeflags)
/*
参数:struct espconn *espconn:对应网络连接的结构体
remot_info **pcon_info:连接 client 信息,如 IP 地址,端口号等等,注
意是指针的指针;
uint8 typeflags:0:正常 server,1:SSL server
返回值:0:成功;其他:失败,返回错误码 ESPCONN_ARG:未找到参
数 espconn 对应的 TCP 连接

二、程序的编写:

程序的功能:

将我们的ESP8266设置为AP模式,充当UDP_Server,用野火串口模拟UDP_Client进行通信。

我们直接拷贝软件定时器的工程,然后新建wifi.c和wifi.h文件,然后将他们分别添加到app/driverapp/include/driver下,刷新工程。

!!!为了方便大家理解程序的运行流程,我按照程序的执行流程来粘贴代码

1.我们要先将ESP8266设为AP模式,主函数中调用WIFI_AP_MODE_Init()

//主程序
void ICACHE_FLASH_ATTR user_init(void)
{
  uart_init(9600,9600);
  os_printf("\r\nESP8266——AP_UDP_TEST\r\n");
  WIFI_AP_MODE_Init();//AP模式初始化
  OS_Timer_Init(1000,1);//1s,重装载
}

2.设置好AP模式后,我们打开了定时器,每隔1s进入定时器回调函数OS_Timer_1_Cb(),查询AP模式下ESP8266的IP地址,若查到了,即AP模式就设置好了,然后关闭定时器,调用WIFI_UDP_Init()初始化网络连接(UDP通信)。

//软件定时器回调函数
void OS_Timer_1_Cb(void)
{
	struct ip_info ST_ESP8266_IP;	// IP信息结构体

		u8  ESP8266_IP[4];		// 点分十进制形式保存IP


		wifi_get_ip_info(SOFTAP_IF,&ST_ESP8266_IP);	// 查询AP模式下ESP8266的IP地址

		if(ST_ESP8266_IP.ip.addr != 0)				// ESP8266成功获取到IP地址
		{
			ESP8266_IP[0] = ST_ESP8266_IP.ip.addr;		// 点分十进制IP的第一个数 <==> addr低八位
			ESP8266_IP[1] = ST_ESP8266_IP.ip.addr>>8;	// 点分十进制IP的第二个数 <==> addr次低八位
			ESP8266_IP[2] = ST_ESP8266_IP.ip.addr>>16;	// 点分十进制IP的第三个数 <==> addr次高八位
			ESP8266_IP[3] = ST_ESP8266_IP.ip.addr>>24;	// 点分十进制IP的第四个数 <==> addr高八位

			// 打印并显示ESP8266的IP地址
			//-----------------------------------------------------------------------------------------------
			os_printf("ESP8266_IP = %d.%d.%d.%d\n",ESP8266_IP[0],ESP8266_IP[1],ESP8266_IP[2],ESP8266_IP[3]);
			//-----------------------------------------------------------------------------------------------
			os_timer_disarm(&os_timer_1);	// 关闭定时器

			WIFI_UDP_Init();		// 初始化网络连接(UDP通信)
		}

}

//UDP通信初始化
void ICACHE_FLASH_ATTR WIFI_UDP_Init(void)
{

	ESPConnect_Struct.type=ESPCONN_UDP;//UDP通信
	ESPConnect_Struct.proto.udp = (esp_udp *)os_zalloc(sizeof(esp_udp));
	ESPConnect_Struct.proto.udp->local_port=8266; //本地端口号
	espconn_regist_sentcb(&ESPConnect_Struct,ESP8266_UDP_Send_Cb);	// 注册网络数据发送成功的回调函数
	espconn_regist_recvcb(&ESPConnect_Struct,ESP8266_UDP_Receive_Cb);	// 注册网络数据接收成功的回调函数
	espconn_create(&ESPConnect_Struct);//创建连接
}

//接收成功回调函数
void  ICACHE_FLASH_ATTR ESP8266_UDP_Receive_Cb(void *arg,char *pdata,unsigned short len)
{
	struct espconn * pesp_conn=arg;
	remot_info *premot=NULL;//远端结构体信息
	os_printf("接收到数据:%s",pdata);
	if(os_strcmp(pdata,"ledon")==0)
	{
        LED_ON;
		os_printf("LED已打开😀\n");
	}
	if(os_strcmp(pdata,"ledoff")==0)
	{
		LED_OFF;
		os_printf("LED已打开😔\n");
	}

	if(espconn_get_connection_info(pesp_conn,&premot,0)==0)//获取远端设备信息
	{
		pesp_conn->proto.udp->remote_port=premot->remote_port;//端口
		pesp_conn->proto.udp->remote_ip[0]=premot->remote_ip[0];//IP
		pesp_conn->proto.udp->remote_ip[1]=premot->remote_ip[1];
		pesp_conn->proto.udp->remote_ip[2]=premot->remote_ip[2];
		pesp_conn->proto.udp->remote_ip[3]=premot->remote_ip[3];

	}
	espconn_send(pesp_conn,"hello\n",os_strlen("hello\n"));//向远端发送数据
	//os_free(premot);//释放内存

}
//发送成功回调函数
void ICACHE_FLASH_ATTR ESP8266_UDP_Send_Cb(void *arg)
{
  os_printf("数据已成功发送!\n");
}

3. 我们的电脑要先去连接到ESP8266的热点,然后我们打开串口调试助手,模拟一个UDP_Client,就能进行通信了。


以上就是核心的代码。

(可能会有一些注释不太对,请大家自行理解)

三、串口的配置

我们将代码烧入ESP8266后,电脑连接到ESP8266热点后,去配置串口为:UDP_Client

烧写代码:

连接热点:

 配置串口:

打开串口,打印出ESP8266的IP地址,端口号在程序中设置为8266

 


以上就是本篇文章的全部内容了,如果感觉有帮助的话,欢迎大家订阅点赞😘😘😘

​​​​​​​如需源码请在评论区留下邮箱地址!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值