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

VB2005でDelay(Wait)タイマーを作るには

1こじら:2010/03/15(月) 22:29:04
こんばんは。RS232Cではお世話になりました。おかげ様で送受信
できるようになりました。ありがとうございました。
 次に起こった問題なんですが、現在のRS232Cの通信はTX,RX端子のみ
でおこなっているので、PCからの送信時、相手のバッファオーバーフロー
が分かりません。
 しかし、バッファサイズは分かっているので、それを見越した
送信データ数とWaitタイマーで現在はしのいでみようと考えて
います。しかし、VB6の時のようにタイマーがうまく動きません。
Form_Load
Timer1.Interval = 1000
Timer1.Enable = False
:
:
Loadのエンド

Dim Acount as integer
Dim TimerCount as integer

:
送信処理
ACount = 2

For i as integer=0 To X
送信関数(data(i)) 'data配列に送信したいデータを設定
TimerCount = 0
Timer1.Enable =True
Do while Acount>TimerCount
(空)
Loop

Timer1.Enable =False

Next



Private Sub Timer_Tick 〜
 TimerCount = TimerCount+1
end Sub


というようにしているのですが、Do While文で帰ってこなくなります
処理がないことがだめなのかと、この文の中に仮演算 a=a+TimerCountとしても
かえってこなくなりました。
ちなみに、VB6の時につかっていたプログラムで動いていたのですが
正しい書き方かどうか知らず動いたので使っていました。

ネットとかで調べると、VB2005などではマルチタスク処理にすべき
とありましたが、Waitをどのように改造すればよいのでしょうか。

題目とことなるのですが、ICのレジスタアクセスを行うのに
Classプロパティを使用すると良い(質問14)と以前アドバイス頂いた
のですが、例えば512アドレス(レジスタ)あれば、512個のプロパティー
を作る必要があるのでしょうか?

1つのプロパティーを何とか512個のインスタンス化処理みたいな
ことでうまくできないでしょうか。
 プロパティーの中身を替えた時など、全てのプロパティー記述
を直すのが一苦労なので、なにかうまい方法あれば教えていただけ
ないでしょうか

よろしくお願いします

2igoten:2010/03/16(火) 10:52:53
プログラムの構成が良いか悪いかは提示されたコードが
部分的なので判りませんが、Do while Acountに関しては
このループの中に
Application.DoEvents()
を入れて見て下さい。

3igoten:2010/03/16(火) 14:23:18
Whileは単にタイマーとして使用しているんですね。
それなら
Private Sub timeWaiteTime(ByVal waiteTime As DateInterval)
Dim startTime As DateTime = Now
While (Now.Subtract(startTime).TotalMilliseconds < waiteTime)
System.Threading.Thread.Sleep(1)
Application.DoEvents()
End While
End Sub
と言う関数を作っておいて
timeWaiteTime(5000)
と呼びだした方がいいかも知れません。

4こじら:2010/03/20(土) 00:39:46
有難うございます。(お礼の挨拶遅くなりすみませんでした)
おかげさまで、 PICとPCとで通信させ、操作することができるように
なりました。
HPと、掲示板でアドバイス頂いたおかげです。
ありがとうございました。

現在、そのソースは色々デバッグして、ソースが非常に乱雑で見にくいので、
関数のモジュール参照化と、RS232Cをモジュール化をこころみて整理しよう
としています。
RS232Cモジュールに関しては、また他のソフトでもこの通信モジュールのファイル
を読ませれば簡単に使用できるようにしたいとも思っています。

そこで御相談なのですが、GUI作成時、Form1にSerialPort1を追加
してForm1クラス上に全て記述して使用していますが、
独自関数や、UART操作関数関係を別ファイルに作成し、FORM1では
それらのファイルから使用する、参照するといった方法はないでしょうか
クラスでできるかと思ったのですがSerialPort1なんかは、参照ファイル
(クラスファイル)のなかでFORM1.SerialPort1.〜というような形にし
なければ、エラーになりました。

度々で申し訳ありませんがアドバイスお願いします。

