シリアル書き込みスケッチのユーザー関数化その1


VS-RC003をArduinoのシリアル経由で操作するプロジェクトがまだ続いています。
一気に最後まで作ってしまうべきかもしれませんが、Arduinoの練習がてら完成まで少しずつ前進中です。

今回新たに試したことは、
・ユーザー定義関数を使う。
・ストリング関数を使う。
・配列、文字列、16進数などの相互変換を行う。
のあたりです。



今回定義したユーザー関数は、
VSRC_WnV(x,y)
です。
xには変数番号(0〜255)
yには数値データ(0〜65535)

をそれぞれ入れて使います。
変数番号(たとえばコントローラの接続設定は240)と数値データ(たとえばゲームパッド未接続なら0)を整数で指定して実行すると、アドレスと16進数リトルエンディアンを自動的に作成して書き込んでくれるという、VS-RC使いにとってはなかなか便利な関数です。
書き込みに成功すればtrue、失敗ならfalseを返してくれるようにしてみました。



今回はまだテストで、シリアルモニタで結果を見られるようになっています。
この後、このユーザー関数はarduino nanoなどでも使えるようにハードウェアシリアル(0番1番ピン)用に作り直し、モニタリング機能も排除する予定です。
また、コントロール関連専用のユーザー関数VSRC_CONTROL()や、読み込み専用のVSRC_READ()、ベリファイなしの書き込みVSRC_WRITE()なども同時に作成予定です。
自分的に難しいところは超えたので、あとは作業をしていくだけです。
一通り完成し、実際にロボットを安定的に動かすテストまでできれば、自分的にはVS-RCのシリアルは攻略完了となります。



以下、スケッチです。

// VS-RC003のシリアルを書き込み、ベリファイする関数のモニタリング付きスケッチ。
// シリアルでデータ書き込みコマンドを実行した後、該当箇所のデータを読み込んで、
// 書き込みが成功しているかを確認する。
//
// VSRC_WnV([変数番号(0~255)],[数値データ(0~65535)]) という形式の関数。
// WnVはWrite and Verifyの略。
// ユーザー変数は変数番号64~127。
// 変数番号0~63、128~155、238,239,248~250,253は読み込み専用のため書き込みはエラーとなる。
// 書き込んだ文と読み込んだ文が合致して入ればtrue、合致していなければfalseを返す。
//
// VS-RC003へはArduinoのシリアル1のRX,TXを接続。(MEGA,Leonardo,MICROに対応。UNO系は非対応。)

void setup() {
Serial.begin(115200); // 115200bpsでPCモニタ用ポートを開く
Serial1.begin(115200);// 115200bpsでVS-RC003通信用ポートを開く
}

void loop() {
bool w = VSRC_WnV(67, 3563); //ユーザー関数VSRC_WnV()を用いて、VSRC-003の変数番号64番に、3563を書き込む。
if (w == true) {//書き込みの成否を判定して、結果を表示。
Serial.println("Veriy OK!");
} else {
Serial.println("Write ERROR!");
}
Serial.println();
//while (1);
}


// ■ ■ ■ ■ 以下ユーザー関数 VSRC_WnV() の定義 ■ ■ ■ ■

