イメージ 1

イメージ 2

シリアル通信による八重洲無線機FT-1000MPの周波数を読み取るプログラムにトライしてみた。とにかくVisualC++2010Expressは型変換については厳しい。単純にいって、私の場合は型変換エラーがほとんどを占めています。とは言っても学習しながらだからしょうがないか?。無線機の周波数を読み取るためのデータのやり取りは基本的にバイトデータにて処理を行っています。このためバイトデータから他の型への変換がかなりあります。桁処理もあるし、このため型変換で使うarray配列もかなり使用することになりました。VisualBasic2008Expressのように単純にString配列のみですべてコーディングとはいかない。とにかく今まで出したエラーは型変換が一致していないためのエラーがほとんどだ。がしかし一度変換方法がうまく設定できると後は、応用ができる。ここまでくる過程が実は一番楽しいところである。前置きはこれぐらいにして、本題だが、基本はモード変更と同じくパラメータとコマンドをRS-2323Cで無線機に送ることが最初のステップである。FT-1000MPの場合はCATコントロールコマンド表の中で言うと、No.14のコンファーム・リクエストである。
10,P1, ※ , ※ ,P4
がコマンドとパラメータ構成で表示データ読み出しなのでP1が02、P4はにメモリ読み込みは使わないので 00にする。
10,02,00,00,00
が対応するパラメータコマンドとなる。まずはこれを今回は関数化したft-1000mpcomを使わずに直接書いてゆきます。これは周波数読み取りのコマンドボタンに対応させますが、タイマーコントロールを用意して、このボタンをコールし、タイマーインターバル間隔で連続読み取りにしてゆきます。
データは上記のcntcomdat="1002000000"をセットし、各シリアルポート条件を設定しポートを開きます。その後送るデータを加工して、_serialPort1->Write(kako,0,comlength);で送出します。ここからがシリアルポートへのコンファーム・リクエストコマンドによるデータの読み出し処理となります。最初のトラブルは、次の一行でデータを一回で読み取れると思っていたのですが、デバッグ状態ではうまく全部読み取れますが、ブレークポイントを全てはずすとたった1バイトしか読み出せない状況となりました。原因は不明です。
--------------------------------------------------------------
serialPort1->Read(bin,0,16);
--------------------------------------------------------------
なので上記の方法は止めて、1バイト読みする方法をとりデータ数分のループを行い全部のデータを取り込む方法へ変更しました。なお既定のバッファサイズは4096ですが、今回のデータでは16個(16バイト)なので以下のように設定しループで読み取っています。
--------------------------------------------------------------
int aa=16;
int ac=0;
for(ac=0 ; ac<=aa-1 ;ac++){
bin[ac]=_serialPort1->ReadByte();
}
--------------------------------------------------------------
ここで上記のbin[]にバイトデータで周波数データが16個入ります。
ここまでくれば安心します。周波数のデータかどうかはわかりませんが、データらしきものが取得できているという事が、とてもうれしくなります。
次は上記の読み取ったデータ郡を16進の文字に変換します。変換したデータは1桁と2桁になるため、常に2桁になるように1桁の場合には"0"をつけてあらためて書き直します。ここが意外と何でかという疑問がわいてきますが、周波数の算出にかかわるということがあるために必要な処理ということになります。16バイトのデータ中の1から4までのバイナリーとしての範囲は00027100~02DC6C00(Hex) LSB=0.625Hz(step)となっています。これは10進で160000~48000000(10進)ステップの0.625Hzをかけると 100000~30000000とFT-1000MPの受信周波数範囲単位(Hz)となることより16進の4バイトのデータがフルでいることがわかります。ここで1バイトとは8ビットのことです。16進でたとえば1だとすると2進の4ビットで0001ですが、データとしては1バイト必要ですから実際は上位の4ビットが必要になるわけです。0000と0001で全部で8ビットの1バイトということです。ここで1桁のデータには0をつける必要が出てくるのです。1(hex)のデータは 01(hex)ということです。ということで周波数の計算も上記の各4バイトのデータ値の合計を求めて0.625をかけることで周波数がHz単位で求まることがわかります。つまり2バイト目からのデータが4バイト分周波数データなので、周波数の4ビット毎の各桁の値(10進値)に重みデータにかけて値を出しそれぞれを和算してから0.625をかけることになります。
重みをかける16進値は文字から次の変換で10進化しておきます。以下にここの関係するコードを記します。
-------------------------------------------------------------------
array<String^>^binasc=gcnew array<String^ >(16);
int abc=0;
for (abc=0 ; abc<=aa-1 ;abc++){
binasc[abc]=bin[abc].ToString("X");
//  binasc[abc]=String::Format("{0:x}",bin[abc].ToString("X"));//これもOK
  }
