2012-10-12 30 views
1

目前在我的大學我們正在做這些老的56k調制解調器之間的溝通。由於消息從PC到調制解調器通過串口,我想使用System.IO.Ports.SerialPort.NET類。當調制解調器處於DATA模式時,爲什麼System.IO.Ports.SerialPort.DataReceived事件不會觸發?

我寫了相當大的C#應用​​程序與調制解調器通訊,撥打到其他調制解調器,並通過他們溝通。這一切都運行良好,直到我設法建立兩個調制解調器之間的連接。當發生這種情況時,兩個調制解調器(應該是)從命令模式(我可以將海耶斯的命令發送到調制解調器)切換到數據模式(所有發送到調制解調器的數據都被轉發到另一個調制解調器)。

我的應用程序可以從串口發送的東西,以及接受的事情。它安裝在兩臺連接的PC上。但是當我在我的應用程序中輸入某些內容時「你好」,它沒有收到另一邊。這裏出現了怪異的部分。下面是我如何通過串口發送消息(「口」是SerialPort類的一個實例,「數據」是一個字符串的一個實例):

port.Write(data); 

所以它的工作原理。它必須工作。特別是,因爲如果我使用我的應用程序發送一方和PuTTy接收另一方 - 它的作品!連接到有效串口的PuTTy接收我的消息。它也暗示,不僅我的信息來到第一個調制解調器;它被網絡發送到另一個調制解調器,然後另一個調制解調器通過串口將它發送到接收PC。但那不是全部。當我用我的應用程序來接收,我用SerialPort.DataReceived事件,像這樣的(當然方法一直+ =編到事件處理程序):

void port_DataReceived(object sender, SerialDataReceivedEventArgs e) 
{ 
    //this message box should pop up if event hit: 
    MessageBox.Show("Data from serial port received!"); 
    //calling my method to handle incoming message 
    DataReceived((SerialPort)sender); 
} 

而且它的工作原理,當調制解調器(一個連接到PC接收)處於COMMAND模式。例如。當我向調制解調器發送「AT」Hayes命令時(這意味着無非是一個'ping'),調制解調器響應「OK」,我收到它。 SerialPort.DataReceived事件觸發。但是當這個調制解調器處於數據模式時(當我不能發送Hayes的命令給它時),並且它從發送調制解調器收到一條消息,並將它轉發到串口 - 什麼都沒有。事件甚至不會發生。我檢查得很好。

這很奇怪!

這只是讓我得出結論,調制解調器向串口發送消息的方式在數據模式和命令模式下略有不同,並且PuTTy以某種方式理解了另一種方式,並且SerialPort類的作用不。

我真的不明白這一點。

+0

自從我完成調制解調器編程已經很長時間了,但我不記得命令與透明模式之間有什麼「稍微不同」。如果有的話,「差異」必須在EIA/RS-232控制線中。因此,也許你需要附上一個帶有LED指示燈的「接線盒」,用於每個握手線的狀態。順便說一句,你沒有提及調制解調器的撥號和應答模式。我一直在遠端使用「自動應答」,即遠端調制解調器已經處於「數據」模式,並準備通過串口發送/接收數據。 – sawdust

+0

我被教過調制解調器有兩種模式:海耶斯命令的命令和數據傳輸的數據。我**正在撥號和回答:我只是發送命令_ATDT _到調制解調器撥號,另一方面,當調制解調器發送_RING_消息時,我發送ATA命令。我沒有故意使用自動回答,但是當我這樣做時,問題仍然存在。我寧願考慮一些方案解決方案,而不是帶LED的「突破箱」......這絕對可以克服我的能力(和時間)。 – Sushi271

+0

您不必使用分線盒,但它是快速驗證正確的HW流量控制和調制解調器握手信號的一種簡單方法。否則,您最好確認在所有調制解調器和PC程序上正確配置了流量控制(HW&SW)和調制解調器信號。 *「它收到來自發送調制解調器的消息,並將其轉發到串口」* - 您怎麼知道這一點?如果真的如此,那麼你的程序的「門徒」需要檢查。你的程序是否在等待一行*文本,但是你只發送了一個沒有CR和LF的「Hello」? BTW「數據」模式也被稱爲「在線」或「透明」模式。 – sawdust

回答

2

你說,當調制解調器在命令模式,並有人在串行/調制解調器通信我敢說,你正在做一些阻塞操作,當你從串口採集數據的親身經歷DataReceived事件檢索不火。

到現在爲止我做了幾個項目,SerialPort類來處理使用.NET40和交流發揮預期的調制解調器通信。

我最好的猜測是,你的方法DataReceived((的SerialPort)發送者);正在阻止進一步接收數據。

我在收集收到的數據時,爲了避免死鎖而從鎖中的端口讀取數據,但在鎖之外處理它們並確保處理完成某些操作並完成(不要做任何冗長的操作或將其掛起接收),這樣的:

void port_DataReceived(object sender, SerialDataReceivedEventArgs e) 
{ 
    var com = sender as SerialPort; 
    var lst = new List<byte>(); 

    if (com != null) 
    { 
     lock (com) 
     { 
      do 
      { 
       if (com.BytesToRead == 0) break; 
       var one = com.ReadByte(); 
       if (one >= 0 && one < 256) lst.Add(Convert.ToByte(one)); 
      } while (one >= 0 && one < 256); 

      // lst.ToArray(); // get bytes 
     } 

     // ... // do something with received data 
    } 
} 

你沒有提供有關數據處理的細節,所以我只能猜測,該代碼中是某種塊。

在提供的樣品主要有兩個要點:

  1. 讀出的數據完全,但只有當有數據讀取,不用等待數據
  2. 過程鎖外部接收的數據儘可能快和完成功能執行

此外,提供的代碼(以類似的形式)總是用於多線程應用程序,所以在Main!上的[MTAThread]屬性

一個解決串行通信最快的方式可能是安裝 com0com,虛擬串口從 http://com0com.sourceforge.net/ 並嘗試沒有調制解調器直接溝通,只是爲了確保數據交換的作品。

其實你可以在你的應用程序中使用它。 只需安裝一對虛擬通信端口,將您的應用程序連接到一個串行端口,將putty連接到其他設備上,並且當您在putty上看到ATZ時,只需迴應即可\ r \ n :) 但是,如果您使用pinout讀數,不能幫助你,至少我不知道從膩子換旗子的方法。

我知道這個線程有點舊了,但是有些反饋是可以接受的。

Happy Codding。

1

SerialDataReceivedEventHandler未被觸發,因爲Handshake設置不正確。

我不得不使用硬件流量控制,這是Handshake.RequestToSend它現在正在爲我工​​作。

相關問題