回答

收藏

[原创] 【CurieNano项目3】结合IMU和BLE的计步服务

DFROBOT DFROBOT 5646 人阅读 | 0 人回复 | 2017-05-15

概述:
      作为可穿戴芯片,首先应该能完成的就是计步服务。CurieIMU库提供了计步功能的函数,BLE GATT服务里也提供了 "Running Speed and Cadence" (跑步速度与节奏) 服务,但具体如何把IMU和BLE结合起来,完成一个完整的计步服务,例程里并没有。本帖提供一个完整的,结合IMU和BLE的计步服务。

图:达到的效果




目的:
      使用CurieNano,编写使用IMU计步,使用BLE传输数据的程序。并使用手机APP NRF toolbox显示计步数据。



需要:
       硬件需要:CurieNano、手机
       软件需要:Arduino 101 2.x+库、NRF toolbox(一款手机上的多功能BLE服务获取APP)
       知识储备:查询GATT服务、使用CurieNano编写GATT服务

下载NRF toolbox可以去奈何大大的帖子:http://www.arduino.cn/thread-22901-1-1.html

编写CurieNano的GATT服务可以参考我的帖子:【CurieNano教程1】教你查询GATT并编写相关BLE服务https://www.cirmall.com/bbs/thread-95296-1-1.html



编程思路:
1、使用IMU完成计步
       使用IMU计步非常简单,只需要调用现成的函数。首先,在setup()函数里,需要初始化设置CurieIMU为计步模式:
  1. CurieIMU.begin();
  2.   CurieIMU.setStepDetectionMode(CURIE_IMU_***_MODE_NORMAL);
  3.   CurieIMU.setStepCountEnabled(true);
复制代码
然后CurieIMU就会自动完成计步,你随时可以调用以下函数获取当前累计步数:
  1. CurieIMU.getStepCount();
复制代码
仅仅获取累计步数是不行的,因为接下来我们会看到BLE RSC服务需要传送的数据是“每分钟步数”,我们设法在Curie上完成这个数据的计算。方法很简单,每4分钟运行一次loop函数,获取新的步数并减去旧的步数,得到4秒内计步的数值。然后乘以15,就是每分钟步数。


2、查询计步相关的GATT服务
       BLE计步服务是 "Running Speed and Cadence" (RSC) ,蓝牙官网对该服务描述请参考:
https://www.bluetooth.com/specifications/gatt/viewer?attributeXmlFile=org.bluetooth.service.running_speed_and_cadence.xml
        如果不明白如何查询GATT服务,或查到了不知道如何编写相应的Arduino程序,可以参考我的这篇帖子:
【CurieNano教程1】教你查询GATT并编写相关BLE服务https://www.cirmall.com/bbs/thread-95296-1-1.html

       我们看到,在RSC服务提供了众多服务数据,包括行走速度、每步长度、每分钟步数等。因为我们只有Curie自带的加速度计陀螺仪,无法测出这么多数据,因此我们只计算每分钟步数,其他数据统统置0。
       仔细阅读RSC服务的要求后,得到编程思路如下:程序要建立一个UUID为0x1814的RSC服务、一个UUID为0x2A53的CSC Measurement特征、一个UUID为0x2A54的CSC Feature特征。其中CSC Feature特征包括2字节,我们让它恒为0。CSC Measurement特征包括4字节(最短情况下):第一字节为控制字符Flags,我们让它恒为0;中间2字节是行走速度,我们让它恒为0;后1字节是每分钟步数,我们使用计算出的每分钟步数数据,不断地更新它。




代码:
  1. #include <CurieIMU.h>
  2. #include <CurieBLE.h>

  3. BLEPeripheral blePeripheral;

  4. // Running Speed and Cadence (RSC) 服务: UUID=1814
  5. // 完整的RSC服务字段描述请见 https://www.bluetooth.com/specifications/gatt/viewer?attributeXmlFile=org.bluetooth.characteristic.rsc_measurement.xml
  6. BLEService RSC("1814");
  7. // RSC Feature 特征:UUID=2A54,Property=Read,数据长度=2 (因此直接使用Short类型)
  8. BLEShortCharacteristic RSCFeature("2A54", BLERead);
  9. // RSC Measurement 特征:UUID=2A53,Property=Notify,数据长度=4Byte
  10. BLECharacteristic RSCMeasure("2A53", BLENotify , 4);

  11. void setup() {
  12.   // 初始化BLE
  13.   blePeripheral.setLocalName("Curie");
  14.   blePeripheral.setAdvertisedServiceUuid(RSC.uuid());
  15.   blePeripheral.addAttribute(RSC);
  16.   blePeripheral.addAttribute(RSCFeature);
  17.   blePeripheral.addAttribute(RSCMeasure);
  18.   blePeripheral.begin();
  19.   RSCFeature.setValue(0);

  20.   // 初始化IMU为计步模式并开始计步
  21.   CurieIMU.begin();
  22.   CurieIMU.setStepDetectionMode(CURIE_IMU_***_MODE_NORMAL);
  23.   CurieIMU.setStepCountEnabled(true);
  24. }

  25. // 每 INTERVAL 秒,BLE发送一次数据
  26. #define INTERVAL 4

  27. void loop() {
  28.   // RSC Measurement 特征 的4Byte发送缓冲区
  29.   static uint8_t data[4] = {0,0,0,0};
  30.   // 上一次计步的步数,即INTERVAL秒前的计步步数
  31.   static uint32_t lastStepCnt=0;
  32.   // 每分钟步数
  33.   static uint8_t spm;

  34.   // 每分钟步数 = (此次计步步数-INTERVAL秒前的计步步数) * 每分钟60秒 / INTERVAL
  35.   spm = (CurieIMU.getStepCount() - lastStepCnt) * 60 / INTERVAL;
  36.   
  37.   lastStepCnt = CurieIMU.getStepCount();

  38.   // 根据RSC的字段描述
  39.   // RSC Measurement 特征的第三字节为每分钟步数
  40.   // 在仅有加速度计陀螺仪的情况下,仅能完成计步
  41.   // 而其他字段,Curie缺乏相关传感器无法测量,因此保持为0
  42.   data[3] = spm;
  43.   
  44.   // 更新RSC Measurement
  45.   RSCMeasure.setValue(data,4);

  46.   // 等待INTERVAL秒
  47.   delay(INTERVAL*1000);
  48. }
复制代码
程序测试:
         首先,你需要一个装有NRF toolbox的手机,下载NRF toolbox可以去奈何大大的帖子:http://www.arduino.cn/thread-22901-1-1.html
         上传代码到CurieNano后,打开NRF toolbox,点击RSC,在下方点击Connect,选择"Curie"进行连接,然后带着CurieNano走几步路,就可以看到手机屏幕上的计步数据更新。

图:程序测试流程


关注下面的标签,发现更多相似文章
分享到:
回复

使用道具 举报

您需要登录后才可以回帖 注册/登录

本版积分规则

关闭

站长推荐上一条 /2 下一条