> 文档中心 > W801/W800-wifi-socket开发(二)-UDP蓝牙控制wifi连接

W801/W800-wifi-socket开发(二)-UDP蓝牙控制wifi连接

这是目录

  • 一、项目概述
  • 二、项目设计
  • 三、程序设计
  • 四、测试
    • 4.1、连接测试
    • 4.2 重连测试
    • 4.3 停止测试

本文使用环境:
主控:W800-KIT (开发板)
兼容:W800 W801 AIR101
开发环境:CDK
SDK:W801/W800的SDK(tls库)

我的联盛德问答社区主页

前文:
W801/W800-wifi-socket开发(一)-UDP

W801蓝牙收发数据与控制设计(一)-INDICATE
W801蓝牙收发数据与控制设计(二)-NOTIFY方式

本文github工程
这份代码包含前文的某些函数,所以可能会比较乱。

写在前面:
这个代码有很多地方都有BUG,有遇到的请联系我修改。比如未对传输的数据进行严格筛查,每次都要重新输入账户和密码,可以将数据写入flash。。。。因为只是一个基础的学习思路,所以并未深入完善代码。

一、项目概述

^^^^程序功能: 通过手机的蓝牙输入wifi密码和账户连接至路由器,使用开发板I连接电脑端的服务器(UDP协议,使用网络调试助手模拟),传输数据。同时手机端支持重连和停止连接。

^^^^本文是在前文的基础上完成的 。需要借鉴前文的配置。。。

二、项目设计

1、项目整体设计
^^^^整体流程如下所示。指令字符串必须严格执行,程序只判断每一串字符的前四个进行状态的选择。
连接WIFI指令的格式为:conn+账号+密码。比如:conn+yyds+1234567890
在这里插入图片描述
注意:上述流程只是本文设计所用函数,并不是整个工程的流程图。

三、程序设计

1、主任务设计
^^^^主任务主要创建两个任务,一个用于蓝牙信息解析,一个用于wifi连接和数据发送。

//add by zxx satrt//创建任务void My_task(void){//蓝牙接收消息队列if(tls_os_queue_create(&ble_q, 32)!=TLS_OS_SUCCESS){printf("create queue fail\n");return;}//wifi连接消息队列if(tls_os_queue_create(&ble_wifi_q, 32)!=TLS_OS_SUCCESS){printf("create queue fail\n");return;}tls_os_task_create(NULL, NULL,  my_ble_msg_task,//蓝牙接收任务  NULL,  (void *)MyBLETaskStk,   /* task's stack start address */  MYBLE_TASK_SIZE * sizeof(u32), /* task's stack size, unit:byte */  MYBLE_TASK_PRIO,  0);tls_os_task_create(NULL, NULL,  my_ble_wifi_task,//wifi连接任务  NULL,  (void *)MyBLEWIFITaskStk,   /* task's stack start address */  MYBLE_TASK_SIZE * sizeof(u32), /* task's stack size, unit:byte */  MYBLE_TASK_PRIO,  0);}//add by zxx end

2、蓝牙数据解析
^^^^首先重新解析一下蓝牙接收的数据,这里因为要处理字符串,所以不再单字节进行处理,打开gatt_svr_chr_demo_access_func()函数,做如下修改:

