シリアル読取&書き込みスケッチのリファイン


見えるぞ!私にもシリアルが見える!!




VS-RC003→Arduinoのシリアル解読」でVS-RC003のデータ表示に挑戦した後、
シリアル検証スケッチ」でシリアルの厳密な配列が判明してきました。
前回やや当てずっぽうだった必要データの切り出し方法を厳密なものに改め、スケッチを書き直してみました。
さらに、書き込んでベリファイするものも書いてみました。
だいぶスッキリしました。




PCでモニタリングするプログラムのため、
Arduinoはハードウェアシリアルが使えるMEGAがおすすめです。
Serial1が使えるMICROやLeonardoでも動くと思います。
VS-RC003の設定で好きな方をシリアルに設定し、また、
ArduinoのRXピン、TXピン、5V、GNDを、VS-RC003のTXピン、RXピン、5V,GNDにそれぞれ接続します。




補足ですが、VS-RC003の拡張コネクタは、
CN6:ゲームパッド使える/IXBUS使えない/シリアル使える
CN7:ゲームパッド使えない/IXBUS使える/シリアル使える

となっているようです。
IXBUS機器を複数使う場合CN7に数珠つなぎにします。
CN6にはコントロールパッドの代わりにシリアルをつなぐことが可能です。




まず読み取りです。
電圧の取得を例にします。
指定したアドレスのデータを読み込み、データを表示。
さらにエンディアンを交換し、整数データとして表示するところまでを行います。

// VS-RC003のシリアルを読み取るプログラム作例
// rコマンドで読み出し命令を出し、結果を変数VSmsgsに入れて表示する。
// 例では、r 2009dc 04で電圧を読み取る。
// 2009dc 02 00 xx yy が読み出されるが、xx yy の部分が、該当の電圧データとなる。
// また、リトルエンディアンからビッグエンティアンへ、
// さらにアスキーコードの16進数を数値に変換し、10進数に換算する。
// データの切り出し方を厳密化。

int vcc1, vcc2, vcc3, vcc4;// 換算用の変数を宣言。
bool ERR = false;// 読み取りエラーのフラグ用変数を宣言。
bool Loading = false; //必要データ読取中フラグ

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

void loop() {
 char VSmsgs[64];// 読み取ったシリアルを入れる配列を宣言。
 Serial1.println("r 2009dc 04");//電圧を読み込む命令
 delay(30);//このディレイが小さすぎると失敗しやすい。
 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; //必要データ読取中のフラグを立てる。
       VSmsgs[0] = 0x23; //配列の1文字目にプロンプト記号#を入れ直しておく。
       i = 0;
     }
     if (VSmsgs[i] == 0x0D && Loading == true)//必要データ読取中なら「CR」が来たら読取終了。
     {
       Loading = false;
       break;
     }
     i ++;
   }

   VSmsgs[i] = 0x00;//データにヌル終端を追加
   Serial.println(VSmsgs);//取得データを表示。
   Serial.print("Big endian : ");//以下、該当の電圧データをエンディアンを交換して表示する。
   Serial.print(VSmsgs[17]);
   Serial.print(VSmsgs[18]);
   Serial.print(" ");
   Serial.print(VSmsgs[14]);
   Serial.println(VSmsgs[15]);
   Serial.print("ASCII to HEX to DEC : ");

   //以下、取得したASCIIコードを16進数に換算していく。
   //その際、範囲にない文字であれば、エラーフラグを立てる。
   if (VSmsgs[17] <= 0x2f) {//取得した文字が0よりも前の文字であればエラー。
     ERR = true;
   } else if (VSmsgs[17] >= 0x67) {//取得した文字がfよりも後の文字であればエラー。
     ERR = true;
   } else if (VSmsgs[17] >= 0x41) {
     vcc1 = VSmsgs[17] - 0x57;//取得した文字がa以上であれば10からの数字に換算。
   } else {
     vcc1 = VSmsgs[17] - 0x30;//それ以外であれば、0から9の数字に換算。
   }

   if (VSmsgs[18] <= 0x2f) {
     ERR = true;
   } else if (VSmsgs[18] >= 0x67) {
     ERR = true;
   } else if (VSmsgs[18] >= 0x41) {
     vcc2 = VSmsgs[18] - 0x57;
   } else {
     vcc2 = VSmsgs[18] - 0x30;
   }

   if (VSmsgs[14] <= 0x2f) {
     ERR = true;
   } else if (VSmsgs[14] >= 0x67) {
     ERR = true;
   } else if (VSmsgs[14] >= 0x41) {
     vcc3 = VSmsgs[14] - 0x57;
   } else {
     vcc3 = VSmsgs[14] - 0x30;
   }

   if (VSmsgs[15] <= 0x2f) {
     ERR = true;
   } else if (VSmsgs[15] >= 0x67) {
     ERR = true;
   } else if (VSmsgs[15] >= 0x41) {
     vcc4 = VSmsgs[15] - 0x57;
   } else {
     vcc4 = VSmsgs[15] - 0x30;
   }

   Serial.print(vcc1, DEC);//ビッグエンディアンに変更後の16進数を並べる。
   Serial.print(" ");
   Serial.print(vcc2, DEC);
   Serial.print(" ");
   Serial.print(vcc3, DEC);
   Serial.print(" ");
   Serial.println(vcc4, DEC);
   Serial.print("VCC : ");
   int vcc = vcc1 * 4096 + vcc2 * 256 + vcc3 * 16 + vcc4;//16進数を10進数に換算する。
   Serial.print(vcc, DEC);//結果の数値を表示する。
   Serial.println();
   //Serial1.flush();
   if (ERR == true) {//取得データにエラーが出ていればエラーと表示する。
     Serial.println("*** READ ERROR!! ***");
     ERR = false;
   }
     Serial.println();
   delay (1);
 }
}




