PMXサーボを使ってみよう C#Lib「MemWRITE編」
前回の記事から引き続きPMXサーボを制御する方法を解説します。今回は、サーボの設定を書き換える「MemWRITE」コマンドについてです。
【関連記事】
この記事で解説するPython向けライブラリ、及びサンプルプログラムは、下記のページからダウンロードしてください。
PMXシリーズのサーボモータを制御するためのオンラインマニュアルを公開しています。PMXサーボを制御するための詳しい情報が記載されていますので、下記の解説と一緒にご一読ください。
■MemWRITEコマンドについて
MemWRITEコマンドは、RAM領域のメモリマップにデータを書き込むためのコマンドです。このコマンドを使用することで下記の項目に対してデータを書き込み、設定を変更することができます。
・PIDゲインなど制御に関連する設定値
・入力電圧最小値設定など制限値の設定値
・トルクON/OFFの切り替え、制御モードの変更など
メモリマップの内容や、各設定値の解説はオンラインマニュアルの『6.メモリマップ』をご参照ください。
なお、サーボIDや通信速度、パリティを書き換える場合はSystemWRITEコマンドを使用します。こちらの使用方法については別の記事で解説します。
■コマンドの使用方法
MemWRITEコマンドは、「先頭アドレス」と「書込データ」を指定してデータを書き込みます。
「先頭アドレス」は、メモリマップに書き込むデータの先頭のアドレスを指定することができます。下図はメモリマップの一部を抜粋した表です。たとえば「入力電圧最小値設定」の設定値を書き換える場合、アドレスは76ですので、先頭アドレスとして黄色いセルの76を指定します。
「書込データ」は、サーボに対して実際に書き込むデータです。各項目のサイズに合わせたデータを用意してサーボに送信します。PMXサーボ内の各データはリトルエンディアン形式でメモリマップに格納されています。そのため、PMXサーボに2バイト以上のデータを書き込む場合、リトルエンディアンを考慮してデータを分割し、送信する必要があります。詳しくはオンラインマニュアルの『データ構造』にある「データ」の解説をご参照ください。
例えば、2バイトのデータとして"9500"を書き込む場合、”9500”は16進数で0x251Cですので、"0x1C"と"0x25"に分け、且つ順番を入れ替えてサーボに送ります。Pythonでの具体的なデータの分割方法は、以下のプログラムの解説時に解説します。
例として「入力電圧最小値設定」から「入力電圧最小時の出力%値」までのデータを書き込む場合は、下図の緑のセルの通りそれぞれ2バイトのデータのため「書込データ」として4バイトのデータを用意します。
メモリマップの詳細は、オンラインマニュアルの『メモリマップ一覧』をご参照ください。こちらに各データのアドレスとデータバイト数が一覧になっています。
■プログラム解説
ここからC#ライブラリのサンプルプログラム「MemWRITE_Sample」を使用してMemWRITEコマンドを実行し、PMXサーボにデータを書き込む方法を解説します。
ファイルの参照やライブラリのインスタンス化は『PMXサーボを使ってみよう C#Lib「MemREAD編」』をご参照ください。
●基本のMemWRITE()関数
1 2 3 4 5 6 |
// MemWRITE関数を直接使って入力最小電圧値に9500を書き込む short newMinVoltageLimit = 9500; byte[] txDataArray = BitConverter.GetBytes(newMinVoltageLimit); Console.WriteLine("76番地(入力電圧最小値設定)に[9500](9.5V)を書き込みます"); ushort flag = pmx.MemWRITE(ServoID, (ushort)RamAddrList.MinVoltageLimit, txDataArray, 0); Console.WriteLine("0x{0}", flag.ToString("x")); |
このプログラムは「入力電圧最小設定値」に9500を書き込みます。データはUint16(符号なし2バイト)で格納されています。
MemWRITE()関数を使用して「先頭アドレス」で指定した個所に「書込データ」を書き込みます。「先頭アドレス」は上記で説明した通りです。書き込む項目の先頭アドレスを指定してください。
MemWRITE()関数の「書込データ」はリトルエンディアンで1バイトずつに分割したデータをバイト型の配列(byte[])で渡します。C#には、データを分割するためのBitConverter.GetBytesという便利な関数が用意されています。
1 |
byte[] txDataArray = BitConverter.GetBytes(newMinVoltageLimit); |
引数に分割したい配列を渡すと、戻り値としてリトルエンディアンに分割した配列を受け取ることができます。この受け取ったリストを「書込データ」として使用します。
MemWRITE()関数の戻り値は、PMXサーボに書き込めたかどうかの判定を含む、PMXサーボのステータスになります。内容が0でしたら問題ありません。0以外の場合は、エラー状態を確認してください。PMXサーボのエラーに関しては、オンラインマニュアルの『5.エラー状態』を参照してください。
データを書き込み、エラーが発生しなかったら、同じアドレスのデータをMemREADコマンドで読み出して正常にデータが書き込まれているか確認します。読みだしたデータが書き込んだデータ(9500)と同じであれば成功です。
1 2 3 4 5 |
// 正しく書き込めたかを確認するため、同じ番地からデータを読み出す Console.WriteLine("76番地(入力電圧最小値設定)から2byte読み出します(返り値はbytes型)"); flag = pmx.MemREAD(ServoID, (ushort)RamAddrList.MinVoltageLimit, 2, out List<byte> rxDataArray); int data = BitConverter.ToInt16(rxDataArray.ToArray(), 0); Console.WriteLine("入力電圧最小値設定 {0}", data); |
以上がMemWRITE()関数の基本的な使用方法です。
●数値のまま書き込むデータを指定できる関数
このように、毎度データをリストにして送信するのはプログラムの行が増えて手間がかかります。そのため、ライブラリでは便利な関数を用意しました。下記の関数を使用することで、数値のままMemWRITEコマンドを実行することができます。データのサイズや型に合わせて使い分けてください。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
// 符号あり2byte型の場合 Console.WriteLine("CW方向最大角値に25000を書き込みます"); flag = pmx.MemWRITEToInt16(ServoID, (ushort)RamAddrList.CwPositionLimit, 25000, 1); Console.WriteLine("0x{0}", flag.ToString("x")); // 符号なし2byte型の場合 Console.WriteLine("入力電圧最大値設定に13000を書き込みます"); flag = pmx.MemWRITEToUint16(ServoID, (ushort)RamAddrList.MaxVoltageLimit, 13000, 1); Console.WriteLine("0x{0}", flag.ToString("x")); // 符号なし4byte型の場合 Console.WriteLine("位置制御のPゲインに2000を書き込みます"); flag = pmx.MemWRITEToUint32(ServoID, (ushort)RamAddrList.PositionKp, 2000, 1); Console.WriteLine("0x{0}", flag.ToString("x")); // 符号なし1byte型の場合 Console.WriteLine("トルクスイッチに2(free)を書き込みます"); flag = pmx.MemWRITEToByte(ServoID, (ushort)RamAddrList.TorqueSwitch, 2, 1); // TorqueSwitch Data: 0x01=TorqueON, 0x02=Free, 0x04=Brake, 0x08=Hold Console.WriteLine("0x{0}", flag.ToString("x")); |
各関数の引数は共通して下記のようになっています。
第一引数 = サーボID
第二引数 = 先頭アドレス
第三引数 = 書込データ(数値のままでOK)
第四引数 = トルクオンの状態でMemWRITEコマンドの実行を許可するかを指定
第四引数は、MemWRITEコマンドの「オプション」です。サーボがトルクオンの状態でMemWRITEコマンドの実行を許可するかを指定できます。PMXサーボは、予期せぬ誤動作を防ぐために基本的にトルクオンの状態でのMemWRITEコマンドの実行を禁止にしています。しかし、制御によってはトルクオンの状態で設定値を書き換えたい場合があります。そこで、「オプション」を1にすることで、トルクオンの状態でもMemWRITEコマンドの実行を許可することができます。許可しない場合は0にします。また、0を指定する場合は、第四引数の省略が可能です。制御モードの書き換えやPIDゲインの変更など、制御に関わる設定値を書き換えた場合はサーボの動作に影響し、振動や一瞬の脱落などが発生する可能性がありますので、なるべくトルクスイッチをFree、Brake、Holdに設定してから変更することをお勧めします。
●各設定値に特化した専用関数
また、ライブラリには書き込む項目専用の関数を用意しています。以下は「入力電圧最小値」を設定する関数です。この関数は、サーボの入力電圧が入力電圧最小値の設定値を下回った場合のサーボ出力を指定できる「入力電圧最小時の出力%値」も同時に設定できるようになっています。
1 2 3 |
Console.WriteLine("入力電圧最小値(入力電圧最小値:8000と入力電圧最小時の出力%値:50)の設定をします"); flag = pmx.setMinVoltageLimit(ServoID, 8000, 50); Console.WriteLine("0x{0}", flag.ToString("x")); |
第一引数はサーボIDです。第二引数に入力電圧最小値(アドレス76)、第三引数に入力電圧最小時の出力%値(アドレス78)を渡しています。
ライブラリには他にも多彩な関数をご用意しています。詳しくはライブラリをご参照ください。
●書き換えたデータをサーボに保存することができるSAVEコマンド
最後にSAVEコマンドについて解説します。MemWRITEコマンドで書き換えたデータは、メモリマップのRAM領域のデータを書き換えています。RAM領域のデータは、サーボの電源がオフになりますと消えてしまいます。もしMemWRITEコマンドで書き換えたデータを保存したい場合は、電源を切る前にSAVEコマンドを実行してください。SAVEコマンドは、RAM領域のデータをROM領域に保存することができます。これにより、サーボを再起動してもMemWRITEコマンドで書き換えたデータで起動することができます。
サンプルプログラムでは、下記のプログラムがコメントアウトで記述されていますので、必要に応じてコメントを外して実行してください。
1 2 3 |
ushort flag = pmx.SAVE(ServoID); Console.WriteLine(flag.ToString("x")); await Task.Delay(500); // サーボのSAVEコマンドの処理が完了するまで待つ |
なお、SAVEコマンドは保存する先のアドレスを指定することはできません。RAM領域の全てのデータをROM領域に保存しますのでご注意ください。
以上でMemWRITEコマンドの解説を終わります。次回からは、MotorWRITEコマンドに関する解説をします。MotorWRITEコマンドは、サーボの動作を指定するコマンドです。制御モードや応答データの指定などサーボの制御に関する内容も同じ記事で解説します。
次の記事『PMXサーボを使ってみよう C#Lib「MotorWRITE (位置制御)編」』
前の記事『PMXサーボを使ってみよう C#Lib「MemREAD編」』
PMX-SCR-9203HVの詳細をみる PMX-SCR-9204HVの詳細をみる PMX-SCR-5203HVの詳細をみる PMX-SCR-5204HVの詳細をみる