701|5

148

帖子

0

资源

一粒金砂(中级)

蜜袋鼯 第④贴 RSL10-SENSE-GEVK 玩耍BHI160,步数、运动识别?不用处理,直接获取!! [复制链接]

本帖最后由 justd0 于 2021-6-27 01:42 编辑

     本是周末是要被想出游的家人拉出去当司机,奈何计划有变,于是终于有了自己的周末空闲时间~~撒花啊!

 

     蜜袋鼯 第③贴 上一贴写了 由于官方对RSL10-SENSE-GEVK开发板进行了硬件升级,替换了光照度传感器而导致的相应例程无法使用,故写了个写了个驱动代码分享给大家。

 

本帖主要内容:

1、介绍姿态传感器、磁力计传感器背景及功能。

2、修改RSL10-SENSE-GEVK官方例程,读取加速度、角速度、磁力计、重力等数据。

3、修改例程中的BHI160应用层配置,将该传感器的特殊数据读取出来,例如:步数检测、运动状态识别等,此处得圈下@w494143467 ,没记错的话你项目里要用它来做运动识别的话,传感器已经实现了,你就不用自己算了哈~~

 


正文开始:

 

按照我的项目计划(哦,忘记写了,下一贴写下项目的计划内容吧),还需要运动信息,比如角速度、旋转圈数等,而这些数据可以由开发板上的BHI160传感器获取到。

 

在玩板之前,本以为这个传感器就是个普通的六轴姿态传感器,

但查了下资料之后才发现,这可是大名鼎鼎的博世 的 姿态传感器啊!

 

你可能会问博世是啥?跟普通的姿态传感器有啥区别啊。。

 

哈哈,我也有这个疑问来的,在我看完他的datasheet之后,不得不说这传感器很牛b。

 

image-20210627010749-1.png

 

从他官网上的简介可以看到,这个小传感器不仅仅是三轴加速度计、三轴角速度计这么简单,

 

他在内部就对原始数据进行了处理,能够输出

“加速度计、重力、线性加速度、陀螺仪、陀螺仪未校准、游戏旋转矢量、计步器、步数检测器、

有效运动识别(significant motion)、倾斜检测器、拾取识别、唤醒识别、手势识别、站立、

跑步、骑自行车、开车的活动识别”

 

而且传感器还能串联一个其他类别的传感器,例如地磁计,就又可以输出

“地磁场、未校准磁场、方向矢量、旋转矢量、地磁旋转矢量”

 

在官网的下方还可以看到博世已经给提供了这个传感器的使用例程,还有固件?

 

固件什么鬼,点开看下,原来用传感器串联他家自己传感器的时候,都不用自己配置信息了,直接按照固件烧进去就行了,如下图的BMM150,这不正是RSL10-SENSE-GEVK开发板上的磁力计传感器么~~

 

另外博世还给提供了详细的驱动库和示例代码,感兴趣的可以去github看下

 

image-20210627010749-2.png

 

 

那么回来再看RSL10-SENSE-GEVK开发板的电路图上,就是采用的博世的BHI160+BMM150方案

image-20210627010749-3.png

 

 

我们直接打开SDK中的sense_bhi160来先体验下,copy下工程,然后看下例程里面是怎么个逻辑,

 

我画了个流程图,可以看到这个例程还是很好理解的,

 

初始化了必要组件之后,初始化了下BHI160传感器,并对它初始化过程做了个计时。

 

接下来就是注册了三组数据的回调处理函数,以便获取传感器数据更新值。

image-20210627010749-4.png

然后编译下载到开发板,我们通过Jlink RTT viewer 就可以看到数据了,

 

下图中可以看到,BHI160初始化的时间显示的是805ms

感兴趣的同学可以进入到初始化函数中看下,可以看到用这么久时间进行初始化,其实都是前面说的给BHI160烧写了BMM150的配置程序那个过程。

image-20210627010749-5.png

 

用RTT viewer看log数据就是一堆的打印信息,如下图所示,

但实时刷新的时候,根本看不清数据是啥。。。

image-20210627010749-6.png