実行結果は、

#2009dc 02 00 98 0f
Big endian : 0f 98
ASCII to HEX to DEC : 0 15 9 8
VCC : 3992

#2009dc 02 00 8f 0f
Big endian : 0f 8f
ASCII to HEX to DEC : 0 15 8 15
VCC : 3983
(以降くりかえし)


のように表示されます。




次に書き込みです。
VS-RC003にシリアルで指定アドレスに変数を書き込みます。
同じアドレスを読み取って比較することで書き込みの成否までを確認します。

// VS-RC003のシリアルを書き込み、ベリファイするスケッチ例
// シリアルでデータ書き込みコマンドを実行した後、該当箇所のデータを読み込んで、
// 書き込みが成功しているかを確認する。
// WRITE_MSG1で書き込み用のw文を指定し、
// WRITE_MSG2で書き込み検証用にデータを読み込むr文を指定する。
// 読み込みデータは#200...で始まるが、w 20..になるように書き換え、比較しやすくしておく。
// 書き込んだ文と読み込んだ文が合致して入れば、Verify OK!を表示する。

bool Loading = false; //必要データ読取中フラグ

String WRITE_MSG1 = "w 2009f6 01 00"; //書き込み用のライト文
String WRITE_MSG2 = "r 2009f6 02"; //検証用のリード文。該当アドレスから2バイト読み込む指示。

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

void loop() {
 char VSmsgs[64];// 読み取ったシリアルを入れる配列を宣言。
 Serial1.println(WRITE_MSG1);//書き込み用のライト文を送信。
 Serial.print("wrote:");//モニタ用。
 Serial.println(WRITE_MSG1);//モニタ用書き込んだ文字列を表示する。
 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;
     }
   }
   Serial1.println(WRITE_MSG2);//検証用のリード文
   delay(30);//このディレイが小さすぎると失敗しやすい。
   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.print("read :");
     Serial.println(VSmsgs);//モニタ用。読み込んだデータ(#をw に書き換えたもの)を表示する。
     String VSmsgssrg = VSmsgs;
     if (WRITE_MSG1.compareTo(VSmsgssrg)) {//書き込んだ文字列と読み込んだ文字列を比較する。
       Serial.println("Veriy OK!");
     } else {
       Serial.println("Write ERROR!");
     }
     Serial.println();
     delay (1);
   }
 }
}




こちらの実行結果は、


wrote:w 2009f6 01 00
read :w 2009f6 01 00
Veriy OK!

wrote:w 2009f6 01 00
read :w 2009f6 01 00
Veriy OK!
(以降くりかえし)


のように表示されます。




実際にロボットと接続してみて安定的に動くようであれば、ベリファイの部分を省略してしまうのもArduinoへの負担が減ってよいかと思います。
ついでにユーザー関数化やライブラリ化ができれば運用しやすいのですが、そのやり方はまだいまいちわかっていません><




これでついにVS-RC003&Arduinoのシリアル制御を完全攻略!
・・・ができたような気がします^^
ここまでできれば、SBDBTのファームを書き換えてVS-RC003に直付けすることもできてしまいそうです。
(これはライト級的に欲しい機能です。)
スポンサーサイト

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

VS-RC003変数番地計算機


VS-RC003の変数番号を、VS-RC003がシリアル受信で理解できる番地に変換するプログラムのarduino版です。
使いたい変数を設定したスケッチをArduinoにアップすると、シリアルモニタに答えを表示します。
あとで必要になりそうな単機能のスケッチです。




//使いたい変数番号を設定すると、PCのシリアルモニタに番地を
//教えてくれるスケッチ
//変数番号のアドレスへの換算方法は、
//16進数で、「200800 + 変数番号の2倍」

long val_num = 240;//いじりたい変数番号を設定。

void setup() {
 Serial.begin(115200);
}

void loop() {
 //変数番号を2倍して、200800を10進数換算をしたものを足す。
 val_num = val_num * 2 + 2099200;
 Serial.print(val_num, HEX);  //16進数で表示する。
 while (1);
}

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

シリアル検証スケッチ


VS-RC003のシリアル関連についてですが、前回のスケッチでは動くもののデータの切り出し方にちょっと無駄がありました。
シリアルの情報は公式に開示されているのですが、細かな点が素人にはちょっとわかりづらいです。
コールバック、#プロンプト、[CR]、[LR]の受信順について厳密に理解しておくため、改めて専用のスケッチを作って検証しておきたいと思います。いそがばまわれ。




使うのは例によってハードウェアシリアルの安定性も高いMEGAです。
Serial1のTX,RXピンをVS-RC003のRX,TXとそれぞれ繋ぎます。
LeonardoやMICROでもたぶん大丈夫だと思います。


//VS-RC003等から送られてくるデータの順番を可視化するプログラム。
//特例として、復帰記号[CR]は「C」、改行記号[LF]は「L」として可視化する。

