データ取得の表示


nike  2007-02-25 02:00:55  No: 135478

こんにちわ

まずはプログラムを見てください。
Private Sub Timer1_Timer()
    If MSComm1.PortOpen = True Then
    
        MSComm1.Output = "Q" + vbCr
        comd = MSComm1.Input
        comd = Format(comd, "0.################")
        Label9.Caption = comd
        
        MSComm1.Output = "F" + vbCr
        comd = MSComm1.Input
        Label20.Caption = comd
        
    End If
End Sub
これはロックインアンプへ信号を送りその後データを取得し、プログラム内の各ラベルにその値を表示させるためのものですが、
片方のラベルにだけ表示されてしまいます。
なぜなのかまったくわからず困っています。
誰か助けてください。


通ってみた  2007-02-25 02:40:22  No: 135479

>片方のラベルにだけ

具体的に、どちらに表示されてどちらに表示されないのですか?

表示されない方のコマンドは正しく送信されていますか?


nike  2007-02-25 02:55:10  No: 135480

通ってみた さんありがとうございます。

補足を追加いたします。
label9.captionのほうに値が入るのですが、もう一方は表示されません。
コマンドに関しては正しく送信されていることは確認できています。

どうかよろしくお願いします。


我龍院  2007-02-25 05:19:05  No: 135481

シリアル通信は非同期ですから、コマンドを出しても
すぐに応答が有るか否かわかりません。
また相手の機器がすぐに応答を返してもそのコードでは
受信は難しいでしょう。
受信の方法はMSDNにポーリングによる方法と、
イベントによる方法が出ていますので、参照してください。


nike  2007-02-26 05:23:01  No: 135482

我龍院さん、回答ありがとうございます。
さっそく我龍院さんが言われた方法を参照してみたいと思います。

もしよろしければ、受信の難しい理由を教えていただけないでしょうか?
最初の命令だけしか応答がないのはなぜだかわかりませんか?


我龍院  2007-02-26 17:05:22  No: 135483

MSComm.Inputはその時に受信バッファに有るデーターを返すだけです。
相手機器が100文字送る予定でも、現時点で受信バッファに10文字しか
届いて居ない場合は、10文字を返します。
従って送信要求を出してから相手機器が送信を終了するまで待つ必要が
有ります。
ただし相手の機器の送信が終わったことを知る方法は、シリアル通信の
プロトコルには有りません。
と言うか、そもそもシリアル通信には送信終了の概念が有りません。
その為通常複数のデータを送受信する場合は、データーのプロトコルで
各データーの区切りを明確にします、これにはデーター長を固定する
方法や、CSVで送る方法等が有ります。
>MSComm1.Output = "F" + vbCr
となっていますから、データーの区切りにはvbCrが使われていますね、
おそらく送られて来るデーターの最後にもvbCrが付いてくるのでしょう、
従って受信側では、vbCrが来るまで、MSComm.Inputで読みつづける
必要が有ります。
片方のデーターだけ受信出来ているように見える理由ですが、
一回目は、送信要求を出して直ぐ受信していますので、多分
データーは何も無いでしょう。
一回目のデーター要求の応答を2回目で受信している可能性が高いですね。


nike  2007-02-26 21:24:58  No: 135484

我龍院さん、たびたびの回答ありがとうございます。

我龍院さんの指摘>送信要求を出してから相手機器が送信を終了するまで待つ必要が有ります。
を参考に次のようなプログラムを書いてみました。
Private Sub Timer1_Timer()
    If MSComm1.PortOpen = True Then
        MSComm1.Output = "F" + vbCr 
        comd = MSComm1.Input
        Label9.Caption = comd
        
        For i = 0 To 10000
            For j = 0 To 1300
            Next j
        Next i
        
        MSComm1.Output = "Q" + vbCr
        comd = MSComm1.Input
        Label20.Caption = comd
    End If
End Sub

For文を用いて送信終了を待ってみたんですが、今度は指定のラベルに受信されない
問題が発生してしまいました。
この場合、信号"F"をLabel9に、信号"Q"をLabel20に表示したいのですが。
逆に表示してしまいます。なぜだかわかるでしょうか?

もしよろしければ質問の回答お願いします。


我龍院  2007-02-26 23:08:22  No: 135485

えーと、一定周期で交互にコマンドを出すのですね。
ループではなくてOnCommイベントを使いましょう。

Option Explicit
'---------------------------
'コマンド定義
Const FCOMMAND = "F" & vbCr
Const QCOMMAND = "Q" & vbCr
'---------------------------
Private Type com
    strCommand As String    '送信コマンド
    boolComBusy As Boolean  '状態フラグ
    strReciveData As String '受信データ
End Type
Dim MyCom As com

'データの受信
Private Sub MSComm1_OnComm()
    '受信データ
    Static strInputData As String
    '受信+データ連結
    strInputData = strInputData & MSComm1.Input
    If Right(strInputData, 1) = vbCr Then
        'データの区切りが来た
        MyCom.strReciveData = strInputData  'データのコピー
        strInputData = vbNullString 'データバッファの初期化
        ShowData  'データ表示
        
        'データーが返ってきたので次のコマンドを出す。
        MyCom.boolComBusy = False
    End If
End Sub
'データ表示
Private Sub ShowData()
    If MyCom.strCommand = FCOMMAND Then
        Label9.Caption = MyCom.strReciveData
    ElseIf MyCom.strCommand = QCOMMAND Then
        Label20.Caption = MyCom.strReciveData
    End If
End Sub
Private Sub Timer1_Timer()
    'データーが完全に返るまで送信コマンドは送らない
    If Not MyCom.boolComBusy Then
       '前のコマンドを見て次のコマンドを出す
       If MyCom.strCommand = vbNullString Or MyCom.strCommand = QCOMMAND Then
           MyCom.strCommand = FCOMMAND
       ElseIf MyCom.strCommand = FCOMMAND Then
           MyCom.strCommand = QCOMMAND
       End If
       MSComm1.Output = MyCom.strCommand
       MyCom.boolComBusy = True
    End If
End Sub


我龍院  2007-02-26 23:18:47  No: 135486

strReciveData は正しくは  strReceiveData ですね。(^^;


nike  2007-02-27 03:07:07  No: 135487

詳しい回答ありがとうございます。
ご足労おかけして大変申し訳ありません。

我龍院さんのおかげでプログラムを完成させることができました。
私の知らない知識がまだまだたくさんあり勉強する部分が多く、我が身を一段階も二段階も成長することができましたのも我龍院さんのおかげです。

私も早く我龍院さんのレベルまで追いつけるように勉強していきたいと思います。
今回は助けていただいて本当にありがとうございました!


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加