過去ログを検索した結果、いくつか似た症状の質問があったのですが、
どれも自己解決してしまったようでどうして直ったのかわからなかったので
質問させていただきます。
今回はじめてVBをさわることになったのですが、下記のようなプログラムでADXL202というセンサとRS232C通信を行うソフトを独自に作っています。
いろいろなものを参考にしてなんとか通信を行うことができるとことまでは
いったのですが、2回に1回くらいの確率で20秒ぐらいフリーズして
しまいます。なにかアドバイスをいただけたら幸いです。
*******************************
Private Sub cmd_Send_Click()
Dim t As Byte
MSComm1.InBufferCount = 0
MSComm1.OutBufferCount = 0
MSComm1.InputLen = 0
Text2.Text = "読み取り中"
MSComm1.Output = txt_Send.Text & Chr(13) & Chr(10)
Do
DoEvents
Loop Until MSComm1.OutBufferCount = 0
Do
If t < 50 Then
t = t + 1
Call Delay(10)
End If
Loop Until MSComm1.InBufferCount >= 4
'InBufferCount:受信バッファに格納されているバイト数を返す.
Text2.Text = "読み取り終了"
s0 = MSComm1.Input
txt_rec1.Text = s0 & Chr(13) & Chr(10) + txt_rec1.Text
End Sub
Private Sub Delay(ByVal t As Long)
'Delay関数(tの単位はミリ秒)
Dim t_0 As Long
Dim t_1 As Long
t_0 = GetTickCount
t_1 = t_0
While ((t_1 - t_0) < t) '条件が満たされるまで続ける
t_1 = GetTickCount '更新
DoEvents 'ループ中でも操作可能
Debug.Print GetTickCount
Wend
End Sub
*******************************
何を送るんだかわかりませんが、MSCommは文字列で
送信する場合送れないコードがあった気がします。
バイナリモードで送信してみてはどうでしょうか?
それと、下のループですがタイムアウト処理をした
いのかもしれませんが、4バイト以上データが来ない
と、永久に抜けないんじゃないでしょうか?
Do
If t < 50 Then
t = t + 1
Call Delay(10)
Else
'ここでループして操作不能
End If
Loop Until MSComm1.InBufferCount >= 4
おそらく、送信データがちゃんと送れていないか
受信の待ち時間が短すぎるのか、どちらかじゃな
いでしょうか?
返信ありがとうございます。
ご指摘いただいた点ですが、このセンサは「g」という文字列を送信すること
で4バイトの数値を返す仕様になっています。
それなので、受信データは最低4バイトになります。
また、comEvSendで送信状態を確認しているのですが、
送信自体はできているようです。
受信の待ち時間ですが、待ち時間ではなく、受信しきるまでの
空ループで対応しているつもりなのですができていないでしょうか?
アナデバの加速度センサーはとても232Cのインターフェースを
持っているとは思えませんが。。。
それはさておき、単に相手からデーターが送られてこないだけでは。
それと、変なディレー使うより、イベント ドリブンでデーターを
受けた方が良いような気がしますが。
返信ありがとうございます。
載せていませんでしたが、使用しているのは正確にはADXL202を使った
「PC接続・マイコン2軸加速度センサモジュールキット」という秋月の
キットを使用しています。そのため入出力がRS232Cになっています。
イベントドリブン方式について理解しきれていないのかもしれませんが、
「イベント ドリブンでデーターを受ける」というのはOnComm イベントの
ComEvReceive内でデータ処理を行うということでしょうか?
私としては送られてくるデータが4バイトなので、受信が途中で終わらないように
「4バイト受信しきるまで待つ」としただけのつもりだったのですが・・・
>それはさておき、単に相手からデーターが送られてこないだけでは。
こちらを先に書きましたが、これはどうですか。
>「4バイト受信しきるまで待つ」としただけのつもりだったのですが・・・
私が説明するよりMSDNの「OnComm イベント」の「OnComm イベントの例」を読んで下さい。
ヒントは「RThreshold プロパティ」です。
GetTickCountの値が受信中に10以上大きくなるとDoEventsが実行されなく
なる可能性があるにょ
> にゃ〜さん
> GetTickCountの値が受信中に10以上大きくなるとDoEventsが実行されなく
> なる可能性があるにょ
Delay()の中身でし?
それなら一度はDoEvents実行されるとおもうです…
※と、キモぃ語調で言ってみるテスツ ( ´Д`)
「txt_Send.Textがプロトコールに無い文字でした。」
などと言うことは無しとして、
MSComm1.Output = txt_Send.Text & Chr(13) & Chr(10)
Do
DoEvents
Loop Until MSComm1.InBufferCount >= 4
だけのコードでデーター受信まで時間がかかるかどうか試されたら。
時間がかかってる時にDoEventsでブレークをかけて、止まる様だと相手から
データーが送られて来ていない可能性が有ります。
皆さん返信ありがとうございます。
>>それはさておき、単に相手からデーターが送られてこないだけでは。
>こちらを先に書きましたが、これはどうですか。
おそらく、そうだと思います。実際、センサを動かさない状態では安定して
一瞬でデータを受信できるのです。しかしセンサを動かしたりすると
20秒フリーズが出てしまうのです。ネットで拾ったソフトや付属のソフトでは
そんなことはなく、安定して出力を得ています。ですのでプログラムに
問題があると思われる状態です。
>「txt_Send.Textがプロトコールに無い文字でした。」
そのままだと長くなってしまうので、書き込み用にMSCommに関係のない
部分は消していました。書いていなくて申し訳ありませんでした。
そのほかの部分は大変申し訳ないのですが、今日・明日はプログラムを
いじることができないので、また後日試してみます。
みなさんのアドバイスを試し次第状況を報告いたしますので、
またよろしくお願いいたします。
>おそらく、そうだと思います。実際、センサを動かさない状態では安定して
>一瞬でデータを受信できるのです。しかしセンサを動かしたりすると
>20秒フリーズが出てしまうのです。
情報の小出し良くないことあるね。
加速度センサーなんだから、センサーを動かすとGの変化のデーターをかなりの
スピードで送ってくるのでしょう。
最初に送ってるコマンドは送信開始要求かな。
いずれにしてもこのコードでは、ボタンを押して送信要求を受けた瞬間の
データーしか取得できないのでだめ、再設計ですね。
たとえば、こんなことかな。ただし当方RS232Cのデバック環境に無いので
動作の保証は×。
Const ComGetStringLen As Integer = 4 '4バイト受信
Const ComSendBuffZero As Integer = 1 '送信バッファ0で受信
Const ComUsePort As Integer = 1
Const ComSetString = "9600,n,8,1"
Private Sub Form_Load()
With MSComm1
.SThreshold = ComGetStringLen
.RThreshold = ComSendBuffZero '送信バッファ空でOnComm開始
.CommPort = ComUsePort
.Settings = ComSetString
End With
End Sub
Private Sub cmd_Sen_Click()
If MSComm1.PortOpen = False Then
MSComm1.PortOpen = True
End If
MSComm1.Output = txt_send.Text & vbCrLf '送信要求
End Sub
Private Sub cmd_Stop_Click()
MSComm1.Output = "??" & vbCrLf '送信中止コマンドは??
If MSComm1.PortOpen = True Then
MSComm1.PortOpen = False
End If
End Sub
Private Sub MSComm1_OnComm()
Dim Buff As String
Select Case MSComm1.CommEvent
' RThreshold プロパティで指定された数のバイトを受信。
Case comEvReceive
Buff = MSComm1.Input
txt_rec1.Text = txt_rec1 & Buff & vbCrLf
DoEvents
End Select
End Sub
大変失礼いたしました。
最初は必要ないと思ったことや、途中で気がついたことを随時書いていたら
小出しするという形になってしまっていました。以後気をつけます。
書いていただいたプログラムを試してみたのですが、症状は改善されませんでした。
いくつか変更した点は
・Private Sub cmd_Stop_Click()の部分を削除
→'G'という文字を一回送ると1回値を受信するという形なので、
何もしなくても止まるようになっています。
・Private Sub MSComm1_OnComm()の DoEventsのあとに計算項を挿入
→一番初めに書いたプログラムでは消していますが、出力された結果を
計算して表示するプログラムがありますのでそれを挿入しました。
あとは基本的には同じように書きました。
どこでフリーズするのかわかるように、各部分にテキスト出力をしたところ、
Private Sub MSComm1_OnComm()の一番最初の部分に書いたテキストが
出てこなかったので、OnCommイベントを呼び出すのに時間がかかって
いるようです。
この辺りについてなにかアドバイスをいただけたらと思います。
センサーを動かさなければ、直ちにデーターは
送られて来るのですか?
はい。
それでも時々フリーズすることはあるのですが、センサをまったく
動かさないようにした状態では、連続してクリックしてもすぐに
値が返ってきます。
追加
一度フリーズするとそのあとも何度かフリーズします。
一度MSDNのヘルプでOnComm を調べて見て下さい。
OnComm イベントはCommEvent プロパティの値が変化すると発生します。
使用例も良く見ておいて下さいね。
そこで、センサーを動かさなければ、センサーキッドが『g』コマンドを
受け付けてデーターを返すと言うことは、少なくてもこちらのデーター
受け取りプログラムは正常に動作していると思いませんか。
センサーを動かすと、PICマイコンが忙しくて『g』コマンドを受け付けて
いる暇が無いのでは。
『g』以外に連続でデーターを送ってくるコマンドは無いのですか?
それと『フリーズ』と言うのはどのような意味でしょう、普通フリーズと言うと
アプリが反応しなくなり、再起動する必要が有りますが。
ねろさん何度もありがとうございます。返答の順序はきにしないでください。
>一度MSDNのヘルプでOnComm を調べて見て下さい。
>OnComm イベントはCommEvent プロパティの値が変化すると発生します。
>使用例も良く見ておいて下さいね。
失礼しました。冷静に考えればわかることだったのですが、もうなにが
なんだかわからなくなって基本を忘れていました。
>それと『フリーズ』と言うのはどのような意味でしょう、普通フリーズと言うと
>アプリが反応しなくなり、再起動する必要が有りますが。
フリーズという表現が誤っていました。平均で20秒ほどたつと値が返って
くるので正確には”ビジー状態”というのでしょうか?しかし、固まった
あと、値が返ってくるときにはソフトがVB画面の裏側に隠れてしまうという
よくわからない現象が起こるので"フリーズ"と表現しました。
>『g』以外に連続でデーターを送ってくるコマンドは無いのですか?
ないようです。説明書には"連続して測定する場合には、[Gを送信後、
4倍と受信し、データを処理保存する]を繰り返してください。"とだけ
書いてあります。
>そこで、センサーを動かさなければ、センサーキッドが『g』コマンドを
>受け付けてデーターを返すと言うことは、少なくてもこちらのデーター
>受け取りプログラムは正常に動作していると思いませんか。
>センサーを動かすと、PICマイコンが忙しくて『g』コマンドを受け付けて
>いる暇が無いのでは。
自分もそうだと思います。例として書いていただいたプログラムで言うと
Private Sub cmd_Sen_Click()の終わりの部分(①)と、
Private Sub MSComm1_OnComm()の始めの部分(②)に
MSComm1.InBufferCountをテキスト出力するように書き加えたところ、
止まるところは(①)で"=0"と出力した後なので、センサからの
データが受信できていない状態で止まっているようです。
また、確かに値を受け取ることはできるのでプログラム自体、
間違ってはいないと思います。しかし、他のソフトでは安定した出力を
得ていますので、プログラムでその"PICマイコンが忙しくて『g』
コマンドを受け付けている暇が無い"と思われる状態も回避できるのだと
思っているのですが・・・
ちなみに"他のソフト"というのは
http://www.ast-j.com/software/scc.htm
です。ソースも有料で公開していますが、ちょっと高くて手が出ません。
このソフトで通信すると"ビジー状態"になることもなく、とても安定した
出力を得られます。
幾つかの疑問点があります。先ず
>MSComm1.Output = txt_Send.Text & Chr(13) & Chr(10)
Chr(13) & Chr(10)これをつけるのは相手側の仕様ですね。
>[Gを送信後、4倍と受信し、データを処理保存する]を繰り返してください。
4倍とは4byteの書き間違いと思いますが、こちら側はByteモードで受信
する必要は無いのですか?
と言うか、正常に受信した時はどんなデーターが取れてますか。
>Private Sub MSComm1_OnComm()の始めの部分(②)に
OnCommイベントが発生しないと言うことですね、
>Const ComSetString = "9600,n,8,1"
この部分は適当に書いてますが、相手に合わせてかいかえてますよね。
>Chr(13) & Chr(10)これをつけるのは相手側の仕様ですね。
その他に参考にしていたプログラムがそうしていたのでマネしたのですが、
確認したところ、あってもなくても変わりありませんでした。
>4倍とは4byteの書き間違いと思いますが、
その通りです。失礼いたしました。
>こちら側はByteモードで受信する必要は無いのですか?
>と言うか、正常に受信した時はどんなデーターが取れてますか。
"Byteモード"というのは"InputMode"の"バイナリモード"のことでしょうか?
こちらはセンサの仕様上、4バイトのテキストデータが送られてくるので、
たとえば"ョp"という出力を得ます。これを"Hex"や"Asc"で数字に変えて
計算しています。
>>Private Sub MSComm1_OnComm()の始めの部分(②)に
>OnCommイベントが発生しないと言うことですね、
>>Const ComSetString = "9600,n,8,1"
>この部分は適当に書いてますが、相手に合わせてかいかえてますよね。
はい。適した値にしています。正確には変えていないのですが、
今回はたまたまそのままの設定であっていますので問題はないと思います。
と、言った状態ですがいかがでしょうか?
少し訂正します。
"Byteモード"というのは"InputMode"の"バイナリモード"のことでしょうか?
こちらはセンサの仕様上、4バイトのテキストデータが送られてくるので、
>(ここを追加)テキストモードで受信しています。
たとえば"ョp"という出力を得ます。これを"Hex"や"Asc"で数字に変えて
計算しています。
大間違いでした
×.SThreshold = ComGetStringLen
×.RThreshold = ComSendBuffZero '送信バッファ空でOnComm開始
○.SThreshold = ComSendBuffZero
○.RThreshold = ComGetStringLen
です、これじゃだめなわけだ。
>こちら側はByteモードで受信する必要は無いのですか?
バイナリモードの間違いです。
>この部分は適当に書いてますが、相手に合わせてかいかえてますよね。
「かいかえて」ではなく書き換えてです。
何を書いてるのかな、申し訳ない、全て暑さのせいです。(^^;
>たとえば"ョp"という出力を得ます。これを"Hex"や"Asc"で数字に変えて計算しています。
要するにバイナリーモードですね。
気を取り直して、1番単純に
Private Sub Form_Load()
With MSComm1
.RThreshold = 1
.CommPort = 1
.Settings = "9600,n,8,1"
.InputMode = comInputModeBinary
.PortOpen = True
End With
End Sub
Private Sub cmd_Sen_Click()
MSComm1.Output = "G"
End Sub
Private Sub MSComm1_OnComm()
Dim Buffer As Variant
Dim Arr() As Byte
Select Case MSComm1.CommEvent
Case comEvReceive
Buffer = MSComm1.Input '<-ブレークポイントを設定
Arr = Buffer
End Select
End Sub
とやって
Buffer = MSComm1.Inputのところにブレークポイントを置いて
データーがすぐ返って来るか否か試してください。
私の文章がへたなせいでねろさんに誤解を招いてしまったようです。
申し訳ありませんです。えっと、まとめて返答させていただきます。
>×.SThreshold = ComGetStringLen
>×.RThreshold = ComSendBuffZero '送信バッファ空でOnComm開始
>○.SThreshold = ComSendBuffZero
>○.RThreshold = ComGetStringLen
>です、これじゃだめなわけだ。
確かにそうでした。値を最後まで受信していませんでした。
ただ4バイト受信するところを、1バイトしか受信しないだけだったので、
後半の値が0になるだけで、プログラム自体には支障はなかったようです。
>>たとえば"ョp"という出力を得ます。これを"Hex"や"Asc"で数字に変えて計算しています。
>要するにバイナリーモードですね。
バイナリモードではなく、テキストモードでないとデータを受信できません。
テキストモードで受信したときが
>>たとえば"ョp"という出力
になります。バイナリで受信すると"??"しか返ってきません。
>Buffer = MSComm1.Input '<-ブレークポイントを設定
>Arr = Buffer
例で書いてもらったプログラムではMSComm1.Inputをバイト関数で受け取って
いますが、仕様書によると送られてくるのは4バイト分の16進数で送られて
くるそうです。ホントこの仕様書わかりずらくて秋月に文句を言いたいくら
いなのですが、"~"は16進数が文字化けしているだけのようで、
私は"~"を受信して"Hex()"で"11, 7E, 13, 11"というように変換しています。
ですので送られてくる"~"はバイトではないので"エラー13、型が一致
しません"と出てしまいます。実際試してみてもこのエラーが出ました。
少し問題を整理してみましょう。
Hさんの当面の問題はセンサーを動かした時、データーが20秒近く
返ってこないことですよね。
まず先にデーターが返ってくるか否かをチェックしてみましょう。
返って来たデーターがByteなのかTextなのかは、次の問題としましょう。
その為に最小のコードです、センサーを動かしながら、
ここに
>Buffer = MSComm1.Input '<-ブレークポイントを設定
ブレークポイントを設定して下さい。
ブレークポイントを設定したらセンサーをうごかしたまま、「G」コマンドを
送って見ましょう。ブレークポイントの設定の仕方はわかりますよね。
データーが送られて来ると、プログラムが止まりますので、すぐデーターが送られて
来るか否かがわかります。
はい。確認したところ、固まるときはブレークポイントまで行きません。
"Buffer = MSComm1.Input"に相当する部分は私のプログラムでも
"comEvReceive"内の一番最初にあるので、"comEvReceive"自体が実行されて
いないようです。
以前,17個目のレスでお話した"(①)と(②)の間でで止まる"ということ
からも、固まるときはデータが送られてきていない状態のようです。
ハイパーターミナルを使用してコマンドを送って見てください。
それでも固まりますか?
> それでも固まりますか?
>
ちょっと間違い^^;
×・・・それでも固まりますか?
○・・・データが受信できないことがありますか?
>確認したところ、固まるときはブレークポイントまで行きません。
固まる時はということは、固まらない時もあるということですか。
センサーを振りながら「G」を送ると1回目はどうですか。
>ハイパーターミナルを使用してコマンドを送って見てください。
すみません。ハイパーターミナルを使っての送受信の仕方がわかりません。
今、調べていますのでちょっとお待ちください。
>センサーを振りながら「G」を送ると1回目はどうですか。
振る度合いにもよりますが、普通に動かしていれば最初の1回は必ず固まります。
その後、固まり終わるまで振り続け、再度送信すると1〜2回は
値が返ってきますが、またすぐ固まります。
>>ハイパーターミナルを使用してコマンドを送って見てください。
>すみません。ハイパーターミナルを使っての送受信の仕方がわかりません。
>今、調べていますのでちょっとお待ちください。
>
ハイパーターミナルを起動して適当な名前を入力("Test"でもOK)後、接続設定画面で
通信するCOMポートを選択する。そうするとCOMxのプロパティ画面が表示されるので
適宜(ADXL202の設定と合わせる必要あり)設定すれば下準備はOKです。
あとは普通にキーボードからコマンド(G+Enter)を入力すれば相手側にデータが送られます。
その後に画面に自分が入力した以外の文字が表示されているようなら受信は出来ている
と思います。(16進数で返すとの事なので文字化けはしているでしょうが・・・)
>GODさん
ポートの設定をした後は、テキストエリアのようなものが出てくるのですが、
黒いアンダーバーが点滅しているだけで、Gを押してもENTERを押しても
反応がないのですがどうしたらよいでしょうか?設定変更とかですか?
自分が送信した文字を表示するには
ファイル(F)→プロパティ(R)→設定タブ→ASCII設定ボタン→ローカルエコーする
にチェックをつけてOKして下さい。
ただ、コマンドを送信しても反応が無いということは相手が応答してないのかな?
通信設定は正しく設定してますか?(通信速度、パリティ、ビット長、ストップビ
ット、フロー制御とか)
>GODさん
通信することができました。
文字化けして何がなんだかわかりませんが、最初にg+ENTERとした後に
ENTERを押すと、動かしながらでも表示が変化します。
安定して通信できているようにも見えますが、いかんせん文字化けして
いるのでよくわかりません・・・
> 文字化けして何がなんだかわかりませんが
>
文字化けしちゃうのはテキストボックスにそのまま表示しているのでどうしようももないです(泣
ここで一つ気になったのですが送信するコマンドはどのようになっているのでしょうか?
1回目のデータを取得するときは「G」だけで取れるものなのでしょうか?
Enterキーを押下する必要あり?2回目以降はEnterキーのみでよいのかな?
# ハイパーターミナルで安定して受信できているということは手動では動作し# ているようですね。
>1回目のデータを取得するときは「G」だけで取れるものなのでしょうか?
>Enterキーを押下する必要あり?2回目以降はEnterキーのみでよいのかな?
はい。1度目はgを押すだけで、それ以降は、gでもENTERでも値が出ています。
>ハイパーターミナルで安定して受信できているということは手動では動作しているようですね。
確かにそのようです。どうしたらハイパーターミナルのようになるやら・・
>>1回目のデータを取得するときは「G」だけで取れるものなのでしょうか?
>>Enterキーを押下する必要あり?2回目以降はEnterキーのみでよいのかな?
>はい。1度目はgを押すだけで、それ以降は、gでもENTERでも値が出ています。
わかりずらくてすみません。えっと、gを押すだけで値が返ってきます。
また、最初にgを押した後ならENTERを押すだけでも値が返ってきます。
>>ハイパーターミナルで安定して受信できているということは手動では動作しているようですね。
>確かにそのようです。どうしたらハイパーターミナルのようになるやら・・
>
う〜ん、そうですね。
MSCommの初期化部分に間違いとかはないでしょうか。
DTREnableやRTSEnable(ハードウェアフロー使用時)はTrueにしてますか?
実際今のプログラムってどうなっているんでしょうか。
ねろさんが作ってくれたようなMSCommとボタンのみ配置したプログラムで実
験しているのかな?
>MSCommの初期化部分に間違いとかはないでしょうか。
>DTREnableやRTSEnable(ハードウェアフロー使用時)はTrueにしてますか?
DTRはTrueでもFalseでも出力に影響がなかったので設定していません。
RTSはTrueにしないとセンサキットのLEDがつかないのでTrueにしています。
そのほかのフロー制御は設定していません。これが原因でしょうか?
>RTSはTrueにしないとセンサキットのLEDがつかないのでTrueにしています。
DTRはデフォルトでON、RTSはデフォルトでOFFなんですが、
この辺を操作してるとなると、Hさんの実際に動かしているコードと、
このキットの仕様を見ないとわかりませんね。
これはもともとキットなんでハードに強いなら、LEDと抵抗で
信号線のモニターをキットに追加すれば早いのですが。。。。
>DTRはTrueでもFalseでも出力に影響がなかったので設定していません。
>
う〜ん、信号関係ないのかな?
とりあえず新しいプロジェクトに下記プログラムをコピペして動作させてみてください。
正しく動作すればリストボックスに"日時 xx xx xx xx"みたいな形で表示できると思います。
あと、フォームにはMSComm, ボタン, リストボックス, タイマーを貼り付けて下さい。(名前はデフォルトのままで)
これで動作してくれるといいんだけど・・・
Private Sub Form_Load()
Timer1.Enabled = False
Command1.Caption = IIf(Timer1.Enabled, "停止", "開始")
With MSComm1
.DTREnable = True
.RTSEnable = True
.RThreshold = 1
.InputMode = comInputModeBinary
'設定値はADXL202に合わせてください
.CommPort = 1
.Settings = "9600,n,8,1"
.Handshaking = comRTS
.PortOpen = True
End With
End Sub
'終了処理
Private Sub Form_QueryUnload(Cancel As Integer, UnloadMode As Integer)
Timer1.Enabled = False
MSComm1.PortOpen = False
End Sub
'コマンドの送信開始/停止
Private Sub Command1_Click()
Timer1.Interval = 10
Timer1.Enabled = Not Timer1.Enabled
Command1.Caption = IIf(Timer1.Enabled, "停止", "開始")
End Sub
'一定間隔でGコマンドを送る
Private Sub Timer1_Timer()
Timer1.Interval = 5000
List1.AddItem Format(Now, "hh:nn:ss "), 0
MSComm1.Output = "G"
End Sub
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
'Gコマンドを送る前は無効
MSComm1.InBufferCount = 0
Exit Sub
End If
Do
bytBuf = MSComm1.Input
strDisp = ""
For lngCount = LBound(bytBuf) To UBound(bytBuf)
'受信した文字列をxxと言う形で保存
strDisp = strDisp & Right("00" & Hex(bytBuf(lngCount)), 2) & " "
Next
'リストボックスのTopに表示
List1.List(0) = List1.List(0) & strDisp
Loop While MSComm1.InBufferCount <> 0
End Select
End Sub
>ねろさんへ
作成中なのできたないですが下記URLに現在作成中のプログラムをアップしました。もしよろしければ見てください。
http://www.ii-park.net/~rindou-fan/RS232C_2.zip
キットの仕様書のほうも午後にはスキャナで取り込んでアップします。
ハードのほうですが、いずれは自分で最初から作成しようと思うのですが、
今はまだ知識がないので断念している状態です。
また、関連掲示板等で調べたところこのキットに使われているピックには
かなり複雑なプログラムが書かれているようで、キットを改造しようにも
難しいようです・・
>GODさんへ
そのまま実行した結果、
"11:39:11""11:39:16""11:39:22""11:39:27""11:39:33"・・・
といったように、時間しか出ませんでしたので少し変更しました。
①.InputMode を comInputModeText に変更
②.Handshaking を comNone に変更
自分のプログラムでは、ハンドシェイクを使うと固まったまま動かなく
なるのでcomNoneにしています。
結果として出たのは,
11:50:29 11 00 78 FF 13 00 00 00
11:50:14 11 00 63 FF 13 00 00 00
11:49:57 11 00 7B FF 13 00 00 00
11:49:29 11 00 FB 30 00 00
といった感じで、値は出るものの、5秒以上あいてしまいました。
ちなみに変更前も後もセンサをまったく動かさない状態です。
> 1).InputMode を comInputModeText に変更
> 2).Handshaking を comNone に変更
>
丸付き文字は掲示板では嫌われます。^^;
機種依存。文字掲示板を見れるのはWIN系マシンだけじゃないから。
.InputMode はcomInputModeBinaryにしておいても大丈夫だと思います。
.Handshaking は相手が対応してないのかな?またはケーブルが対応してないのかな?(とりあえずはcomNoneの方が良さそうですね)
>5秒以上あいてしまいました
>
受信部分にブレークポイントをつけて止めましたか?つけているようなら外して実験してみてください。
特に受信部分で止めていないようなら受信の処理が重過ぎるのかな?そんなこと無いと思うけど(謎
あと気になる点ですが、初回は4バイト分もデータを受け付けないのかな?
少し前の記事になるけど
>>センサーを振りながら「G」を送ると1回目はどうですか。
>振る度合いにもよりますが、普通に動かしていれば最初の1回は必ず固まります。
>その後、固まり終わるまで振り続け、再度送信すると1〜2回は
>値が返ってきますが、またすぐ固まります。
>
というのが有りましたが、.RThreshold = 4になっていたためかと。(H氏のプログラム参考)
>丸付き文字は掲示板では嫌われます。^^;
そうとは知らず多用してしまい申し訳ありません。以後気をつけます。
>受信部分にブレークポイントをつけて止めましたか?
つけていなかったのですが、こうなってしまいました。
>InputMode はcomInputModeBinaryにしておいても大丈夫だと思います。
確かに大丈夫でした。むしろcomInputModeBinaryのほうが
13:52:24 12 19 12 48
13:52:24 12 3D 12 2F
ときれいな結果が得られました。しかも0.1秒間隔で動かしながらでも
安定した出力を得られました。どやら解決してきたみたいです!
わからないのが、GODさんもねろさんもDim 〜 As Byteの関数で
受信データを受けていたのですが、自分のプログラムでは
型が一致しません、とエラーになってしまいます。
しかしGODさんのプログラムではエラーが出ませんでした。
ほかにもInputModeなど私のプログラムではできなかったことが
できていたりするのが不思議です(?o?)
あとセンサキットの仕様書のコピーです。
http://big.freett.com/rindoufan/ADXL202.zip
>>受信部分にブレークポイントをつけて止めましたか?
>つけていなかったのですが、こうなってしまいました。
>
デバッグなどで止めながらやるとあのような結果になるのは分かるのですが、何でしょうね。
タイマーがうまく働かなかった要因が別にあるんでしょうか?
(プログラムを見てもらえば分かるのですがリストに表示している時間はGコマンド
を送信した時間です。)
でも0.1秒単位だと正しく動作するというのがさらに謎要因です。
>わからないのが、GODさんもねろさんもDim 〜 As Byteの関数で
>受信データを受けていたのですが、自分のプログラムでは
>型が一致しません、とエラーになってしまいます。
>
この部分については実際にどのようなプログラムを書かれたか分からないので何とも^^;
配列定義時に予め数字を入れてしまったとか?(Dim bytBuf(4) As Byteみたいに)
>ほかにもInputModeなど私のプログラムではできなかったことが
>できていたりするのが不思議です
>
このプロパティはInputプロパティの返すものを決める(MSDN参照)だけなんで出来
ないということはないと思うのですが。
>安定した出力を得られました
これは初回時も4バイト受信できたということでいいのかな?
仕様書を読んで見ました。
私も、レスの途中から送られてくるデーターはバイナリーモードであると思いましたが、
2つのデーターが2Byte、2Byteで来た場合、データーが(上位バイト+下位バイト)+(上位バイト+下位バイト)
なのか(下位バイト+上位バイト)+(下位バイト+上位バイト)なのか判らなかった為
>返って来たデーターがByteなのかTextなのかは、次の問題としましょう。
としました。(どちらを先にするかと言うことを、Endian--エンディアンと言います。)
仕様書を提示して頂いたので、それを見ますと、151Bと142Cのデータが 151B142Cと送られる
と書いてあります、つまり上位バイトが先に送られる(Big Endianと言う)方式である事が
判りました。
ただしデーターをASCIIモードとして読み込んでいるHさんのコードでデーター取得になぜ時間が
かかるかは分析出来ていません。(今日は死ぬ程忙しかった)
通信部分ではないのですがちょっと気になったので
>s0 = MSComm1.Input
>txt_rec1.Text = s0 & Chr(13) & Chr(10) + txt_rec1.Text
一番初めのHさんのソースの引用で、文字列の連結で"&"と"+"の違いとか気にしてます?
例えば s0をstringで宣言してないと暗黙の型宣言でバリアントに・・・とかも
提示されたコードを一通り読んでみました。
先ずデバッグに不必要なコードが多すぎます。
Hさんの問題は、「G」コマンドを出した後データーを取得するまで時間がかかる
と言う問題ですよね、テストコードはそれを再現できる最小のコードでいいのです。
つまりコードの余分な部分は全て削り、必要なコードだけを書きます。
私の書いた2番目のコードを見てください、この程度のコードでいいのです。
単純化、ブレークポイントの設定、変数のウオッチこの3点が重要です。
アスキーモードかバイナリーモードか?
相手がアスキーモードでデーターを送って来る場合、それを文字列に入れて、文字化けすることは、
デリミタを除いて、よほどのへそ曲がり方式で無い限り有りません。
アスキーモードで"4E"を送ってくる場合、数字の52(Asc("4"))、69(Asc("E"))を送って来ます、
一方バイナリーモードの場合は78(Val(&H4E))を送って来ます。
この差はお解りですよね。
ハードウエアーモニター
キットの場合、PCBと素子が露出していますので、RS232Cの場合簡単な改造で、
ハードウエアーのモニターを作ることが出来ます。
RS232Cのバスはアクティブローという方式で、その入出力ピンは、アクティブの
場合電圧がLowになり電流を吸い込みます。
従って100オーム位の抵抗とLEDをシリーズに5V電源からモニターしたい端子に
ぶら下げることにより、その端子がアクティブの場合、LEDが光り、モニター出来ます。
今回の場合は必要なさそうですが、ソフトウェアーのデバグの時のこのモニターを
併用すればデバッグの効率は上がります。
>GODさん
>でも0.1秒単位だと正しく動作するというのがさらに謎要因です。
comInputModeBinaryにしたことで、5秒でも1秒でも0.1秒でも出力を
得ることができた、ということでした。言葉足らずですみません。
>>安定した出力を得られました
>これは初回時も4バイト受信できたということでいいのかな?
タイマーのインターバルにもよるのですが、やはい初回は何回か
データが返ってこない(スペースで表示される)場合があります。
しかしこの程度なら少しの作業で改善できそうです。
>にゃ〜さん
プログラムを何度も書き直しているうちに&と+が混同してしまったようです。
自分では意識していなかったので落ち着いて見て自分でびっくりしました。
ちゃんと調べて直します。
>ねろさん
>どちらを先にするかと言うことを、Endian--エンディアンと言います。
エディアンというのは初めて知りました。これから勉強したいと思います。
そのほかの点も、自分の知識不足な部分が多いので、ねろさんのコメントを
参考に引き続き勉強していきたいと思います。
さしあたってはハードのほうをやりたいと思います。
>返信していただいた皆様へ
皆さんありがとうございました。皆さんのアドバイスのおかげでなんとか
目的は達成できそうです。まだわからない点や解決していない点も多少
ありますが、その辺はもう少し自分で勉強して進めて行きたいと思います。
その上でまたどうしてもわからない点が出てきたらここでお聞きしたいです。
取り合えず「MSCommでの出力を安定化について」については
これで解決としたいと思います。
ねろさん、GODさん、コメントをくださった皆さん、
本当にありがとうございました。
ツイート | ![]() |