none
VB6.0 與PLC內部位元讀取的疑問 RRS feed

  • 問題

  • 小弟近來剛好碰專題上的問題,依購買的參考書那的範例練習時發現,一樣的程式及比對元件設定方式均相同,

    自行KEYIN的程式就是無法運行

     

    我在元件的強制ON/OFF功能下是正常的.

    但是暫存區的寫入及讀取就無法執行..會變成程式無回應

    MSComm1: 9600,e,7,1

    TIMER linterval: 200

    FROM1:元件ON/OFF...OK

    FROM2:元件狀態讀取顯示...OK

    FROM3:暫存區資料變更及讀取...NG

    這是我KEYIN的程式(FROM3)

    Code Snippet

    Dim Set_X1, Set_X2, Set_X3 As String
    Dim Read_D1 As String

    Private Sub Command1_Click()
    MSComm1.PortOpen = True
    MSComm1.Output = Set_X1
    MSComm1.PortOpen = False


    End Sub

    Private Sub Command2_Click()
    MSComm1.PortOpen = True
    MSComm1.Output = Set_X2
    MSComm1.PortOpen = False
    End Sub

    Private Sub Command3_Click()
    MSComm1.PortOpen = True
    MSComm1.Output = Set_X3
    MSComm1.PortOpen = False
    End Sub

     

    Private Sub Command4_Click()
    Dim Data, Write_data As String
    Data = Hex(Text1.Text)
    If Len(Data) < 4 Then
    Do While Len(Data) < 4
    Data = "0" + Data
    Loop
    Else
    Data = Right$(Data, 4)
    End If
    Write_data = Right$(Data, 2) + Left$(Data, 2)
    Write_D0 = Chr(2) + "1100002" + Write_data + Chr(3) + CheckSum("1100002" + Write_data)
    MSComm1.PortOpen = True
    MSComm1.Output = Write_D0
    MSComm1.PortOpen = False
    End Sub

     

    Private Sub Command5_Click()
    End
    End Sub

    Private Sub Form_Activate()
    Set_X1 = Chr(2) + "70104" + Chr(3) + CheckSum("70104")
    Set_X2 = Chr(2) + "70204" + Chr(3) + CheckSum("70204")
    Set_X3 = Chr(2) + "70304" + Chr(3) + CheckSum("70304")
    Read_D1 = Chr(2) + "0100202" + Chr(3) + CheckSum("0100202")
    Text1.SetFocus

    End Sub

     

    Private Sub Form_Load()
    Timer1.Enabled = True
    End Sub

     

    Private Sub Timer1_Timer()
    Dim n As Integer
    Dim strTmp, strTmp1 As String
    Dim a, intTmp, intTmp1 As Integer
    MSComm1.PortOpen = True
    MSComm1.Output = Read_D1
    Do While Len(strTmp) < 8
    strTmp = strTmp + MSComm1.Input
    Loop
    strTmp = Mid$(strTmp, 2, 4)
    strTmp = Right$(strTmp, 2) + Left$(strTmp, 2)
    intTmp = Val("&H" + strTmp)
    Text2.Text = intTmp
    MSComm1.PortOpen = False
    For n = 1 To 10000
    DoEvents
    Next n
    MSComm1.PortOpen = True
    MSComm1.Output = Chr(2) + "000A001" + Chr(3) + CheckSum("000A001")
    Do While Len(strTmp2) < 6
    strTmp1 = strTmp1 + MSComm1.Input
    Loop
    strTmp1 = Mid$(strTmp1, 2, 2)
    intTmp1 = Val("&H" + strTmp1) And 3
    Select Case intTmp1
    Case 0
    Label1.Caption = "0"
    Shape1.BackColor = vbGreen
    Case 1
    Label1.Caption = "1"
    Shape1.BackColor = vbRed
    End Select
    MSComm1.PortOpen = False

    End Sub

     

     


    2008年7月7日 上午 07:46

解答

  • 跟硬體溝通你要用Timeout的處理,比如說我指令傳送出去,正常是會收到"12345"的回應,那假設今天傳輸過程中"2"不見了(或是機器沒有回應),程式中又沒有Timeout,那就等不完了。

     

    Code Snippet
    For n = 1 To 1000
        DoEvents
    Next n

     

     

    一般看起來是在做延遲用,就好像在C語言的時候 for(i=0;i<1000;i++); 這樣來作延遲,不過這樣的方式在不同的環境會有不同的結果,不準,而且CPU那個時間是在空轉的狀態就是了;另外要特別說的是DoEvents在VB裡面是會將控制權交還給系統,讓系統看看有沒有其他等待處理的工作,所以控制權一交出,什麼時候會回來是不確定的,所以如果上面的程式碼拿來

    做計時之類的動作會更不準的。設計上也是要看你的需求,是不是能夠容許誤差。
    2008年7月9日 上午 02:53
    版主

所有回覆

  • 設一下中斷點,或是程式無回應的時候再IDE的環境裡面按ctrl+break,看看程式是卡在哪裡。

    2008年7月7日 下午 12:07
    版主
  • 感謝bauann大大的提醒

    目前發現程式會卡在Loop這個迴圈

    但有時卻ok..請問這個問題有方法能改善ㄇ

     

    小弟能否再向各位大大請教一各問題呢

    For n = 1 To 1000
        DoEvents
      Next n

    這段程式有什麼作用呢???

    若我將1000這個值變大或變小對程式又有何影響

     

    再次感謝大大們替我解答~~

     

    2008年7月9日 上午 01:55
  • 跟硬體溝通你要用Timeout的處理,比如說我指令傳送出去,正常是會收到"12345"的回應,那假設今天傳輸過程中"2"不見了(或是機器沒有回應),程式中又沒有Timeout,那就等不完了。

     

    Code Snippet
    For n = 1 To 1000
        DoEvents
    Next n

     

     

    一般看起來是在做延遲用,就好像在C語言的時候 for(i=0;i<1000;i++); 這樣來作延遲,不過這樣的方式在不同的環境會有不同的結果,不準,而且CPU那個時間是在空轉的狀態就是了;另外要特別說的是DoEvents在VB裡面是會將控制權交還給系統,讓系統看看有沒有其他等待處理的工作,所以控制權一交出,什麼時候會回來是不確定的,所以如果上面的程式碼拿來

    做計時之類的動作會更不準的。設計上也是要看你的需求,是不是能夠容許誤差。
    2008年7月9日 上午 02:53
    版主
  • 一.變數宣告方式:

    Dim a, intTmp, intTmp1 As Integer

    你這樣宣告等於是 Dim a As Variant, intTmp As Variant, intTmp1 As Integer

    二.建議你那SET_X1 SET_X2....變數給值不要放在Form_Activate()內, 因為Form_Activate()不只會觸發一次,當有其他表單蓋到本表單再移開時,或者有MSGBOX()顯示之後關閉時,也都會觸發!

    三.Timer1_Timer()內有一個變數strTmp2 沒有宣告,也沒有給值,不知此變數是那裡來的,如果是筆誤,那麼該迴圈就會出不來了!

    建議最好加上 Option Explicit ,這樣如果程式內有變數沒有宣告(也可能是變數名稱寫錯)時就會告訴你!

     

    2008年7月9日 上午 06:42
  • 謝謝大大們給的參考...

    加了延遲TIMER後..目前程式穩定多了...

    至於偵錯的方法..也非常謝謝大大的提醒...

     

    2008年7月15日 上午 06:57