int LEN = 128;//読み込むシリアル文字列の長さ。仮に決める。
String WRITE_MSG ="r 2009dc 04";//送信したいシリアル文字列はここで指定する。

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

void loop() {
 char VSmsgs[LEN];// 読み取ったシリアルを入れる配列を宣言。
 Serial1.println(WRITE_MSG);//こちらから送信するシリアル命令。
 delay(30);//このディレイが小さすぎると失敗しやすい。
 //if (Serial1.available() > 0 ) {
   for (int i = 0; i < LEN; i++) {
     char data = Serial1.read();
     if (data == 0x0d) {//受信した文字が復帰記号[CR]だったら配列に「C」を代入して可視化する。
       VSmsgs[i] = 0x43;
     }
     else if (data == 0x0a) {//受信した文字が改行記号[LF]だったら配列「L」を代入して可視化する。
       VSmsgs[i] = 0x4c;
     }
     else {
       VSmsgs[i] = data;//受信した文字が上記以外なら、そのまま配列に入れる。
     }
   }
 //}
 Serial.println("Arduino read...");
 Serial.println(VSmsgs);//取得データを表示。
 Serial.println("from Serial1.");
 Serial.println();
 delay (1000);
}




まず、読み込みのテストです。

r 2009dc 04[CR][LR]を送信すると、帰ってくるのは、

Arduino read...
r 2009dc 04C#L
from Serial1.

Arduino read...
r 2009dc 04C#L#2009dc 02 00 d2 0f CL
from Serial1.

Arduino read...
r 2009dc 04C#L#2009dc 02 00 d2 0f CL
from Serial1.
(以降繰り返し)

という結果になりました。
Cは[CR]、Lは[LF]を示します。
1発目はVS-RC003からの返信がこないことが多いので扱いに注意が必要ということがわかります。
最初の#は、VS-RC003からのコマンド受領合図です。[CR]を受け取るとまずこの#を返してきます。
また、2回目の#よりも前の文字列は、送信したコマンドのコールバック(受領したデータを一文字ずつ返してくる仕様)になりますので、データとしては不要なものです。
[LF]#と2バイト連なる文字列を受け取ってから、次の[CR]が来るまでの文字列を読み取るようにプログラムすれば、欲しいデータを切り出せそうです。



次に、書き込みのテストです。

w 2009f6 01 00を送信すると、帰ってくるのは、

Arduino read...
w 2009f6 01 00C#L
from Serial1.

Arduino read...
w 2009f6 01 00C#L
from Serial1.

Arduino read...
w 2009f6 01 00C#L
from Serial1.
(以降繰り返し)

という結果になりました。
書き込みコマンドを受領したVS-RC003は、[CR]を受け取ってすぐに#を返してくれることがわかります。
書き込みが成功しているかのチェックは、もう一度該当箇所を読み込んで比較するのが良さそうです。



そこで、書き込んだ後に読み込み実行するスケッチも簡易的に書いてみました。
こちらを実行すると、ずらずらと改行なしで結果を出力します。
どういう順番でシリアルが帰ってくるのでしょうか。


//VS-RC003等から送られてくるデータの順番を可視化するプログラム。
//特例として、復帰記号[CR]は「C」、改行記号[LF]は「L」として可視化する。

int LEN = 128;//読み込むシリアル文字列の長さ。仮に決める。
String WRITE_MSG1 = "w 2009f6 00 00"; //送信したいシリアル文字列その1を指定。
String WRITE_MSG2 = "r 2009f6 02"; //送信したいシリアル文字列その2を指定。
void setup() {
 Serial.begin(115200); // 115200bpsでPCモニタ用ポートを開く
 Serial1.begin(115200);// 115200bpsでVS-RC003通信用ポートを開く
}

void loop() {
 char VSmsgs1[LEN];// 読み取ったシリアルを入れる配列を宣言。
 Serial1.println(WRITE_MSG1);//こちらから送信するシリアル命令。
 delay(30);//このディレイが小さすぎると失敗しやすい。
 for (int i = 0; i < LEN; i++) {
   char data = Serial1.read();
   if (data == 0x0d) {//受信した文字が復帰記号[CR]だったら配列に「C」を代入して可視化する。
     VSmsgs1[i] = 0x43;
   }
   else if (data == 0x0a) {//受信した文字が改行記号[LF]だったら配列「L」を代入して可視化する。
     VSmsgs1[i] = 0x4c;
   }
   else {
     VSmsgs1[i] = data;//受信した文字が上記以外なら、そのまま配列に入れる。
   }
 }

 char VSmsgs2[LEN];// 読み取ったシリアルを入れる配列を宣言。
 Serial1.println(WRITE_MSG2);//こちらから送信するシリアル命令。
 delay(30);//このディレイが小さすぎると失敗しやすい。
 for (int i = 0; i < LEN; i++) {
   char data = Serial1.read();
   if (data == 0x0d) {//受信した文字が復帰記号[CR]だったら配列に「C」を代入して可視化する。
     VSmsgs2[i] = 0x43;
   }
   else if (data == 0x0a) {//受信した文字が改行記号[LF]だったら配列「L」を代入して可視化する。
     VSmsgs2[i] = 0x4c;
   }
   else {
     VSmsgs2[i] = data;//受信した文字が上記以外なら、そのまま配列に入れる。
   }
 }
 Serial.print(VSmsgs1);//取得データを改行なしで表示。
 Serial.print(VSmsgs2);//取得データを改行なしで表示。
 delay (100);
}



