したらばTOP ■掲示板に戻る■ 全部 1-100 最新50 | メール | |

SerialPort.Readについて

1たか:2010/02/16(火) 11:27:38
お世話になります。

WEB(VB2005)で調べたソースをお借りして
シリアル通信のプログラムを作成しています。
受信することは出来たのですが
数十回に一度、以下のような異常が発生しています。
何か良い対処方法を教えていただきたいです。


Private Sub SerialPort1_DataReceived(ByVal sender As System.Object,
ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) _
Handles SerialPort1.DataReceived

Dim dlgData As ReceiveDataDelegate = New

ReceiveDataDelegate(AddressOf DataAnalyze)

Dim ReadBuff(SerialPort1.BytesToRead - 1) As Byte

SerialPort1.Read(ReadBuff, 0, SerialPort1.BytesToRead) ←①

For i As Integer = 0 To ReadBuff.Length - 1
Me.Invoke(dlgData, CInt(ReadBuff(i)))
Next
End Sub

 ①の部分で ArgumentException
配列のオフセットおよび長さが範囲を超えているか、カウンターがソースコレクションのイ
  ンデックスから最後までの要素の数より大きい値です。

 ReadBuff{Length=1}
(0)0

宜しくお願いします。

2igoten:2010/02/16(火) 12:54:12
今日は
SerialPort1_DataReceivedの処理中に次のSerialPort1_DataReceived割り込みがかかっている
可能性がありますね。
Static又はSerialPort1_DataReceivedイベントの外側でFlgを設定して
処理中は次の割り込みがかからないようにしてみて下さい。

Private Sub SerialPort1_DataReceived(ByVal sender As System.Object, _
ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) _
Handles SerialPort1.DataReceived
Static flg As Boolean
If flg = True Then
Exit Sub
End If
flg = True
'処理
flg = False
End Sub

3たか:2010/02/16(火) 14:50:47
回答ありがとうございます。

最初に書き込んだプログラムと少し異なるのですが
flg を Static や
SerialPort1_DataReceivedイベントの外側(Public)で指定したのですが
①の部分で、同じ異常が発生します。

受信データに改行が見つからないので
②のようにしているのですが
その操作が、悪影響を与えているのでしょうか?

宜しくお願いします。


Private Sub SerialPort2_DataReceived(ByVal sender As Object, _
ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) _
Handles SerialPort2.DataReceived

If flg = True Then
Exit Sub
End If

flg = True

'データ受信用のバイト配列
Dim inByte2(SerialPort2.BytesToRead - 1) As Byte

'データの読み込み
SerialPort2.Read(inByte2, 0, SerialPort2.BytesToRead) ←①

'読み込んだデータを改行を確認しながらジェネリクスに移す
For i As Integer = 0 To inByte2.Length - 1

lByte2.Add(inByte2(i)) 'ジェネリクスに足しこむ

'改行が有った
'If lByte2.Count > 2 AndAlso lByte2(lByte2.Count - 2) = 13 AndAlso lByte2(lByte2.Count - 1) = 10 Then
If lByte2.Count > 2 AndAlso lByte2.Count = 8 Then ←②

'ジェネリクスからByte配列に移す
Dim tmpByte2(lByte2.Count - 1) As Byte
For j As Integer = 0 To lByte2.Count - 1
tmpByte2(j) = lByte2(j)
Next

lByte2.Clear() 'ジェネリクスをクリアー

'Shift-Jisからユニコードに変換
Dim uniByte2() As Byte = Encoding.Convert(encSjis2, encUni2, tmpByte2)

'Unicodeの配列から文字列に変換
Dim uniString2 As String = encUni2.GetString(uniByte2)

'メインスレッドのテキストに追加する
Me.Invoke(New dlgAddText2(AddressOf AddText2), New Object() {uniString2})

End If
Next

flg = False
End Sub

