• 締切済み

MSCommについて

↓例の桁数、データブロックが不定で連続して受信されます。 最後の1桁は(ETX)です。 (STX)XXXXXX...(ETX)(STX)XXXXX...(FS)XXXXX...(ETX)(STX)XXXXX.......(FS)XXXX...............(ETX) すべての桁数、データブロックが対象なので一度に受信します。 1. 質問はInputプロパティで1桁ずつデータをREC変数に読み込んで、ある条件で、Loop分を抜けたいのですが、 VB6の定義方法がわかりません。 1-1.最後の(ETX)の読み込み 1-2.先頭30桁  MSComm1.InBufferCount = 0 MSComm1.InputLen = 1 Dim REC As String Do DoEvents If MSComm1.InBufferCount Then REC = REC & MSComm1.Input If ..... '最後の(ETX)の読み込み '先頭30桁 Exit Do End If   End If Loop 2. スピート重視で処理するために、InBufferCountに値があったら、すべての受信データをRECにいれたいのですが 取得できていません。 アドバイスはございますか? MSComm1.InBufferSize = 2048 MSComm1.InBufferCount = 0 MSComm1.InputLen = 0 Dim REC As String Do DoEvents If MSComm1.InBufferCount >= 1 Then Exit Do End If Loop REC = MSComm1.Input

noname#187796
noname#187796

みんなの回答

回答No.2

何度も同種の質問を繰り返されているようですが。 まずはMSDNや参考書にサンプルコードはいくらでも載っていますからそれを理解することですね。 全く進歩が見られません。

回答No.1

もし、受信したブロックが最終ブロックだと判定する方法があるなら OnCommイベントの中で処理したいなら、 CommEventプロパティがcomEvReceiveのときに While MSComm1.InBufferCount <> 0 DoEvents TotalBuffer$ = TotalBuffer$ & MSComm1.Input If Right$(Buffer$, 1) = Chr(3) Then ' Buffer$の先頭がSTXなら、正常なブロックとする。 If Left$(Buffer$, 1) = Chr(2) Then ' TotalBuffer$ = ToTalBuffer$ & Buffer$ If (Buffer$が最後のブロックかどうかの判定) Then Call hogehoge(TotalBuffer$) ' 全ブロックの処理を呼ぶ TotalBuffer$ = "" End If End If Buffer$ = "" End If Wend とすれば、STXからETXまでを1ブロックとして受信し、最後のブロックを受信したら、 これまで受信したすべてのブロックを渡してhogehoge()で処理できます。 ただし、予め MSComm1.RThreshold = 1 MSComm1.InputLen = 1 と設定する必要があります。 それとも、最終ブロックの判定はデータ送信に間が空いたことでしか判らないのでしょうか?

noname#187796
質問者

お礼

ありがとうございました。 >最終ブロックの判定はデータ送信に間が空いたことでしか判らないのでしょうか? はい、デバッカーで↓コード、連結したBuffer$をみると各ブロック間が空いています。 あと、OnCommイベントの中で処理はこのケースでは使用しません。 一つ解らないことがございます。 8秒以上待って、連結処理を開始するとすべてのデータがBuffer$に取れています。 Sleepの指定をしないと、1桁もデータが取れていません。 考えられる原因・対策をお分かりましたら教えていただけないでしょうか? 対策はございますか? Dim Buffer$ MSComm1.Handshaking=3 MSComm1.InBufferSize = 2048 MSComm1.InBufferCount = 0 MSComm1.InputLen = 1 Sleep 8000 While MSComm1.InBufferCount <> 0 DoEvents   Buffer$ = Buffer$ & MSComm1.Input Wend

