【问题标题】:GSM communication, cross threadingGSM通讯,交叉线程
【发布时间】:2013-08-19 17:21:41
【问题描述】:

我在 C# 编程方面有点新手,但不知何故,我设法找到了一个需要使用 serialPort 进行 GSM (SMS) 通信的高超技能和知识的项目。

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(object sender, SerialDataReceivedEventArgs e) 中的输入数据由于跨线程问题而无法传递到 textBox1 中。 .,并且可能是错误的 AT 命令来读取已收到的 UNREADED MESSAGES...)

如果有人能帮我解决这个问题,我将非常感激......

谢谢你和最好的问候。

【问题讨论】:

  • 你遇到了跨线程异常?

标签: c# multithreading serial-port at-command


【解决方案1】:

跨线程异常原因:

您正在尝试更新线程上的 GUI 元素,而不是创建它的线程。这是不允许的。

解决方案:

为了避免跨线程异常。你应该像这样更新你的代码

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

    });

【讨论】:

  • 我会试试的,但是你能告诉我是否正确地打开和关闭了 serialPort1,因为它让我感到困惑......我不确定我是否设置了 serialPort1.Open() 和 serialPort1 .Close() 在正确的地方...
【解决方案2】:
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 答案了解更多详情。

【讨论】:

    猜你喜欢
    • 2018-04-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-11
    • 2014-08-03
    相关资源
    最近更新 更多