bool VSRC_WnV(long vsrc_address, int vsrc_value) {

//■■■■変数の定義など■■■■
bool Loading = false; //必要データ読取中フラグ
char vsrc_value_buf[4];//書き込む数値の配列
vsrc_address = vsrc_address * 2 + 2099200;//変数番号のアドレスへの変換
String vsrc_address2 = String(vsrc_address, HEX);//アドレスの文字列への変換
String vsrc_value2 = String(vsrc_value, HEX);//代入数値を16進数表記の文字列に変換

//■■■■書き込み用の変数を配列に入れる■■■■
int i = 0;//代入数値(16進数表記4桁)を配列に入れる際のケタ番号
int i3 = 3 - (vsrc_value2.length());// 16進数4桁未満の時に、配列に0を何回入れるか
while (i <= i3) {//16進数4桁の冒頭が0で始まる場合、配列に0を入れて埋める処理
vsrc_value_buf[i] = 0x30;//配列に0を入れる
i++;//配列の番号を足す
}
int i2 = 0;//配列に入れる元の文字列の配列番号
while (i <= 3) {
vsrc_value_buf[i] = vsrc_value2.charAt(i2);//16進数4桁の文字列を、配列に入れる。
i++;//配列の番号を足す
i2++;//文字列の番号を足す
}
vsrc_value_buf[4] == 0X00;//ヌル終端を追加

//■■■■書き込み用のシリアル文をリトルエンディアンで組み立てる■■■■
String vsrc_write_conposit = String ("w " + vsrc_address2 + " " + vsrc_value_buf[2] + vsrc_value_buf[3] + " " + vsrc_value_buf[0] + vsrc_value_buf[1]);

//■■■■実際の書き込み■■■■
Serial.println("Serial1_write_command:");//モニタ用。
Serial.println(vsrc_write_conposit);//モニタ用。書き込んだ文字列を表示する。
Serial1.println(vsrc_write_conposit);//実際に読み込み用のライト文を送信。

//■■■■書き込み完了確認■■■■
delay(38);//18以下だと失敗する。すこし余裕をもたせるべき。
if (Serial1.available() > 0 ) {//受信シリアルのプロンプト「#」を待つ。
for (int i = 0; i <= 64; i++) {//「#」を受け取るまで64文字まで待つ。普通は1発目で見つける。
char data = Serial1.read();
if (data == 0x23)//「#」を受け取り次第抜ける。
{
i = 64;
}
}

//■■■■ベリファイ用のシリアル文を送信する■■■■
String vsrc_read_conposit = String ("r " + vsrc_address2 + " 02");//書き込んだアドレスの数値を読み込むための文章組み立て
Serial.println("Serial1 vsrc_read_command:");//モニタ用。
Serial.println(vsrc_read_conposit);//モニタ用。ベリファイ用のシリアル文
Serial1.println(vsrc_read_conposit);//ベリファイ用のシリアル文を送信する。
delay(30);//このディレイが小さすぎると失敗しやすい。

//■■■■ベリファイ用の読み込み文を組み立てる■■■■
char VSmsgs[64];// 読み取ったシリアルを入れる配列を宣言。
if (Serial1.available() > 0 ) {
int i = 0; //文字配列カウンタ
while (1) {
char data = Serial1.read();
VSmsgs[i] = data; //文字配列に文字を一個入れる。
if (VSmsgs[i - 1] == 0x0a && VSmsgs[i] == 0x23)// 「[LF]」と「#」が連続している文字列を探す。
{
Loading = true; //必要データ読取中のフラグを立てる。
//取得するデータの冒頭を「#」から「w 」に変換して書式を合わせておき、あとで比較できるようにする。
VSmsgs[0] = 0x77; //配列の1文字目にwを入れ直しておく。
VSmsgs[1] = 0x20; //配列の2文字目にスペースを入れ直しておく。
i = 1;
}
if (VSmsgs[i] == 0x0D && Loading == true)//必要データ読取中かつ「CR」が来たら読取終了。
{
Loading = false;
break;
}
i ++;
}
VSmsgs[i] = 0x00;//データにヌル終端を追加

Serial.println("serial1 read data:");
String VSmsgssrg = String(VSmsgs);//読み込んだ配列を文字列に変換
VSmsgssrg.trim();//変換時に発生した空白文字をトリム
Serial.println(VSmsgssrg);//モニタ用。読み込んだデータ(#をw に書き換えたもの)を表示する。

//■■■■書き込んだデータを読み込んだデータを文字列で比較する■■■■
bool Verify = vsrc_write_conposit.equalsIgnoreCase(VSmsgssrg);//大文字小文字を無視して文字列を比較する。合致ならtrue
return Verify;
}
}
}




実行したシリアルモニタは下記のようになります。


Serial1_write_command:
w 200886 eb 0d
Serial1 vsrc_read_command:
r 200886 02
serial1 read data:
w 200886 eb 0d
Veriy OK!
スポンサーサイト

テーマ : 自然科学
ジャンル : 学問・文化・芸術

コメントの投稿

非公開コメント

プロフィール

二名川(ニナガワ)

Author:二名川(ニナガワ)
ホビーロボットをレトロゲームが発展したものと捉えて楽しく遊び倒します。
子供が夢を見ている時間帯に稼働します。

宣伝:電子出版しました。
「コンソロイド ガイドブック」
46107_CONSOLOID_GUID_FACE_200.jpg





■作成中の機体
汎用ヒト型決戦遊具 ~RX計画~
RX-7.5 ゼロタンク
RRf-0.6 ゼニィ
RXM-7.9 ゼムネス
RX-7.5R 量産型ゼロタンク
RX-7.5Fp ファミタンク仮設1号
RX-7.7 ゼロキャノン
RX-7.8 ゼログレイ
SMS-0.1 ゼロライナー
以下続く

ブログ内検索
最近の記事
最近のコメント
カテゴリ
月別アーカイブ
リンク