tagCANDY CGI VBレスキュー(花ちゃん)の Visual Basic 6.0用 掲示板 [ツリー表示へ]   [Home]
一括表示(VB6.0)
タイトルMScommの通信について
記事No15474
投稿日: 2012/05/31(Thu) 19:38
投稿者ミロク
お疲れ様です。VB6初心者です。色々調べたのですがわからなかったので教えてください。

VB6を使用して相手側の装置から16進数のデータを受信したいのですがうまくいかないので教えてください。

受信データ(0xFE,0x00,0x00,0x02,0x01......(20〜30Byte?))を受信しています。

受信コード
MSComm.InputMode = comImputModeBinary

Dim Buffer() As Byte

Buffer = MSComm.Input
MsgBox= Hex$(Buffer(0)) 表記ーF3(FEと表記したいです)
MsgBox= Hex$(Buffer(1)) 表記ーF8(00と表記したいです)


後、16進数で送信するとき(&HFF)を送信すると相手側が7Fになってしまいます。なぜでしょうか?
送信コード
Dim Buffer(20) As Byte
Buffer(0) = &HFF  相手側-7F
Buffer(1) = &H0     -00
Buffer(2) = &H0      -00
Buffer(3) = &H0      -00
Buffer(4) = &H2      -02
Buffer(5) = &H0....
MSComm.Output = Buffer
で相手側に送信しています。

宜しくお願い致します。

[ツリー表示へ]
タイトルRe: MScommの通信について
記事No15475
投稿日: 2012/05/31(Thu) 22:41
投稿者魔界の仮面弁士
> なぜでしょうか?
MScomm は専門外ゆえ、すぐには思い当らないのですが、まずは確認事項の1つとして、
OnComm イベント内で、CommEvent プロパティを Debug.Print するようにしておき、
何か異常が検出されていないかをチェックしておいては如何でしょう。


> 受信データ(0xFE,0x00,0x00,0x02,0x01......(20〜30Byte?))を受信しています。
文字化けしていますが、〜 は、"WAVE DASH" の文字ですね。


> MsgBox= Hex$(Buffer(0)) 表記ーF3(FEと表記したいです)
> MsgBox= Hex$(Buffer(1)) 表記ーF8(00と表記したいです)
文法的なミスにはとりあえず目を瞑るとして。

Buffer の中身は、すでに化けてしまっているようですね。
バイナリでは無く文字列として受信されれば、そういう化け方になりそうです。

まさか comInputModeText に戻しているわけでも無いでしょうし、
Settings プロパティの指定が適切でないとか…でしょうか(適当)。


ちなみに、当方(Win7)、強制的に vbUnicode 変換してみたら、
『FE 00 00 02 01』であったデータの内容が
『F2 F8 00 00 00 00 02 00 01 00』に化けました。

現象としては近いですが… F3,F8 ではなく F2,F8 ですね。関係ないのかな。

'----------------------------
Dim bin() As Byte, v As Variant
bin = ChrB(&HFF) & ChrB(&H0) & ChrB(&H0) & ChrB(&H2) & ChrB(&H1)
For Each v In bin
    'この時点では化けていない: FF,00,00,02,01
    Debug.Print " "; Hex(v);
Next
Debug.Print Tab(30); "Original"

bin = StrConv(bin, vbUnicode)
For Each v In bin
    'この時点では化けている: F3,F8,00,00,00,00,02,00,01,00
    Debug.Print " "; Hex(v);
Next
Debug.Print Tab(30); "String"
'----------------------------

[ツリー表示へ]
タイトルRe: MScommの通信について
記事No15476
投稿日: 2012/05/31(Thu) 22:43
投稿者オショウ
> お疲れ様です。VB6初心者です。色々調べたのですがわからなかったので教えてください。
> VB6を使用して相手側の装置から16進数のデータを受信したいのですがうまくいかないので教えてください。

  シリアル通信のデータビット数・パリティービット数・ストップビット数
  が、装置側の仕様と合致していますか?

  バケ具合からボーレートは合っていると思われますが・・・

以上。

[ツリー表示へ]
タイトルRe^2: MScommの通信について
記事No15478
投稿日: 2012/06/01(Fri) 11:45
投稿者ミロク
魔界の仮面弁士さん、オショウさん、
ありがとう御座います。
相手側への送信文字化けについては、シリアル通信のデータビット数・パリティービット数・ストップビット数の修正により解決致しました。

受信に関してなのですが、
魔界の仮面弁士さんカラ教えて頂いた通りに確認してみたのですが、
Dim bin() As Byte, v As Variant
bin = ChrB(&HFF) & ChrB(&H0) & ChrB(&H0) & ChrB(&H2) & ChrB(&H1)
For Each v In bin
    'この時点では化けていない: FF,00,00,02,01
    Debug.Print " "; Hex(v);
Next
Debug.Print Tab(30); "Original"
は問題なく表記できました。