5igoten:2010/03/23(火) 11:53:15
やりたいことはおよそ見当が付くのですが、実は.NETではFormもクラスなんです。
先ず共通はModuleにしましょう、Moduleと言ってもクラスですが。
さて問題はSerialPortです、もちろんこれを他のクラスに置くことは可能です。
しかし問題はすっきりするかどうかですが多分すっきりしないでしょう。
マルチフォームでSerialPort専用のフォームを作ってその中にSerialPort関係は
全て入れてしまい、ほかのプログラムでも使用できるようにする方が良いと思います。

6こじら:2010/03/23(火) 13:36:38
有難うございます。
「マルチフォームでSerialPort専用のフォームを作って」という部分は
新しいSerialPort専用のフォームを作ってそのフォーム内に設定関係
を全て記述するという事ですよね。
「ほかのプログラムでも使用できるようにする方が良い」という箇所
に関しては、例えばSerialPort関係のフォームをfrmSeriPortとすると、
MainFormからの呼びだしは frmSeriPort.〜とすべきとおっしゃって
おられるのでしょうか。
 それとも クラスのオブジェクト呼び出しでインスタンス化で
使用とおっしゃっておられるのでしょうか。
 それと、以前教えて頂いたRead時のデリゲート設定は、frmSeriPort
フォームで行うのではなくMainFormに記載するのがベストなのか
とも思ったのですが、他にプログラミング記述でいい方法あれば
アドバイスいただけないでしょうか

7igoten:2010/03/23(火) 14:13:38
実際のところFormとClassの違いはないのです。
従ってFormにしようかClassにしようかと言う問いは意味がありません。
.NET上でのFormはデザイナーがインスタンスやイベントハンドラーを自動で作成してくれます。
従ってプログラムの容易さや作業スピードのことを考えると、Formを上手に使いましょう
と言うことになります。
SerialPort専用のフォームを作ってFomSerialPortとしたとします。
そしてその中にSerialPort1を置いたとしますよね、そうすると
FomSerialPortはクラスですからForm1の中でインスタンスを作る必要が
有ります。
Public Class Form1
Dim FormSerialPort1 As New FormSerialPort

'ポートをオープンする
Private Sub Button1_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles Button1.Click
FormSerialPort1.SerialPort1.Open()
End Sub
End Class
こんな具合になるわけです。
もちろんデリゲートなんかもFomSerialPortクラスの中に書きます。
「FormSerialPort1.」はフォームのメンバーに対するアクセス子ではなく
Classのメンバーに対するアクセス子なのです。
SerialPortの受信はセカンドスレッドで行われますから、その処理は
SerialPortのインスタンスのあるクラスのインスタンスすなわち
FormSerialPort1で行われる方法が判り易いと思います。

8こじら:2010/03/25(木) 00:05:35
どうもです。
やはり、SerialPortのクラスを作成し、デリゲートのところではまって
しまいました。
内容はForm1に ボタン1,2,3、TextBox1,2,3があり、
FormUARTクラスを別ファイルで作成し、SerialPort関係を
このクラスに記載しています。

ボタン1を押すと データが送信され、送信結果が返ってきてTextBox1
に文字列で表示されます。
ボタン2を押すと 同様データ送信、送信結果が返ってきてTextBox2に
数字で表示されます。

Class Form1
 
 Dim UART1 as FormUART = New FormUART
Dim rootNo as integer = 0
Delegate Sub dlgAddText(ByVal GetText As String)

 Private Sub Button1_click 〜
   Dim Data as String = "ABC"

   UART1.Send(Data)

End Sub

Public Sub AddText(ByVal strGetText As String)

Select Case rootNo
Case 1
Dim strTmp As String = ""
Dim strVer_Array() As String = Split(strGetText)

For i As Integer = 0 To strVer_Array.Length - 1
strTmp = strTmp + Chr(strVer_Array(i))
Next
TextBox1.Text = strTmp
Case 2

   
End Select
End Sub

  −−−−−−−−−−−−−−−
  Class FormUART

  Dim LByte As List(Of Byte) = New List(Of Byte)