那么我们可以借助jscope来看下数据变化,接下来只要定义个全局变量,

把传感器数据传出来,jscope就可以监控到变化的数据。

 

代码修改如下:

main.c

//定义数据结构,实例化数据
typedef struct
{
	float x;
	float y;
	float z;
}Data_t;

Data_t orientation;
Data_t acc;
Data_t gyro;

........

/** Converts measured orientation data into degrees.
 *
 * GREEN LED will be turned on if board heading is within 10 degrees of
 * magnetic north (<=10 or >=350).
 */
void ao_vector_cb(bhy_data_generic_t *data, bhy_virtual_sensor_t sensor)
{
	orientation.x = data->data_vector.x / 32768.0f * 360.0f;
	orientation.y = data->data_vector.y / 32768.0f * 360.0f;
	orientation.z = data->data_vector.z / 32768.0f * 360.0f;

    if (orientation.x > 350.0f || orientation.x < 10.0f)
    {
        LED_On(LED_GREEN);
    }
    else
    {
        LED_Off(LED_GREEN);
    }

    //printf("Orientation: h=%.1f p=%.1f, y=%.1f (%d)\r\n", h, p, y, data->data_vector.status);
}

/** Converts measured linear acceleration data based on sensors dynamic range
 * and prints it to debug terminal.
 *
 * Also turns on RED LED if total acceleration applied to the board is over 1g.
 */
void la_vector_cb(bhy_data_generic_t *data, bhy_virtual_sensor_t sensor)
{
    /* Linear Acceleration sensor values are scaled using dynamic range. */
    uint16_t dyn_range = BHI160_NDOF_GetAccelDynamicRange();

    acc.x = data->data_vector.x / 32768.0f * dyn_range;
    acc.y = data->data_vector.y / 32768.0f * dyn_range;
    acc.z = data->data_vector.z / 32768.0f * dyn_range;

    if (fabsf(acc.x) + fabsf(acc.y) + fabsf(acc.z) >= 1.0f)
    {
        LED_On(LED_RED);
    }
    else
    {
        LED_Off(LED_RED);
    }

//    printf("Linear Accel: x=%.2f g, y=%.2f g, z=%.2f g\r\n", x, y, z);
}

void gyro_vector_cb(bhy_data_generic_t *data, bhy_virtual_sensor_t sensor)
{
    uint16_t dyn_range = BHI160_NDOF_GetGyroDynamicRange();

    gyro.x = data->data_vector.x / 32768.0f * dyn_range;
    gyro.y = data->data_vector.y / 32768.0f * dyn_range;
    gyro.z = data->data_vector.z / 32768.0f * dyn_range;

    if (fabsf(gyro.z) > 45.0f)
    {
        LED_On(LED_BLUE);
    }
    else
    {
        LED_Off(LED_BLUE);
    }

//    printf("Rate of Rotation: x=%.2f , y=%.2f /s, z=%.2f \r\n", x, y, z);
}

 

然后,打开jscope,新建个project

在配置界面的specify target device中输入rsl10

elf file中选择工程编译目录下的sense_bhi160.elf

如下图所示,就可以点ok

image-20210627011729-1.png

 

然后在下面添加我们定义的全局变量,点击start就可以看到数据变化了,如下图。

但各位看下下图中的数据,是存在明显的锯齿的,也就是刷新频率很低。

image-20210627010749-8.png

 

     这个问题我们可以看下  注册回调函数的那个api,其中最后一个参数,便是设置采样率的,

他的数值代表的是频率,数值越大更新速度越快,

当然了,功耗也会相对高一点点,这里我们把它设置为1000hz,看看效果,代码修改如下所示:

 

main.c


int main(void)
{
.......

    retval = BHI160_NDOF_EnableSensor(BHI160_NDOF_S_ORIENTATION, &ao_vector_cb, 1000);
    ASSERT_DEBUG(retval == BHY_SUCCESS);

    retval = BHI160_NDOF_EnableSensor(BHI160_NDOF_S_LINEAR_ACCELERATION, &la_vector_cb, 1000);
    ASSERT_DEBUG(retval == BHY_SUCCESS);

    retval = BHI160_NDOF_EnableSensor(BHI160_NDOF_S_RATE_OF_ROTATION, &gyro_vector_cb, 1000);
    ASSERT_DEBUG(retval == BHY_SUCCESS);

.......
}

 

