目に触れていただきありがとうございます。
以前『N88BASICを移植するには?』という記事で投稿した者です。
N88BASICをVBに移植してみました。
データの吸い出しはできるのですが、
たまにフリーズしてしまい、マウスの指示すら受け付けない状態です。
N88BASICの方では安定して動いているので、VBの問題なのでしょうか?
読み出しの部分は以下の通りです。
Private Sub DataRead()
Dim NegativeFlag As Integer
MSComm1.Output = Chr(GKCommand) ’PCから出力
Timer1.Enabled = True '④タイマー作動(200ms待つ)
While Time_Out_1 = 0
dmy = DoEvents()
Wend
Time_Out_1 = 0
Timer1.Enabled = False 'タイマー停止
While MSComm1.InBufferCount < 2 ’2byteを待つ
dmy = DoEvents()
Wend
Instring = MSComm1.Input ’PCに入力
upperstring = Left(Instring, 1)
lowerstring = Right(Instring, 1)
upperbyte = Asc(upperstring)
NegativeFlag = Not (upperbyte) And &H10
upperbyte = upperbyte And &HF
lowerbyte = Asc(lowerstring)
Zd = (upperbyte * 256 + lowerbyte)
If NegativeFlag <> 0 Then
Zd = 0 - Zd
End If
end sub
'タイマー1
Private Sub Timer1_Timer()
Time_Out_1 = 1
End Sub
何かアドバイスいただけたらと思います。
どうぞよろしくお願いいたします。
マウスが動かなくなるかはわかりませんが、
RS-232CポートをオープンしてからDataReadの処理が完了する前に回線断が
発生すると2回目のWhile〜Wendの処理で無限Loopします。
とりあえず、While〜Wendの内側でMscomm1.CDHoldingの値がFalseになって
いる場合、回線断による中断(エラー処理)をするようにしたほうがいいですね。
あと、MSComm1.Input で3バイト以上受信した場合うまくいかないかもしれません。
あと、DoEventsの返り値を格納するdmyは削除しても問題ないと思います。
あと、While〜WendよりDo〜Loop にしたほうがLoopから抜けやすいです。
あと、Zd = 0 - Zd の 0 を削除しても問題ないと思います。
最後に、受信データが文字列を想定している点も気になりますが見るほうも
大変ということで、まずはエラー処理をいれて動かしてみてください。
直接の原因ではないのですが、情報ということで・・・
因みに、VB6では、サービスパックは、当てておられますか?
当ててない場合、問題が出るケースがあります。
MsCommで、初期版(SP0と言うべきか)では、受信しても
受信割り込みが発生しないで、ロストすると言う現象があり
ボーレートが高速な場合、かなり受信ミスすると言う現象を
確認しました。
解決策が当時無かったので、旧文化オリエント社のPDQComm
を購入し、回避したことがあります。
あと、送受信のアルゴリズムですが、同期式で行われています
が、複雑にはなりますが、非同期式で行われた方が、MsCommも
安定するようです。MSComm1_OnComm()で、受信割り込みを拾
った方が、回線の変化も監視できますので安全です。
以上。
とらお様、岡田之仁様、ご返信ありがとうございます。
>とらお様
原因と改善点を詳しく教えていただきありがとうございます。
使っている機材は、1バイトのデータを送信したら、
必ず2バイトしか返してこないと盲信しておりました。
3バイトになる可能性もあるのでしょうね。
行き詰まっていたところでしたから、これを参考にまた改良してみます。
>岡田之仁様
なかなか聞けない情報ありがとうございます。
こちらで使っているのはVB6.0です。
発売された時期を考慮すると、問題は修正されているのかもしれませんね。
Microsoftのページでみたら、サービスパック5があるようなので、
これも利用してみたいと考えております。
非同期についても、置き換えられるように勉強したいと思います。
進展がありましたら経過を報告いたします。
早速、SP5をインストールし、読み込みのデータを書き換えてみました。
デバッグしてみると、一カ所だけ処理がたまに重くなる場所がありました。
Inputコマンドで、データをPCに取り出すところです。
そこでInputに関わるコマンドを、
MSComm1.InputMode = comInputModeText
MSComm1.InputLen = 2
としてみましたが、やはり重かったです。
何か心当たりのある方がいらっしゃいましたら、
アドバイスいただけたらと思います。
読みとり部分のソースは以下の通りです。
Private Sub DataRead()
Dim NegativeFlag As Integer
re:
RSOpen
MSComm1.Output = Chr(GKCommand)
Timer3.Enabled = True
Do While Time_Out_3 = 0
dmy = DoEvents()
Loop
Time_Out_3 = 0
Timer3.Enabled = False
If MSComm1.InBufferCount = 2 Then '2文字受信できていたら
GoTo ex:
ElseIf MSComm1.InBufferCount <> 2 Then'2文字受信できてなかったら
RSClose '回線を切断する
MSComm1.InBufferCount = 0 'ジャンクデータを空にする
GoTo re:
End If
ex:
Character = MSComm1.Input '***どうやらここで吸い出しに時間がかかるようです
'文字を吸い出して数値に変換
Head_Chr = Left(Character, 1)
Tail_Chr = Right(Character, 1)
Head_byte = Asc(Head_Chr)
NegativeFlag = Not (Head_byte) And &H10
Head_byte = Head_byte And &HF
Tail_byte = Asc(Tail_Chr)
Zd = (Head_byte * 256 + Tail_byte)
If NegativeFlag <> 0 Then
Zd = -Zd
End If
RSClose
End Sub
よろしくお願いいたします。
重くなるのが毎回でなく、たまにということなので以下の箇所を
見直したほうが良いかもしれません。
(1)操作手順を見直す
(2)通信相手の処理を見直す
(3)両方の通信プロトコルが同じになっているかを見直す
(ビット長やxon/xoffなど)
ちなみにケーブルをつながない状態でこの関数を実行するとやはり無限に・・・
ようやく解決いたしました。
今までご返信いただいた、とらお様、岡田 之仁様、どうもありがとうございました。
解決しました。
ツイート | ![]() |