Private Sub SerialPort1_DataReceived(ByVal sender As System.Object, _
       ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) _
      Handles SerialPort1.DataReceived

        〜(strInに取り込んだデータを格納)

Me.Invoke(New Form1.dlgAddText(AddressOf Form1.AddText), New Object() {strIn})
   End Sub
 
としていますが、 InvokeのところでErrorになり、はまってしましました。
こういう使いかたはできないのでしょうか?
ポインタイメージでいたので、FORM1のaddTextアドレスを指定すればよいのかと
簡単に捕らえていました。

すみませんがアドバイスお願いできないでしょうか。
ちなみに、 addTextをForm1にしているのは、 Form1のボタンによって
処理(表示形態)が変わるからで、また、FormUARTクラスを今後RS232Cを
使用するプログラムに利用できるように、汎用性を持たせたかったからです。

9igoten:2010/03/25(木) 10:22:10
Me.Invoke(New Form1.dlgAddText(AddressOf Form1.AddText), New Object() {strIn})

Form1.Invoke.....
としたらいかがでしょうか。

10こじら:2010/03/25(木) 13:54:46
すみません。御指摘頂いた内容でも同じエラーでました
試した内容は
Form1.invoke  (エラーにはならないが実行時以下のようなエラーメッセージがでます)
FOrm1.addText.invoke(この場合は引き数でエラーですというエラーメッセージ)

以下エラーです
System.InvalidOperationException' のハンドルされていない例外が System.Windows.Forms.dll で発生しました。

追加情報: ウィンドウ ハンドルが作成される前、コントロールで Invoke または BeginInvoke を呼び出せません。

お気づきの点などありましたら、アドバイスお願いします

11igoten:2010/03/25(木) 17:13:51
問題はFormUARTで新しいForm1のインスタンスを作って
それに受信データーを書き込んでしまってるんですね。
Form1からFormUARTに自分のインスタンスを渡す必要が
有ります。
下のコードの感じになるんですが、デリゲートはFormUART
側に有った方がいいですね。

Public Class Form1
Dim UART1 As FormUART

'FormUARTから呼ばれる
Public Sub AddText(ByVal strGetText As String)
TextBox1.Text = TextBox1.Text + strGetText
End Sub

Private Sub Form1_Load(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles MyBase.Load
UART1 = New FormUART()
UART1.Visible = True
UART1.SetForm(Me) 'Form1のインスタンスを渡す
End Sub
End Class


Public Class FormUART
Dim F1 As Form1
Delegate Sub dlgAddText(ByVal GetText As String)
Public Sub AddText(ByVal strText As String)
F1.AddText(strText)
End Sub

Private Sub SerialPort1_DataReceived(ByVal sender As System.Object, _
ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) Handles SerialPort1.DataReceived
Dim inStr As String = SerialPort1.ReadChar()
Me.Invoke(New dlgAddText(AddressOf Me.AddText), _
New Object() {inStr})
End Sub
Public Sub SetForm(ByVal f As Form1)
F1 = f
End Sub

Private Sub FormUART_Load(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles MyBase.Load
SerialPort1.Close()
SerialPort1.Open()
End Sub
End Class

12こじら:2010/03/26(金) 00:46:43
ありがとうございます

Form1をFormUART内でoFORM1インスタンス化し、
Me.Invokeとしている箇所を oForm1.Invoke〜
そして
Form1クラスで 
 Private Sub Form1_Load 〜
  Dim UART1 as FORM1 = New FormUART(Me) 

なんてして渡したつもりにしていましたが、うまくできませんでした
教えて頂いた記述みるとなるほどと思うのですが、自分では
なかなか思いつかないです。

ありがとうございました。頂いたアドバイスでトライしてみます。
というインスタンスに

19inexpensive ugg boots:2013/09/28(土) 09:25:35
Hello to every single one, it’s truly a fastidious for me to go to see this site, it contains useful Information.
inexpensive ugg boots http://bestoflakejames.com/inexpensive-ugg-boots.html


新着レスの表示


名前: E-mail(省略可)

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

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

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

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