
- 一、项目概述
- 二、项目设计
- 三、程序设计
- 3.1、主任务设计
- 3.2、蓝牙数据解析
- 3.3、wifi连接
- 四、测试
- 4.1、连接测试
- 4.2、 重连测试
- 4.3 、停止测试
- 4.4 、功耗测试
本文使用环境:
主控: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
注意:上述流程只是本文设计所用函数,并不是整个工程的流程图。
^^^^主任务主要创建两个任务,一个用于蓝牙信息解析,一个用于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
3.2、蓝牙数据解析
^^^^首先重新解析一下蓝牙接收的数据,这里因为要处理字符串,所以不再单字节进行处理,打开gatt_svr_chr_demo_access_func()函数,做如下修改:
static int
gatt_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);
//首字节为长度,需要添加一个'[',所以字节长度加一
ble_data0]= + om->om_len1;//其他的原样复制
memcpy
(&[ble_data1],,om->om_data)om->om_len;printf
("rec: %s len:%d\n",,om->om_data)om->om_len;//添加字符串结束符号
[
ble_data+om->om_len1]= ';' if(
0)om->om_len>tls_os_queue_send(
,,ble_q0ble_data) ;//add by zxx end}
=
SLIST_NEXT
om ( ,)om; om_next}return
0
; default:
assert(
0);return;
} BLE_ATT_ERR_UNLIKELY}
全局变量
//全局变量,表示wifi的重连状态,0表示正常,1表示重新连接
^^^^定义一个=,用于wifi的重连,手机端可以通过发送信息,改变该状态:
0
u8 wifi_reconnect_state ; //定义四种状态#
^^^^蓝牙信息解析函数
define
MY_BLE_WIFI_STATE_START1 //开始连接 # define
MY_BLE_WIFI_STATE_STOP2 //停止连接 # define
MY_BLE_WIFI_STATE_RECONNECT3 //重新连接 # define
MY_BLE_WIFI_STATE_CONNECT4 //连接wifi,并执行发送程序 void my_ble_msg_task
( void*) [sdata4
{
u8 msg_state];=0
u8 ble_wifi_state ; *;
u8 demo_bt_enablemsg(
);while(
==)bt_adapter_state tls_os_time_delay WM_BT_STATE_OFF(
{
5000/) ;HZ}tls_os_time_delay
(
5000/) ;HZdemo_ble_server_on(
);printf(
"ble ready ok \r\n");while(
1)//接收手机发送的数据,注意是数据是按照字节进行的接收//msg[0]表示数据长度已经包含有'tls_os_queue_receive'
{
(
,
&,ble_q0,msg0 ); printf("rev main:%s len:%d\n"
,&[1]msg,[0 ]msg);//提取前4位,前四位为状态标志strncpy(
,
&[msg_state1]msg,4);//判断前四位的状态if(
!
strncmp(,"star",msg_state4))=;else ble_wifi_state if MY_BLE_WIFI_STATE_START(
! strncmp(,"stop",msg_state4))=;else ble_wifi_state if MY_BLE_WIFI_STATE_STOP(
! strncmp(,"reco",msg_state4))=;else ble_wifi_state if MY_BLE_WIFI_STATE_RECONNECT(
! strncmp(,"conn",msg_state4))//conn命令至少应该是"conn+s+p'if'" 九个字节([
{
0
]<msg9)//小于9说明命令是错的 printf ("conn err...\n" )
{
;tls_ble_server_demo_api_send_notify_msg("conn err...",
sizeof("conn err..."));=0;}
ble_wifi_state else =;
}
else
ble_wifi_state = MY_BLE_WIFI_STATE_CONNECT0
;
switch ble_wifi_state ( )case
:tls_ble_server_demo_api_send_notify_msgble_wifi_state(
{
"\'conn+ssid+pwd\'" MY_BLE_WIFI_STATE_CONNECT,
sizeof("\'conn+ssid+pwd\'"));=0;//重置
wifi_reconnect_state tls_os_queue_send (, &
[6ble_wifi_q],msg0);break ;case:
tls_ble_server_demo_api_send_notify_msg(
"stop connect" MY_BLE_WIFI_STATE_STOP,
sizeof("stop connect"));=1;//断开连接
wifi_reconnect_state break ;case :
tls_ble_server_demo_api_send_notify_msg(
"start reconnect" MY_BLE_WIFI_STATE_RECONNECT,
sizeof("start reconnect"));=1;//断开连接
wifi_reconnect_state break ;//只发送信息至手机端 case
:tls_ble_server_demo_api_send_notify_msg
(
"ready connect" MY_BLE_WIFI_STATE_START,
sizeof("ready connect"));break;default:
printf(
"ble_wifi_state is err \n")
;break;}}
}wifi_reconnect_state
while
closesocket
void
3.3、wifi连接
^^^^连接函数较为简单,使用消息队列等待蓝牙解析任务发送的数据,正确接收后,进入服务器连接,并循环发送数据。当接收重连指令后,会更新my_ble_wifi_task,退出(发送程序,重连时,必须void,否者无法正常绑定端口。
* )//密码和账户的数组,其实这里可以定义指针并使用malloc灵活申请,我图方便直接定义固定长度[ 50sdata]
{
;
u8 ssid[50];
u8 pwd//测试发送数组[10]
=
u8 test_data0,1 , {2,3,4,5,6,7,8,9};//消息队列接收*;while
(
u8 1msg)
printf("wait connect..\n")
{
;//必须关闭socket,否者不能正常绑定端口close_udp_socket_demo()
;
//消息队列,接收蓝牙解析任务传输的账号和密码tls_os_queue_receive(,
&
,0ble_wifi_q,0msg) ;printf ("rev task:%s len:%d\n",
,strlen()msg);//字符串的总长度 不带结束字符的长度msg=strlen(
)
u8 msg_len ; =0msg;//账户的长度 不带结束字符
u8 ssid_size //下列循环主要用于找出账户的长度 for( int
=
0;[ i]!=';' msg++i) if ([ i]!=
{
'+')msg++i; else break;
ssid_size}//拷贝账户名
memcpy
(,
,
)
;//添加结束字符ssid[msg]ssid_size=';'
//拷贝密码,注意要排除加号
ssidmemcpyssid_size( , &[
+
1]pwd,-msg-ssid_size1);//排除掉+号msg_len//末尾加上结束字符ssid_size[--1 ]
=
pwd';'msg_lenprintfssid_size("ssid:%s len:%d pwd:%s len:%d \n", , strlen(
),,strlenssid())ssid;//连接WIFIpwddemo_connect_net(,pwd);//延时
tls_os_time_delay
(3000ssid)pwd;//连接服务器
socket_udp_demo
(1,10086,
"192.168.1.87"
);//正常情况下发送程序,当wifi_reconnect_state为1时,表示重新连接while(0==)udp_send_data_self
(
,10) ; wifi_reconnect_statetls_os_time_delay
{
(500test_data);}}
}close_udp_socket_demo()wm_udp_demo.cvoidclose_udp_socket_demo
(
void
)
^^^^上述程序中printf为自定义函数,在(文件中。
"close udp socket \n" );closesocket(
{
);}wm_demo_console.hextern
voidudp_send_data_selfdemo_udp->socket_num(*
,
^^^^同时在int申明。
) ; externvoidu8 close_udp_socket_demodata(void data_len);
# endif /*__WM_DEMO_CMD_H__*/账户+密码重连账户+密码停止
四、测试
^^^^在手机端提前设置好如下发送指令。
^^^^手机蓝牙APP如下:
^^^^程序下载至开发板,点击。程序运行正常,配网成功,并且正常和服务器发送数据。
服务器
^^^^点击后开发板断开连接,并等待新连接。
^^^^再次发送指令。
^^^^点击,开发板断开连接
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)