実行結果は、
w 2009f6 00 00C#Lr 2009f6 02C#L#2009f6 00 00 CLw 2009f6 00 00C#Lr 2009f6 02C#L#2009f6 00 00 CLw 2009f6 00 00C#Lr 2009f6 02C#L#2009f6 00 00 CL (以下繰り返し)
となります。

ここから上手に該当箇所を切り出すことができれば、ArduinoとVS-RC003は晴れて通信開通となる・・・はずです。
パズルゲームを遊んでいるようで、面倒ながらも楽しいです^^

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

VS-RC003→Arduinoのシリアル解読


以前挫折してほったからしになっていた案件。
ArduinoとVS-RC003の安定したシリアル通信について、突然思い立ってリベンジ中です。

前回の挫折からもう3年も経っているのが驚きです。
ブログではあまり書いてきませんでしたが言語の勉強はチクチクと進めており、C言語、RASPBERRY PI、ROS、LINUX、PYTHONなどの入門書を2冊ぐらいずつ読んだところです。入門書ばかりで何も身にはついていませんが、少しは理解力が向上していると信じたいです。




今回のリベンジでは純粋にソフトウェアのことに集中できるよう、万全を期してArduino MEGAを購入しました。
Arduino MEGAはやや高いのですがハードウェアシリアルを複数扱うことができます。
ハードウェアシリアルが複数あることで、115200のスピードでVS-RC003とのシリアル通信の実験をしながら、
同時にUSB経由でPCでモニンタリングもできるというわけです!
ハードウェアの限界に悩まされなければ、あとはソフトの話なのでパズルゲームのように楽しめるはず・・・です。




ArduinoからVS-RC003に命令を書き込む場合には、115200のスピードのシリアルで文字列を一方的に送りつければ済む話です。あとは安定性をアップさせるための仕掛けをいれれば大丈夫でしょう。

一方、読み取りの方はグッと難易度があがります。
今回はシリアルの読み取りから攻略してみます。




読み取りにはクリアすべきいろいろな難題があります。

・VS-RC003は送った命令をエコーバックしてくるが、データとの区別はどうするか?
・Arduinoが扱えるシリアルデータは1バイトずつだが、文字列のシリアルパケットをどう受け取るか?
・リトルエンティアンのビックエンディアンへの入れ替えは?
・ASCIIコードから16進数への変換は?
・16進数から10進数への変換は?

などなど。絡まったテグスを解きほぐすように、順番に解決していく必要があります。




さっそく、VS-RC003の信号をArduinoで読み取るためのスケッチを書いて見ました。
シリアル仕様マニュアルの例にもある電圧の読み取りに挑戦です。
作業の途中経過がわかるよう、

・読み取った信号
・該当箇所のデータをビッグエンディアンに変更したもの
・それを10進数に置き換えたもの
・さらに換算し、電圧の数値として読み取れるように直したもの

のそれぞれを表示するようにしてみました。




実際のコードです。


// VS-RC003のシリアルを読み取るプログラム作例
// rコマンドで読み出し命令を出し、結果を変数VSmsgsに入れて表示する。
// 例では、r 2009dc 04で電圧を読み取る。
// 2009dc 02 00 xx yy が読み出されるが、xx yy の部分が、該当の電圧データとなる。
// また、リトルエンディアンからビッグエンティアンへ、
// さらにアスキーコードの16進数を数値に変換し、10進数に換算する。
// ArduinoのTX,RX(MEGAなら18,19番ピン、LeonardoやMICROなら1,0番ピン)を
// VS-RC003のRX,TXにそれぞれ配線する。5VとGNDもそれぞれ接続する。
// ※ UNO系等ではハードウェアシリアル(Serial1.begin())が使えないので注意。

int vcc1, vcc2, vcc3, vcc4;// 換算用の変数を宣言。
bool ERR;// 読み取りエラーのフラグ用変数を宣言。

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

