?
?劉麗紅
OpenHarmony 知識體系工作組 電子指南針是現代的一種重要導航工具,大到飛機船舶的導航,小到個人手機導航,電子指南針可以說和咱們生活息息相關,密不可分。為什么電子指南針能指示方向?本 Demo 將為你呈現,其中蘊含了人類智慧及大自然的奧妙。本項目分為數據采集端(設備端)和效果展示端(應用端):
1、指南針數據采集端:使用的是 Geek_Lite_Board 開發(fā)板,其內置了三軸磁力計 AK8963,通過解析磁力計數據獲得指南針數據信息,操作系統(tǒng)版本為 OpenAtom OpenHarmony 3.0(以下簡稱“OpenHarmony”);
2、指南針效果展示端:使用的是潤和 RK3568 開發(fā)板,操作系統(tǒng)版本為 OpenHarmony 3.1 release。
效果展示端則體現了 OpenHarmony JS UI、Canvas 組件和 NAPI 的能力:
1、Canvas 組件是一個畫布組件,獲取到畫布對象后,可以自定義繪制圖形,比如圓形,線條等,本項目中應用端的指南針界面是基于 Canvas 組件開發(fā);
2、NAPl (NativeAPI)是 OpenHarmony 標準系統(tǒng)的一種 JS API 實現機制,通過 NAPI 可以實現 JS 與 C/C++ 代碼互相訪問。本項目應用端通過 NAPI 來接收設備端發(fā)出的檢測信息。
當設備應用啟動之后,運行效果如下動圖所示:
?
?
一、基本原理
地球是一個大磁體,地球的兩個極分別在接近地理南極和地理北極的地方,一般情況下地球的磁場強度在 0.5 高斯左右(高斯是磁場強度單位)。 Geek_Lite_Board 開發(fā)板帶有 AK8963 三軸磁力計。三軸磁力計能夠測出相互垂直的三個方向的磁力大小。通常我們把傳感器平放,即讓重力方向與傳感器垂直,假設重力方向為 z 軸,其余兩軸為 x 軸和 y 軸。在只受地球磁場的環(huán)境下(忽略其余弱小干擾),x 軸 y 軸檢測到的磁力數據的矢量和就等于接收到的地球磁場。我們利用 x 軸與 y 軸的比值,就能確定目前朝向正北邊差多少角度。例如現測到 x 軸數據接近 0.5 高斯,y 軸數據接近 0,就認為目前的 x 軸方向就是正北方。那 x 軸方向是哪個方向?關于 x 軸方向,生產傳感器芯片的廠商會預定義好傳感器的 x 軸、y 軸及 z 軸方向(通常垂直芯片表面的為 z 軸)。
?
數據流程
?
智能指南針整體方案如上圖所示,主要由 Geek_Lite_Board 開發(fā)板和潤和 RK3568 開發(fā)板構成,它們采用局域網(路由器)TCP 協(xié)議的通信方式。
1. Geek_Lite_Board 開發(fā)板通過板載的磁力計獲取磁場數據,磁場數據經過處理后得到角度數據;
2. 角度信息通過 ESP8266 無線 Wi-Fi 模塊發(fā)送到指南針應用端;
3. 指南針應用端通過 NAPI 接口獲取底層網絡數據,并在頁面展示。
?二、功能實現
指南針數據的獲取
Geek_Lite_Board 開發(fā)板通過 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] 這六個字節(jié)的數據就是磁力計的數據。此時的磁力計數據還不穩(wěn)定不能直接用來計算指南針的角度,還需要進行濾波處理,此處用到的濾波算法是滑動均值濾波。數據處理代碼如下:
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
?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 開發(fā)板外掛 ESP8266 Wi-Fi 模組通過局域網 TCP 通信的方式將角度數據傳輸給潤和 RK3568 開發(fā)板,潤和 RK3568 開發(fā)板通過 NAPI 接口獲取底層網絡數據,從網絡數據中解析出角度數據,并在顯示屏上顯示出來。 ?角度數據的顯示
角度數據的顯示由潤和 RK3568 開發(fā)板實現,主要分為指南針顯示頁面的繪制和 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 標準系統(tǒng)的一種 JS API 實現機制,適合封裝 IO、CPU 密集型、OS 底層等能力并對外暴露 JS 接口,通過 NAPI 可以實現 JS 與 C/C++ 代碼互相訪問。潤和 RK3568 應用端通過 NAPI 來接收設備端發(fā)出的檢測信息。
底層 NAPI 模塊封裝
●?本應用封裝的模塊名為 tcpserverapi,先下載源碼,源碼路徑為: ?https://gitee.com/openharmony-sig/knowledge_demo_temp/tree/master/dev/team_x/napi_tcpservermodule/tcpservermodule
?●?下載完成后放到 OpenHarmony 3.1 Release 版本源碼根目錄,并配置編譯腳本;第一次編譯完成需要燒寫整個鏡像,請參考[開發(fā)板上新 | RK3568 開發(fā)板上絲滑體驗 OpenHarmony 標準系統(tǒng)]:
?https://gitee.com/openharmony-sig/knowledge_demo_smart_home/tree/master/dev/docs/rk3568_quick_start
?●?后面修改模塊源碼,只需將庫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板子發(fā)送過來的角度
tcpserverapi.recvMsg().then((result) => {
var resultAngle = result.angle;
????????????????})
?
更多 NAPI 相關知識請參考《標準設備應用開發(fā) Native Api》視頻課程。 ?https://www.bilibili.com/video/BV1L44y1p7KE/
? ? 應用端代碼地址https://gitee.com/openharmony-sig/knowledge_demo_temp/tree/master/FA/electronic_compass
設備側代碼地址
https://gitee.com/openharmony-sig/knowledge_demo_temp/tree/master/dev/team_x/electronic_compass
https://gitee.com/geekros/OpenHarmony_For_STM32F427/tree/master/dev-code
參考文檔
【電子指南針】
https://gitee.com/openharmony-sig/knowledge_demo_temp/tree/master/docs/electronic_compass_FA
https://gitee.com/openharmony-sig/knowledge_demo_temp/tree/master/docs/electronic_compass_Dev
【RK3568指導】
https://gitee.com/openharmony-sig/knowledge_demo_temp/tree/master/docs/rk3568_helloworld
【Geek_Lite_Board相關網址】
www.geekros.com
豐富多樣的 OpenHarmony 開發(fā)樣例離不開廣大合作伙伴和開發(fā)者的貢獻,如果你也想把自己開發(fā)的樣例分享出來,歡迎把樣例提交到 OpenHarmony 知識體系 SIG 倉來。
?如何共建開發(fā)樣例
https://gitee.com/openharmony-sig/knowledge/blob/master/docs/co-construct_demos/README_zh.md
?
評論
查看更多