编译并烧录,在看下jscope的数据图,就变的连贯很多了。

image-20210627010749-9.png

 

     在传感器数据回调注册的函数中我们还可以看到第一个参数,是选择需要的数据类型的,

改变这个参数就可以获取传感器的不同类型数据了,这里可看到库中给的定义,列写了五种数据,包括姿态角度、重力、线性加速度、角速度、磁场强度数据,可以分别改动下看看数据是怎样的。

image-20210627011958-2.png

至此,这个例程的功能我们就体验完了。

 

 

但本帖还没完。。。。。

  

 

就像开头所说的,BHI160传感器支持的数据可不止上面例程库中给列写的那几个,

在看了芯片的datasheet之后,发现还支持

游戏旋转矢量、计步器、步数检测器、有效运动识别(significant motion)、

倾斜检测器、拾取识别、唤醒识别、手势识别、站立、跑步、骑自行车、开车的活动识别”这些数据。

image-20210627010749-11.png

 

看下RSL10的工程,其实也是引用了博世提供的SDK的,如下图:

image-20210627010749-12.png

 

 

在回看下上面传感器数据的枚举变量中

image-20210627012149-3.png

定义的变量其实就是这些支持的功能

image-20210627012223-4.png

那么也就是说,我们需要哪个数据,只要在BHI160_NDOF_Sensor这个枚举体中再定义下,

按照例程的方式,就可以直接使用啦。

 

只是这些不同类型的数据,会有对应的数据格式,这个格式可以参考BHI160的数据手册中定义的来,

如上面Table14 virtual sensor ID 表中VS data type中定义的数据类型,

再看下面这张图中的data values 使用就行了。

image-20210627010749-14.png

 

 

下面以行走步数和活动识别来举例,

 

因为步数更新和活动识别都是传感器内部实现的,

我们读取数据的频率就可以降低些,以1hz频率更新

这里用RTT viewer来打印,

把例程自带的三个原始数据的回调注册的打印给注释掉了,防止顶掉我们想要的数据显示

并实现行走步数和活动识别的回调和相应处理,实现代码如下:

 

main.c


void step_counter_cb(bhy_data_generic_t *data, bhy_virtual_sensor_t sensor)
{
	bhy_data_scalar_u16_t step_data;
	step_data.data = data->data_scalar_u16.data;
	printf("Step counter is %d\r\n", step_data.data);
}

void activity_recognition_cb(bhy_data_generic_t *data, bhy_virtual_sensor_t sensor)
{
	bhy_data_scalar_u16_t act_data;
	static uint16_t last_act;
	act_data.data = data->data_scalar_u16.data;
	if(act_data.data != last_act)
	{
		switch (act_data.data)
		{
			case 0x0000:
				break;
			case 0x0001:
				printf("Still activity ended. \r\n");
				break;
			case 0x0002:
				printf("Walking activity ended. \r\n");
				break;
			case 0x0004:
				printf("Running activity ended. \r\n");
				break;
			case 0x0008:
				printf("On Bicycle activity ended \r\n");
				break;
			case 0x0010:
				printf("In Vehicle activity ended. \r\n");
				break;
			case 0x0020:
				printf("Tilting activity ended. \r\n");
				break;

			case 0x0040:
				break;
			case 0x0080:
				break;

			case 0x0100:
				printf("Still activity start. \r\n");
				break;
			case 0x0200:
				printf("Walking activity start. \r\n");
				break;
			case 0x0400:
				printf("Running activity start. \r\n");
				break;
			case 0x0800:
				printf("On Bicycle activity start \r\n");
				break;
			case 0x1000:
				printf("In Vehicle activity start. \r\n");
				break;
			case 0x2000:
				printf("Tilting activity start. \r\n");
				break;

			case 0x4000:
				break;
			case 0x8000:
				break;
			default:
				break;
		}
	}
	last_act = act_data.data;
}