void loop() {
char VSmsgs[64];// 読み取ったシリアルを入れる配列を宣言。
Serial1.println("r 2009dc 04");//電圧を読み込む命令
delay(30);//このディレイが小さすぎると失敗しやすい。
if (Serial1.available() > 0 ) {
int i = 0; //文字配列カウンタ
int CRcounter = 0; //CR記号カウンタ。これが2回出たら1パケット終了。
int SHcounter = 0; //#記号カウンタ。これの2回目から本データ取得。(それまではエコーバックの文字列ということ。)
while (1) {
char data = Serial1.read();
VSmsgs[i] = data; //文字配列に文字を一個入れる。
i ++;
if (data == 0x23) { //#文字が出てきたら#カウンタを加算。
SHcounter ++;
if (SHcounter >= 2) {
i = 0; //#カウンタが2になったら、コールバック終了なので改めてデータを取る。
}
}
if (data == 0x0D) { //改行文字が出てきたらCRカウンタを加算。
CRcounter ++;
if (CRcounter >= 2) { //2回目の改行文字が出てきたら、データ取得完了し、換算と表示処理へ。
VSmsgs[i] = 0x00;//データにヌル終端を追加
Serial.println(VSmsgs);//取得データを表示。
Serial.print("Big endian : ");//以下、該当の電圧データをエンディアンを交換して表示する。
Serial.print(VSmsgs[16]);
Serial.print(VSmsgs[17]);
Serial.print(" ");
Serial.print(VSmsgs[13]);
Serial.println(VSmsgs[14]);
Serial.print("ASCII to HEX to DEC : ");

//以下、取得したASCIIコードを16進数に換算していく。
//その際、範囲にない文字であれば、エラーフラグを立てる。
if (VSmsgs[16] <= 0x2f) {//取得した文字が0よりも前の文字であればエラー。
ERR = 1;
}
else if (VSmsgs[16] >= 0x67) {//取得した文字がfよりも後の文字であればエラー。
ERR = 1;
}
else if (VSmsgs[16] >= 0x41) {
vcc1 = VSmsgs[16] - 0x57;//取得した文字がa以上であれば10からの数字に換算。
} else
{
vcc1 = VSmsgs[16] - 0x30;//それ以外であれば、0から9の数字に換算。
}

if (VSmsgs[17] <= 0x2f) {
ERR = 1;
}
else if (VSmsgs[17] >= 0x67) {
ERR = 1;
}
else if (VSmsgs[17] >= 0x41) {
vcc2 = VSmsgs[17] - 0x57;
} else
{
vcc2 = VSmsgs[17] - 0x30;
}

if (VSmsgs[13] <= 0x2f) {
ERR = 1;
}
else if (VSmsgs[13] >= 0x67) {
ERR = 1;
}
else if (VSmsgs[13] >= 0x41) {
vcc3 = VSmsgs[13] - 0x57;
} else
{
vcc3 = VSmsgs[13] - 0x30;
}

if (VSmsgs[14] <= 0x2f) {
ERR = 1;
}
else if (VSmsgs[14] >= 0x67) {
ERR = 1;
}
else if (VSmsgs[14] >= 0x41) {
vcc4 = VSmsgs[14] - 0x57;
} else
{
vcc4 = VSmsgs[14] - 0x30;
}

Serial.print(vcc1, DEC);//ビッグエンディアンに変更後の16進数を並べる。
Serial.print(" ");
Serial.print(vcc2, DEC);
Serial.print(" ");
Serial.print(vcc3, DEC);
Serial.print(" ");
Serial.println(vcc4, DEC);
Serial.print("VCC : ");
int vcc = vcc1 * 4096 + vcc2 * 256 + vcc3 * 16 + vcc4;//16進数を10進数に換算する。
Serial.print(vcc, DEC);//結果の数値を表示する。
Serial.println();
Serial1.flush();
break;
if (ERR = 1) {//取得データにエラーが出ていればエラーと表示する。
Serial.println("*** READ ERROR!! ***");
ERR = 0;
delay (100);
}
}
}
}
}
Serial.println();
delay (1);
}


実行結果は、PCシリアルモニタで見ると


2009dc 02 00 3c 0e
Big endian : 0e 3c
ASCII to HEX to DEC : 0 14 3 12
VCC : 3644

2009dc 02 00 33 0e
Big endian : 0e 33
ASCII to HEX to DEC : 0 14 3 3
VCC : 3635

2009dc 02 00 29 0e
Big endian : 0e 29
ASCII to HEX to DEC : 0 14 2 9
VCC : 3625
・・・


のような感じになります。
たぶん、結果の換算もうまくいっていると思います。

スケッチ文はかなり雑で下手くそですが、とりあえず基本ができてきたと思います。
これをベースに、使える関数にしていきたいと思います。

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

3Dプリンタのスイッチ位置変更


軽くエクササイズをしてからじゃないと電源を入れることができないという家電製品があったとしたら、買いますか?
私は買ってしまいました!




CUBIS 1.5 という3Dプリンタを使っていて機能的にもなかなか満足なのですが、気力が満タンの時以外はなかなかスイッチを入れる気がおきません。
スイッチを押すのが非常にめんどうなためです。

この3Dプリンタはメインスイッチが本体の裏側にあるのですが、都合により本体を机の下に設置してあります。
使うためには一度しゃがんだ上に身をよじった変な態勢のまま手探りでスイッチを探すという儀式を経なくてはならないのですが、これがちょっとしたエクササイズなのです。
無事にスイッチを入れた後、万力にガツンと後頭部をぶつけたりした日には作業をやめてふて寝するしかありません。




引越しにより置き場所を変えようとも、裏側スイッチの不便さは変わらないであろう!
と思えましたので、メインスイッチの位置を変更することにしました。
(※改造は大変危険なので自己判断でお願いします。通常の電子工作とは違い、交流を扱いますので特別な訓練を受けてない方や資格を持っていない方はこれ以上はやらないでください。ちなみに私は第二種電気工事士の資格を持っています。)




th_CIMG9009.jpg
CUBISのケースの底面のネジをすべて外し、ケースを取り外すと、スイッチの部分が露出します。
スイッチを押さえているパネルのネジをはずすと、スイッチを取り出すことが出来ます。




ぴったりのギボシを探すのも手間なので、スイッチのケーブルを途中で切断して延長します。
延長ケーブルをつかっての再接続時には、リングスリーブなどを使ってケーブル同士を圧着し、絶縁テープで養生しておきます。
電子工作ではハンダを使いますが、交流を扱う電気工事ではハンダは使わない方が安全です。




th_CIMG9011.jpg

