GR-SAKURA
GR-KURUMI
GR-COTTON
GR-CITRUS
GR-PEACH
GR-KAEDE
GR-ADZUKI
GR-LYCHEE
GR-ROSE
GR-MANGO(*)
SNShield
Web Compiler
IDE for GR
TOPPERS関連
女子美コラボ
その他
※プロデューサミーティング中
作り方使い方資料
イベント関連
作品記事
体験記事
ライブラリ
ツール
その他・過去ファイル
近藤科学B3Mシリアルサーボの制御を試みているのですが、どうにも動きません。
やったことは、
/* GR-ROSE Sketch template V0.01 */ #include <Arduino.h> #define B3MSerial Serial3 //B3M Command //reset uint8_t cmd0[] = {0x06, 0x05, 0x00, 0x00, 0x00, 0x0B}; //Free mode uint8_t cmd1[] = {0x08, 0x04, 0x00, 0x00, 0x02, 0x28, 0x01, 0x37}; //Normal mode uint8_t cmd2[] = {0x08, 0x04, 0x00, 0x00, 0x00, 0x28, 0x01, 0x35}; //position 180deg = 18000 = 0x4650 uint8_t cmd3[] = {0x09, 0x04, 0x00, 0x00, 0x50, 0x46, 0x2a, 0x01, 0xce}; //position 0deg = 0x0000 uint8_t cmd4[] = {0x09, 0x04, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x01, 0x38}; void setup() { B3MSerial.begin(115200); B3MSerial.direction(OUTPUT); delay(500); B3MSerial.write(cmd1, cmd1[0]); delay(1000); B3MSerial.write(cmd2, cmd2[0]); delay(1000); } void loop() { B3MSerial.write(cmd3, cmd3[0]); delay(1000); B3MSerial.write(cmd4, cmd4[0]); delay(1000); }
です。
このコードをArduino UNO + LTC485で動かすと、正しく動作します。(tweet)※B3MSerial.direction(OUTPUT);をコメントアウトして、Serialを正しく指定するまた、GR-ROSEの出力を1.で作ったケーブルを用いてPC用RS485アダプタと接続し、PCでモニタすると想定通りのデータを受信できています。(tweet)
B3MSerial.direction(OUTPUT);
確認のため、Serial5からRS-485トランシーバ経由で接続しようと思っていたのですが、何故か次の出力をするまでの間、最後に出力したデータを送信し続けるという謎現象に悩まされて出来ていません。
とりあえず現状報告でした。
追加情報。スケッチとオシロの波形は以下の通りです。
#include <Arduino.h> void setup() { Serial1.begin(115200); //Serial1.direction(HALFDUPLEX); } void loop() { Serial1.write(0xA5); delay(1); }
direction(HALFDUPLEX)があるとき
ないとき
時間は1コマ100usecです。
MAX3485を入手できたので、3.3V版のRS-485インターフェイスを作りました。(tweet)
GR-ROSEのSerial5に接続してみたものの動作しません。
試しにGR-SAKURAに接続してみたところ、こちらは動作しました。
オシロの波形を見ていて問題ないと思っていたのですが、GR-SAKURAと比べるとGR-ROSEの方がちょっと長いので、ビットレートの誤差が許容を超えているのかもしれません。
上がGR-SAKURAで下がGR-ROSEです。SAKURAの方はコマンドの後に応答が返ってきています。
根本的な解決はしていませんが、ひとまず動くようになったのでまとめです。
動作しなかった原因は、ビットレートの誤差がB3Mサーボの許容範囲内に収まっていなかったものと推定します。
GR-ROSEとGR-SAKURAで、SerialX.begin()して設定されたレジスタ値をまとめたのが下表です。
115200bpsの時に誤差が1%を越えています。PCLKが48MHzから60MHzに変わったことの影響でしょうか。※4800bpsはどちらも異常なのはまあいいか。ユーザーズマニュアル ハードウェア編を参照すると、RX64からSEMRにBGDMが追加になっていました。こちらも利用することで誤差が0.16%になり、問題なく動作することを確認しました。
Serial3であれば、
Serial3.begin(115200); Serial3.direction(OUTPUT); //115200bps SCI5.SCR.BIT.RE = 0; SCI5.SCR.BIT.TE = 0; SCI5.BRR = 64; SCI5.SEMR.BIT.ABCS = 1; SCI5.SEMR.BIT.BGDM = 1; SCI5.SMR.BIT.CKS = 0; SCI5.SCR.BIT.RE = 1; SCI5.SCR.BIT.TE = 1;
でOK。
最後に。Serial3,4で難しいと思ったのが、読み込みのタイミングです。SerialXの送信は非同期のため、SerialX.write()の直後にSerialX.directoin(INPUT)を実行すると送信が完了しないうちに受信モードになってしまうので送信が中断してしまいます。ビットレートとデータ長から待ち時間を計算して、delayするしかないのでしょうか。※送信完了から850usくらいで応答データは送られて来ます。
Akagawaさん、多大なるご協力(人柱)、大変ありがとうございました。SDKを更新しました。
ボーレート設定の部分はFITモジュールの部分をポーティングしました。いずれはFITを使う検討をしますが、バッファリングをどうするか課題があるため、これはTODOにしました。
以下、115200の波形です。
対処前が以下の通りで、確かにズレが見られました。
以下は、対処後の1500000bpsの波形です。Akagawaさんのコードを1500000bpsにして、Serial3によるB3M(デフォルト)での制御ができました。
以下は、対処後の3000000bpsの波形です。ギリギリセーフな感じではありますが、こちらでのB3M動作は確認してません。B3M ManagerがROSEを使ったブリッジですんなり動いてくれませんでした。
B3M_Manager用のスケッチを貼り付けます。もう少しシンプルにできそうですが、コマンドを送るときはdirection(INPUT)せずに、バイト数分を送らないとうまいこと動きませんでした。
#include <Arduino.h>#define B3MSerial Serial3void setup() { Serial.begin(9600); B3MSerial.begin(1500000); B3MSerial.direction(INPUT);}void loop() { if(B3MSerial.available()){ Serial.write(B3MSerial.read()); } if(Serial.available()){ char c = Serial.read(); while(!(Serial.available() == (c - 1))); B3MSerial.direction(OUTPUT); B3MSerial.write(c); for(int i = 0; i < (c - 1); i++){ B3MSerial.write(Serial.read()); }// while(!SCI5.SSR.BIT.TEND); // necessary at V0.03 or before B3MSerial.direction(INPUT); }}
中間リアルミーティングに持っていくの忘れたので、Serial5用に作ったRS-485ボードの写真載せておきます。XHとEH両方付けたのでKondo, Futaba両対応にしてあります。ボード上に電源用のVHコネクタ付けていますが、レギュレータ等は載せていないので、GR-ROSEには給電できません。
オマケで、XH vs EHの良く分かる画像。