tagCANDY CGI VBレスキュー(花ちゃん) の Visual Basic 2010 用 掲示板(VB.NET 掲示板) [ツリー表示へ]   [Home]
一括表示(VB.NET VB2005)
タイトルVB2005でバイナリデータをシリアル通信
記事No9720
投稿日: 2009/12/15(Tue) 16:40
投稿者ロージー
初めまして、VB2005を始めて4ヶ月程の者です。
いつもこちらの掲示板を参考にさせていただいてます。

現在、無線機(IC910D)にコマンドを送り周波数を変更するプログラムを作っています。
コマンドを配列に格納し、バイナリデータとしてRS232Cケーブルを経由し送信するというものです。

色々と見ていたら
SerialPort.Write メソッド (Byte[], Int32, Int32)
を用いるのが適切ということですので、こちらを使用しているのですが、なかなか上手くいきません。

コードは全て載せるのは不適切かと思いますので、バイナリデータを送信する箇所のみ載せます。
また、載せるか迷いましたが、周波数データの設定のプログラムは、無線機にデータを送る際、 12345678 → 78563412 という形式にする必要があるため、そのような処理を行っています。


書き込み自体が初めてなので、不備などがあるかと思いますが、どうぞよろしくお願いいたします。


'*************以下コード**************


    '無線機の周波数設定コマンドを送信するプロシージャ
    Sub SendComPort_Ic910(ByRef Frequency As Double)
        '変数宣言
        Dim CH(99) As String '10進数を16進数に変換する配列
        Dim m, n As Byte 'カウンタ
        Dim k As Short 'カウンタ
        Dim frequency2 As Object '周波数を入れる変数
        Dim DA As Object 'データを入れる変数
        Dim bytOut() As Byte

        '無線機に送信するデータを入れる配列

        '10進数を16進数に変換する配列CH()を設定する.
        For m = &H0S To &H9S
            For n = &H0S To &H9S
                CH(&HAS * m + n) = Chr(&H10S * m + n)
            Next n
        Next m

        frequency2 = VB.Right("00000" & Mid(Str(CInt(Frequency * 1000000.0#)), 2), 10)

'周波数データの設定
        For k = 1 To 10 Step 2
            DA = CH(Val(Mid(frequency2, k, 2))) + DA
        Next k

        bytOut = System.Text.UnicodeEncoding.Unicode.GetBytes(Chr(&HFE) & Chr(&HFE) & Chr(&H60) & Chr(&HE0) & Chr(&H5) + DA + Chr(&HFD)) '送信コマンド [ FEFEE005(周波数データ)FD ]

        SerialPort1.Write(bytOut, 0, bytOut.Length)

'************End**************

[ツリー表示へ]
タイトルRe: VB2005でバイナリデータをシリアル通信
記事No9722
投稿日: 2009/12/15(Tue) 20:00
投稿者オショウ
> 色々と見ていたら
> SerialPort.Write メソッド (Byte[], Int32, Int32)
> を用いるのが適切ということですので、こちらを使用しているのですが、なかなか上手くいきません。

  どう、うまくいかないのか、解りません・・・

  しかしながら、推測するに、バイナリデータを送信するところ
  わざわざUnicodeEncodingしているのが間違いかと・・・

  bytOut配列にそのまま値を代入して送信すればOKかと・・・

以上。参考まで

[ツリー表示へ]
タイトルRe^2: VB2005でバイナリデータをシリアル通信
記事No9724
投稿日: 2009/12/16(Wed) 02:59
投稿者ロージー
オショウさん、返信ありがとうございます。


>   どう、うまくいかないのか、解りません・・・
すみません、確かに不足してますね。

プログラム自体は実行出来るのですが、目標である無線機の周波数が変わらないという状況です。
bytOut配列に格納する箇所が間違っているのか、シリアルポートにWriteする箇所が間違っているのか、それとも根本的に何かが違うのか…という所で悩んでました。


>   bytOut配列にそのまま値を代入して送信すればOKかと・・・
アドバイスありがとうございます。
ただいま掲示板を確認せず帰宅してしまったので(自宅PCでプログラムが出来ないため)、また明日その箇所を色々変更して実行してみようと思います。

[ツリー表示へ]
タイトルRe^2: VB2005でバイナリデータをシリアル通信
記事No9731
投稿日: 2009/12/17(Thu) 02:26
投稿者ロージー
何度もすみません。

>   bytOut配列にそのまま値を代入して送信すればOKかと・・・
bytOutがByte型なのでString型は入れれないということでエラーが返ってきます。。

そして、今さらなのですが、現在書いているプログラムには元のコード(私が作ったものではないです)があります。
VB6のコードなのですが、これをVB2005に修正したいと考えています。

ようやく探しあてて変換(アップグレード?)前のコードを表示できるようになったのでこちらを示します。


色々と見てきましたが、ChrB$の箇所がどうも上手く書き換えられない状況です。
他も間違っている箇所があるかもしれませんので、合わせてご教示願いたいです。



'******元のコード(VB6)******
Sub SendComPort3WFForward(Frequency As Double)
    '変数宣言
    Dim CH(0 To 99) As String    '10進数を16進数に変換する配列
    Dim m As Byte, n As Byte     'カウンタ
    Dim k As Integer             'カウンタ
    Dim fre As Variant           '周波数を入れる変数
    Dim DA As Variant            'データを入れる変数
    Dim bytOut() As Byte         '無線機に送信するデータを入れる配列
    
    '10進数を16進数に変換する配列CH()を設定する.
    For m = &H0 To &H9
      For n = &H0 To &H9
        CH(&HA * m + n) = ChrB$(&H10 * m + n)
      Next n
    Next m

    fre = Right$("00000" + Mid$(Str$(CLng(Frequency * 1000000#)), 2), 10)
    For k = 1 To 10 Step 2
      DA = CH(Val(Mid$(fre, k, 2))) + DA
    Next k

    bytOut() = ChrB$(&HFE) + ChrB$(&HFE) + ChrB$(&H60) + ChrB$(&HE0) _
             + ChrB$(&H0) + DA + ChrB$(&HFD)   '←ここが問題かと思います。
    msSerialRadio.Output = bytOut
End Sub




よろしくお願いいたします。

[ツリー表示へ]
タイトルRe^3: VB2005でバイナリデータをシリアル通信
記事No9734
投稿日: 2009/12/17(Thu) 09:52
投稿者GOD
>     bytOut() = ChrB$(&HFE) + ChrB$(&HFE) + ChrB$(&H60) + ChrB$(&HE0) _
>              + ChrB$(&H0) + DA + ChrB$(&HFD)   '←ここが問題かと思います。
>     msSerialRadio.Output = bytOut
>
とりあえず固定値を送信できることを確認した方が良いですよ。
例えば、ボタンをクリックしたら100kHzのデータを送るとか。
↓プログラムの N 部分は 必要な数値に置き換えてください。
「'bytOut(5) 〜 bytOut(N)  <--- 100kHzの周波数データ」は私にはどう変換してよいか
わからないので補完してください。

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    Dim bytOut() As Byte = New Byte(N + 1) {}

    bytOut(0) = &HFE
    bytOut(1) = &HFE
    bytOut(2) = &H60
    bytOut(3) = &HE0
    bytOut(4) = &H0
    'bytOut(5) 〜 bytOut(N)  <--- 100kHzの周波数データ
    bytOut(N + 1) = &HFD
    SerialPort1.Write(bBuf, 0, bBuf.Length)
End Sub

[ツリー表示へ]
タイトル解決いたしました、本当にありがとうございました。
記事No9738
投稿日: 2009/12/17(Thu) 18:18
投稿者ロージー
アドバイス下さった方々へ。
ありがとうございました、なんとか解決いたしました。

原因はBaudRateの値が一致していないという根本的な所でした。。。
1ヶ月半もそこに気づかなかったのが情けなく半べそでした。


GODさん、返信ありがとうございます。
> とりあえず固定値を送信できることを確認した方が良いですよ。
> 例えば、ボタンをクリックしたら100kHzのデータを送るとか。

分かりやすいコードを示していただきありがとうございます。
確かに最初からやろうとしていたのは良くなかったですね。
今後は手順を踏んでコード作成していこうと思います。


魔界の仮面弁士さん、返信ありがとうございます。

>  9876.987654 → エラー("9876987654" にならない)
これは型の数の限界を超えるからという認識でよろしいでしょうか?
おっしゃている通り、そこまで値は大きくならないので大丈夫です。

> ごっそり書き替えてみました。
わざわざありがとうございます、本当に助かります。
>'Debug.WriteLine(BitConverter.ToString(data.ToArray()))
これで見ることが出来るのですね、今までSystem.byte[]のような形で見ることが出来なかったので勉強になります。

コマンドに関してですが
> というコードがありましたよね。ここで &H60 が登場しているのは何故でしょうか?
こちらは私のコメント欄への入力ミスです、気づいてませんでした、しっかり確認してから書きこむように致します。

データの食い違いに関してですが、こちらはコピーしてくるコードを間違えていました。
別のコマンドの分をコピーしていたようです。


以上です、ありがとうございました。

[ツリー表示へ]
タイトルRe^3: VB2005でバイナリデータをシリアル通信
記事No9735
投稿日: 2009/12/17(Thu) 10:19
投稿者魔界の仮面弁士
> VB6のコードなのですが、これをVB2005に修正したいと考えています。
元のコードからして、実装が怪しい気がします。

たとえば、Frequency → fre の変換処理の部分では、現在の実装では
    0.000012 → "0000000012"
 1234.987654 → "1234987654"
 9876.987654 → エラー("9876987654" にならない)
となってしまいます。
まぁ、そういう値が来る事は無いのかも知れませんが。


> 色々と見てきましたが、ChrB$の箇所がどうも上手く書き換えられない状況です。
> 他も間違っている箇所があるかもしれませんので、合わせてご教示願いたいです。
ごっそり書き替えてみました。

Dim fre As String = Math.Abs(Frequency * 1000000).ToString("0000000000")

'送信コマンド [ FEFE60E005(周波数データ)FD ]
Dim header() As Byte = {&HFE, &HFE, &H60, &HE0, &H5}
Dim footer() As Byte = {&HFD}

Dim data As New List(Of Byte)()
For i As Integer = 1 To fre.Length Step 2
    data.Insert(0, Convert.ToByte(Mid(fre, i, 2), 16))
Next

data.InsertRange(0, header)
data.AddRange(footer)

'Debug.WriteLine(BitConverter.ToString(data.ToArray()))
SerialPort1.Write(data.ToArray(), 0, data.Count)


なお、変数 header/footer の内容が違うようなら、適宜書き換えてください。

何が正しいのか良く分からないのですが、 No9720 を見ると、
> '送信コマンド [ FEFEE005(周波数データ)FD ]
というコメントと
> Chr(&HFE) & Chr(&HFE) & Chr(&H60) & Chr(&HE0) & Chr(&H5) + DA + Chr(&HFD)
というコードがありましたよね。ここで &H60 が登場しているのは何故でしょうか?

一方、 No9731 については、
> ChrB$(&HFE) + ChrB$(&HFE) + ChrB$(&H60) + ChrB$(&HE0) + ChrB$(&H0) + DA + ChrB$(&HFD)
です。

No9720 の VB.NET 版のコメントを見る限りでは、
  FE,FE,E0,05,(周波数データ),FD
というデータ列を期待しているようですが、実際の VB.NET コードでは、
  FE,FE,60,E0,05,(周波数データ),FD
というデータを作ろうとしているかのように見えますし、No9731 の VB6 版では、
  FE,FE,60,E0,00,(周波数データ),FD
というデータを送出しており、それぞれで、データが食い違っているようです。

[ツリー表示へ]