电子指南针是现代的一种重要导航工具,大到飞机船舶的导航,小到个人手机导航,电子指南针可以说和咱们生活息息相关,密不可分。为什么电子指南针能指示方向?本 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 (NativeAPI)是 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<len; 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 组件构成,包含了三个部分,分别为刻度盘、角度数字、方位文字,他们的效果图分别如下:
● 刻度盘
● 角度数字
● 方位文字
Canvas组件相关知识可以参考:https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/arkui-js/js-components-canvas-canvas.md
NAPI
NAPI(Native API)是 OpenHarmony 标准系统的一种 JS API 实现机制,适合封装 IO、CPU 密集型、OS 底层等能力并对外暴露 JS 接口,通过 NAPI 可以实现 JS 与 C/C++ 代码互相访问。润和 RK3568 应用端通过 NAPI 来接收设备端发出的检测信息。
底层 NAPI 模块封装
● 本应用封装的模块名为 tcpserverapi,先下载源码,源码路径为:https://gitee.com/openharmony-sig/knowledge_demo_temp/tree/master/dev/team_x/napi_tcpservermodule/tcpservermodule
● 下载完成后放到 OpenHarmony 3.1 Release 版本源码根目录,并配置编译脚本;第一次编译完成需要烧写整个镜像,请参考[开发板上新 | RK3568 开发板上丝滑体验 OpenHarmony 标准系统]:https://gitee.com/openharmony-sig/knowledge_demo_smart_home/tree/master/dev/docs/rk3568_quick_start
● 后面修改模块源码,只需将库send到板子里面。命令如下:
`hdc_std shell mount -o remount,rw /`
`hdc_std file send libtcpserverapi.z.so ``system``/lib/module/libtcpserverapi.z.so`
经常有很多小伙伴抱怨说:不知道学习鸿蒙开发哪些技术?不知道需要重点掌握哪些鸿蒙应用开发知识点?
为了能够帮助到大家能够有规划的学习,这里特别整理了一套纯血版鸿蒙(HarmonyOS Next)全栈开发技术的学习路线,包含了鸿蒙开发必掌握的核心知识要点,内容有(ArkTS、ArkUI开发组件、Stage模型、多端部署、分布式应用开发、WebGL、元服务、OpenHarmony多媒体技术、Napi组件、OpenHarmony内核、OpenHarmony驱动开发、系统定制移植等等)鸿蒙(HarmonyOS NEXT)技术知识点。
《鸿蒙 (Harmony OS)开发学习手册》(共计892页)
如何快速入门?
1.基本概念
2.构建第一个ArkTS应用
3.……
开发基础知识:
1.应用基础知识
2.配置文件
3.应用数据管理
4.应用安全管理
5.应用隐私保护
6.三方应用调用管控机制
7.资源分类与访问
8.学习ArkTS语言
9.……
基于ArkTS 开发
1.Ability开发
2.UI开发
3.公共事件与通知
4.窗口管理
5.媒体
6.安全
7.网络与链接
8.电话服务
9.数据管理
10.后台任务(Background Task)管理
11.设备管理
12.设备使用信息统计
13.DFX
14.国际化开发
15.折叠屏系列
16.……
鸿蒙开发面试真题(含参考答案)
OpenHarmony 开发环境搭建
《OpenHarmony源码解析》
- 搭建开发环境
- Windows 开发环境的搭建
- Ubuntu 开发环境搭建
- Linux 与 Windows 之间的文件共享
- ……
- 系统架构分析
- 构建子系统
- 启动流程
- 子系统
- 分布式任务调度子系统
- 分布式通信子系统
- 驱动子系统
- ……
OpenHarmony 设备开发学习手册