int main(void)
{
.......

    /* Enable desired virtual sensor outputs. */

    retval = BHI160_NDOF_EnableSensor(BHI160_NDOF_S_ORIENTATION, &ao_vector_cb, 1000);
    ASSERT_DEBUG(retval == BHY_SUCCESS);

    retval = BHI160_NDOF_EnableSensor(BHI160_NDOF_S_LINEAR_ACCELERATION, &la_vector_cb, 1000);
    ASSERT_DEBUG(retval == BHY_SUCCESS);

    retval = BHI160_NDOF_EnableSensor(BHI160_NDOF_S_RATE_OF_ROTATION, &gyro_vector_cb, 1000);
    ASSERT_DEBUG(retval == BHY_SUCCESS);

    retval = BHI160_NDOF_EnableSensor(BHI160_NDOF_S_STEP_COUNTER, &step_counter_cb, 1);
    ASSERT_DEBUG(retval == BHY_SUCCESS);

    retval = BHI160_NDOF_EnableSensor(BHI160_NDOF_S_ACTIVITY_RECOGNITION, &activity_recognition_cb, 1);
    ASSERT_DEBUG(retval == BHY_SUCCESS);

........
}

 

活动识别的数据具体定义可以参考芯片数据手册中的描述:

image-20210627012607-6.png

然后我们烧录,并用RTT viewer可以看到我模拟走路的步数被有效的记录了下来,

这相比自己用原始数据来计算出来,功耗、效果方面都会好很多了。

  模式切换.gif

本文就先到这了,以上用到的数据手册我放到下面连接了,各位随意取用。

  bst-bmm150-ds001.pdf (7.29 MB, 下载次数: 2)


回复

1986

帖子

3

资源

版主

哈哈,突然被Q到,原来还有这东西,看来世博提供的SDK还是比较丰富的,这些算法源码开源不,还是只提供接口?

点评

BHI160内部的程序干的,firmware是二进制数据形式。  详情 回复 发表于 2021-6-27 10:05
应该是找不到源码的,它可能被固话到传感器芯片了。 不过你可以通过数据和识别结果,做个黑箱测试,或者用它的结果跟你的结果做个对比  详情 回复 发表于 2021-6-27 09:59

回复

148

帖子

0

资源

一粒金砂(中级)

w494143467 发表于 2021-6-27 08:05 哈哈,突然被Q到,原来还有这东西,看来世博提供的SDK还是比较丰富的,这些算法源码开源不,还是只提供接口 ...

应该是找不到源码的,它可能被固话到传感器芯片了。

不过你可以通过数据和识别结果,做个黑箱测试,或者用它的结果跟你的结果做个对比

点评

我后面试试,那这个传感器还是非常不错的!  详情 回复 发表于 2021-6-27 11:02

回复

1485

帖子

2

资源

五彩晶圆(初级)

w494143467 发表于 2021-6-27 08:05 哈哈,突然被Q到,原来还有这东西,看来世博提供的SDK还是比较丰富的,这些算法源码开源不,还是只提供接口 ...

BHI160内部的程序干的,firmware是二进制数据形式。

点评

哦哦哦,原来如此,那我后面又时间可以试一下!  详情 回复 发表于 2021-6-27 11:02

回复

1986

帖子

3

资源

版主

cruelfox 发表于 2021-6-27 10:05 BHI160内部的程序干的,firmware是二进制数据形式。

哦哦哦,原来如此,那我后面又时间可以试一下!


回复

1986

帖子

3

资源

版主

justd0 发表于 2021-6-27 09:59 应该是找不到源码的,它可能被固话到传感器芯片了。 不过你可以通过数据和识别结果,做个黑箱测试,或 ...

我后面试试,那这个传感器还是非常不错的!


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

最新文章 更多>>
    关闭
    站长推荐上一条 1/10 下一条

    About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

    站点相关: 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

    北京市海淀区知春路23号集成电路设计园量子银座1305 电话:(010)82350740 邮编:100191

    电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2021 EEWORLD.com.cn, Inc. All rights reserved
    快速回复 返回顶部 返回列表