本篇博文最后修改时间:2017年01月06日,11:06。


一、简介

本文以TI提供的SimpleBLECentral工程和SimpleBLEPeripheral工程为例,介绍SimpleBLECentral工程连接时读取RSSI、SimpleBLECentral工程不连接时读取RSSI、SimpleBLEPeripheral工程连接时读取RSSI的方法。

二、实验平台

协议栈版本:BLE-CC254x-1.4.0

编译软件:IAR 8.20.2

硬件平台:Smart RF(主芯片CC2541)

、版权声明

博主:甜甜的大香瓜

声明:喝水不忘挖井人,转载请注明出处。

原文地址:http://blog.csdn.NET/feilusia

联系方式:897503845@qq.com

香瓜BLE之CC2541群:127442605

香瓜BLE之CC2640群:557278427

香瓜BLE之Android群:541462902

香瓜单片机之STM8/STM32群:164311667
甜甜的大香瓜的小店(淘宝店):https://shop217632629.taobao.com/?spm=2013.1.1000126.d21.hd2o8i
四、 实验前提
1、在进行本文步骤前,请先 阅读 以下博文:
暂无

2、在进行本文步骤前,请先 实现以下博文:
1)《CC2541之串口收发》:http://blog.csdn.net/feilusia/article/details/47431659

五、基础知识

1、什么是RSSI?

答:Received Signal Strength Indication,接收的信号强度指示。

2、RSSI有什么用?
答:可根据RSSI来测主从机之间的距离。

3、RSSI需不需要连接才能读取?

答:不需要。但需要不停地数据交互,才能更新结构体中得到的RSSI。

六、解析代码(SimpleBLECentral工程中以连接方式读RSSI)

注:该工程默认即是可读RSSI,下面只是解析代码。

1、添加RSSI回调函数

1)定义一个函数simpleBLECentralRssiCB(SimpleBLECentral.c中)

static void simpleBLECentralRssiCB( uint16 connHandle, int8 rssi )
{LCD_WRITE_STRING_VALUE( "RSSI -dB:", (uint8) (-rssi), 10, HAL_LCD_LINE_1 );//输出RSSI的值到串口NPI_PrintValue("RSSI:-", (uint8) (-rssi), 10);NPI_PrintString("dB\r\n");
}

2)声明函数simpleBLECentralRssiCB(SimpleBLECentral.c中)

static void simpleBLECentralRssiCB( uint16 connHandle, int8  rssi );

3)将回调函数与函数指针结构体挂钩(SimpleBLECentral.c中)

// GAP Role Callbacks
static const gapCentralRoleCB_t simpleBLERoleCB =
{simpleBLECentralRssiCB,       // RSSI callbacksimpleBLECentralEventCB       // Event callback
};

4)注册回调函数(SimpleBLECentral.c中)

  if ( events & START_DEVICE_EVT ){// Start the DeviceVOID GAPCentralRole_StartDevice( (gapCentralRoleCB_t *) &simpleBLERoleCB );// Register with bond manager after starting deviceGAPBondMgr_Register( (gapBondCBs_t *) &simpleBLEBondCB );return ( events ^ START_DEVICE_EVT );}

2、读取RSSI过程
1)按下“down”键,若此时处于“连接”、且“不读取RSSI”状态时,则调用RSSI开始读的周期函数(SimpleBLECentral.c中)

 if ( keys & HAL_KEY_DOWN ){// Start or cancel RSSI pollingif ( simpleBLEState == BLE_STATE_CONNECTED ){if ( !simpleBLERssi ){simpleBLERssi = TRUE;GAPCentralRole_StartRssi( simpleBLEConnHandle, DEFAULT_RSSI_PERIOD );}else{simpleBLERssi = FALSE;GAPCentralRole_CancelRssi( simpleBLEConnHandle );LCD_WRITE_STRING( "RSSI Cancelled", HAL_LCD_LINE_1 );}}}

2)GAPCentralRole_StartRssi函数