スイッチを移設する場所にノコギリで穴をあけていきます。
ちょっと変な場所ですが、CUBISは全体的に丸みがあるので、スイッチがしっくり取り付けられる場所は限られます。
スイッチの幅ぴったりにしないとガバガバになってしまうので、この手の作業はいつも緊張します。




th_CIMG9012.jpg

本当は正面が理想的でしたが、サイドに取り付けてみました。
ぴったりとハマりました。とりあえずできあがりです^^




th_P1120145_20170420003547203.jpg

th_P1120146_2017042000354904b.jpg

ついでにCNCの箱のサイズ感を見るためにダンボールで囲ってみました。
動かしてみて問題がなければ家具を改造した「ミニ工場タワー」として再作成する予定です。(動かし方はまだ知らないです。)

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

道具のホームポジション設定


工作道具をどこに置いたか、どこにしまったか、本当によく分からなくなります。
ネットの検索のように、その道具を使いたいと思った時に散らかった部屋の中からパッと浮かび上がるというのが一番の理想ですが、そうもいきません。



th_P1120149_20170420003631c68.jpg

部屋の写真なのでものすごく恥ずかしいですが、道具や資材の棚のビフォーです。
100円ショップのポリプロの靴箱などにラベルを貼ってありますが、ラベリングできているのはほぼ資材のみです。
中身がなんとなく分かるように半透明のハコを使っていますが、道具等がいくつかのハコなどに分かれて収納されていたりするので、検索は記憶だのみです。

ロボット作りの資材がどういう規模になるのか分からないまま、ハコをその都度買い足していった結果、山積みになってしまいました。
棚がないので下のハコにあるものを取り出すときは上のハコを全部どかす必要があります><
下のハコにたどり着いたのに目的のものが出てこなかった時は、200ypほどゴッソリもっていかれます。(yp=やる気ポイントの略)

また、作業中はほとんどのハコが開いた状態になり机、床ともに埋まってしまい、メインの作業スペースがなくなってしまうという致命的な欠陥もあります。
さらに、100円ショップ製品なので、買い足すと規格がずれてサイズが揃わなくなるというのもジワジワypを削ってきます。
ここ数年間、そういう劣悪な環境で作業をしていました。仕事でヨレヨレになって帰ってからの作業となりますと、そりゃ開発スピードも遅くなるというものです。




リフォーム後のロボット資材容量の目安のために、引っ越し前ですが道具収納の部分だけでも進めてみます。
道具収納の改訂のポイントは、
・半透明がよい。中身が何となくわかるように。
・同一規格が長く続き、種類が豊富なこと。
・ラベルをつけられる。
・引き出し式が望ましい。
・引き出しはなるべく浅い方がよい。(物を重ねずに入れた方が探しやすい)
・道具ごとに引き出しを設定できる。
というものです。




th_CIMG9013.jpg

まだ途中ですがアフターです。
選んだのは無印のポリプロケースです。今後も長く同じ規格を続けてくれることを期待できそうなブランドです。
質感の割りに割高感は否めませんが、規格が続き、サイズが豊富に揃っていることも含めての価格だと自分に言い聞かせます。

「文具」とか「工具」のようなざっくりとした分け方ではなく、品目ごとに細かく分類し、ほぼ1対1で引き出しとラベルを用意してみました。それぞれの道具が帰るべき部屋、住所を持っているという感じになりました。

道具に住所が出来た結果、バツグンに検索性が向上しました。
ハサミを使おうと思った時に、ハサミと書いてある引き出しをあけるとそこにハサミがちゃんと入っているという気持ちよさ!
住所の中に道具が収まっていなければ、机の上あたりに必ず出ている、ということになるので、それも手がかりになります。
また、片付ける際にも、片付ける場所を考えなくてよいので、脳への負担が少なく快適です。




追加で考えている収納は、
・製作プロジェクトごとのケース
・作業中の物をとりあえず入れてしまえるごちゃ入れケース
・よく使う工具をまとめたスタメン道具格納所
などです。

面倒と思って後回しにし続けた収納計画も、いざやり始めてみると楽しいものです。

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

工作室はキッチンの叡知を借りて


最近はヒマな時間は購入した中古物件のリフォーム案の検討で時間がつぶれてしまっています。
リフォームの検討のためにはまず持ち物の棚卸しから!ということで泥縄的ですがいろいろと整理中です。




th_CIMG9014.jpg

自分の部屋が確保できたのでレトロゲームコレクションの収納庫付きのロボット工作部屋にする予定です。
作業場部分のコンセプトは「工作キッチン」。キッチンの機能的なレイアウトを紹介している本などを参考に、それを作業場に当てはめて考えています。
上の写真は「住まいの解剖図鑑」のキッチンのページです。料理の手順に合わせ、冷蔵庫→シンク→まな板→コンロという順番で配置するのがよいと書いてあります。なるほどなるほど。




ロボットや電子工作の場合は、
設計→切削/3D出力→板金/加工→半田付け/組み立て→塗装→動作テスト
のような順番かと思います。
料理同様、同時に行ったり行程を行ったり来たりもしますから、
理想論ですが、それぞれの行程についての作業場所が確保できていると便利そうです。




まず、CNCと3Dプリンタは細長いワードローブのような安物のロッカーに納めて、内側に防音ウレタンを貼るのがよいかなと思っています。そのロッカーにフィラメントやアルミ板といった関連物資も納めてしまい、「ミニ工場」にする予定です。
「ミニ工場」はキッチンで言えば電子レンジかオーブンのようなイメージですが、カタチは冷蔵庫っぽくなります。
プリンタがその近くにあっても良さそうです。

