电子指南针是现代的一种重要导航工具,大到飞机船舶的导航,小到个人手机导航,电子指南针可以说和咱们生活息息相关,密不可分。为什么电子指南针能指示方向?本 Demo 将为你呈现,其中蕴含了人类智慧及大自然的奥妙。本项目分为数据采集端(设备端)和效果展示端(应用端):
1、指南针数据采集端:使用的是 Geek_Lite_Board 开发板,其内置了三轴磁力计 AK8963,通过解析磁力计数据获得指南针数据信息,操作系统版本为 OpenAtom OpenHarmony 3.0(以下简称“OpenHarmony”); 2、指南针效果展示端:使用的是润和 RK3568 开发板,操作系统版本为 OpenHarmony 3.1 release。 效果展示端则体现了 OpenHarmony JS UI、Canvas 组件和 NAPI 的能力: 1、Canvas 组件是一个画布组件,获取到画布对象后,可以自定义绘制图形,比如圆形,线条等,本项目中应用端的指南针界面是基于 Canvas 组件开发; 2、NAPl (Na tiveAPI)是 OpenHarmony 标准系统的一种 JS API 实现机制,通过 NAPI 可以实现 JS 与 C/C++ 代码互相访问。本项目应用端通过 NAPI 来接收设备端发出的检测信息。
当设备应用启动之后,运行效果如下动图所示:
一、基本原理地球是一个大磁体,地球的两个极分别在接近地理南极和地理北极的地方,一般情况下地球的磁场强度在 0.5 高斯左右(高斯是磁场强度单位)。
Geek_Lite_Board 开发板带有 AK8963 三轴磁力计。三轴磁力计能够测出相互垂直的三个方向的磁力大小。通常我们把传感器平放,即让重力方向与传感器垂直,假设重力方向为 z 轴,其余两轴为 x 轴和 y 轴。在只受地球磁场的环境下(忽略其余弱小干扰),x 轴 y 轴检测到的磁力数据的矢量和就等于接收到的地球磁场。
我们利用 x 轴与 y 轴的比值,就能确定目前朝向正北边差多少角度。例如现测到 x 轴数据接近 0.5 高斯,y 轴数据接近 0,就认为目前的 x 轴方向就是正北方。那 x 轴方向是哪个方向?关于 x 轴方向,生产传感器芯片的厂商会预定义好传感器的 x 轴、y 轴及 z 轴方向(通常垂直芯片表面的为 z 轴)。 数据流程
智能指南针整体方案如上图所示,主要由 Geek_Lite_Board 开发板和润和 RK3568 开发板构成,它们采用局域网(路由器)TCP 协议的 通信方式。 1. Geek_Lite_Board 开发板通过板载的磁力计获取磁场数据,磁场数据经过处理后得到角度数据; 2. 角度信息通过 ESP8266 无线 Wi-Fi 模块发送到指南针应用端; 3. 指南针应用端通过 NAPI 接口获取底层网络数据,并在页面展示。 二、功能实现指南针数据的获取 Geek_Lite_Board 开发板通过 IIC 接口与 AK8963 三轴磁力计通信,读取三轴方向的磁场数据,通过磁场数据计算后得到指南针的方位数据。 ● AK8963介绍 AK8963是采用高灵敏度霍尔传感器技术,内部集成了检测x、y、z轴的磁传感器、传感器驱动 电路、信号放大器和用于处理每个传感器信号的算术电路。同时,还配备了自测功能。其紧凑的封装,还可适用于配备gps的手机的地图导航,实现行人导航等功能。 ● AK8963测量数据的读取 AK8963 和 单片机通过 IIC 接口连接,单片机操作 IIC 总线按照数据手册的操作时序操作即可读取 AK8963 的数据,AK8963 获取测量数据的函数实现如下:
- uint8_t Mpu_Read_Bytes(uint8_t const regAddr, uint8_t *pData, uint8_t len)
- {
- int i = 0;
- MPU_ENABLE;
- while (SPI_I2S_GetFlagStatus(SPI5, SPI_I2S_FLAG_TXE) == RESET);
- SPI_I2S_SendData(SPI5, regAddr | 0x80);
- while (SPI_I2S_GetFlagStatus(SPI5, SPI_I2S_FLAG_RXNE) == RESET);
- SPI_I2S_ReceiveData(SPI5);
- for(i=0; i
- while(SPI_I2S_GetFlagStatus(SPI5, SPI_I2S_FLAG_TXE) == RESET);
- SPI_I2S_SendData(SPI5, 0x00);
- while(SPI_I2S_GetFlagStatus(SPI5, SPI_I2S_FLAG_RXNE) == RESET);
- pData[i] = SPI_I2S_ReceiveData(SPI5);
- }
- MPU_DISABLE;
- return 0;
- }
复制代码
● AK8963数据处理得到磁力数据 调用 Mpu_Read_Bytes 函数获取测量数据,其中 MPU_BUFF[15] 到 MPU_BUFF[20] 这六个字节的数据就是磁力计的数据。此时的磁力计数据还不稳定不能直接用来计算指南针的角度,还需要进行滤波处理,此处用到的滤波算法是滑动均值滤波。数据处理代码如下:
- Mpu_Read_Bytes(MPUREG_ACCEL_XOUT_H, MPU_BUFF, 28);
- if(MPU_BUFF[14] == 1) {
- // 从 MPU_BUFF[]中提取磁力数据
- Mpu_Data.mag_x = (MPU_BUFF[16] << 8) | MPU_BUFF[15];
- Mpu_Data.mag_y = (MPU_BUFF[18] << 8) | MPU_BUFF[17];
- Mpu_Data.mag_z = (MPU_BUFF[20] << 8) | MPU_BUFF[19];
- // 对x轴方向磁力计数据进行滤波,取滑动平均
- for(i=0;i<14;i++) {
- mag_x_buff[i] = mag_x_buff[i+1] //滑动
- }
- if(Mpu_Data.mag_x > -500 && Mpu_Data.mag_x < 500) {
- mag_x_buff[14] = Mpu_Data.mag_x;
- }
- //取平均值
- Mpu_Calc.mag_x = ( mag_x_buff[0] + mag_x_buff[1] + mag_x_buff[2]
- + mag_x_buff[3] + mag_x_buff[4] + mag_x_buff[5] + mag_x_buff[6]
- + mag_x_buff[7] + mag_x_buff[8] + mag_x_buff[9] + mag_x_buff[10]
- + mag_x_buff[11] + mag_x_buff[12] + mag_x_buff[13]
- + mag_x_buff[14] )/15.0f;
- // 对y轴方向磁力计数据进行滤波,取滑动平均
- for(i=0;i<14;i++){
- mag_y_buff[i] = mag_y_buff[i+1]; //滑动
- }
- if(Mpu_Data.mag_y > -500 && Mpu_Data.mag_y < 500){
- mag_y_buff[14] = Mpu_Data.mag_y;
- }
- //取平均值
- Mpu_Calc.mag_y = ( mag_y_buff[0] + mag_y_buff[1] + mag_y_buff[2]
- + mag_y_buff[3] + mag_y_buff[4] + mag_y_buff[5] + mag_y_buff[6]
- + mag_y_buff[7] + mag_y_buff[8] + mag_y_buff[9] + mag_y_buff[10]
- + mag_y_buff[11] + mag_y_buff[12] + mag_y_buff[13]
- + mag_y_buff[14] )/15.0f;
- // 对磁力计z轴方向进行滤波
- mag_z_buff[0] = mag_z_buff[1];
- mag_z_buff[1] = Mpu_Data.mag_z;
- Mpu_Calc.mag_z = (int16_t)((mag_z_buff[0] + mag_z_buff[1])/ 2.0f);
- }
复制代码
● 角度数据计算 磁力计数据通过滤波后得到 x y z 三个轴方向的磁力分量,计算出 x 和 y轴的 tan 值,再通过反正切计算出角度,角度经过滑动平均得到最终需要显示出来的指南针角度值,计算过程见如下代码。
- angle_buff[0] = angle_buff[1];
- angle_buff[1] = angle_buff[2];
- angle_buff[2] = ((uint16_t)(atan2((Mpu_Calc.mag_y - Mag_y_OffSet),
- (Mpu_Calc.mag_x - Mag_x_OffSet)) *180 / PI + 180 ));
- angle = ((uint16_t)((angle_buff[0] + angle_buff[1] + angle_buff[2])
- / 3.0 + 0.5));
复制代码
指南针数据的传输 Geek_Lite_Board 开发板外挂 ESP8266 Wi-Fi 模组通过局域网 TCP 通信的方式将角度数据传输给润和 RK3568 开发板,润和 RK3568 开发板通过 NAPI 接口获取底层网络数据,从网络数据中解析出角度数据,并在显示屏上显示出来。
角度数据的显示 角度数据的显示由润和 RK3568 开发板实现,主要分为指南针显示页面的绘制和 NAPI 从局域网上获取角度数据并展示到界面上。
指南针显示页面 指南针的显示页面主要通过 Canvas 组件画图完成,包含方位角度、指南针针盘和指示线,显示整体效果如下图所示。
指南针针盘由一个 Canvas 组件构成,包含了三个部分,分别为刻度盘、角度数字、方位文字,他们的效果图分别如下: ● 刻度盘 |