bStatus_t GAPCentralRole_StartRssi( uint16 connHandle, uint16 period )
{gapCentralRoleRssi_t  *pRssi;// Verify link is upif (!linkDB_Up(connHandle))   //没连接则退出{return bleIncorrectMode;}// If already allocatedif ((pRssi = gapCentralRole_RssiFind( connHandle )) != NULL)  //如果“RSSI的connHandle值”等于“主从机的connHandle”{// Stop timerosal_CbTimerStop( pRssi->timerId );}// Allocate structureelse if ((pRssi = gapCentralRole_RssiAlloc( connHandle )) != NULL)//connHandle不相等,说明还没有给RSSI分配connHandle,则分配下{pRssi->period = period;}// Allocate failedelse{return bleNoResources;}// Start timerosal_CbTimerStart( gapCentralRole_timerCB, (uint8 *) pRssi,    //这是一个带回调函数的定时器函数,到时即会调用回调函数gapCentralRole_timerCBperiod, &pRssi->timerId );return SUCCESS;
}

3)回调定时器函数gapCentralRole_timerCB

static void gapCentralRole_timerCB( uint8 *pData )
{gapCentralRoleRssiEvent_t *pMsg;// Timer has expired so clear timer ID((gapCentralRoleRssi_t *) pData)->timerId = INVALID_TIMER_ID;     //清除定时器ID// Send OSAL messagepMsg = (gapCentralRoleRssiEvent_t *) osal_msg_allocate( sizeof(gapCentralRoleRssiEvent_t) );if ( pMsg ){pMsg->hdr.event = GAPCENTRALROLE_RSSI_MSG_EVT;pMsg->pRssi = (gapCentralRoleRssi_t *) pData;osal_msg_send ( gapCentralRoleTaskId, (uint8 *) pMsg );    //发送消息到gapCentralRoleTaskId任务的GAPCENTRALROLE_RSSI_MSG_EVT事件中}
}

4)GAPCENTRALROLE_RSSI_MSG_EVT事件

      case GAPCENTRALROLE_RSSI_MSG_EVT:{gapCentralRoleRssi_t *pRssi = ((gapCentralRoleRssiEvent_t *) pMsg)->pRssi;// If link is up and RSSI reads activeif (pRssi->connHandle != GAP_CONNHANDLE_ALL &&linkDB_Up(pRssi->connHandle)){// Restart timerosal_CbTimerStart( gapCentralRole_timerCB, (uint8 *) pRssi,  //不停地定时地调用本事件,从而读取RSSIpRssi->period, &pRssi->timerId );// Read RSSIVOID HCI_ReadRssiCmd( pRssi->connHandle );  //调用读取RSSI的函数,调用完后会进到回调函数simpleBLECentralRssiCB}}break;

3、实验结果

疑问:测试中发现多次读到-129dB,暂不知原因,有人知道的话麻烦告诉我一声~谢谢!

答:

感谢群友“崔氏小农”的答疑解惑:

七、实验步骤(SimpleBLEPeripheral工程以连接方式读RSSI)

1、定义并注册一个回调函数

1)定义一个函数(SimpleBLEPeripheral.c中)

/********************************************************************** @fn      simpleBLEPeripheralRssiCB** @brief   RSSI callback.** @param   newRSSI - RSSI** @return  none*/
static void simpleBLEPeripheralRssiCB( int8 newRSSI )
{HalLcdWriteStringValue( "RSSI -dB:", (uint8) (-newRSSI), 10, HAL_LCD_LINE_1 );// 可以输出一个值,用10进制表示NPI_PrintValue("RSSI:-", (uint8) (-newRSSI), 10);NPI_PrintString("dB\r\n");
}

注:从机端的RssiCB会比主机端少一个connHandle参数。


2)函数声明(SimpleBLEPeripheral.c中)

static void simpleBLEPeripheralRssiCB( int8 newRSSI );


3)将回调函数与函数指针结构体挂钩(SimpleBLEPeripheral.c中)

// GAP Role Callbacks
static gapRolesCBs_t simpleBLEPeripheral_PeripheralCBs =
{peripheralStateNotificationCB,  // Profile State Change CallbackssimpleBLEPeripheralRssiCB       // When a valid RSSI is read from controller (not used by application)
};

