學習目標 : 利用faya電子積塊組出具有動力指針的的指北羅盤
學習時間 : 240min
使用模組 : (1) faya brickNano
(2) faya 步進馬達模組
(3) faya 電子羅盤模組
(4) faya 光感應模組
工具 : 樂高積木(相容)
一字螺絲起子
====================相關知識====================
這篇文章中所用到的模組使用方式及相關知識整理如下,需進一步了解時可點進去參考:
模組介紹 : faya brickNano
模組介紹 : faya 步進馬達模組
模組介紹 : faya 電子羅盤模組
模組介紹 : faya 光感應模組
======================開箱======================
動力羅盤(型號NTG-507)是fayalab的第七款創意組合作品,此作品的目標是利用現有的faya模組,配合Arduino程式,組出一個能夠自我校正功能的指北羅盤,當作品通上電源後,羅盤上的步進馬達會帶動指針自動校正位置,之後馬達上的指針會持續指向北方。
盒內包含了製作動力羅盤所需的全部模組及附件:
1.faya brickNano 2.步進馬達模組 3.電子羅盤模組 4.光感應模組
5.積木柱子 6. 積木蓋子 7. 電源線(B) 8. micro USB傳輸線
9. 跳線組 10. 積木組 11. 積木底板
===================範例實作=====================
目標:
(1) 利用faya電子積塊,製作出指北針功能的羅盤
(2) 透過光感應器模組校正步進馬達位置
(3) 透過電子羅盤模組定位方向
(4) 透過步進馬達帶動指針指向北方
組裝:
首先把 [1.faya brickNano]、[2.步進馬達模組]、[3.電子羅盤模組]、[4.光感應模組]的四個角落裝上[5.積木柱子]。
積木柱子的組裝過程可參考[功能介紹 : faya電子積塊與LEGO積木的結合]
接著把 [1.faya brickNano]、[2.步進馬達模組]、[4.光感應模組]的四個積木柱子上方,裝上[6. 積木蓋子],注意[3.電子羅盤模組]不需要裝積木蓋子。
積木蓋子的組裝過程可參考[小技巧 : 積木柱子太鬆時如何處理?]
最後在[2.步進馬達模組]的軸上,裝上一個[5.積木柱子]。
接下來示範線路的連接和積木的組裝,因為這次的作品牽涉到馬達定位的問題,模組位置須配合程式,因此大家可以按照底下的範例跟著做一次,熟悉系統運作的方式後,再按照自己的喜好修改造型。如果照著我們的範例,組完後會長這個樣子:
首先將[10. 積木包] 裡面的積木,利用1x1,1x2,1x4在6x8的平板上組出東南西北的四個英文簡寫,[E] [S] [W] [N]
東- East [E]
南 - South [S]
西 - West [W]
北 - North [N]
接著我們要組馬達上的指針,步驟如下
(1) 將兩個2x10平板以一格之差相疊
(2) 在尾巴的地方裝上一個2x6的平板
(3) 在2x6平板上裝上兩個1x4的積木,使其有尾翼的感覺
接下來拿出16x16的底板,在以下的位置,安裝2x6的平板和2x2的一般積木
完成後如下圖所示
接著在2x2積木上跨上2x6平板,每邊各兩層,如下所示
再來我們將剛剛組成的東南西北四個字,併到底版的四周如下所示
接著在以下用圓點標註的地方安裝相關模組:
(1) 紫色圓點為brickNano的位置
(2) 綠色圓點為步進馬達模組的位置
(3) 黃色圓點為 電子羅盤模組的位置
安裝方向請參考底下第二張圖,注意到光感測器模組還不需要安裝
從另一個角度看模組安裝的位置
連接訊號與電源線
首先連接訊號線,請利用[9.跳線組]完成Arduino和模組之間的訊號連接
步進馬達模組:
Arduino_D2 ===> 步進馬達模組_A
Arduino_D3 ===> 步進馬達模組_B
Arduino_D4 ===> 步進馬達模組_/A
Arduino_D5 ===> 步進馬達模組_/B
注意我們把訊號線繞到模組下方保持美觀
Arduino_A4 ===> 電子羅盤模組_SDA
Arduino_A5 ===> 電子羅盤模組_SCL
接著連接電源線,請利用[7.電源線(B)]連結模組間的電源座,連接的詳細說明可參考這篇文章 或簡易版。
首先連接brickNano和步進馬達間的電源線
再把電源從光感應模組連到下方的電子羅盤模組,完成電源線的連接。
最後連接光感應模組的訊號線
Arduino_A0 ===> 光感應模組_Vout 安裝指針:
拿出剛開始製作好的指針,翻到背面,記住下圖箭頭所指的第二個孔位位置
將此孔位扣在步進馬達模組上的積木柱子上,完成後如下圖所示,完成硬體的組裝部分。
校正指針位置:
本段介紹如何透過光感應模組與步進馬達模組進行位置校正,首先複習一下我們在[模組介紹 : faya 電子羅盤模組]介紹到:電子羅盤模組上的標示,Y字樣的方向代表晶片方位的南方(S),X字樣的方向代表晶片方位的西方(W),因此-X的方向為晶片方位的東方(E),-Y的方向為晶片方位北方(N)。
在文章中我們提到透過.heading()指令,能夠利用I2C介面輸出[晶片北方]與[磁北方]的夾角,因此如果輸出顯示23度,代表-Y和磁北方相差23度 (順時),如果顯示0度,代表現在-Y正指著磁北方。
如果我們能讓步進馬達指針在開機後自動跑到-Y的位置,透過電子羅盤模組的輸出得到和磁北方的角度差,我們就可以反推回去,把指針指向磁北方。
因此我們必須思考如何讓步進馬達的指針開機後能自動指到-Y的方向,答案就是透過一個光感應模組,解釋如下:
首先注意到電子羅盤模組的安裝方向如下圖所示,對於羅盤指針而言,如果指向圖中的右方三點鐘方向,代表指針指向[晶片南方],如果羅盤指針指向九點鐘方向,代表指針指向[晶片北方位]。
由於每個環境的光源強度不同,因此我們必須先校正光感應模組的敏感度,讓程式容易判斷。底下範例程式我們一邊讓馬達順時針旋轉到光感應模組的位置,一邊讀取光感應模組的類比數值,並顯示在串列埠監控視窗。
光感應模組的介紹請參考 [模組介紹 : faya光感應模組]
校正指針位置範例程式:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 2018/06/08 | |
// Faya-Nugget 範例程式 (motorCalibration_1.ino) | |
// 單元: 動力羅盤 | |
// 網址: https://fayalab.blogspot.com/2018/05/stepping-compass.html | |
// 目標: (1) 校正光感應器的敏感度 | |
// (2) 讓步進馬達停在光感應模組的上方 | |
// (3) 再讓步進馬達逆時針旋轉半圈 | |
// 接線: Arduino ==> faya模組 | |
// D2 ==> A (步進馬達模組) | |
// D3 ==> B (步進馬達模組) | |
// D4 ==> /A (步進馬達模組) | |
// D5 ==> /B (步進馬達模組) | |
// A0 ==> Vout (光感應模組) | |
#include<Stepper.h> // 引入Stepper.h 標頭檔 (步進馬達函式) | |
//定義腳位 | |
int motorPin_A = 2; // 步進馬達腳位 A, B, /A, /B | |
int motorPin_B = 3; | |
int motorPin_AP = 4; | |
int motorPin_BP = 5; | |
int CDSpin = A0; // 光感應器腳位 | |
//定義Stepper函示庫中的參數 | |
//轉子每32steps轉一圈 | |
//埠 A B /A /B 分別接到 2 3 4 5 | |
Stepper fayaStepper(32, motorPin_A , motorPin_AP, motorPin_B, motorPin_BP); | |
void setup() { | |
Serial.begin(9600); //宣告UART的Board rate為9600 | |
fayaStepper.setSpeed(768); //步進馬達速度調整: 轉子768rpm = 馬達轉軸768/64 = 12rpm = 5秒轉一圈 | |
motorCalibration(); //校正步進馬達到設定的原點位置 | |
} | |
void loop() { | |
} | |
void motorCalibration() | |
{ | |
do{ //順時針一次移動一步,直到遮到光感測器 (光感測器在羅盤模組上方位置,此時的馬達指向電子羅盤晶片的South方位) | |
fayaStepper.step(1); //順時一次走一步 | |
showCdsValue(); | |
} while(analogRead(CDSpin) > 550); //遮到光感測器(類比數值小於等於550前,馬達持續運轉,請調整此數值,讓步進馬達指針能夠停在光感應模組正上方 | |
delay(1000); | |
fayaStepper.step(-1024); // 指針反轉180度,讓馬達指向電子羅盤的N晶片北方,此行可以適時修正,讓指針停在正南方 | |
delay(1000); | |
stepMotorPowLow(); //馬達停止運轉 | |
} | |
void stepMotorPowLow() //馬達停止運轉副程式 | |
{ | |
digitalWrite(motorPin_A,LOW); | |
digitalWrite(motorPin_B,LOW); | |
digitalWrite(motorPin_AP,LOW); | |
digitalWrite(motorPin_BP,LOW); | |
} | |
void showCdsValue() //顯示光感應類比值 | |
{ | |
Serial.print("CDS Value= "); | |
Serial.println(analogRead(CDSpin)); | |
} |
備註:
- 光感應模組的程式控制原理,請參考 [模組介紹 : faya 光感應模組]
- 步進馬達模組的程式控制原理,請參考[模組介紹 : faya 步進馬達模組]
- L40~43 : 開機後指針會順時針旋轉,當指針遮到光感應模組時,類比數值會低淤550 (可根據環境修改此數值),此時指針不再移動,停在光感應模組上方,也就是指向晶片南方。
- L45: 馬達順時轉一圈需要2048步,因此逆時轉半圈需要-1024步
校正步驟 :
(1) 開啟串列埠監測視窗,利用一字起子調整可變電阻,改變輸出類比數值 CDS Value
(2) 當光感應模組還未被指針遮住時,CDS Value 大約介於800~850
(3) 當光感應模組被指針遮住時,CDS Value 需低於550門檻值
以上是針對筆者的環境進行的調整,由於每個環境的光線強度不同,因此CDS Value也會不同,大家可以自行斟酌調整第43行的550門檻值,並搭配調整可變電阻,最終目的是要讓指針旋轉到光感應模組時,自動停下來即可。
校正結果:
主範例程式:
底下為動力羅盤的程式,如果沒有先經過之前的校對過程,直接執行底下的程式也可以,此時由於沒有光感應數值顯示於串列監控視窗,因此必須靠感覺調整光感應模組的可變電阻,直到步進馬達指針第一次順時針旋轉時,會自動停在光感應模組上方。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 2018/06/11 | |
// Faya-Nugget 範例程式 (stepCompass_1.ino) | |
// 單元: 動力羅盤 | |
// 網址: https://fayalab.blogspot.com/2018/05/stepping-compass.html | |
// 目標: (1) 透過光感應器模組校正步進馬達位置 | |
// (2) 透過電子羅盤模組定位方向 | |
// (3) 透過步進馬達帶動指針指向北方 | |
// 接線: Arduino ==> faya模組 | |
// D2 ==> A (步進馬達模組) | |
// D3 ==> B (步進馬達模組) | |
// D4 ==> /A (步進馬達模組) | |
// D5 ==> /B (步進馬達模組) | |
// A0 ==> Vout (光感應模組) | |
// A4 ==> SDA (電子羅盤模組) | |
// A5 ==> SCL (電子羅盤模組) | |
#include <Wire.h> //引入Wire.h 標頭檔 (I2C介面函式) | |
#include <LSM303.h> //引入LSM303.h 標頭檔 (電子羅盤函式) | |
#include<Stepper.h> // 引入Stepper.h 標頭檔 (步進馬達函式) | |
//定義腳位 | |
int motorPin_A = 2; // 步進馬達腳位 A, B, /A, /B | |
int motorPin_B = 3; | |
int motorPin_AP = 4; | |
int motorPin_BP = 5; | |
int CDSpin = A0; // 光感應器腳位 | |
int heading_new; //目前指向方位 (和北方的夾角) | |
int heading_old; //最後指向方位 (和北方的夾角) | |
int minAngleToNorth; // 目前指向方位和北方的最小角度 | |
int motorStepToNorth; //馬達移動到北方所需的步數 | |
//定義Stepper函示庫中的參數 | |
//轉子每32steps轉一圈 | |
//埠 A B /A /B 分別接到 2 3 4 5 | |
Stepper fayaStepper(32, motorPin_A , motorPin_AP, motorPin_B, motorPin_BP); | |
LSM303 compass; //匯入LSM303Library | |
void setup() { | |
Serial.begin(9600); //宣告UART的Board rate為9600 | |
Wire.begin(); //I2C的初始設定 | |
fayaStepper.setSpeed(768); //步進馬達速度調整: 轉子768rpm = 馬達轉軸768/64 = 12rpm = 5秒轉一圈 | |
compass.init(); //電子羅盤模組的初始設定 | |
compass.enableDefault(); | |
compass.m_min = (LSM303::vector<int16_t>){-32767, -32767, -32767}; //偏差值校正 | |
compass.m_max = (LSM303::vector<int16_t>){+32767, +32767, +32767}; | |
motorCalibration(); //校正步進馬達指針到晶片北方 | |
motorToNorth(); //指針到磁北方(最短距離) | |
} | |
void loop() { | |
delay(10); | |
compass.read(); //讀取電子羅盤的資料 | |
heading_new = compass.heading(); //將從電子羅盤的讀出資料放到heading_new變數 | |
Serial.print("current heading = "); | |
Serial.println(heading_new); | |
traceNorth(); //指針追蹤磁北方 | |
} | |
void motorCalibration() | |
{ | |
do{ //順時針一次移動一步,直到遮到光感測器 (光感測器在羅盤模組上方位置,此時的馬達指向電子羅盤晶片的South方位) | |
fayaStepper.step(1); //順時一次走一步 | |
}while(analogRead(CDSpin) > 550); //遮到光感測器(類比數值小於等於550前,馬達持續運轉,請調整此數值,讓步進馬達指針能夠停在光感應模組正上方 | |
delay(1000); | |
fayaStepper.step(-1024); // 指針反轉180度,讓馬達指向電子羅盤的North方位,如需指南針,則將此行註解即可 | |
delay(1000); | |
compass.read(); //讀取目前方位 (和北方差距的角度) | |
stepMotorPowLow(); //馬達停止運轉 | |
} | |
void motorToNorth() | |
{ | |
heading_new = compass.heading(); //儲存目前方位 (和北方差距的角度) | |
if(heading_new>=180) //和北方差距角度大於180度時,只要繼續順時針轉(360-目前方位)就會轉回北方 | |
{ | |
minAngleToNorth = 360 - heading_new; | |
motorStepToNorth = map(minAngleToNorth,0,359,0,2047); //馬達轉一圈360度轉需要走2048步,利用map指令轉換所需的步數 | |
fayaStepper.step(motorStepToNorth); //轉到北方 | |
} | |
else if(heading_new<180) //小於180度時,逆轉回北方比較快 | |
{ | |
minAngleToNorth = heading_new; | |
motorStepToNorth = map(minAngleToNorth,0,359,0,2048); //馬達轉一圈360度轉需要走2048步,利用map指令轉換所需的步數 | |
fayaStepper.step(-motorStepToNorth); //轉到北方 | |
} | |
heading_old = heading_new; //更新角度資訊 | |
Serial.println(" Calibration Completed ... "); | |
Serial.println(" Calibrated Heading = "); | |
Serial.println(heading_old); | |
} | |
void stepMotorPowLow() // 關閉步進馬達 | |
{ | |
digitalWrite(motorPin_A,LOW); | |
digitalWrite(motorPin_B,LOW); | |
digitalWrite(motorPin_AP,LOW); | |
digitalWrite(motorPin_BP,LOW); | |
} | |
void traceNorth() //指針追蹤磁北副程式 | |
{ | |
if(abs(heading_new-heading_old)>3) //偵測到旋轉時 | |
{ | |
if(heading_old<180) // 當最後位置heading_old落在第I,II象限 | |
{ | |
if ((heading_old<heading_new) && (heading_new<(heading_old+180))) //判斷新的位置小於舊位置180度內時 (藍色區域) | |
{ // ==> 此時馬達透過逆轉,可用最少的步數回到heading_old位置 | |
minAngleToNorth = heading_new-heading_old; //計算舊位置與新位置相差的角度 | |
motorStepToNorth=map(abs(minAngleToNorth),0,359,0,2048); //換算成步進馬達移動的步數 | |
fayaStepper.step(-motorStepToNorth); //步進馬達逆時針旋轉回heading_old位置 | |
} | |
else if ((heading_new>(heading_old+180)) || (heading_new<heading_old)) //判斷新的位置大於舊位置180度時 (褐色區域) 或者 (綠色區域) | |
{ //==> 此時馬達透過順轉,可用最少的步數回到heading_old位置 | |
if (heading_new>(heading_old+180)) //判斷新的位置大於舊位置+180度 (褐色區域) | |
minAngleToNorth = (360-heading_new)+heading_old; //計算舊位置與新位置相差的角度 | |
else if (heading_new<heading_old) //判斷新的位置小於舊位置的角度 (綠色區域) | |
minAngleToNorth = heading_old-heading_new; //計算舊位置與新位置相差的角度 | |
motorStepToNorth=map(abs(minAngleToNorth),0,359,0,2048); //換算成步進馬達移動的步數 | |
fayaStepper.step(motorStepToNorth); //步進馬達順時針旋轉回heading_old位置 | |
} | |
} | |
else if(heading_old>180) // 當最後位置heading_old落在第III,IV象限 | |
{ | |
if ((heading_new>heading_old) || (heading_new<(heading_old-180))) //判斷新的位置小於舊位置180度內時 (粉紅色區域) 或者 (橘色區域) | |
{ // ==> 此時馬達透過逆轉,可用最少的步數回到heading_old位置 | |
if(heading_new>heading_old) //判斷新的位置大於舊位置的角度 (粉紅色區域) | |
minAngleToNorth = heading_new-heading_old; //計算舊位置與新位置相差的角度 | |
else if (heading_new<(heading_old-180)) //判斷新的位置小於舊位置-180的角度 (橘色區域) | |
minAngleToNorth = (360-heading_old)+heading_new; //計算舊位置與新位置最小相差的角度 | |
motorStepToNorth=map(abs(minAngleToNorth),0,359,0,2048); //換算成步進馬達移動的步數 | |
fayaStepper.step(-motorStepToNorth); //步進馬達順時針旋轉 | |
} | |
else if ((heading_old>heading_new) && (heading_new>(heading_old-180))) //判斷新的位置大於舊位置180度時 (紫色區域) | |
{ // ==> 此時馬達透過順轉,可用最少的步數回到heading_old位置 | |
minAngleToNorth = heading_old-heading_new; //計算舊位置與新位置相差的角度 | |
motorStepToNorth=map(abs(minAngleToNorth),0,359,0,2048); //換算成步進馬達移動的步數 | |
fayaStepper.step(motorStepToNorth); //步進馬達逆時針旋轉 | |
} | |
} | |
heading_old = heading_new; //更新最後位置 | |
} | |
} |
- 程式主要由三部份組成,L46、L47、L56,其中L46和L47只需要執行一次,因此放在Setup()區域,L56必須重複執行,因此放在Loop()迴圈。
- L46 motorCalibration() : 校正指針,使其指向晶片北方,這部份我們在上一段解釋過了
- L47 motorToNorth () : 讓指針由晶片北方轉到磁北方
- L56 traceNorth() : 讓指針持續指向磁北方
- L71~90: motorToNorth副程式,由於我們已經先執行了motorCalibration()副程式,讓指針指向晶片北方,這段副程式能夠讓指針由晶片北方經過最小角度(最短路徑)轉到磁北方。
-L74、L80: 我們將磁北方與晶片北方的夾角我們儲存在heading_new變數內,由於此夾角是以磁北方為起點,順時針方向計算與晶片北方之間的夾角度,因此為了達到最短路徑旋轉到磁北方,我們設了大於和小於180度的判斷
-L74~L79: 下圖中N代表磁北位置,如果 heading_new大於180度,指針只要繼續順時針旋轉 (360-heading_new)的角度即可指向磁北方,也就是下圖中的綠色路線 (最短路徑)。
-L77~78: 步進馬達走一圈(360度)需要2048步,因此我們可以用map()函式算出(360-heading_new)角度所要走的步數,又由於是順時針旋轉,因此78行裡面的步數是正的。步進馬達的原理可以參照 [模組介紹 : faya步進馬達模組]
-L80~85: 下圖中N代表磁北位置,如果heading_new小於180度,指針只要逆時針旋轉heading_new的角度即可指向磁北方,也就是下圖中的藍色路線 (最短路徑)。
-L83~84: 步進馬達走一圈(360度)需要2048步,因此我們可以用map()函式算出(heading_new)角度所要走的步數,又由於是逆時針旋轉,因此84行裡面的步數是負的。步進馬達的原理可以參照 [模組介紹 : faya步進馬達模組]
- 截至目前都在解釋馬達指針在setup()區域所完成的兩個動作 (1) 指針校正,使其自動指向晶片北方,(2) 指針指向磁北方。接下來,我們在loop()迴路中,要處理當偵測到羅盤有任何移動或轉動的時候,Arduino會根據轉動的角度,馬上修正使指針依然指向磁北方,這段功能寫在traceNorth()副程式中。
- L102: heading_new是紀錄最新的方位,heading_old是上一筆的方位,當羅盤都沒有移動或轉動時,heading_new = heading_old,但是當轉動時,兩者差距會改變,此時程式進入迴圈,讓馬達轉動修正方為使指針轉回磁北方。使用絕對值函數abs()可以一次偵測到順逆方向的旋轉變化:
- 當順時針旋轉羅盤時,heading_new 會大於 heading_old
- 當逆時針旋轉羅盤時,heading_new 會小於 heading_old
-L104、L124: 跑完setup()裡的指針的 motorToNorth () 後,指針會指著磁北方,並把最後的晶片位置儲存到headling_old變數裡。當我們轉動羅盤時,馬達指針會被羅盤帶動,瞬間偏離磁北,為了讓馬達能夠用最短的距離轉回到磁北 (順時針或逆時針),我們必須先知道晶片最後位置在那一個方位。 下圖中N是磁北方,也就是馬達指針指的方位, 當我們旋轉羅盤時,會有以下四種狀況產生
- 順時針旋轉羅盤,指針瞬間停在I/II象限(轉180度內),我們讓馬達逆時針轉回磁北即為最短距離
- 順時針旋轉羅盤,但是轉的速度很快,指針瞬間停在III/IV象限(轉超過180度),此時讓馬達繼續順時針轉回磁北即為最短距離
- 逆時針旋轉羅盤,指針瞬間停在IV、III象限(轉180度內),此時我們讓馬達順時針轉回磁北即為最短距離
- 逆時針旋轉羅盤,但是轉的速度很快,指針瞬間停在II/I象限(轉超過180度),此時讓馬達繼續逆時針轉回磁北即為最短距離。
為了處理以上四種狀況,必須先了解最後晶片北方的位置(heading_old),再進行分類處理,個別解釋如下
-L104、L106~L111 : 當最後位置heading_old落在第I,II象限(L104),且羅盤旋轉角度小於180度時,這時候heading_new會落於下圖藍色線條區域 (L106),此時只需要讓步進馬達逆轉heading_new和heading_old角度差(L108),即可讓指針以最短距離回到磁北(L109~L110)。
如果是落於褐色區域(L114),只需讓步進馬達繼續順時針轉回heading_old位置,也就是 (360-heading_new)+heading_old (L115),即可讓指針以最短距離回到磁北(L119~L120)。
如果是落於褐色區域(L116),只需讓步進馬達繼續順時針轉回heading_old位置,也就是heading_old-heading_new (L117),即可讓指針以最短距離回到磁北(L119~L120)。
如果是落於粉紅色區域(L128),只需讓步進馬達逆時針轉回heading_old位置,也就是 heading_new-heading_old (L129),即可讓指針以最短距離回到磁北(L133~L134)。
如果是落於橘色區域(L130),只需讓步進馬達逆時針轉回heading_old位置,也就是(360-heading_old)+heading_new (L131),即可讓指針以最短距離回到磁北(L133~L134)。
-L124、L136~L141 : 當最後位置heading_old落在第III,IV象限(L124),且羅盤旋轉角度大於180度時,這時候heading_new會落於下圖紫色線條區域 (L136),此時只需讓步進馬達繼續順時針轉回heading_old位置,也就是heading_old-heading_new(L138),即可讓指針以最短距離回到磁北(L139~L140)。
結果演示:
影片解釋:
5秒處 : 馬達指針遮到光感應模組,代表指針指向晶片南方,步進馬達停止前進
8秒處 : 馬達逆時針全轉180度,讓指針指向晶片北方
12秒處 : 馬達指針指向磁北方
14秒處 : 手機裡的電子羅盤app顯示的磁北方向和馬達指針所指的方向一致
16秒處 : 傳統的指北針指的北方也和馬達指針所指的方向一致
17~29秒處 : 無論順時或逆時旋轉羅盤,三個裝置的指針方向皆一致,維持指向磁北方
31~34秒處 : 校正手機方位,讓指北針指向外圍文字的北方
35~39秒處 : 校正羅盤方位,讓羅盤指針指向積木的N
43~44秒處 : 校正傳統指北針,讓指針指向外圍文字的N
48~53秒處 : 三個裝置的南方(S)皆一致
54~1:00處 : 三個裝置的東方(E)皆一致
討論:
以下是我們開發此創意組合時得到的經驗,大家可以參考參考
- 當馬達指針順時針往光感應模組轉動時,由於光源強度與角度的不同,有可能會提早遮到光感應模組,造成馬達指針沒有真正只到晶片南方,遇到此現象,大家可以在程式L63-64之間插入一行 fayaStepper.step(20); ,讓步進馬達多走幾步,使其完全的指向晶片南方位置。
- 此羅盤最終指向的方位是北方,如果想要做指南針,則將程式65、66行刪除,讓一開始校準的方位指向晶片南方即可。
- 和傳統羅盤一樣,如果周邊有磁力裝置,例如手機或喇叭,會影響到羅盤感應磁北的方位,降低感應準確性。
歡迎大家在底下留言或到我們的粉絲團留言喔!
====================================
fayalab 粉絲團
FB本篇留言版
沒有留言:
張貼留言