###### tags: `自駕車`
# F-Drive 馬達霍爾編碼器轉數計算
我們使用的是 [GM25-370](https://item.taobao.com/item.htm?spm=a1z09.2.0.0.67002e8dBeRVLp&id=523820484160&_u=ns4b4pq219b) 帶霍爾編碼器的馬達:

不過這個型號有許多規格差異:

經過檢視馬達上的標籤:

確認是 12V 140RPM 的這一款, 所以規格就是:

霍爾編碼器的原理可參考[這一篇的教學](https://blog.csdn.net/robotixworkshop/article/details/114275629), 主要就是 A、B 兩個感測器的變化:

自駕車內的程式是參考這[一篇的範例](https://www.arduino.cn/thread-42559-1-1.html), 計算轉速的程式片段如下:
```cpp=
unsigned long times; //舊時間
unsigned long newtime; //新時間
int AM1 = 7; //相位A腳位
int BM1 = 8; //相位B腳位
int valA = 0; // A的累積值
int valB = 0; // B的累積值
int flagA = 0; // A的狀態
int flagB = 0; // B的狀態
int d_time = 7; //週期時間
void setup()
{
pinMode(AM1, INPUT); //脈衝腳位1
pinMode(BM1, INPUT); //脈衝腳位2
}
void loop()
{
newtime = times = millis();
while ((newtime - times) < d_time)
{
if (digitalRead(AM1) == HIGH && flagA == 0)
{
valA++;
flagA = 1;
}
if (digitalRead(AM1) == LOW && flagA == 1)
{
valA++;
flagA = 0;
}
if (digitalRead(BM1) == HIGH && flagB == 0)
{
valB++;
flagB = 1;
}
if (digitalRead(BM1) == LOW && flagB == 1)
{
valB++;
flagB = 0;
}
newtime = millis();
}
double r = (valA + valB) / (1.98 * d_time); // Rotating speed
}
```
其中 45 行的 1.98 是因為根據規格表:
- 內部馬達每一轉會有 11 個脈衝訊號
- 減速馬達減速比是 1:45
所以減速馬達轉軸實際轉一圈, 內部馬達要轉 45 圈, 總共有 $11\times45 = 495$ 次脈衝。
上述程式會加總 A、B 感測器相位變化次數, 每個脈衝 A、B 均會低->高->低, 總計 2 個感測器各 2 次變化, 加總為 4 次, 因此每秒轉數可由以下算式計算 (d_time 是計算區間的毫秒數):
$$
\begin{align}
每秒轉數 &= { 相位變化總數 \over 495 \times 4} \times {1000 \over d\_time} \\
&= { 相位變化總數 \over 1980} \times {1000 \over d\_time} \\
&= { 相位變化總數 \over 1.98 \times d\_time}
\end{align}
$$