電子指南針是現(xiàn)代的一種重要導(dǎo)航工具,大到飛機(jī)船舶的導(dǎo)航,小到個(gè)人手機(jī)導(dǎo)航,電子指南針可以說和咱們生活息息相關(guān),密不可分。為什么電子指南針能指示方向?本 Demo 將為你呈現(xiàn),其中蘊(yùn)含了人類智慧及大自然的奧妙。
本項(xiàng)目分為數(shù)據(jù)采集端(設(shè)備端)和效果展示端(應(yīng)用端):
數(shù)據(jù)采集端(設(shè)備端):
1、指南針數(shù)據(jù)采集端:使用的是 Geek_Lite_Board 開發(fā)板,其內(nèi)置了三軸磁力計(jì) AK8963,通過解析磁力計(jì)數(shù)據(jù)獲得指南針數(shù)據(jù)信息,操作系統(tǒng)版本為 OpenAtom OpenHarmony 3.0(以下簡(jiǎn)稱“OpenHarmony”);
2、指南針效果展示端:使用的是潤(rùn)和 RK3568 開發(fā)板,操作系統(tǒng)版本為 OpenHarmony 3.1 release。
效果展示端則體現(xiàn)了 OpenHarmony JS UI、Canvas 組件和 NAPI 的能力:
效果展示端(應(yīng)用端)
1、Canvas 組件是一個(gè)畫布組件,獲取到畫布對(duì)象后,可以自定義繪制圖形,比如圓形,線條等,本項(xiàng)目中應(yīng)用端的指南針界面是基于 Canvas 組件開發(fā);
2、NAPl (NativeAPI)是 OpenHarmony 標(biāo)準(zhǔn)系統(tǒng)的一種 JS API 實(shí)現(xiàn)機(jī)制,通過 NAPI 可以實(shí)現(xiàn) JS 與 C/C++ 代碼互相訪問。本項(xiàng)目應(yīng)用端通過 NAPI 來接收設(shè)備端發(fā)出的檢測(cè)信息。
當(dāng)設(shè)備應(yīng)用啟動(dòng)之后,運(yùn)行效果如下動(dòng)圖所示:
一、基本原理
地球是一個(gè)大磁體,地球的兩個(gè)極分別在接近地理南極和地理北極的地方,一般情況下地球的磁場(chǎng)強(qiáng)度在 0.5 高斯左右(高斯是磁場(chǎng)強(qiáng)度單位)。
Geek_Lite_Board 開發(fā)板帶有 AK8963 三軸磁力計(jì)。三軸磁力計(jì)能夠測(cè)出相互垂直的三個(gè)方向的磁力大小。通常我們把傳感器平放,即讓重力方向與傳感器垂直,假設(shè)重力方向?yàn)?z 軸,其余兩軸為 x 軸和 y 軸。在只受地球磁場(chǎng)的環(huán)境下(忽略其余弱小干擾),x 軸 y 軸檢測(cè)到的磁力數(shù)據(jù)的矢量和就等于接收到的地球磁場(chǎng)。
我們利用 x 軸與 y 軸的比值,就能確定目前朝向正北邊差多少角度。例如現(xiàn)測(cè)到 x 軸數(shù)據(jù)接近 0.5 高斯,y 軸數(shù)據(jù)接近 0,就認(rèn)為目前的 x 軸方向就是正北方。那 x 軸方向是哪個(gè)方向?關(guān)于 x 軸方向,生產(chǎn)傳感器芯片的廠商會(huì)預(yù)定義好傳感器的 x 軸、y 軸及 z 軸方向(通常垂直芯片表面的為 z 軸)。
數(shù)據(jù)流程
智能指南針整體方案如上圖所示,主要由 Geek_Lite_Board 開發(fā)板和潤(rùn)和 RK3568 開發(fā)板構(gòu)成,它們采用局域網(wǎng)(路由器)TCP 協(xié)議的通信方式。
1. Geek_Lite_Board 開發(fā)板通過板載的磁力計(jì)獲取磁場(chǎng)數(shù)據(jù),磁場(chǎng)數(shù)據(jù)經(jīng)過處理后得到角度數(shù)據(jù);
2. 角度信息通過 ESP8266 無線 Wi-Fi 模塊發(fā)送到指南針應(yīng)用端;
3. 指南針應(yīng)用端通過 NAPI 接口獲取底層網(wǎng)絡(luò)數(shù)據(jù),并在頁(yè)面展示。
二、功能實(shí)現(xiàn)
指南針數(shù)據(jù)的獲取
Geek_Lite_Board 開發(fā)板通過 IIC 接口與 AK8963 三軸磁力計(jì)通信,讀取三軸方向的磁場(chǎng)數(shù)據(jù),通過磁場(chǎng)數(shù)據(jù)計(jì)算后得到指南針的方位數(shù)據(jù)。
● AK8963介紹
AK8963是采用高靈敏度霍爾傳感器技術(shù),內(nèi)部集成了檢測(cè)x、y、z軸的磁傳感器、傳感器驅(qū)動(dòng)電路、信號(hào)放大器和用于處理每個(gè)傳感器信號(hào)的算術(shù)電路。同時(shí),還配備了自測(cè)功能。其緊湊的封裝,還可適用于配備gps的手機(jī)的地圖導(dǎo)航,實(shí)現(xiàn)行人導(dǎo)航等功能。
● AK8963測(cè)量數(shù)據(jù)的讀取
AK8963 和單片機(jī)通過 IIC 接口連接,單片機(jī)操作 IIC 總線按照數(shù)據(jù)手冊(cè)的操作時(shí)序操作即可讀取 AK8963 的數(shù)據(jù),AK8963 獲取測(cè)量數(shù)據(jù)的函數(shù)實(shí)現(xiàn)如下:
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數(shù)據(jù)處理得到磁力數(shù)據(jù)
調(diào)用 Mpu_Read_Bytes 函數(shù)獲取測(cè)量數(shù)據(jù),其中 MPU_BUFF[15] 到 MPU_BUFF[20] 這六個(gè)字節(jié)的數(shù)據(jù)就是磁力計(jì)的數(shù)據(jù)。此時(shí)的磁力計(jì)數(shù)據(jù)還不穩(wěn)定不能直接用來計(jì)算指南針的角度,還需要進(jìn)行濾波處理,此處用到的濾波算法是滑動(dòng)均值濾波。數(shù)據(jù)處理代碼如下:
Mpu_Read_Bytes(MPUREG_ACCEL_XOUT_H, MPU_BUFF, 28);if(MPU_BUFF[14] == 1) { // 從 MPU_BUFF[]中提取磁力數(shù)據(jù) 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]; ?// 對(duì)x軸方向磁力計(jì)數(shù)據(jù)進(jìn)行濾波,取滑動(dòng)平均 ?for(i=0;i<14;i++) { ? ?mag_x_buff[i] = mag_x_buff[i+1] ? //滑動(dòng) ?} ? ? ?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; ? ? // 對(duì)y軸方向磁力計(jì)數(shù)據(jù)進(jìn)行濾波,取滑動(dòng)平均 ? ?for(i=0;i<14;i++){ ? ? ?mag_y_buff[i] = mag_y_buff[i+1]; ?//滑動(dòng) ? ? ? ? ? ?} ? ? ? ? ? ?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; ? ?// 對(duì)磁力計(jì)z軸方向進(jìn)行濾波 ? ?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);}
● 角度數(shù)據(jù)計(jì)算
磁力計(jì)數(shù)據(jù)通過濾波后得到 x y z 三個(gè)軸方向的磁力分量,計(jì)算出 x 和 y軸的 tan 值,再通過反正切計(jì)算出角度,角度經(jīng)過滑動(dòng)平均得到最終需要顯示出來的指南針角度值,計(jì)算過程見如下代碼。
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));
指南針數(shù)據(jù)的傳輸
Geek_Lite_Board 開發(fā)板外掛 ESP8266 Wi-Fi 模組通過局域網(wǎng) TCP 通信的方式將角度數(shù)據(jù)傳輸給潤(rùn)和 RK3568 開發(fā)板,潤(rùn)和 RK3568 開發(fā)板通過 NAPI 接口獲取底層網(wǎng)絡(luò)數(shù)據(jù),從網(wǎng)絡(luò)數(shù)據(jù)中解析出角度數(shù)據(jù),并在顯示屏上顯示出來。
角度數(shù)據(jù)的顯示
角度數(shù)據(jù)的顯示由潤(rùn)和 RK3568 開發(fā)板實(shí)現(xiàn),主要分為指南針顯示頁(yè)面的繪制和 NAPI 從局域網(wǎng)上獲取角度數(shù)據(jù)并展示到界面上。
指南針顯示頁(yè)面
指南針的顯示頁(yè)面主要通過 Canvas 組件畫圖完成,包含方位角度、指南針針盤和指示線,顯示整體效果如下圖所示。
指南針針盤由一個(gè) Canvas 組件構(gòu)成,包含了三個(gè)部分,分別為刻度盤、角度數(shù)字、方位文字,他們的效果圖分別如下:
● 刻度盤
● 角度數(shù)字
● 方位文字
Canvas組件相關(guān)知識(shí)可以參考:https://gitee.com/openharmony/do ... ts-canvas-canvas.md
NAPI
NAPI(Native API)是 OpenHarmony 標(biāo)準(zhǔn)系統(tǒng)的一種 JS API 實(shí)現(xiàn)機(jī)制,適合封裝 IO、CPU 密集型、OS 底層等能力并對(duì)外暴露 JS 接口,通過 NAPI 可以實(shí)現(xiàn) JS 與 C/C++ 代碼互相訪問。潤(rùn)和 RK3568 應(yīng)用端通過 NAPI 來接收設(shè)備端發(fā)出的檢測(cè)信息。
底層 NAPI 模塊封裝
● 本應(yīng)用封裝的模塊名為 tcpserverapi,先下載源碼,源碼路徑為:
https://gitee.com/openharmony-sig/knowledge_demo_temp/tree/master/dev/team_x/napi_tcpservermodule/tcpservermodule
● 下載完成后放到 OpenHarmony 3.1 Release 版本源碼根目錄,并配置編譯腳本;第一次編譯完成需要燒寫整個(gè)鏡像,請(qǐng)參考[開發(fā)板上新 | RK3568 開發(fā)板上絲滑體驗(yàn) OpenHarmony 標(biāo)準(zhǔn)系統(tǒng)]:
https://gitee.com/openharmony-sig/knowledge_demo_smart_home/tree/master/dev/docs/rk3568_quick_start
● 后面修改模塊源碼,只需將庫(kù)send到板子里面。命令如下:
先掛載,再sendhdc_std shell mount -o remount,rw /hdc_std file send libtcpserverapi.z.so system/lib/module/libtcpserverapi.z.so應(yīng)用端導(dǎo)入NAPI模塊import tcpserverapi from '@ohos.tcpserverapi'應(yīng)用端NAPI接口調(diào)用//調(diào)用initServer接口 初始化 TCP 服務(wù)器tcpserverapi.initServer()//調(diào)用recvMsg 獲取并解析SMT32板子發(fā)送過來的角度tcpserverapi.recvMsg().then((result) => { var resultAngle = result.angle; })
更多 NAPI 相關(guān)知識(shí)請(qǐng)參考《標(biāo)準(zhǔn)設(shè)備應(yīng)用開發(fā) Native Api》視頻課程。
-
電子指南針
+關(guān)注
關(guān)注
0文章
5瀏覽量
6115
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論