none
VB2008 RS232 接收問題。 資料長時間大量接收下,會造成停止接收資料。 RRS feed

  • 一般討論

  • 您好~感謝抽空查看,請麻煩幫忙除錯。謝謝

    目前VB2008 RS232 接收問題。 資料長時間大量接收下,會造成停止接收資料

    ,但是程式畫面還可以點選按鈕等等功能正常。(會出現錯誤訊息 MessageBox.Show("讀取錯誤:" + ex.ToString, "錯誤通知", MessageBoxButtons.OK, MessageBoxIcon.Exclamation))

    唯獨 RS232資料無法接收(PIC持續發射RS232資料)
    關閉VB程式(....\bin\Debug\ComEvent.exe) 從新執行,便可以正常接收RS232資料

    程式如下  謝謝

        Private Sub OpenPort()
            Try
                SerialPort1.PortName = "COM4"
                SerialPort1.BaudRate = 19200
                SerialPort1.Parity = Parity.None
                SerialPort1.DataBits = 8
                SerialPort1.StopBits = StopBits.One
                SerialPort1.Open()               '開啟串列埠
                Timer_Graphics.Enabled = True  '啟動 繪圖
                Timer_modbus_Outdata.Enabled = True '啟動 傳送資料於單晶片
            Catch ex As Exception
                MessageBox.Show("RS232通訊埠錯誤", "錯誤通知", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
            End Try
        End Sub

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

           Dim InString As String
            InString = ""
            Dim i, len As long

            If Not SerialPort1.IsOpen Then Exit Sub

            len = SerialPort1.BytesToRead

            For i = 0 To len
                Try
                    inByte = SerialPort1.ReadByte
                    If modbus_i >= 7 Then
                        modbus_content_of_data(modbus_i) = inByte '// 接收單筆資料 完整儲存
                        If modbus_number_of_data_temp = modbus_i Then '//接收次數 是否等於 接收資料量大小
                            If modbus_content_of_data(modbus_i) = CRC16_int_H And modbus_content_of_data(modbus_i - 1) = CRC16_int_L Then
                                Select_Command()
                                chip_RX_flag = True          '單晶片 準備接收狀態    false:off   true:OK
                            End If
                            modbus_i = 0                            '//結束接收 接收次數歸零
                        Else
                            modbus_i += 1                           '    //累加
                        End If
                    ElseIf modbus_i = 6 Then
                        modbus_Byte = inByte                         '// 程式指令
                        modbus_number_of_data = inByte               '// 接收資料量
                        modbus_content_of_data(modbus_i) = inByte    '// 接收單筆資料 完整儲存
                        modbus_number_of_data_temp = modbus_number_of_data + modbus_i + 2 '//接收資料量 加上 2 BYTE (CRC)
                        modbus_i = 7
                    ElseIf modbus_i = 5 Then
                        modbus_WORD_L = inByte                       '// 字元 低
                        modbus_content_of_data(modbus_i) = inByte    '// 接收單筆資料 完整儲存
                        modbus_i = 6
                    ElseIf modbus_i = 4 Then
                        modbus_WORD_H = inByte                       '// 字元 高
                        modbus_content_of_data(modbus_i) = inByte    '// 接收單筆資料 完整儲存
                        modbus_i = 5
                    ElseIf modbus_i = 3 Then
                        modbus_address_L = inByte                    '// 位址 低
                        modbus_content_of_data(modbus_i) = inByte    '// 接收單筆資料 完整儲存
                        modbus_i = 4
                    ElseIf modbus_i = 2 Then
                        modbus_address_H = inByte                    '// 位址 高
                        modbus_content_of_data(modbus_i) = inByte    '// 接收單筆資料 完整儲存
                        modbus_i = 3
                    ElseIf modbus_i = 1 Then
                        modbus_function = inByte                    '// 程式指令
                        modbus_content_of_data(modbus_i) = inByte    '// 接收單筆資料 完整儲存
                        modbus_i = 2                                '//累加
                    ElseIf modbus_i = 0 And inByte = &H1 Then
                        modbus_address = inByte                     '//站號
                        modbus_content_of_data(modbus_i) = inByte   '//接收單筆資料 完整儲存
                        modbus_i = 1                                '//累加

                    End If
                Catch ex As Exception
                    MessageBox.Show("讀取錯誤:" + ex.ToString, "錯誤通知", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
                End Try
            Next


        End Sub








    LEO

    2013年2月2日 上午 02:52

所有回覆

  • exception 的詳細內容是什麼 ?


    在現實生活中,你和誰在一起的確很重要,甚至能改變你的成長軌跡,決定你的人生成敗。 和什麼樣的人在一起,就會有什麼樣的人生。 和勤奮的人在一起,你不會懶惰; 和積極的人在一起,你不會消沈; 與智者同行,你會不同凡響; 與高人為伍,你能登上巔峰。

    2013年2月2日 上午 05:06
    版主
  • 謝謝回復~~錯誤是隨機不定時出現!!
    等等系統出現錯誤訊息時~~我再回報! 謝謝

    LEO

    2013年2月2日 上午 05:16
  • 這時後 利用按鈕(button)關閉 comport 後,再點選按鈕重新開啟comport,也會直接出現一樣的錯誤訊號

    SerialPort1.Close() '關閉

    SerialPort1.Open() '開啟


    LEO

    2013年2月2日 上午 05:56
  • 你好~~或許我發現問題了。我猜想是矩陣溢位
    程式最前頭 廣域變數宣告

    Dim modbus_content_of_data(1024) As Byte    '//接收單筆資料 完整儲存

    PIC傳輸格是為modbus

    可能傳輸上有"漏接"幾筆資料,導致modbus_i 一直累加 ,超過 ( modbus_content_of_data(modbus_i)) 矩陣宣告
    請問我該如何撰寫程式可以判斷訊息有"走漏"
    以下有簡易的修改程式,我在試試看

    謝謝

        

    /////////////////////原始程式

               If modbus_i >= 7 Then
                        modbus_content_of_data(modbus_i) = inByte '// 接收單筆資料 完整儲存
                        If modbus_number_of_data_temp = modbus_i Then '//接收次數 是否等於 接收資料量大小
                            If modbus_content_of_data(modbus_i) = CRC16_int_H And modbus_content_of_data(modbus_i - 1) = CRC16_int_L Then
                                Select_Command()
                                chip_RX_flag = True          '單晶片 準備接收狀態    false:off   true:OK
                            End If
                            modbus_i = 0                            '//結束接收 接收次數歸零
                        Else
                            modbus_i += 1                           '    //累加
                        End If

    //////////////////////

    /////////////////////修改程式

                    If modbus_i >= 7 Then
                        modbus_content_of_data(modbus_i) = inByte '// 接收單筆資料 完整儲存
                        If modbus_number_of_data_temp = modbus_i Then '//接收次數 是否等於 接收資料量大小(+CRC碼)
                            CRC16_int = CRC(modbus_content_of_data, modbus_i - 1)       '取CRC碼
                            CRC16_int_L = CRC16_int Mod 256                             'CRC L
                            CRC16_int_H = CRC16_int >> 8                                'CRC H
                            If modbus_content_of_data(modbus_i) = CRC16_int_H And modbus_content_of_data(modbus_i - 1) = CRC16_int_L Then
                                Select_Command()
                                chip_RX_flag = True          '單晶片 準備接收狀態    false:off   true:OK
                            End If
                            modbus_i = 0                            '//結束接收 接收次數歸零
                        Else
                            modbus_i += 1                           '    //累加
                            If modbus_i >= 1000 Then        '   //疑似訊號錯亂  <----------------------
                                modbus_i = 0                        '   //從新抓取   <----------------------
                            End If                                                             <----------------------
                        End If

    //////////////////////////////////


    LEO

    2013年2月2日 上午 06:17
  • 我倒覺得, 你應該先判斷完 ReadByte 回來的資料, 再決定要不要放入陣列中.


    在現實生活中,你和誰在一起的確很重要,甚至能改變你的成長軌跡,決定你的人生成敗。 和什麼樣的人在一起,就會有什麼樣的人生。 和勤奮的人在一起,你不會懶惰; 和積極的人在一起,你不會消沈; 與智者同行,你會不同凡響; 與高人為伍,你能登上巔峰。

    2013年2月2日 上午 06:49
    版主
  • 既然是 Modbus ,就不用擔心記憶體爆掉,直接看這些既有討論:

    http://social.msdn.microsoft.com/Search/zh-TW/?Refinement=112&query=SerialPort%20MemoryStream


    論壇是網友平等互助 保證解答請至 微軟技術支援服務


    提問時,錯誤情境描述與錯誤訊息很重要,情境描述包含你做了什麼,預期的結果與實際發生的結果。一個最爛的問法範例:「我的電腦電腦怎麼不能開機?」誰知道你家是不是沒電還是你根本找不到電源鈕。

    2013年2月2日 上午 09:59
  • 謝謝 Bill Chung 版主回復我應該如何先"判斷" ReadByte 回來的資料, 再決定要不要放入陣列中??
    程式該如何撰寫呢??


    LEO

    2013年2月3日 上午 06:34
  • 你可以參考以下系列文

    serialport


    在現實生活中,你和誰在一起的確很重要,甚至能改變你的成長軌跡,決定你的人生成敗。 和什麼樣的人在一起,就會有什麼樣的人生。 和勤奮的人在一起,你不會懶惰; 和積極的人在一起,你不會消沈; 與智者同行,你會不同凡響; 與高人為伍,你能登上巔峰。

    2013年2月3日 上午 07:03
    版主
  • 謝謝~~版主回復

    目前我先使用舊方式(如下),目前測試上暫時沒有出現錯誤。(時間壓力下,先暫時如此)

     If modbus_i >= 500 Then        '   //疑似訊號錯亂  <----------------------
          modbus_i = 0                       '   //從新抓取        <----------------------
     End If                                                                  <----------------------

    請問這樣的語法下。是否延伸出現其他的問題呢??
    感謝所有回覆文章內容,我會詳閱。謝謝


    LEO

    2013年2月6日 上午 05:47
  • Modbus 上限是 255 bytes ,你有看過規範嗎?

    http://www.modbus.org/docs/Modbus_Application_Protocol_V1_1b3.pdf

    範例及相關文件:

    http://www.modbus.org/tech.php

    如果是雜訊,可以看看這篇:

    [殘念] 電腦接地很重要


    論壇是網友平等互助 保證解答請至 微軟技術支援服務


    提問時,錯誤情境描述與錯誤訊息很重要,情境描述包含你做了什麼,預期的結果與實際發生的結果。一個最爛的問法範例:「我的電腦電腦怎麼不能開機?」誰知道你家是不是沒電還是你根本找不到電源鈕。

    2013年2月6日 下午 01:07