受信したデータで下記のように確認してみたら、
Dim bin() As Byte, v As Variant
bin = MSComm.Input

For Each v In bin
    この時点では化けしてしまいました: F3,F8,00,00,00,00,02,00,01,00
    Debug.Print " "; Hex$(v);
    
Next
Debug.Print Tab(30); "TEST"

理解力が乏しくて大変申し訳御座いません。
間違いのご指摘を宜しくお願い致します。

備考-受信側送信側のPCともにWin7です。
   > 現象としては近いですが… F3,F8 ではなく F2,F8 ですね。関係ないのかな。
   ご指摘の通りでした。

[ツリー表示へ]
タイトルRe^3: MScommの通信について
記事No15479
投稿日: 2012/06/01(Fri) 13:08
投稿者魔界の仮面弁士
> データビット数・パリティービット数・ストップビット数の修正により解決致しました。
おぉ、良かったです。


> 魔界の仮面弁士さんカラ教えて頂いた通りに確認してみたのですが、
ごめんなさい、コードそのものの内容については忘れてください。

あれは、そういう変換を行う必要があるという意味ではなく、どちらかといえば逆で、
あれと同じような誤変換が、どこかで間違って発生しているかも、という程度の話です。


---------- 以下、超蛇足 ----------

そもそもは、問題箇所の切り分けが必要と思い、頭の中で

(1)環境依存性(OSやハードなど)
 (1.1)他のOSで実行して再現するか?
 (1.2)ハードウェアの交換で結果が異なるか?
(2)再現性
 (2.1)特定のデータだけで再現するのか?
 (2.2)化け方は一定か、同じデータでも化け方が異なることがあるか?
(3)利用方法
 (3.1)コントロールの使い方や設定に問題は無いか?
 (3.2)コントロールは正常でも、受信データの確認方法が間違っていたりはしないか?

という回答手法を描いたのですが、まず、(3.2) は問題が無さそうだと思いました。

あの場合の Hex 関数が、文字化けを誘発させることは考えられないので、そうすると
>> Buffer の中身は、すでに化けてしまっているようですね。
であろうと判断しました。


次に(3.1)の利用法ミスの可能性ですが、化けた理由を考えるにあたり、最初に疑ったのが
「Binary ではなく Text で扱われているのではないか」という仮説でした。
そのために、とりあえず StrConv する実験コードで化け方を比較してみた、
というのが先のコードです。

仮に同じ化け方になるようなら、InputMode 指定が Text になっているか、または
受信時の変数の受け方(String 変数で受けるなど)に問題があることになりますので。

ところが、結局は異なる化け方でしたし、受信コードも
>>> MSComm.InputMode = comImputModeBinary
>>> Dim Buffer() As Byte
>>> Buffer = MSComm.Input
であれば問題無さそうなので、実際には、あのコードは
完全に蛇足だったわけです。混乱させて済みません…。


で、Text 以外で可能性がありそうだと思い当たったのが、通信設定のミスであり、先の
>> Settings プロパティの指定が適切でないとか
という回答の部分になります。

とはいえ、私は通信系・制御系には疎いので、具体的な情報が出せるわけでは
ありません。そのため先の回答では
>> …でしょうか(適当)。
といった逃げ口上を書いていたりします。

通信系の話題だったので、ここの常連者回答者のオショウさんであれば、
きっと具体的な話もできるのだろうな……とは密かに思っていたのですが、
あの時点ではまだ誰も回答をつけていない状態だったので、とりいそぎ
投稿してみました。ですが、投稿内容の見直しも不十分だったので、
かえって混乱させてしまったかも知れませんね。失礼しました。

# 実際には、ほぼ同時にオショウさんの回答もついていたし。orz

[ツリー表示へ]
タイトルRe^4: MScommの通信について
記事No15480
投稿日: 2012/06/01(Fri) 15:58
投稿者ミロク
魔界の仮面弁士さんありがとうございます。
ご丁寧にご説明頂き感謝致します。

> (1)環境依存性(OSやハードなど)
>  (1.1)他のOSで実行して再現するか?
>  (1.2)ハードウェアの交換で結果が異なるか?
> (2)再現性
>  (2.1)特定のデータだけで再現するのか?
>  (2.2)化け方は一定か、同じデータでも化け方が異なることがあるか?
> (3)利用方法
>  (3.1)コントロールの使い方や設定に問題は無いか?
>  (3.2)コントロールは正常でも、受信データの確認方法が間違っていたりはしないか?

上記に関して再度調べて確認をしてみます。

何か情報が御座いましたら教えて頂けたら幸いです。
宜しくお願い致します。