static intgatt_svr_chr_demo_access_func(uint16_t conn_handle, uint16_t attr_handle,   struct ble_gatt_access_ctxt *ctxt, void *arg){    int i = 0;    struct os_mbuf *om = ctxt->om;    switch (ctxt->op) { case BLE_GATT_ACCESS_OP_WRITE_CHR:while(om) {    if(g_ble_uart_output_fptr)    {      g_ble_uart_output_fptr((uint8_t *)om->om_data, om->om_len);    }else    {//add by zxx start  //print_bytes(om->om_data, om->om_len);  //首字节为长度,需要添加一个'\0',所以字节长度加一  ble_data[0] = om->om_len+1;  //其他的原样复制  memcpy(&ble_data[1],om->om_data,om->om_len);  printf("rec: %s len:%d\n",om->om_data,om->om_len);  //添加字符串结束符号  ble_data[om->om_len+1] = '\0';  if(om->om_len>0)tls_os_queue_send(ble_q,ble_data, 0);//add by zxx end    }    om = SLIST_NEXT(om, om_next);}return 0; default:     assert(0);     return BLE_ATT_ERR_UNLIKELY;    }}

^^^^定义一个全局变量,用于wifi的重连,手机端可以通过发送信息,改变该状态:

//全局变量,表示wifi的重连状态,0表示正常,1表示重新连接u8 wifi_reconnect_state = 0;

^^^^蓝牙信息解析函数

//定义四种状态#define MY_BLE_WIFI_STATE_START  1//开始连接#define MY_BLE_WIFI_STATE_STOP  2//停止连接#define MY_BLE_WIFI_STATE_RECONNECT  3//重新连接#define MY_BLE_WIFI_STATE_CONNECT  4//连接wifi,并执行发送程序void my_ble_msg_task(void *sdata){u8 msg_state[4];u8 ble_wifi_state = 0;u8 *msg;demo_bt_enable();while(bt_adapter_state == WM_BT_STATE_OFF){tls_os_time_delay(5000 /HZ);}tls_os_time_delay(5000 /HZ);demo_ble_server_on();printf("ble ready ok \r\n");while(1){//接收手机发送的数据,注意是数据是按照字节进行的接收//msg[0]表示数据长度已经包含有'\0'tls_os_queue_receive(ble_q,&msg, 0, 0);printf("rev main:%s len:%d\n",&msg[1] ,msg[0]);//提取前4位,前四位为状态标志strncpy(msg_state,&msg[1],4);//判断前四位的状态if(!strncmp(msg_state,"star",4)) ble_wifi_state = MY_BLE_WIFI_STATE_START;else if(!strncmp(msg_state,"stop",4)) ble_wifi_state = MY_BLE_WIFI_STATE_STOP;else if(!strncmp(msg_state,"reco",4)) ble_wifi_state = MY_BLE_WIFI_STATE_RECONNECT;else if(!strncmp(msg_state,"conn",4)) {//conn命令至少应该是"conn+s+p'\0'" 九个字节if(msg[0] < 9) //小于9说明命令是错的{printf("conn err...\n");tls_ble_server_demo_api_send_notify_msg("conn err...",sizeof("conn err..."));ble_wifi_state = 0;}else  ble_wifi_state = MY_BLE_WIFI_STATE_CONNECT;}else ble_wifi_state = 0;switch(ble_wifi_state){case MY_BLE_WIFI_STATE_CONNECT: tls_ble_server_demo_api_send_notify_msg("\'conn+ssid+pwd\'",sizeof("\'conn+ssid+pwd\'"));wifi_reconnect_state = 0;  //重置tls_os_queue_send(ble_wifi_q,&msg[6], 0);break;case MY_BLE_WIFI_STATE_STOP: tls_ble_server_demo_api_send_notify_msg("stop  connect",sizeof("stop connect"));wifi_reconnect_state = 1;//断开连接break;case MY_BLE_WIFI_STATE_RECONNECT: tls_ble_server_demo_api_send_notify_msg("start reconnect",sizeof("start reconnect"));wifi_reconnect_state = 1;//断开连接break;//只发送信息至手机端case MY_BLE_WIFI_STATE_START: tls_ble_server_demo_api_send_notify_msg("ready connect",sizeof("ready connect"));break;default: printf("ble_wifi_state is err \n");break;}}}

3、wifi连接
^^^^连接函数较为简单,使用消息队列等待蓝牙解析任务发送的数据,正确接收后,进入服务器连接,并循环发送数据。当接收重连指令后,会更新wifi_reconnect_state,退出while发送程序,重连时,必须closesocket,否者无法正常绑定端口。

void my_ble_wifi_task(void *sdata){//密码和账户的数组,其实这里可以定义指针并使用malloc灵活申请,我图方便直接定义固定长度u8 ssid[50];u8 pwd[50];//测试发送数组u8 test_data[10] = {0,1,2,3,4,5,6,7,8,9};//消息队列接收u8 *msg;while(1){printf("wait connect..\n");//必须关闭socket,否者不能正常绑定端口close_udp_socket_demo();//消息队列,接收蓝牙解析任务传输的账号和密码tls_os_queue_receive(ble_wifi_q,&msg, 0, 0);printf("rev task:%s  len:%d\n",msg,strlen(msg));//字符串的总长度 不带结束字符的长度u8 msg_len = strlen(msg);u8 ssid_size = 0;//账户的长度 不带结束字符//下列循环主要用于找出账户的长度for(int i=0; msg[i] != '\0'; i++){if(msg[i] != '+')ssid_size++;elsebreak;}//拷贝账户名memcpy(ssid,msg,ssid_size);//添加结束字符ssid[ssid_size] = '\0';//拷贝密码,注意要排除加号memcpy(pwd,&msg[ssid_size+1],msg_len-ssid_size-1); //排除掉+号//末尾加上结束字符pwd[msg_len-ssid_size-1] = '\0'; printf("ssid:%s len:%d pwd:%s len:%d \n",ssid,strlen(ssid),pwd,strlen(pwd));//连接WIFIdemo_connect_net(ssid,pwd);//延时tls_os_time_delay(3000);//连接服务器socket_udp_demo(1,10086,"192.168.1.87");//正常情况下发送程序,当wifi_reconnect_state为1时,表示重新连接while(0 == wifi_reconnect_state){udp_send_data_self(test_data,10);tls_os_time_delay(500);}}}

^^^^上述程序中close_udp_socket_demo()为自定义函数,在wm_udp_demo.c文件中。

void close_udp_socket_demo(void){printf("close udp socket \n");closesocket(demo_udp->socket_num);}

^^^^同时在wm_demo_console.h申明。

extern void udp_send_data_self(u8 *data,int data_len);extern void close_udp_socket_demo(void);#endif /*__WM_DEMO_CMD_H__*/

四、测试

^^^^在手机端提前设置好如下发送指令。
在这里插入图片描述
^^^^手机蓝牙APP如下:
在这里插入图片描述

4.1、连接测试

^^^^程序下载至开发板,点击账户+密码。程序运行正常,配网成功,并且正常和服务器发送数据。
在这里插入图片描述

服务器
在这里插入图片描述

4.2 重连测试

^^^^点击重连后开发板断开连接,并等待新连接。
在这里插入图片描述
^^^^再次发送账户+密码指令。
在这里插入图片描述

4.3 停止测试

^^^^点击停止,开发板断开连接
在这里插入图片描述