Feetechサーボの内部メモリテーブルと車輪モード

![SS 192.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565043/a41cd967-f549-8677-1efa-2e99bf69518d.png) いっきに全部わかりたい

## やること
秋月などでも買えるFeetechのコマンドサーボについて、外国語のシートがわかりずらいので一旦脳にやさしくまとめてみました。自分用メモ。
Arduino系のマイコンからジカに使う場合に便利だと思います。
最後に無限回転モードについての説明もあります。

専用ソフトを使わずにマイコンから動かしたい時の基本的な解説は[こちら](https://qiita.com/Ninagawa123/items/7b79c5f5117dd1470ac9)。

## 参考
秋月でDLできる資料を参考に記事にしています。

https://akizukidenshi.com/catalog/g/gM-16312/


## SCS内部メモリテーブル
サーボ内のデータのアドレスとコマンドの対応表です。
アドレス 39番までがEEPROM、40番以降がSRAMの内容になります。
またSTSサーボの場合は内容が若干異なります。
参考まで右の列にSTS版の命令項目を追記しました。

|アドレス<BR> (10進数)|アドレス<BR> (16進数)|SCS命令項目 |R/W |初期値 |STS版|
|----------------|----------------|--------|-------|-------|-------|
|0|0x00 |-- |--|-|ファームウェアバージョン(H)|
|1|0x01 |-- |--|-|ファームウェアバージョン(L)|
|2|0x02 |-- |--|-||
|3|0x03 |ソフトウェアバージョン(H)|Read|- ||
|4|0x04 |ソフトウェアバージョン(L)|Read|- ||
|5|0x05 |ID |R/W|00||
|6|0x06 |通信速度 |R/W|00||
|7|0x07 |返信遅延時間 |R/W|00||
|8|0x08 |応答状態レベル |R/W|01<BR>(0x01)||
|9|0x09 |最小角度制限(H)|R/W|00<BR>(0x00)||
|10 |0x0A |最小角度制限(L)|R/W|00<BR>(0x00)|
|11 |0x0B |最大角度制限(H)|R/W|03<BR>(0x03)||
|12 |0x0C |最大角度制限(L)|R/W|255<BR>(0xFF)||
|13 |0x0D |最高温度上限 |R/W |80<BR>(0x50)||
|14 |0x0E |最高入力電圧 |R/W |250<BR>(0xFA)||
|15 |0x0F |最低入力電圧 |R/W |50<BR>(0x32)||
|16 |0x10 |最大トルク(H)|R/W |03<BR>(0x03)||
|17 |0x11 |最大トルク(L)|R/W |255<BR>(0xFF)||
|18 |0x12 |高圧警告 |R/W |00<BR>(0x00)||
|19 |0x13 |トルクオフ条件 |R/W |37<BR>(0x25)||
|20 |0x14 |LED警告条件 |R/W |37<BR>(0x25)||
|21 |0x15 |Pゲイン |R/W |15<BR>(0x0F)||
|22 |0x16 |Dゲイン |R/W |00||
|23 |0x17 |Iゲイン |R/W |00||
|24 |0x18 |最小PWM(H)|R/W |00||
|25 |0x19 |最小PWM(L)|R/W |00||
|26 |0x1A |時計回りのデッドゾーン |R/W |02<BR>(0x02)||
|27 |0x1B |反時計回りのデッドゾーン |R/W |02<BR>(0x02)||
|28 |0x1C |積分限界(L)|R/W |00|保護電流|
|29 |0x1D |積分限界(H)|R/W |00||
|30 |0x1E |微分サンプリング係数 |R/W |00|角度分解能|
|31 |0x1F |-|R/W |-|位置補正(H)|
|32 |0x20 |-|R/W |-|位置補正(L)|
|33 |0x21 |-|R/W |-|運行モード|
|34 |0x22 |-|R/W |-|保護トルク|
|35 |0x23 |-|R/W |-|保護時間|
|36 |0x24 |-|R/W |-|過負荷トルク|
|37 |0x25 |-|R/W |-|速度閉ループP比例係数|
|38 |0x26 |-|R/W |-|過電流保護時間|
|39 |0x27 |-|R/W |-|速度閉ループI積分係数|
|40 |0x28 |トルクON/OFF |R/W |00||
|41 |0x29 |-|R/W |-|加速度|
|42 |0x2A |目標位置(H)|R/W |- ||
|43 |0x2B |目標位置(L)|R/W |- ||
|44 |0x2C |実行時間(H)|R/W |00||
|45 |0x2D |実行時間(L)|R/W |00||
|46 |0x2E |実行速度(H)|R/W |00||
|47 |0x2F |実行速度(L)|R/W |00||
|48 |0x30 |ロックフラグ |R/W |00||
|55 |0x37 ||R/W |00|ロックフラグ|
|56 |0x38 |現在位置(H)|Read |- ||
|57 |0x39 |現在位置(L)|Read |- ||
|58 |0x3A |現在速度(H)|Read |- ||
|59 |0x3B |現在速度(L)|Read |- ||
|60 |0x3C |現在負荷(H)|Read |- ||
|61 |0x3D |現在負荷(L)|Read |- ||
|62 |0x3E |現在の電圧 |Read |- ||
|63 |0x3F |現在の温度 |Read |- ||
|64 |0x40 |REG WRITEフラグ |Read |00||
|65 |0x41 |-|Read |-|サーボ状態|
|66 |0x43 |-|Read |-|移動フラグ|
|69 |0x46 |-|Read |-|現在の電流|

- 2バイト(16ビット)でLとHに分けられたパラメータの範囲は、0x000から0x03FF。
- 1バイト（8ビット）のパラメータの範囲は、0x00から0xFE。

### アドレス 0 ~ 2 : 不使用

### アドレス 3,4 : サーボのバージョン情報

### アドレス 5 : サーボID
サーボのIDです。これはよく使うと思います。

### アドレス 6 : 通信速度
いわゆる通信速度です。
115,200以下だと設定速度からほんのちょっとずれるそうです。おそらく周波数の都合です。あとはマイコン側のUART速度と相談ですね。
|値|Hex|目標通信速度|
|--|--|--:|
|0|0x00|1,000,000|
|1|0x01|500,000|
|2|0x02|250,000|
|3|0x03|128,000|
|4|0x04|115,200|
|5|0x05|76,800|
|6|0x06|57,600|
|7|0x07|38,400|

### アドレス 7 : 返信遅延時間
サーボが命令を受信してから応答するまでの遅延時間です。
遅延時間は0から254の範囲で設定でき、単位は2マイクロ秒（US）です。
たとえば、250を設定すると、500マイクロ秒後にサーボが応答します。
0を設定した場合、サーボはできるだけ早く応答します。

### アドレス 8 : サーボに返信させるかどうか

|値|内容|
|--|--|
|0|読み取り命令やPINGに対してのみ応答パケットを返送。<br>他の命令に対しては応答しない。|
|1|受信したすべての種類の命令（読み取り、書き込み、設定変更など）に対して応答パケットを返送する。|

通常は0で良さそう。
1の場合に、書き込み命令に対してどのデータを返信してくるのかわからないですがたぶん同じデータなので、それをみてサーボが実行できているかを確認する感じになるのかな？


### アドレス 9 ~ 12 : サーボの最大角度

サーボが動作可能な角度範囲を設定します。
実際にサーボを動作させる時の目標角度は、この範囲に収める必要があります。
また、当然のことですが最小値＜最大値となるように設定します。
サーボの最大角を設定しておけると、実際に使うときに物理ロックを避けられて便利ですよね。

### アドレス 13 : 最高温度上限
数値がそのまま摂氏温度のようです。
例えば80に設定した場合、最高温度は80度になります。設定精度は1度とのことです。
（設定温度を越えると電源オフになるのかな？）

### アドレス 14 : 最高入力電圧
最低動作電圧です。
例えば85に設定した場合、最高動作電圧は8.5Vになります。設定精度は0.1Vです。
書き換え可能ということは... 魔改造は自己責任で！

### アドレス 15 : 最低入力電圧
最低動作電圧です。例えば45に設定した場合、最低動作電圧は4.5Vになります。設定精度は0.1Vです。

### アドレス 16,17 :  最大出力トルク
サーボの最大出力トルクを設定します。
0x03FFがSCSの最大出力トルクに対応すると説明書きにあるので、たぶん1,023が最大。（65,283ではないですよね？）

### アドレス 18 :  高圧警告
特に解説がありませんが、たぶんここで設定した電圧値を越えるとアドレス19のエラーに反映されるのだと思います。

### アドレス 19 :  トルクオフ条件およびLED警告条件

|ビット|説明|
|--|--|
|BIT7|-|
|BIT6|-|
|BIT5|1に設定されている場合、過負荷発生時に力の出力を減らす/LED警告|
|BIT4|-|
|BIT3|-|
|BIT2|1に設定されている場合、過熱発生時にトルクオフ/LED警告|
|BIT1|-|
|BIT0|1に設定されている場合、電圧範囲を超えた際にトルクオフ/LED警告|

どれか一つでも当てはまればLEDは警告状態になります。（点灯とは違うのかな？）

### アドレス 20 :  LED点灯条件
このLED点灯条件（0=オフ、1=オン）が優先されるようです。
エラー判定等によりLEDがオンの条件となっていても、この値が0の場合はLEDをオフにします。

### アドレス 21 ~ 25 :  P,I,Dと最小PWM
説明書には説明が見当たらず。

### アドレス 26,27 :  位置クローズドループのデッドゾーン
サーボが目標位置に非常に近づいた際に、微小な動作を無視するためのデッドゾーン。
計回りと反時計回りの両方を1に設定すると、デッドゾーンは約0.38度になるそうです。

### アドレス 28 ~ 30 : 積分限界,微分サンプリング係数
説明書には説明が見当たらず。

### アドレス 31 ~ 39 : 不使用
    
### アドレス 40 : トルク出力スイッチ
この設定はサーボのトルク（力）の出力をオンまたはオフにします。
1でトルクを有効、0でトルク無効。
このアドレスはけっこう使いそうですね。

### アドレス 41 : 不使用

### アドレス 42, 43 : 目標位置

サーボの目標位置です。
範囲は0x0000から0x03FFで、0x0000は0度、0x03FFは200度に対応し、誤差は±2%です。

### アドレス 44 ~ 47 : 目標位置への移動時間（44,45）と速度（46,47）
サーボが目標位置まで移動するための時間と速度を設定します。
速度パラメータが時間パラメータより優先され、同時に時間と速度のパラメータを書き込むと速度パラメータが制御パラメータとして選ばれます。
時間の単位はミリ秒、速度の単位は0.19度/秒です。
例えば1000を設定した場合、速度は(1000*0.19)度/秒になります。
0を設定すると、SCSの最大速度62RPMに対応します。

### アドレス 48 : パラメータのロック機能
このビットを0に設定してロック保護をオフにすると、EEPROM領域のパラメータの変更が電源オフ後も保存されます。つまりEEPROMの内容を書き換えたいときに使うようです。

**注意**:ロック機能ビットが0に設定されている場合、書き込み速度が遅くなり、またEEPROM領域のパラメータに頻繁に書き込みを行うと、SCSの寿命に影響があります。

### アドレス 49 ~ 55 : 不使用

### アドレス 56 ~ 63 : 現在情報のもろもろ
56,57 : 現在位置
58,59 : 現在速度
60,61 : 現在負荷
62 : 現在電圧
63 : 現在温度
    
サーボの状態を取得したいときに頻繁に使いそうな領域です。

### アドレス 64 : REG WRITE指令の状態表示
「REG WRITE」命令は、通常、複数の命令を一度に実行するために使われる命令で、命令が登録されて実行を待っている場合はこのビットが「1」に設定されます。
すべての「REG WRITE」命令が実行された後、このビットは「0」に戻ります。

サーボモーターの制御システムでは、「REG WRITE」命令を利用して効率的に複数の操作を一度に実行することができます。このビットは、そのような命令群の実行状態を確認するために使われるとのことです。
（わかるようなわからないような。）


# 電動モーター速度制御モード！

最後に、車輪や履帯などのアクチェーターとして使う時のモード設定についてです。
電動モーターの速度制御モードに切り替えることで実現します。

- 最小角度制限と最大角度制限（0x09～0x0C）を両方とも0に設定。
- 速度（0x2C～0x2D）を設定。

こうすると、サーボは電動モーター速度制御モードで動作を開始します。

|0x2C～0x2Dのビット|説明|
|--|--|
|BIT11 ~ 15|値は0固定|
|BIT10|0は順方向、1は逆方向|
|BIT 0 ~ 9|速度の大きさ|

アドレス0x2C～0x2Dにおいて、BIT10は方向ビットで、0は正方向の回転、1は反方向の回転を意味します。BIT0～BIT9は速度の大きさを表します。

## マイコン系から動かしたい時

ESP32などからコマンドを送る方法を下記にまとめました。

https://qiita.com/Ninagawa123/items/7b79c5f5117dd1470ac9


# リターンパケット考察

サーボから返信されるパケットについてです。（推測含む）

### 頼んでなくても返してくるリターンパケット
デフォルト設定の場合に、読み取りではないコマンドを送信したとしても、返してくるパケットです。以下のような内容になります。
```
[FF][FF][サーボID][データ長][エラーコード][チェックサム]
```
サーボIDが来るので、送信に対して実行されたかを判断するのには良さそうです。

たとえば返信を要求しない、位置情報の指定をID1番のサーボに対して送信すると、
```
FF FF 1 2 0 FC
```
というパケットを返してきます。
返信がうるさい場合には、アドレス8を0にすることでミュートできるようです。

### エラーコード
さきほどのリターンパケットに含まれる内容です。

|ビット|内容|説明|
|--|--|--|
|BIT7|-||
|BIT6|-||
|BIT5| 過負荷|位置モードで動作中に出力トルクが設定負荷より低い場合に1|
|BIT4|-||
|BIT3|-||
|BIT2|過熱|温度が指定範囲を超えると1|
|BIT1|-||
|BIT0|過電圧/低電圧|電圧が指定範囲を超えると1|

エラーコードが0の場合、サーボにはエラーがありません。


# SCS0009とSTS3215の違い
上記の表はSCSのメモリテーブルとして公開されているものに準じています。
SCS0009とSTS3215ではメモリ構造に違いがあることが確認できており、2バイトデータについてのビッグエンディアン・リトルエンディアンが逆になっているようです。
2バイトのデータをコードで変換する場合にご注意ください。
また、目標位置についての動作範囲は、

- STS3215 (0-4096) 
- SCS0009 (0-1023) 

となっているようです。


# 前回記事
https://qiita.com/Ninagawa123/items/7b79c5f5117dd1470ac9

# 次回記事
https://qiita.com/Ninagawa123/items/e3281d128c6ca1876564

# さいごに

とりあえず内容についてのリストアップでした。
実験はあとでやってみます。

よき電子工作ライフを〜