关于openharmony:基于OpenHarmony的智能指南针

29次阅读

共计 5055 个字符,预计需要花费 13 分钟才能阅读完成。

电子指南针是古代的一种重要导航工具,大到飞机船舶的导航,小到集体手机导航,电子指南针能够说和咱们生存非亲非故,密不可分。为什么电子指南针能批示方向?本 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…
NAPI
NAPI(Native API)是 OpenHarmony 规范零碎的一种 JS API 实现机制,适宜封装 IO、CPU 密集型、OS 底层等能力并对外裸露 JS 接口,通过 NAPI 能够实现 JS 与 C/C++ 代码相互拜访。润和 RK3568 利用端通过 NAPI 来接管设施端收回的检测信息。
底层 NAPI 模块封装
● 本利用封装的模块名为 tcpserverapi,先下载源码,源码门路为:
https://gitee.com/openharmony…
● 下载实现后放到 OpenHarmony 3.1 Release 版本源码根目录,并配置编译脚本;第一次编译实现须要烧写整个镜像,请参考[开发板上新 | RK3568 开发板上丝滑体验 OpenHarmony 规范零碎]:
https://gitee.com/openharmony…
● 前面批改模块源码,只需将库 send 到板子外面。命令如下:

先挂载,再 send
hdc_std shell mount -o remount,rw /
hdc_std file send libtcpserverapi.z.so system/lib/module/libtcpserverapi.z.so
利用端导入 NAPI 模块
import tcpserverapi from '@ohos.tcpserverapi'
利用端 NAPI 接口调用
// 调用 initServer 接口 初始化 TCP 服务器
tcpserverapi.initServer() 
// 调用 recvMsg 获取并解析 SMT32 板子发送过去的角度
tcpserverapi.recvMsg().then((result) => {var resultAngle = result.angle;})

更多 NAPI 相干常识请参考《规范设施利用开发 Native Api》视频课程。
https://www.bilibili.com/vide…
利用端代码地址
https://gitee.com/openharmony…
设施侧代码地址
https://gitee.com/openharmony…
https://gitee.com/geekros/Ope…
参考文档
【电子指南针】
https://gitee.com/openharmony…
https://gitee.com/openharmony…
【RK3568 领导】
https://gitee.com/openharmony…
【Geek_Lite_Board 相干网址】
www.geekros.com
丰盛多样的 OpenHarmony 开发样例离不开宽广合作伙伴和开发者的奉献,如果你也想把本人开发的样例分享进去,欢送把样例提交到 OpenHarmony 常识体系 SIG 仓来。
如何共建开发样例
https://gitee.com/openharmony…

正文完
 0