2013-08-19 53 views
0

我在C#編程方面有點新,但不知何故,我設法找到一個項目,需要使用串口的GSM(SMS)通信方面的高超技能和知識。GSM通信,跨線程

using System; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Drawing; 
using System.Data; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 
using System.Windows.Forms; 
using System.IO.Ports; 

namespace SMSget 
{ 
    public partial class SMSLogPanel : UserControl 
    { 
     #region default constructor 
     public SMSLogPanel() 
     { 
      InitializeComponent(); 
      serialPort1 = new SerialPort(); 
      serialPort1.DataBits = 8; 
      serialPort1.DtrEnable = true; 
      serialPort1.Encoding.Equals("iso-8859-1"); 
      serialPort1.Handshake = Handshake.RequestToSend; 
      serialPort1.Parity = Parity.None; 
      serialPort1.WriteTimeout = 300; 
      serialPort1.StopBits = StopBits.One; 
      checkLink(); 
     } 
    #endregion 
    #region checking communication and setting user controls... 
    private void checkLink() 
    { 
     GetValues value = new GetValues(); 
     string com = value.getPort(); 
     int baud = value.getBaud(); 
     int timeot = value.getTimeout(); 
     serialPort1.PortName = com; 
     serialPort1.BaudRate = baud; 
     serialPort1.ReadTimeout = timeot; 

     serialPort1.Open(); 
     if (serialPort1.IsOpen) 
     { 
      label1.Visible = true; 
     } 
     else 
     { 
      MessageBox.Show("Komunikacija sa modemom se ne može uspostaviti, molimo postavite novu konfiguraciju...!"); 
      this.Controls.Clear(); 
      SMSConfigPanel cfg = new SMSConfigPanel(); 
      cfg.Show(); 
      this.Controls.Add(cfg); 
     } 
     serialPort1.Close(); 
    } 
    #endregion 
    #region setiranje timer-a... 
    private void timer1_Tick(object sender, EventArgs e) 
    { 
     timer1.Stop(); 
     execCommand(); 
     timer1.Start(); 
    } 
    #endregion 
    #region seting handler and executing AT commands 
    public void execCommand() 
    { 
     serialPort1.DataReceived += new SerialDataReceivedEventHandler(getResponse); 
     serialPort1.Open(); 
     //prazni se buffer da se ne pokupe neke vrijednosti koje ne trebaju... 
     serialPort1.DiscardInBuffer(); 

     if (!serialPort1.IsOpen) 
     { 
      MessageBox.Show("Modem nije spojen, molimo provjerite konfiguraciju...!"); 
      timer1.Stop(); 
     } 
     serialPort1.Write("AT+CMGF=1" + (char)(13)); 
     serialPort1.Write("AT+CMGL=\"ALL\"" + (char)(13)); 
    } 
    public void getResponse(object sender, SerialDataReceivedEventArgs e) 
    { 
     SerialPort serPort = (SerialPort)sender; 
     string input = serPort.ReadExisting(); 
     if (input.Contains("ERROR")) 
     { 
      //textBox2.Text = ""; 
     } 
     else if (input.Contains("+CMTI:")) 
     { 
      serialPort1.Write("AT+CMGF=1" + (char)(13)); 
      serialPort1.Write("AT+CMGL=\"ALL\"" + (char)(13)); 
     } 
     else if (input.Contains("+CMGL:")) 
     { 
      textBox1.Text = input; 
     } 
     else 
     { 
      return; 
     } 
     serialPort1.Close(); 
    } 
    #endregion 
} 

}

我認爲不知何故我設法建立在這些領域的錯誤(未打開/關閉serialPort1端口,輸入數據,其中使用單獨的線程的GetResponse(對象發件人,SerialDataReceivedEventArgs E)不能傳遞到textBox1的由於跨線程的問題......,並且可能是錯誤的AT命令用於讀取已收到UNREADED消息...)

如果有人能幫助我,我將非常感激...

謝謝和最好的問候。

+0

你有交叉線程異常? – Ehsan

回答

0

原因跨線程異常:

你總是試圖在其他線程,然後在其上創建一個更新GUI元素。不允許。

解決方案:

爲避免交叉線程異常。您應該更新代碼,這樣

this.Invoke((MethodInvoker) delegate 
    { 
     // update your textbox here 

    }); 
+0

我會嘗試它,但你能否告訴我,如果打開和關閉serialPort1是否正確完成,因爲它使我困惑......我不確定是否在右側設置了serialPort1.Open()和serialPort1.Close()地點... – dovla091

0
serialPort1.Write("AT+CMGF=1" + (char)(13)); 
serialPort1.Write("AT+CMGL=\"ALL\"" + (char)(13)); 

這是不正確的。你必須在每個命令後讀取並解析從調制解調器返回的響應,例如,像

serialPort1.Write("AT+CMGF=1" + (char)(13)); 
waitForFinalResponse(serialPort1); 
serialPort1.Write("AT+CMGL=\"ALL\"" + (char)(13)); 
waitForFinalResponse(serialPort1); 

或可能將serialPort1.Write和waitForFinalResponse組合到一個sendATCommand函數。有關更多詳細信息,另請參閱thisthis答案。