[ツリー表示へ]
タイトルRe^3: MScommの通信について
記事No15481
投稿日: 2012/06/01(Fri) 16:02
投稿者オショウ
> 受信したデータで下記のように確認してみたら、
> Dim bin() As Byte, v As Variant
> bin = MSComm.Input
>
> For Each v In bin
>     この時点では化けしてしまいました: F3,F8,00,00,00,00,02,00,01,00
>     Debug.Print " "; Hex$(v);
>    
> Next
> Debug.Print Tab(30); "TEST"

  わざわざVariantに代入するのが間違いかと。

  For i as Integer = 0 To bin.Length() -1
      Debug.Print " ";Hex$(bin(i));
  Next

  とかにしてやったら、結果どうなりますか?
  bin = MSComm.Input
  の直後にブレークポイントを置いて、binの中身を直接ウォッチしたら
  正しいのは確認済ですよネ?!

※ ソースコードは、直接書いたので間違いがあったらご容赦
  意味は解っていただけますよネ?・・・

以上。

[ツリー表示へ]
タイトルRe^4: MScommの通信について
記事No15482
投稿日: 2012/06/01(Fri) 17:19
投稿者ミロク
オショウさんありがとう御座います。
自分の理解出来てる範囲で確認してみました。

MSComm.InputMode = comImputModeBinary

Dim bin() As Byte
Dim i As Integer

;相手側より0xFE,0x00,0x01,0x00,0x02を送信
;同時にシリアルのモニタリングのソフトで受信を確認してみたところ-FE 00 01 00 02
bin = MSComm.Input

MsgBox Hex$(bin(0))-F2
MsgBox Hex$(bin(1))-F8
MsgBox Hex$(bin(2))-エラー
MsgBox Hex$(bin(3))
MsgBox Hex$(bin(4))

  ;上記メッセージボックスを消して見たところループ3回目でエラーLogにはF2 F8と記載                                 されていました。
    For i = 0 To 5 ※ 0 To bin.Length() -1はデバグしてしまい原因がわからなかったの           でダイレクトに値を入れて回しました。
        Debug.Print " "; Hex$(bin(i));
        
    Next

非常に説明が下手と知識不足で申し訳御座いません。
こんな感じの結果でした。XPのPCでの通信もしてみます。
お手数お掛け致しますが宜しくお願い致します。


※'初期化
MSComm.CommPort = 8
MSComm.Settings = "9600,n,8,1"
MSComm.Handshaking = comNone
MSComm.RThreshold = 1
MSComm.SThreshold = 1
お互い上記の設定で通信しています。

[ツリー表示へ]
タイトルRe^5: MScommの通信について
記事No15483
投稿日: 2012/06/01(Fri) 17:48
投稿者オショウ
> 自分の理解出来てる範囲で確認してみました。

  非同期通信と言うものと、プログラムの構造がマッチして
  いないのだと思います。

  指定したバイト数を受信するまで待つようにプログラムを
  書くか・・・
  一般的には『デリミタ』と呼ぶ固定のコードを受信するま
  延々読み込んでバイト配列等に蓄積していくか・・・
  みたいな書き方をします。

  MSComm1.Input

  として同期的受信方法になっているので、ブレークポイン
  トやプログラムの止め方で、本当は5バイト送信している
  のに、受信バッファに2バイト目が入った段階でブレーク
  してしまい、3バイト目がたまたま受信できたかのように
  なって、4バイト目以降が受信されずに受信バッファに残
  っているか、捨てられてしまったのではないかと思います。

  1バイトでの非同期受信方法で、所定バイト数受信するま
  で待ち合わせるようにするのがよいように思います。

  頑張って下さい!

以上。

[ツリー表示へ]
タイトルRe^4: MScommの通信について
記事No15484
投稿日: 2012/06/01(Fri) 19:35
投稿者魔界の仮面弁士
>   わざわざVariantに代入するのが間違いかと。
それは何故でしょうか?
今回の場合、For でも For Each でも、結果に影響はないような気がしますが…。

>   For i as Integer = 0 To bin.Length() -1
それは VB.NET の構文ですね。VB6 の場合は
 Dim i As Integer
 For i = LBound(bin) To UBound(bin)
のようにしてみてください。

[ツリー表示へ]
タイトルRe^5: MScommの通信について
記事No15496
投稿日: 2012/06/04(Mon) 11:15
投稿者ミロク
返信が遅れて大変申し訳御座いません。

オショウさん魔界の仮面弁士さんありがとう御座います。
土日色々粘って見ましたが、かなり死亡中です。
まだ明るいきざしが見えていません((笑))

これから、魔界の仮面弁士さんの教えて頂いた方法で挑戦してみます。
Dim i As Integer
For i = LBound(bin) To UBound(bin)

本当に色々な情報頂きありがとう御座います。
今後とも宜しくお願い致します。

[ツリー表示へ]
タイトルRe^6: MScommの通信について
記事No15497
投稿日: 2012/06/05(Tue) 16:16
投稿者ミロク
魔界の仮面弁士さんオショウさん。
無事にデータを習得することが出来ました。
ありがとう御座いました。本当に色々と助かりました。
またお世話になると思いますが何卒宜しくお願い致します。

[ツリー表示へ]