none
Serial Port是否忙碌中的判斷 RRS feed

  • 問題

  • 各位大大,我使用Public WithEvents sp As System.IO.Ports.SerialPort來建立一個SerialPort的通訊介面,但是當我要傳送兩個以上的檔案時遇到一個問題,就是當我第一個檔案還沒有傳完時就丟第二個檔案,這樣就會沒辦法將資料完整丟過去,是否有辦法使用軟體的方式來判斷Serial Port目前是否忙線的方法呢?

    Public Sub SendSerialData(ByVal sData As String)
        Dim buff() As Byte = Encoding.Default.GetBytes(sData)
        sp.Write(buff, 0, buff.Length)
    End Sub

    2010年7月28日 上午 04:54

解答

  • 這應該是接收而不是送的問題.

    所以你試著分別用以下兩種方法看看

    (1) 每Write後就Close SerialPort, 再Open

    (2) 每Write完後Sleep 150毫秒


    在現實生活中,你和誰在一起的確很重要,甚至能改變你的成長軌跡,決定你的人生成敗。 和什麼樣的人在一起,就會有什麼樣的人生。 和勤奮的人在一起,你不會懶惰; 和積極的人在一起,你不會消沈; 與智者同行,你會不同凡響; 與高人為伍,你能登上巔峰。
    • 已標示為解答 Benson_Liao 2010年7月28日 上午 08:08
    2010年7月28日 上午 06:41
    版主