半田ごてなどを使う作業スペースはさしずめシンクで、メインの作業場所になりそうです。

削ったり板金をしたりするスペースはまな板でしょうか。すぐソバにPCも必要です。

「ミニ秋葉」と呼んでいる抵抗やコンデンサなどの棚は、キッチンで言えば冷蔵庫。メイン作業場の左側を考えています。

塗装はめったにやりませんが塗装ブースも必要です。この配置はちょっと困りものですね。

ロボットをテストする場所は配膳台のような役割でしょうか。とすると振り向いてすぐに作業できる場所がよさそうです。

道具の収納も重要です。頻繁に使うスタメンの道具は、収納方法は決まっていませんが1カ所にまとめておいた方が良さそうです。
工作のやる気を削ぐ原因の心のベストテン第一は、なんといっても「道具がすぐ見つからない!」ですから。

頻度の少ない道具にもホームポジションを与えておこうと思います。棚にラベルを貼ってそこにしか収納しないようにしておけば、出すのもしまうのもラクになるはず・・・と思っています。
引っ越し前ですが道具のホームポジション化を進めてみます。

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

ゼムネス新学期


th_P1090487.jpg

4月になりました。
競技デビューからもう6年目ですが、改めてゼムネスの自己紹介をしてみたいと思います。




th_P1090483_201704031706372ec.jpg


ゼムネスは市販二足歩行ロボットのロボゼロをベースとしてその応用範囲を広げた「汎用ヒト型決戦遊具」です。

1台のロボットで様々なロボット競技に出場し、遊び倒すことを目的としています。
二足歩行ロボットとしては一番物理的な制限の厳しい1kg以下級のクラスの機体ですが、各所にチューニングを施すことで、重量で格上の相手ともほぼ互角に試合を行うことができるほどになりました。

th_oshiri.jpg
ベース機体をリスペクトしつつも、ほとんどのパーツを再設計しています。






ヒト型レスキューコンテストで優勝したときの動画です。バトルでもいつか優勝したいです。




超合金玩具のように、変形合体的なお楽しみ要素もあります。
ゼムネスは出動する競技内容に合わせ、追加オプションやパーツの換装などにより、ゼムタンク、ゼムキャノンなどにモードチェンジすることが可能です。こんな玩具、子供の頃の自分に見せたら欲しすぎて卒倒すると思います。


71738cfc1da6f459.jpg
ゼムタンク。兵器感が強くちょっと怖いので最近は封印しています。ロボでサバゲという競技で電動ミニガンを放ちます。

th_CIMG8835_20170403170224461.jpg
ゼムキャノン。主にチロルチョコロボット大会の射的コーナーで活躍します。

rxsis_201704031703482b8.png
ベース機体を軸に発展させていくという初期に書いたプランを、ゆっくりと一つずつ実現しています。




操作にファミコン型のコントローラーを採用しているのも大きな特徴です。
現実世界という最高精度の物理エンジンを活用した新作ゲームというコンセプトで、レトロフューチャーな世界観を楽しんでいます。
ロボットの操作は複雑になりがちですが、ファミコン型のコントローラーは少ないボタンで1000以上ものゲームタイトルに対応している実績があります。そのノウハウを、ロボットの操作に応用しています。

バトル競技での楽しさはもちろん、複雑な動作が必要なレスキュー競技で優勝したことは、このコントローラーのポテンシャルの証明になったと言えると思います。


ちょっと古いですが、操作方法などの動画。



いろいろなコントローラをテストしている段階の動画。まだロボットのシステムはチューニング前で、動作も遅いです。




「子供の頃に欲しかった玩具」を大人になってから自分用に作ってみる。
そういう楽しみ方が、いまは比較的簡単に実現できる時代になっています。
一家に一台、自分だけの競技用ロボット。いかがでしょうか。楽しいですよ!
では競技会でおあいしましょう^^

th_tirol_201502152335509ee.jpg




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

DS Liteの修理


久々のゲーム機修理記事です。
DS Liteの上画面の調子が悪くなりました。しかも所持している2台がほぼ同時に故障しました。

電源投入直後はなんとか保つのですが、ほどなく画面に横線が入り見えなくなっていきます。
2台のうち1台は完全に液晶がつかなくなりました。




症状的にコンデンサの劣化かとは思うのですが、液晶基盤内部の抵抗だとすると交換は困難です。
1500円程度で液晶パーツが通販されているので、そちらを購入して交換修理することにしました。
分解方法は下記のブログに詳しいので参考にさせていただきました。
http://korujeri.web.fc2.com/DSlitebunnkaihouhou.html




液晶の交換なのでフレキをコネクタに差し替えるだけの簡単な作業かと侮っていたら、思わぬ難所が!
なんとフレキケーブルにスピーカーが半田付けされています。
フレキケーブルへの半田付けは、フィルムがすぐチリチリになるのでかなりの苦手意識があります。
そもそも半田でやるべきものなのかどうかもよくわかりません。できれば避けたいのですが。。。




th_P1120141.jpg

所持している中で最も低温の183度〜190度の低温はんだで挑戦です。
まずは古い液晶からスピーカーの配線を外します。
①はんだごての先端に半田を少量のせ、熱の伝達力を高めておき
②はんだごてを接点に近づけ、ピトッと半田が接点に吸着するなり配線を抜くっ!