4)注册回调函数(SimpleBLEPeripheral.c中)

  if ( events & SBP_START_DEVICE_EVT ){// Start the DeviceVOID GAPRole_StartDevice( &simpleBLEPeripheral_PeripheralCBs );// Start Bond ManagerVOID GAPBondMgr_Register( &simpleBLEPeripheral_BondMgrCBs );// Set timer for first periodic eventosal_start_timerEx( simpleBLEPeripheral_TaskID, SBP_PERIODIC_EVT, SBP_PERIODIC_EVT_PERIOD );return ( events ^ SBP_START_DEVICE_EVT );}

2、设置RSSI扫描速率(SimpleBLEPeripheral.c的SimpleBLEPeripheral_Init中)

  //设置RSSI的读取速率,默认是0uint16 desired_rssi_rate = 1000;GAPRole_SetParameter(GAPROLE_RSSI_READ_RATE,sizeof(uint16),&desired_rssi_rate);

跟踪下代码看看这是在设置什么参数,如下:

再看看RSSI_READ_EVT事件在做什么:

3、实验结果

从机端读取的RSSI比较正常,不像主机端有异常的“-129dB”。

八、实验步骤SimpleBLECentral工程中以不连接的扫描方式读RSSI

1、修改代码(SimpleBLECentral.c中)

    case GAP_DEVICE_INFO_EVENT:{                // if filtering device discovery results based on service UUIDif ( DEFAULT_DEV_DISC_BY_SVC_UUID == TRUE ){if ( simpleBLEFindSvcUuid( SIMPLEPROFILE_SERV_UUID,pEvent->deviceInfo.pEvtData,pEvent->deviceInfo.dataLen ) ){simpleBLEAddDeviceInfo( pEvent->deviceInfo.addr, pEvent->deviceInfo.addrType );NPI_PrintString("发现设备:");//打印地址 NPI_PrintString((uint8 *)bdAddr2Str(pEvent->deviceInfo.addr));        NPI_PrintString("\r\n");              NPI_PrintValue("rssi:-", (uint8)(-( pEvent->deviceInfo.rssi )), 10);//打印RSSINPI_PrintString("dB\r\n");                                                          }}}break;

可通过不停地按“up”键扫描,不需要连接即可获取RSSI。

因为主机在扫描时获得的结构体数据,就已经有RSSI数据了:

/*** GAP_DEVICE_INFO_EVENT message format.  This message is sent to the* app during a Device Discovery Request, when a new advertisement or scan* response is received.*/
typedef struct
{osal_event_hdr_t  hdr;    //!< GAP_MSG_EVENT and statusuint8 opcode;             //!< GAP_DEVICE_INFO_EVENTuint8 eventType;          //!< Advertisement Type: @ref GAP_ADVERTISEMENT_TYPE_DEFINESuint8 addrType;           //!< address type: @ref GAP_ADDR_TYPE_DEFINESuint8 addr[B_ADDR_LEN];   //!< Address of the advertisement or SCAN_RSPint8 rssi;                //!< Advertisement or SCAN_RSP RSSIuint8 dataLen;            //!< Length (in bytes) of the data field (evtData)uint8 *pEvtData;          //!< Data field of advertisement or SCAN_RSP
} gapDeviceInfoEvent_t;

2、实验结果

至此,SimpleBLECentral工程连接时读取RSSI、SimpleBLECentral工程不连接时读取RSSI、SimpleBLEPeripheral工程连接时读取RSSI的三种方法都成功了。

因此,实验成功。

【BLE】CC2541之RSSI相关推荐

  1. 【IoT】TI BLE CC2541 串口控制蓝牙详解

    一.简介 本文以SimpleBLECentral工程为例,介绍串口控制蓝牙. 过程: 扫描从机 - 根据从机号连接指定从机 - 获取RSSI值(信号强度) - 向char1写入特征值 - 断开连接 二 ...

  2. BLE CC2541 串口BootLoader 即 SBL BootLoader 资料 收集

    1.[CC254X_Bootloader]SBL(串口Bootloader)使用说明 2.CC2540协议栈高速串口通信解决(UART的DMA方式) 3.[BLE]CC2541之SBL 4.[BLE] ...

  3. android获取蓝牙信号强度,2、安卓获取ble蓝牙信号强度rssi

    毕业设计需要,需要用到蓝牙,检测蓝牙强度,当蓝牙强度减弱到一定的程度时,将停止扫描,调用其它函数 下面将实现这样的功能. 环境:Android Studio 官方指南:Ble|Android Deve ...

  4. BLE】CC2541之通过RSSI测距

    本篇博文最后修改时间:2017年01月06日,11:06. 一.简介 本文介绍如何在SimpleBLEPeripheral工程中,通过RSSI粗略测距. 二.实验平台 协议栈版本:BLE-CC254x ...

  5. 物联网专题--基于APP Inventor的BLE蓝牙4.0数据通信

    本文原文为本人新浪博客:http://blog.sina.com.cn/s/blog_12f79c9b90102wbde.html 本科毕业设计要用到蓝牙4.0(芯片选用TI公司的CC254x系列)与 ...

  6. linux 检测蓝牙 rssi,蓝牙LE信号强度Linux

    小编典典 在Linux上,可以通过hcitool命令执行此操作.但是,必须连接才能获得设备的rssi.如果要从命令行实现此目的,请尝试: #hcitool rssi AA:BB:CC:DD:EE:FF ...

  7. 菜鸟哥玩蓝牙Ble4.0系列 ESP32初玩篇① Scan —— 扫描周边蓝牙,了解BLE扫描的方方面面

    文章目录 1.前言 2.ESP32 Scan案例 2.1 直接打开官方示例 3.Scan核心库 -- BLEScan 3.1 管理扫描 3.1.1 创建扫描对象 -- BLEScan 3.1.1.1 ...

  8. NORDIC softDevice 蓝牙协议栈初始化程序分析(蓝牙从机,ble_peripheral)

    https://blog.csdn.net/weixin_42396877/article/details/81240822 基于 NORDIC softDevice 蓝牙协议栈 S132 蓝牙角色: ...

  9. PEPS无钥匙进入系统-传统PEPS与数字钥匙系统

    目录 PEPS系统介绍 1.什么是PEPS 2. 传统PEPS 2.1 PEPS系统架构图 2.2 PEPS硬件框图 2.3 PEPS控制器MCU选型参考(NXP) 2.4 低频驱动器 LF Driv ...

最新文章

  1. 爱立信华为MWC展前叫阵:5G成重头戏
  2. CBS多机器人路径规划
  3. 网页效果图设计之色彩索引
  4. PE文件格式--------------导出表
  5. Python加密—HMACSHA1 加密
  6. 猎豹浏览器网页声音怎么关闭
  7. 任意文件上传之绕过云waf+本地防火墙双重防护
  8. [转]WTL的windows mobile环境的配置(vs2008)[最终版,验证通过]
  9. gdal读写图像分块处理
  10. 第四季-专题3-嵌入式Linux内核制作
  11. 软件工程(英文版 第8版)
  12. Win10中卸载IE11
  13. STC15F2K60S2单片机利用24C02记录单片机上电次数
  14. hiveSQL执行计划(explain使用全网最详细!!)
  15. Visual studio 2017 安装
  16. 【ArcGIS小技巧视频教程】(1):GIS数据来源下载攻略
  17. 小程序  跳转web-view  点击左上角返回需要点击2次才能返回
  18. acc 蓝牙_蓝牙耳机≠音质差,只是你没选对耳机
  19. 手撸架构,Nginx 面试40问
  20. 谷歌浏览器(Google Chrome)官方下载

热门文章

  1. 宝藏学员预备团 | Google Play Academy 系列内容第三讲
  2. 软件智能:aaas系统 度量衡及文法规则
  3. 今天我撞到个奇葩,你说我能不笑吗? 哈哈哈
  4. 面试官:唠唠 Activity 的生命周期
  5. 利用现有资源建立自己的经营模式
  6. IBM咨询提出无边界企业,必须了解的数字化转型大趋势
  7. [转]用例和用户故事的区别 useCase和useStory的区别
  8. netlink简单介绍 (linux-3.14.2)
  9. 【20201211期AI简报】目标检测可达40fps! 标称2.0TOPS的RV1126性能评估实测
  10. 业务规则管理(Business Rules Management,简称BRM)