所有回覆

  • 這兩端都是電腦嗎 ? 如果是的話, 程序上可以改成如下:

    假設有A,B兩部電腦, 要由A傳檔給B

    (1) A to B: 傳送開始訊號, 並且在資料中某些Byte記錄將要傳的Byte陣列長度

    (2) B收到A的開始訊號後, 回應 A, 表示已收到開始訊號

    (3) A收到B的回應後開始傳送資料

    (4) 當B已完全收完資料後, 回應給A一個已經完整收到資料的回應

    (5) 當A收到B的完整接收回應, 表示整個資料已傳輸完成.

    然後就繼續下一個回合


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

    一端是PC沒錯,但是另一端是終端設備(例如:條碼印表機),所以另一端可能沒有辦法控制.

    我之前好像有看過有人將Serial Port這個元件寫成一個Class,這個Class裡面好像有sp.IsBusy的功能,但是突然要找就找不到.所以才會上來再問看看大家有沒有比較好的方式或者我說的那個Class.

    2010年7月28日 上午 05:38
  • 我想問一下以下幾個問題:

    (1) 你是不是開啟一個新的執行緒去做 SeriaPort.Write ? 因為這個方法是同步的, 照理說沒送完前應該會鎖定本身的執行蓄才對

    (2) 終端設備可能調整HandShark的設定嗎 ? 因為如果是硬體交握, 可以用SerialPort. CtsHolding 屬性判斷


    在現實生活中,你和誰在一起的確很重要,甚至能改變你的成長軌跡,決定你的人生成敗。 和什麼樣的人在一起,就會有什麼樣的人生。 和勤奮的人在一起,你不會懶惰; 和積極的人在一起,你不會消沈; 與智者同行,你會不同凡響; 與高人為伍,你能登上巔峰。
    2010年7月28日 上午 05:59
    版主
  • Bill大大,我不是用執行緒去做SerialPort.Write的,是用直接執行該副程式的方式,這樣是不是不好啊??若是的話是否有建議的範例可以參考呢?

    該終端設備沒有硬體交握~~

    2010年7月28日 上午 06:05
  • 你沒有用執行緒, 那它在沒Write結束前, 應該會等在那邊才對. 也就是說理論上他應該會一直鎖定到送完才會送下一筆. 還是你有用 Timer ?


    在現實生活中,你和誰在一起的確很重要,甚至能改變你的成長軌跡,決定你的人生成敗。 和什麼樣的人在一起,就會有什麼樣的人生。 和勤奮的人在一起,你不會懶惰; 和積極的人在一起,你不會消沈; 與智者同行,你會不同凡響; 與高人為伍,你能登上巔峰。
    2010年7月28日 上午 06:13
    版主
  • 我也沒有用Timer耶!!我就是用像下面的方式丟資料

    SendSerialData("THIS IS A TEST A")

    SendSerialData("THIS IS A TEST B")

    SendSerialData("THIS IS A TEST C")

    其實我是想說再每次丟資料前要先判斷通訊埠是否忙線中,若忙線要等結束才能再丟,但是看起來就是資料會重疊到!

    2010年7月28日 上午 06:19
  • 啊~~會不會是因為我丟檔案的關係,程式碼如下:

    我是用2進制的方式丟的,可是照你的說法sp.write()應該也是會等丟完才會離開,對吧!!還是大大你建議我改個方式做會比較好呢??

        Public Sub SendSerialFile(ByVal sFullPath As String, ByVal sFileName As String)
            Dim buff() As Byte
            Dim sPath As String = sFullPath & "\" & sFileName
            Dim iLen As Integer = CInt(FileLen(sPath))
            If File.Exists(sPath) Then
                Dim fs As New IO.FileStream(sPath, IO.FileMode.Open, IO.FileAccess.Read)
                Dim br As New IO.BinaryReader(fs)
                buff = br.ReadBytes(CInt(fs.Length))
                sp.Write(buff, 0, buff.Length)
            Else
                MsgBox("找不到檔案!!")
            End If
        End Sub

    2010年7月28日 上午 06:23
  • 這應該是接收而不是送的問題.

    所以你試著分別用以下兩種方法看看

    (1) 每Write後就Close SerialPort, 再Open

    (2) 每Write完後Sleep 150毫秒


    在現實生活中,你和誰在一起的確很重要,甚至能改變你的成長軌跡,決定你的人生成敗。 和什麼樣的人在一起,就會有什麼樣的人生。 和勤奮的人在一起,你不會懶惰; 和積極的人在一起,你不會消沈; 與智者同行,你會不同凡響; 與高人為伍,你能登上巔峰。
    • 已標示為解答 Benson_Liao 2010年7月28日 上午 08:08
    2010年7月28日 上午 06:41
    版主
  • Bill大大,使用方法(2)就可以了耶!!為什麼會這樣呢??
    2010年7月28日 上午 07:15
  • 這位大大

    或許因為你的終端設備處理速度太慢

    像我就用過當要終端設備切換RELAY時,因為要調動比較大的電流,所以這時候設備會關閉一些IO或是UART停止回應與接收,等待RELAY切換完成,這時間通常也只有幾個ms~幾百個ms甚至更大都有可能。

    小弟在想因為你傳送檔案,會不會剛好你的終端設備在處理檔案中,你有接著丟,所以當UART起來後你的檔案已經傳送一些了。

    或許你做一些測試,準備一些檔案來傳送調整SLEEP的時間,因該可以得到一些答案。

    2010年7月28日 上午 07:33
  • Bill大大,使用方法(2)就可以了耶!!為什麼會這樣呢??


    因為你一直狂送, 設備就一直狂收

    以你的例子

    SendSerialData("THIS IS A TEST A")

    SendSerialData("THIS IS A TEST B")

    SendSerialData("THIS IS A TEST C")

    有可能第一次就收到 THIS IS A TEST A THIS IS A 這樣..

    因為基本上接收端沒有判斷它收到哪邊算結束.


    在現實生活中,你和誰在一起的確很重要,甚至能改變你的成長軌跡,決定你的人生成敗。 和什麼樣的人在一起,就會有什麼樣的人生。 和勤奮的人在一起,你不會懶惰; 和積極的人在一起,你不會消沈; 與智者同行,你會不同凡響; 與高人為伍,你能登上巔峰。
    2010年7月28日 上午 07:36
    版主
  • 謝謝Bill大大及動不了大大的說明!!

    小弟有學到了一些技巧~~感謝!!

    2010年7月28日 上午 08:09
  • 请问: C# serialport 关闭串口调用 close() 方法是出现“因为执行绪结束或应用程式要求,所以已中止I/O操作”错误,请指教!

    “因为执行绪结束或应用程式要求,所以已中止I/O操作”: 这个错误看起来好像是I/O 在关闭的过程中正在被使用。我目前的做法已经在 serialport.DataReceived() 这个函数中添加 closing 和listenning 这2个bool 类型的变量去判断,可是问题还是不能解决...

    非常期盼的能够得到各位的帮助和回复~~

    2010年11月11日 上午 06:52
  • 試著先把 DataReceived事件委派移除再呼叫serialport.Close()
    在現實生活中,你和誰在一起的確很重要,甚至能改變你的成長軌跡,決定你的人生成敗。 和什麼樣的人在一起,就會有什麼樣的人生。 和勤奮的人在一起,你不會懶惰; 和積極的人在一起,你不會消沈; 與智者同行,你會不同凡響; 與高人為伍,你能登上巔峰。
    2010年11月11日 上午 08:04
    版主