というやり方でフレキにダメージを与えずに配線を外すことができました。

次に新しい液晶のフレキの半田づけです。
①はんだごての先端に半田を少量のせ、熱の伝達力を高めておき
②接点にはんだをのせっ!

というやり方で、はんだがのってくれました。
①→②の時間を最小にすると安全です。1秒ぐらいでパパッという感じでやります。
フレキの半田ポイント側は受け入れ体制バッチリのようで、もうすこしゆっくりでも熱に耐えそうです。

フレキに半田がのりさえすれば、あとは簡単です。また、①②のパターンを使ってスピーカーの線を接続します。
スピーカー側の線に半田があまり残っていなければ、少し半田をのせておくのも良いと思います。




th_P1120142.jpg

もう一方のスピーカー配線も無事完了!
怖がることはなかったです。




th_P1120143.jpg

ちなみにこのフレキを丸めて穴を通すときには、セロテープなどで筒状に仮止めしてから通すと楽に通ります。
LRボタンを組み立てる時なども、セロテープで固定すると組み立てやすいです。セロテープ最高です。




あとは組み立て直せば完成。
フレキをコネクタに挿す深さが足りないと、電源が正常に入りません。(一瞬下の画面だけパッと光ってすぐ消える症状。)
ヒューズが切れているだけという症状もありえるので、液晶交換の前にそちらをテストしてみるのもよさそうです。
ヒューズの位置は下記のブログが参考になります。
http://manbou.tea-nifty.com/blog/2009/08/post-d6d3.html




DSぐらい新しいものになると部品交換ですら細かくて大変です。
80年代のレトロ機が修理をしていてちょうどよく楽しいです^^

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

逆ガンダム


オルフェンズ。
ガンダム×任侠モノという雰囲気が強いですが、それ以上に初代ガンダムの要素をすべて逆にしてプロットし、それをつなぎ合わせたような構造が気になります。
ランバラル役、シャア役、ガルマ役がかなりそれと分かりやすい姿で登場したのは、そういう楽しみ方をしてくださいというメッセージだったのでしょう。初期からいわゆるフラグと呼ばれるお決まりの前触れ逆の結果を出してエンディングテーマへとつなぐ手法が頻発し、「フラグクラッシャー」という言葉もネットで見られるほど。オルフェンズは逆ガンダムとして認知されているものと思います。

そもそも初代ガンダムの要素ひっくり返して再構築する手法は小説版ガンダムやZガンダムから続く伝統だとは思います。ガンダムシリーズといえば決まって仮面のライバルが登場し、主人公は敵と恋に落ちるものです。しかし、今回は特にその度合いが強いと思います。ということは、初代ガンダムでの各キャラクターの結果が、該当するオルフェンズのキャラクターの行く末を暗示しているという面があると思います。さて、最終回はどうなるのでしょうか。

まず、ガンダムの要素がオルフェンズではどうひっくり返されてきたのか、分かりやすいところを並べてみたいと思います。


主人公:
アムロ→民間人が、成長するに従って人間兵器になっていく。敵と恋に落ちる。
三日月→人間兵器が、成長するに従って人間性を獲得していく。敵と恋に落ちない。

上司役:
ブライト→アムロの手なずけに苦心。UCシリーズに出続ける。
オルガ→最初から三日月の忠誠度100。

ヒロイン役:
セイラ、フラウ→主人公とくっつかない。
クーデリア、アトラ→両方とも主人公とくっつく?

アドバイザー役:
リュウ、ハヤト:リュウは途中退場。ハヤトはZまで残る。
ビスケット:リュウ役なので残ると思ったが・・・

三枚目役:
カイ:個人主義的、客観的、合理的。規律に合わず劇中で叩かれる。最後まで残る。
ザック:序盤は出ない。劇中で発言をほめられる。

理解あるいい敵役(六枚目):
ランバラル:若い主人公に負け、自害。
クランク:若い主人公に負け、自害できない。

シャア役:
シャア:主人公と敵対。ガルマを謀殺。主人公に執心。権威に刃向かう。
マクギリス:主人公と同盟。ガエリオを利用するが逆襲される。権威を欲しがる。
アイン:主人公に勝つことに執心。ガエリオにくっつく。

ガルマ役:
ガルマ:シャアに謀殺される。
ガエリオ:執心要素を取り込み、シャア役にしっぺ返し。

助っ人外人役:
スレッガー:経験豊富で頼りになる先輩。
ザック・ハッシュ:初心者で頼りにならない後輩。

輸送部隊:
マチルダ隊:女性が率いる補給部隊。
タービンズ:男性が率いる女性部隊。

金斗雲役:
Gファイター:あまり役に立たない。
クタン参型:ガンダムを遠方の前線に速達するという本懐を達成。

・・・みたいな感じです。細かいところはもっといっぱいあると思います。




さて、オルフェンズではどういうエンディングになるのでしょう。
初代ガンダムでは主人公を含む最終話付近の主要メンバーが全員生き残り、連邦軍の勝利となったわけですが、その逆となると・・・。
よい読後感になる作者のさじ加減を祈ります。


続きを読む

テーマ : ひとりごと
ジャンル : 学問・文化・芸術

プロフィール

二名川(ニナガワ)

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 ゼロライナー
以下続く

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