本文將說明AS5600磁編碼器模組的電源電路、電源模式、看門狗(Watchdog)、遲滯(hysteresis)和濾波器(filter)設定。這些資訊都參考AS5600原廠技術文件,以及Adafruit的AS5600程式庫原始碼。
文末也將說明在AS5600程式庫,指定ESP32微控器的I2C腳位的程式寫法。
AS5600模組的電源電路
AS5600晶片內部有電源穩壓電路(LDO),可將5V電源降轉成3.3V,但此穩壓器僅用於AS5600本身,無法為其他IC供電。接5V電源時,要採用下圖左的接法;採3.3V供電時,VDD5V 和 VDD3V3 接腳必須相連,如下圖右,其中的10µF電容是選擇性的。
AS5600模組採用上圖右的電路(VDD3V3腳有接10µF電容),所以電源要接3.3V。
電源模式與看門狗(watchdog)
AS5600晶片提供四種電力設置模式:
- NOM:普通模式(此為預設),晶片始終處於運作狀態,耗電6.5 mA。
- LPM1:低功耗模式1,每隔5ms感測一次,耗電3.4 mA。
- LPM2:低功耗模式2,每隔20ms感測一次,耗電1.8mA。
- LPM3:低功耗模式3,每隔100ms感測一次,耗電1.5 mA。
AS5600程式庫提供setPowerMode()方法設定電力模式,其參數值可為底下任一常數:
- AS5600_POWER_MODE_NOM:普通模式
- AS5600_POWER_MODE_LPM1:低功耗模式1
- AS5600_POWER_MODE_LPM2:低功耗模式2
- AS5600_POWER_MODE_LPM3:低功耗模式3
AS5600晶片也內建看門狗(watchdog),在一般的微處理器中,看門狗用於偵測並在當機時自動重置系統,參閱《超圖解ESP32深度實作》第17章「任務的優先權與看門狗」,以及「認識與實驗Arduino的睡眠模式」貼文。
AS5600的看門狗則用於「省電節能」,可在感測器閒置時,令晶片進入休眠狀態。
若啟用看門狗,它會持續檢查角度測量值是否發生變化:
- 若角度讀數在設定時間內(約一分鐘)維持不變,看門狗將判定晶片處於閒置狀態,自動將感測器切換至極低功耗模式(LPM3)。
- 當看門狗偵測到磁石再次轉動(位移超過4LSB),將立即喚醒感測器恢復至正常運作模式。
AS5600程式庫的enableWatchdog()方法,可啟用(true)或停用(false)看門狗。底下敘述將把電力模式設為「普通」並啟用看門狗:
as5600.setPowerMode(AS5600_POWER_MODE_NOM); // 普通電力模式 as5600.enableWatchdog(true); // 啟用看門狗
遲滯(hysteresis)設定
AS5600內部的霍爾感測元件,能將垂直於晶片表面的磁場分量轉換為電壓,然後經過放大 → 濾波 → ADC(類比數位轉換器)變成數位訊號,最後經過IC內部的「座標旋轉數位計算機(CORDIC)」處理,以計算磁場向量的角度和幅度。
當IC上方的磁石從角度A轉到B,AS5600理應感測到如下圖左的變化,但實際會受到磁石裝設距離、溫度變化和震動等因素影響,導致感應到的角度值會發生跳動,類似普通機械開關的彈跳現象。
處理機械開關彈跳現象的基本對策是「延時(delay)」再確認,AS5600則提供遲滯設定,來避免磁石靜止時,感測器錯誤地偵測到磁場變動,而輸出磁石轉動的訊號。
Adafruit公司編寫的AS5600程式庫,有提供設定遲滯參數的setHysteresis()方法,設定值以LSB(最低有效位元)為單位定義,代表感測器可測量的最小步進值,有效值可為下列常數之一:
- AS5600_HYSTERESIS_OFF:停用遲滯設定(預設值)
- AS5600_HYSTERESIS_1_LSB
- AS5600_HYSTERESIS_2_LSB
- AS5600_HYSTERESIS_3_LSB
較高的LSB設定值比較不會受到震動干擾、輸出更穩定,但對極微小且快速的方向變化反應會略顯遲鈍。
假設遲滯參數設為1 LSB(AS5600_HYSTERESIS_1_LSB,此為感測器可測量的最小增量),而磁石角度值往上增加,例如,從100度轉到101度,則唯有當角度確實越過100和101的中間點,才會切換至101。
如此可避免輸出值因磁鐵在臨界點輕微震動而產生 “100, 101, 100, 101…” 的跳動現象。較大的遲滯參數,例如:AS5600_HYSTERESIS_3_LSB,會讓「遲滯」更明顯,也就是角度必須至少出現「3個步進」變化,輸出才會更新。底下敘述代表將遲滯設成1 LSB:
as5600.setHysteresis(AS5600_HYSTERESIS_1_LSB);
慢速和快速濾波器設定
AS5600內部具有慢速(slow)和快速(fast)濾波器:
- 慢速濾波器:屬低通濾波器,是標準的平均濾波器,也就是透過時間積累平均特定數量的感測器讀數,從而產生更平滑、穩定的輸出訊號。平均次數越多,訊號穩定性越高,但會產生延遲(參閱《超圖解Arduino互動設計入門》第14章「數位濾波」單元)。
慢速濾波器用於過濾輕微機械震動或電磁干擾引起的雜訊,確保磁鐵緩慢移動或靜止時能提供穩定讀數。
- 快速濾波器:一種閾值型(threshold,或者稱「臨界值」)濾波器,可對突發性的大幅位移立即作出反應。它會持續比較目前角度與慢速濾波輸出值,若兩者差異超過設定閾值,便立即更新輸出值,覆蓋慢速濾波器的延遲效應;若兩者差異低於閾值,則由慢速濾波器控制輸出訊號。
如果在充滿雜訊環境中設定過低的閾值,它可能將劇烈雜訊尖峰誤判為真實位移,導致輸出無謂的跳動。
setSlowFilter()方法用於設定慢速濾波器,它接受底下任一可能參數值:
- AS5600_SLOW_FILTER_16X:16倍(最強,延遲最大)
- AS5600_SLOW_FILTER_8X:8倍
- AS5600_SLOW_FILTER_4X:4倍
- AS5600_SLOW_FILTER_2X:2倍(最弱,延遲最小)
setFastFilter()方法用於設定快速濾波器,它接受底下任一閾值:
- AS5600_FAST_FILTER_THRESH_SLOW_ONLY:僅啟用「低速濾波器」,此為預設值。
- AS5600_FAST_FILTER_THRESH_6LSB
- AS5600_FAST_FILTER_THRESH_7LSB
- AS5600_FAST_FILTER_THRESH_9LSB
- AS5600_FAST_FILTER_THRESH_10LSB
- AS5600_FAST_FILTER_THRESH_18LSB
- AS5600_FAST_FILTER_THRESH_21LSB
- AS5600_FAST_FILTER_THRESH_24LSB
設定濾波器的範例:
as5600.setSlowFilter(AS5600_SLOW_FILTER_16X); // 設定慢速濾波器 as5600.setFastFilterThresh(AS5600_FAST_FILTER_THRESH_SLOW_ONLY); // 設定快速濾波器
指定AS5600的角度檢測範圍
AS5600檢測角度有Raw(原始)和Scaled(縮放)兩種範圍:
- 原始(Raw)角度:AS5600為12位元感測器,代表其以4096個步進(0至4095)測量完整360°旋轉角度。getRawAngle()方法將傳回此絕對位置值,每個步進約0.088°(360 / 4096)。
- 縮放(Scaled)角度:透過程式設定,將感測器限制在指定的角度偵測範圍。AS5600程式庫提供下列三個設定縮放角度的相關方法:
setZPosition():設定感測器的零點位置,參數值為12 位元整數(0 ~ 4095),設置成功傳回true。
setMPosition():設定停止位置,參數值為12 位元整數(0 ~ 4095),設置成功傳回true。
setMaxAngle():設定感測器輸出的最大角度值,參數值為 12 位元數值,設置成功時傳回true。
下列兩個方法則可傳回目前檢測到的原始與縮放角度,實際的設定和執行結果請參閱下文的範例程式。
getRawAngle():從感測器返回原始的12 位元角度值。
getAngle():傳回根據零點角度與最大角度設定,限縮的檢測12位元角度值。
AS5600晶片內部有非揮發性記憶體(也就是斷電後仍能保存資料),可儲存縮放角度設定值,但上面提到的角度設定方法不具備這項功能。根據AS5600原廠技術文件第22頁的說明,將角度資料寫入非揮發性記憶體,需要執行下列8大步驟(前提是VDD3V3腳有接10µF電容),感興趣的讀者請自行實驗。
- 啟動AS5600電源。
- 將磁石轉至起始位置。
- 讀取RAW ANGLE(原始角度)暫存器。
將RAW ANGLE值寫入ZPOS暫存器。
等待至少1ms。 - 依據 DIR 腳的電位定義的方向(GND代表順時針,高電位代表逆時針)將磁石旋轉至停止位置。旋轉角度必須大於18 度。
- 讀取 RAW ANGLE(原始角度)暫存器。
將RAW ANGLE(原始角度)值寫入MPOS(停止位置)暫存器。
等待至少 1ms。繼續執行步驟 6,以將設定值寫入晶片內部的非揮發性記憶體。
- 執行BURN_ANGLE(燒錄角度)指令,儲存角度。
等待至少 1 毫秒。 - 驗證 BURN_ANGLE(燒錄角度)指令:
依序將指令 0x01、0x11 與 0x10 寫入暫存器0xFF,以載入之前寫入的角度設定值。
讀取ZPOS(起始)與MPOS(結束)暫存器以確認BURN_ANGLE(燒錄角度)指令成功。 - 重新啟動,再次讀取並驗證 ZPOS 與 MPOS 暫存器。
指定ESP32連接AS5600模組的I2C腳位
假設ESP32的I2C接腳,SDA腳是GPIO 9,SCL腳是GPIO 10,麵包板接線:
ESP32具備兩個硬體I2C控制器,透過TwoWire建構式可選擇使用其中一個:
- TwoWire(0):使用 I2C 控制器 0
- TwoWire(1):使用 I2C 控制器 1
在預設情況下,Wire.h程式庫參照到TwoWire(0),也就是採用ESP32開發環境預設的I2C接腳連線,若要將SDA和SCL連接至非預設的GPIO腳位,就要採用TwoWire(1),例如:
#define AS5600_ADDR 0x36 #define SDA_PIN 9 // 定義SDA腳位 #define SCL_PIN 10 // 定義SCL腳位 TwoWire asWire = TwoWire(1); // 定義TwoWire物件並命名為asWire。
AS5600程式庫的begin()方法可選擇性地參照到TwoWire物件,如下:
as5600.begin(AS5600_ADDR, &asWire)
底下程式將指定採用上面的I2C接腳設定,並設定(縮放)偵測角度:
#include <Wire.h>
#include <Adafruit_AS5600.h>
#define AS5600_ADDR 0x36
#define SDA_PIN 9
#define SCL_PIN 10
TwoWire asWire = TwoWire(1);
Adafruit_AS5600 as5600;
void setup() {
Serial.begin(115200);
while (!Serial)
delay(10);
asWire.begin(SDA_PIN, SCL_PIN); // SDA = GPIO9, SCL = GPIO10
if (!as5600.begin(AS5600_ADDR, &asWire)) {
Serial.println("找不到AS5600感測器,請檢查接線。");
while (1)
delay(10);
}
Serial.println("AS5600找到了!");
as5600.enableWatchdog(false); // 取消看門狗
as5600.setPowerMode(AS5600_POWER_MODE_NOM); // 普通電力模式
as5600.setHysteresis(AS5600_HYSTERESIS_OFF); // 沒有遲滯
as5600.setSlowFilter(AS5600_SLOW_FILTER_16X); // 設置濾波器
as5600.setFastFilterThresh(AS5600_FAST_FILTER_THRESH_SLOW_ONLY);
// 重設位置設定
as5600.setZPosition(1024); // 設置初始位置
as5600.setMPosition(2048); // 設置最大位置
as5600.setMaxAngle(1024); // 設置最大角度
Serial.println("偵測磁場中…");
}
void loop() {
if (! as5600.isMagnetDetected()) {
return; // 若感測不到磁場,則離開迴圈。
}
// 連續讀取並顯示角度值
uint16_t rawAngle = as5600.getRawAngle();
uint16_t angle = as5600.getAngle();
Serial.print("原始角度:");
Serial.print(rawAngle); // 10進位原始角度
Serial.print(" (0x");
Serial.print(rawAngle, HEX); // 16進位原始角度
Serial.print(") | 縮放角度:");
Serial.print(angle); // 10進位角度
Serial.print(" (0x");
Serial.print(angle, HEX); // 16進位角度
Serial.print(")");
if (as5600.isAGCminGainOverflow()) { // 檢查感測器狀態
Serial.print(" | MH: 磁場太強!");
}
if (as5600.isAGCmaxGainOverflow()) {
Serial.print(" | ML: 磁場太弱~");
}
Serial.println();
delay(50);
}
上傳程式碼之後,旋轉附帶磁石的旋鈕,從「序列埠監控窗」可看到原始角度和縮放角度值不一樣了:
當原始角度超過2048時,縮放角度已經到4095。