4igoten:2010/02/16(火) 15:09:32
Byteで取得していますから改行は関係ないかと。
配列を宣言した時と実際に使う時で長さが変わってきているのかも。
読み込みの長さの取得は一回としてみましょう。

Dim LenBytesToRead As Integer = SerialPort1.BytesToRead - 1
Dim ReadBuff(LenBytesToRead) As Byte
SerialPort1.Read(ReadBuff, 0, LenBytesToRead)

5たか:2010/02/16(火) 16:13:33
 変更してみたのですが
 何回か受信しただけでも
 以下の部分で異常が起きてしまいます。

 FormatExceptionはハンドルされませんでした。
【入力文字列の形式が正しくありません。】

'メインスレッドのテキストに追加する
Me.Invoke(New dlgAddText2(AddressOf AddText2), New Object() {uniString2})

6igoten:2010/02/16(火) 16:45:05
2回目の投稿の時隠れた部分を読み込みませんでした。(^^;
私のサンプルは改行の後少し間があって次の送信が来る
サンプルです。
多分改行の後続けて文字送信が有るのでしょう。
その場合はそのコードでは無理です。
受信バッファからジェネリクスに移す時に
Chr(10)が来たら改行とみなしてそこまでジェネリクスに足しこんで
別な配列に移して文字変換を行います。

7たか:2010/02/16(火) 23:41:11
VBがよく分かっていないので
変な質問になるかもしれませんが…

>Chr(10)が来たら改行とみなしてそこまで
②では条件不足になるのでしょうか?
これでも同じように異常が上がっています。

'改行が有った
'If lByte2.Count > 2 AndAlso lByte2(lByte2.Count - 2) = 13 AndAlso lByte2(lByte2.Count - 1) = 10 Then
If lByte2.Count > 2 AndAlso lByte2.Count = 8 Then ←②

8igoten:2010/02/17(水) 07:50:10
少し話を整理してみましょう。
一番最初の質問で確保した配列とそれに入れようとした時に
配列がオーバーフローしてしまうトラブルは解決されたのでしょうか?
データ変換や表示を止めて、データを単に取得するプログラムでエラーが
出ないことを確認する必要があります。

2番目の問題は文字を変換する際に正しい文字の配列が渡されなエラーです。
文字の終わりはChr(10)で改行で有ることは間違いないなら、文字の初めが
間違っていることになります。
そこで「AndAlso lByte2.Count = 8」が問題になります、いつも送られて来る
データが改行も含めて8Byte単位ならこれでも良いわけですが、その辺は
仕様が判らないので私には判断できません。

それと
>受信データに改行が見つからないので
>②のようにしているのですが
の意味が良く分からないのですが、もう少し詳しく説明してください。
Tyr Catch等は使っていませんよね。
ここではエラー処理をしてはいけません。

9たか:2010/02/17(水) 09:53:54
お世話になります。

現在は、3回目に問い合わせしました(投稿日: 2010/02/16(火) 14:50:47 )
ソースで進めようと考えています。

一番最初のオーバーフローしてしまうトラブルは未解決です。
 【配列のオフセットおよび長さが範囲を超えているか、カウンターがソースコレクションのイ
  ンデックスから最後までの要素の数より大きい値です。】←FormatException

これまで、2通りのアドバイスをいただきました。

 ①Static flg As Booleanを使った方法
  
 ②4 名前:igoten 投稿日: 2010/02/16(火) 15:09:32
  Dim LenBytesToRead As Integer = SerialPort1.BytesToRead - 1
  Dim ReadBuff(LenBytesToRead) As Byte
  SerialPort1.Read(ReadBuff, 0, LenBytesToRead)

 ※②の方法で処理行ったときに別なトラブルが発生したので
  その部分は元に戻しています。
 【入力文字列の形式が正しくありません。】←FormatException

初めて、igotenさんの作成したソースで受信したときに
データを受信することができませんでした。
どこがおかしいのかと、msgboxで値を確認していたところ
どのデータも 8Byte単位で受信していることが分かり、
If lByte2.Count > 2 AndAlso lByte2.Count = 8 Then ←②
のように、修正したところ Text3.AppendText(strGetText)へ
値を渡すことができました。

今回は、2つの機器より受信しようと考えていまして
機器A(トラブル発生)、機器B(正常)とあり
機器Bのデータを受信して Text3.AppendText(strGetText)へ値を渡した場合は
改行があるのですが、
機器Aの場合は改行がない状態です。

これまで試みた2つの方法は残したままで良いのですか?

>Tyr Catch等は使っていませんよね。
>ここではエラー処理をしてはいけません。
このような操作をした場合はどうなるのでしょうか。

宜しくお願いします。

10igoten:2010/02/17(水) 10:09:55
おっと、申し訳ない2番目のコード間違ってます。
これだと最後の一文字をとりません。 
  Dim LenBytesToRead As Integer = SerialPort1.BytesToRead - 1
  Dim ReadBuff(LenBytesToRead) As Byte
  SerialPort1.Read(ReadBuff, 0, LenBytesToRead + 1)
としなければいけませんでした。
これでもう一度チェックしてみて下さい。

11たか:2010/02/17(水) 11:18:09
有難うございます。
上手くいきました。SerialPort1.Readメソドついても
ようやく理解できました。

>Tyr Catch等は使っていませんよね。
>ここではエラー処理をしてはいけません。
最後になりますが、
こちらを行った場合はどうなるのか
教えていただけないでしょうか。

12igoten:2010/02/17(水) 12:28:34
OKになりましたか。
ちょっとまとめておきますね。
先ず最初のトラブルはSerialPort2_DataReceived内で配列を確保した後、
受信データ処理中に再度受信が起り、確保した配列の大きさとデータ
の大きさが異なってエラーになった。
それを避ける為に、受信データのサイズの採取を1回にした。
これで上のエラーは回避されたのだが、その際私が提示した
コードに間違いが有って、受信コードの最後のデータを取らないでいた為に、
文字変換でエラーが起きた。
と言うことですか。
(なぜ間違えたかと言う言い訳ですが実はVBとC#で配列確保の仕様が
異なっていて、C#の仕様でVBのコードを書いてしまいました。)

エラー処理の件ですが結論から言いますとTry Catchを必ず入れて
下さい。
私がちょっと気になったのは、Try CatchのCatchの中に何も
書かないでエラーを抜けていたのでは無いかと思ったのです。
自分のコードに間違いがあると気付かなかったので、文字が欠落する
理由をあれこれ考えている中で、唯一可能性があるのは
Catchの中に何も書かないでエラーを抜ける方法かなと思った訳です。

13たか:2010/02/17(水) 16:09:16
はい。
まとめていただいた通りです。

Try Catchを入れて起動できるように修正します。
何から何まで
本当に有難うございました。

14コーチ 財布:2013/10/23(水) 19:41:33
continuously i used to read smaller articles or reviews that as well clear their motive, and that is also happening with this post which I am reading at this time.
コーチ 財布 http://www.sedeinc.com/

15その他の世界一流スーパーコピー:2018/10/23(火) 07:28:26
【2018新作】爆安通販!
2018超人気【即日発送】
在庫一掃販売中信用ある!
【2015人気殺到】激安通販!
大人気本物保証!
2018【品質保証書】
Japan送料無料☆正規販売店
大量入サイト!
発送で送料無料です!
限定セール中市場!
高級品本物保証!
人気新作、ピンクの最新アイテムを海外通販!
新品入荷定番!
激安通販Japan即日発送!
2018【品質保証書】


新着レスの表示


名前: E-mail(省略可)

※書き込む際の注意事項はこちら

※画像アップローダーはこちら

(画像を表示できるのは「画像リンクのサムネイル表示」がオンの掲示板に限ります)

掲示板管理者へ連絡 無料レンタル掲示板