関連するQ&A

  • MSComm; 必要なファイル、設定

    VB6で、ActiveXファイルを作成しています。 デバッカーでは、問題なく動作します。 CABファイルを作成して、ファイルをダウンロードさせて動作させると データ送信は、できるのですが受信データが取得できません。 Do - Loop処理を繰り返しているようです。 必要なファイル、プロパティ設定などございますか? ご意見をお願いします。 CABの中身; TEST.OCX ASYCFILT.DLL COMCAT.DLL MSMASK32.OCX MSMSKjp.DLL MSPRPJP.DLL msstdfmt.dll MSSTKPRP.DLL MSVBVM60.DLL OLEAUT32.DLL OLEPRO32.DLL VB6JP.DLL MSComm1.CommPort = 1 MSComm1.Settings = "9600,N,8,1" MSComm1.PortOpen = True MSComm1.InBufferCount = 0 MSComm1.InputLen = 1 '-----Outputプロパティによるデータ受信 MSComm1.Output = (STX) & "CMD" & (CR) '-----Inputプロパティによるデータ受信 Dim Buffer$ Do DoEvents If MSComm1.InBufferCount Then Buffer$ = Buffer$ & MSComm1.Input Select Case Buffer$ Case Chr(13) Exit Do Case Else End Select End If Loop

  • MSCommのCommEventプロパティ

    質問させてください。 ↓コードで、通信エラーのイベントを取得したいのですが、COMポートは正常に機能しているのですが、comEvReceiveに正しい値(0)が 入らずにデータ受信ができません。 対策を教えていただけませんか? Dim Buffer As String Do '5桁受信するまで待機 DoEvents Loop Until MSComm1.InBufferCount >= 5 MSComm1.RThreshold = 1 Select Case MSComm1.CommEvent '通信ポートのチェック Case comEvReceive 'OK Buffer$ = MSComm1.Input Case Else 'NG ・ ・ End Select

  • QRコードの処理

    2000桁の情報からなるバーコードをMSCommで読み込みたいのですが、すべてのデータを読めません。 対応策はございますか? Dim Record As String MSComm1.InBufferCount = 0 Do DoEvents Loop Until MSComm1.InBufferCount >= 2000 Record = MSComm1.Input '←ここで、Record変数にすべてのデータを読めません

  • MSCommで、文字化け

    こんにちは。いつも質問ばかりで恐縮ですが・・・ VB6(SP5)で、プログラミングをしております。 MSCommが文字化けをして困っております。 TA=NTT:V70MAX Windows2000 下記の通り、プログラミングをしています。文字化けがしない時は、ずっと うまく行きます。が、一度文字化けをしてしまうと、Windowsの再起動等を しなければどうにもなりません。(“・エZ・”等になります) Private Sub Form_Load() ‘初期化 MSComm1.CommPort = 1 MSComm1.Settings = "9600,N,8,1" MSComm1.Handshaking = comRTS MSComm1.RThreshold = 1 MSComm1.InputLen = 0 MSComm1.PortOpen = True End Sub Private Sub MSComm1_OnComm() Dim wBuf As String If MSComm1.CommEvent = comEvReceive Then wBuf = MSComm1.Input Text1.Text = wBuf End If End Sub

  • MSCommでoutputできない

    VB6.0でMSCommを用いてシリアル(レーダとつながってる)にデータを送りたいんですがどうもうまく送れません.outputしてすぐoutbuffercountをチェックしてもcnt=0(cntは下記プログラム参照)のままでバッファにちゃんとデータが送れていないのでは?と悩んでいます. なにが原因なんでしょうか?もしくは,他に送信バッファにデータが届いてるかどうかをチェックする方法などご存知でないでしょうか?よろしくおねがいします. MSComm1.CommPort = 2 MSComm1.InputMode = 1 MSComm1.InputLen = 0 MSComm1.Settings = "9600,N,8,1" MSComm1.RThreshold = 1 MSComm1.PortOpen = True MSComm1.InBufferCount = 0 MSComm1.OutBufferCount = 0 Dim s(16) As Byte   ’←以下のデータを送りたいんですが・・ s(0) = &H2 s(1) = &H0 s(3) = &HA s(4) = &H0 s(5) = &H20 s(6) = &H0 s(7) = &H53 s(8) = &H49 s(9) = &H43 s(10) = &H4B s(11) = &H5F s(12) = &H4C s(13) = &H4D s(14) = &H53 s(15) = &HBE s(16) = &HC5 For j = 0 To 16 MSComm1.Output = s(j) cnt = MSComm1.OutBufferCount Next j End Sub あと,レーザーの説明書に ・レーザーに送信する2バイト間の時間間隔は6msを超えないように ・レーザーに送信する2バイト間の最小時間は55μs以上としてください という記述があるんですが,これを満たしてないという可能性も疑ってます. どうやれば,この時間のタイミングで送れるんでしょうか? 長くなってすいません,なにかヒントなどおねがいします.

  • 16進数の変換

    visualbasic6.0で加速度センサーから傾きを検出するプログラムを作りたいのですが、初心者のため手探りでやっている状態です。 センサーからの信号は16進数で4バイトずつ送られてきます。 これを10進数に直して、前の2バイトと後ろの2バイトを分けて表示したいのですが解かりません。以下が現段階のコードの1部です。 Private Sub MSComm1_OnComm() Dim bytBuf() As Byte Dim strDisp As String Dim lngCount As Long Select Case MSComm1.CommEvent Case comEvReceive If List1.ListCount = 0 Then MSComm1.InBufferCount = 0 End If Do bytBuf = MSComm1.Input strDisp = "" For lngCount = LBound(bytBuf) To UBound(bytBuf) strDisp = strDisp & Right("00" & Hex(bytBuf(lngCount)), 2) & " " Next List1.List(0) = List1.List(0) & strDisp Loop While MSComm1.InBufferCount <> 0 End Select End Sub

  • MSCommを用いたRS-232-Cデータ転送

    Visual Basic ver.6を用いてRS-232-Cデータ転送のプログラムを書いています。 転送には,MSComm controlを用いています。 コンピューター側から命令コードを測定器側に送信すると(例えば,MSComm1.OutPut = "F,3,300," & Chr(13)のように),測定器側からは次のようなテキストデータの転送が指定された回数だけ起こります: @C/R 数値データC/R 数値データC/R ・・・・ ・・・・ (指定回数繰り返す) そこで,質問ですが,このデータをMSComm1.Inputを介してきちんと取得する方法をお教えください。私がよく理解できいない部分は,「どのような形でbufferにデータが落ちているのか?」という部分と「繰り返し処理をどう記述するのか?」という部分です。多分後者は配列型変数を用いて「指定回数」だけ繰り返すことになると思いますが・・・・。 なお,データ転送の制御フォーマットはデータのみの転送で,STXもETXも使用していません。

  • シリアル通信:オフライン時にうまく終了してくれません

    シリアルプリンタの制御をVB6で行っております。 以下のようなコードですが、うまく終了してくれません。 'グローバル 'プリンタの状態 Dim BUF as String '起動時 Private Sub Form_Load() MSComm1.PortOpen = True Text1.Text = "" Timer1.Enabled = True End Sub '終了 Private Sub Form_Unload(Cancel As Integer) Timer1.Enabled = False MSComm1.PortOpen = False End Sub 'タイマー Private Sub Timer1_Timer() Timer1.Enabled = False Call CheckPrint Timer1.Enabled = True End Sub Private Sub MSComm1_OnComm() Dim TimeOut As Long Dim sTime As Long Dim eTime As Long Select Case MSComm1.CommEvent '受信 Case comEvReceive TimeOut = 100 sTime = timeGetTime Do If (TimeOut - eTime) < 0 Then Exit Do End If eTime = (timeGetTime - sTime) Loop Until MSComm1.InBufferCount >= 82 BUF = MSComm1.Input End Select End Sub プリンタの状態チェック Private Sub CheckPrint() Dim sTime As Long Dim eTime As Long Dim TimeOut As Long Dim i As Integer Dim n As Integer BUF = "" 'プリンタの情報取得コマンド MSComm1.Output = "~HS" 'タイマ開始 TimeOut = 400 sTime = timeGetTime eTime = 0 Do DoEvents If BUF <> "" Then Exit Do End If eTime = (timeGetTime - sTime) Loop Until TimeOut - eTime < 0 If BUF <> "" Then ... .. 宜しくお願いします。

  • PLPGSQL レコードセットを列数で取得したい

    Postgresで関数(ストアドプロシージャ)を作成するのに PLPGSQLを使用しています。 レコードセットを取得し、1列目~40列目までを順次値を判定し、特定の値がある場合は、41列~80列のそれぞれ対応する(1列目なら41列目、13列目なら53列目…)列から数値を取得する動きを実現したいと考えています。 上記条件は下記プログラムで実現してますが、再帰処理で同じことが実現できないでしょうか? ※商品マスタを作成して、クエリを作成するのが当たり前と思いますが、よんどころのない事情でこのテーブル形式をを崩せません。(外部システムの汎用データから取り込むためです) ------------------- 以下現状のプログラム ------------------- declare rec record; int1 integer; begin int1:=0; for rec in select * from kudamonouriage where syainid=$1 and kppw=$2 loop if substr(rec.kate1,1,3)='りんご' then int1:=int1+rec.kingaku1; end if; if substr(rec.kate2,1,3)='りんごthen int1:=int1+rec.kingaku2; end if; if substr(rec.kate3,1,3)='りんご' then int1:=int1+rec.kingaku3; end if; … … if substr(rec.kate39,1,3)='りんご' then int1:=int1+rec.kingaku39; end if; if substr(rec.kate40,1,3)='りんご' then int1:=int1+rec.kingaku40; end if; end loop; return int1; end; ---------------- 以上現状のプログラム --------------------- これを ------------------- 希望するプログラム ------------------- declare rec record; int1 integer; begin int1:=0; for rec in select * from kudamonouriage where syainid=$1 and kppw=$2 loop for i 1..40 loop if substr(rec.(i),1,3)='りんご' then int1:=int1+rec.(40+i); end if; end loop; end loop; return int1; end; ---------------- 以上希望のプログラム --------------------- このようにしたいと思っています。 サイト上で色々と検索していますが、解決に至っていません。お力を貸していただけると大変助かります。宜しくお願いいたします。

  • Mscomm を使用してバイナリでデータを受信したい

    Mscommを使用して、垂れ流しデーターをバイナリで受信(受信データ長さは変化する)するとき、このデーターをどうやって、配列に格納していけば良いのでしょうか? (垂れ流しデータ ⇒ < STX >nnn-nnn・・・・< ETX >< CHK >) また、配列に格納したデーターを文字に置き換えるにはどうすれば良いでしょうか? まず考え方として以下の流れでよいでしょうか? バイナリデータをバリアント型の変数に入れる。(受信する)      ↓ このデータを1バイトごとにバイト型変数の配列に入れていく。      ↓ 格納した配列の中の制御文字を取り除く。( ST、EX )      ↓ 配列に入っているデータを文字に変換する。      ↓ 変換した文字をつなぐ。 受信するデーターが制御文字を含んでいる為、テキストで受信するとおかしな動作をすることがあるので(150バイト程度のデーターを、バッファから変数に移すときに、0.5~2.5秒もかかってしまうし、文字化けも時々起こす。)バイナリで受信してその後文字に変換したいのですが・・・。 宜しくお願い致します。

専門家に質問してみよう