int lenasc;
int abc1=0;
for (abc1=0 ; abc1<=aa-1 ; abc1++){
lenasc=binasc[abc1]->Length;
if( lenasc==1 ){
binasc[abc1]="0" + binasc[abc1];
}else{
binasc[abc1]=binasc[abc1];
}
}
array<String^>^KRE=gcnew array<String^ >(16);
Array::Copy(binasc,KRE,binasc->Length);// 配列をbinascからKREへコピーする
String^ WAKRE;//2桁ずつのデータをすべて連結しいれるための変数

WAKRE = (KRE[0]+KRE[1]+KRE[2]+KRE[3]+KRE[4]+KRE[5]+KRE[6]+KRE[7]+KRE[8]+KRE[9]+KRE[10]+KRE[11]+KRE[12]+KRE[13]+KRE[14]+KRE[15])->ToString();

//周波数計算
array<String^>^LRE=gcnew array<String^ >(32);
array<String^>^NRE=gcnew array<String^ >(32);
//一文字ずつ分けてLRE[31]配列にいれる
int abc2=0;
int ab=32;
for (abc2=0 ; abc2<=ab-1 ;abc2++){
LRE[abc2]=WAKRE->Substring(abc2,1);
}

//値変換10進にもどす
array<int^>^SUCHI=gcnew array<int^ >(32);
int abc3=0;
for (abc3=0 ; abc3<=ab-1 ; abc3++){
SUCHI[abc3]=(Int32::Parse(LRE[abc3], System::Globalization::NumberStyles::HexNumber));
}

int GOUKEI;
int VALSUCHI[10]; //10進化
VALSUCHI[0]=(Int32::Parse(SUCHI[0]->ToString()));// NO USE
VALSUCHI[1]=(Int32::Parse(SUCHI[1]->ToString()));// NO USE
VALSUCHI[2]=(Int32::Parse(SUCHI[2]->ToString()));
VALSUCHI[3]=(Int32::Parse(SUCHI[3]->ToString()));
VALSUCHI[4]=(Int32::Parse(SUCHI[4]->ToString()));
VALSUCHI[5]=(Int32::Parse(SUCHI[5]->ToString()));
VALSUCHI[6]=(Int32::Parse(SUCHI[6]->ToString()));
VALSUCHI[7]=(Int32::Parse(SUCHI[7]->ToString()));
VALSUCHI[8]=(Int32::Parse(SUCHI[8]->ToString()));
VALSUCHI[9]=(Int32::Parse(SUCHI[9]->ToString()));
--------------------------------------------------------------------------------
上記の16バイト中の+0のVALSUCHI[0]とVALSUCHI[1]の1バイト分はBANDNO:+1ら+4の周波数が属するバンドなので今回は使いません。周波数データであるVALSUCHI[2]~VALSUCHI[9]までの4バイトが計算で使う値となります。ほかの16バイト中のデータには+5、+6の2バイトがCLARF、+7の1バイトがモード(0=LSB,1=USB,2=CW,3=AM,4=FM,5=RTTY,6=PKT),+8がFILT(省略)、+9がFLAG、他+Aから+Fまでは未使用と割り当てられています。今回は上記の+1から+4に相当する部分だけ使います。
--------------------------------------------------------------------------------
5000文字制限のためこの続きは次にまわします。つづく