0

gsm モデムを制御する C# シリアル ポートを使用しています。送信後、Mikroelectronia USART ターミナルで:

AT+CUSD=1,"*778#",15

それは受け取ります:

AT+CUSD=1,"*778#",15

わかった

+CUSD: 0,"Balance: 0.00 TK. Validity: 29-Jul-13. Bonus: 0.00TK. Free Min: 0. Dial *121*2092# for Ashiqui-2 as ur Caller Tunetk.10" ,64

しかし、データを送信した後、C#で

AT+CUSD=1,"*778#",15

戻ります:

AT+CUSD=1,"*778#",15

わかった

+CUSD: 0,"Balance: 0.00 TK. Validity: 29-Jul-13. Bonus: 0.00TK. Free Min: 0. Dial *121*2092# ur Caller Tune として Ashiqui-2 のヒット曲 3 曲

つまり、C# では「Caller Tune」の後にデータを受信しません。なぜそれが起こっているのですか?私が使用したC#コードの一部は

        private void Form1_Load(object sender, EventArgs e)
        {
            sp1.DataReceived += new SerialDataReceivedEventHandler(sp_DataReceived);
        }

        void sp_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            var valueOfPort = sp1.ReadExisting();
            textBox1.AppendText(valueOfPort);

        }
 private void button1_Click(object sender, EventArgs e)
        {
            TextBox.CheckForIllegalCrossThreadCalls = false;

            try
            {


                if (!sp1.IsOpen)
                {
                    sp1.Open();
                }
                sp1.Write(textBox2.Text+"\r");

            }
            catch(Exception ex)
            {

                MessageBox.Show(string.Format("Exception : {0}", ex.Message), "Port Error");
            }
        }
4

2 に答える 2

3

これTextBox.CheckForIllegalCrossThreadCalls = false;は私を非常に疑わしくさせます。それがあなたのプログラムを壊していると思います。テキストボックスを適切に更新するために呼び出すだけで、うまくいくと思います。イベント コードを次のように変更するだけです。

void sp_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
    if(textbox1.InvokeRequired)
    {
        textbox1.Invoke(new SerialDataReceivedEventHandler(sp_DataReceived), sender, e);
    }
    else
    {
        var valueOfPort = sp1.ReadExisting();
        textBox1.AppendText(valueOfPort);
    }
}

これにより、正しいスレッドで実行されているかどうかがチェックされます。そうでない場合は、同じ引数を使用して UI スレッドで関数が再起動されます。また、必ず取り外してくださいTextBox.CheckForIllegalCrossThreadCalls = false;


更新: MSDNを読み直した後、この発言を見つけました

このメソッドは、SerialPort オブジェクトのストリームと内部バッファの内容を文字列として返します。このメソッドはタイムアウトを使用しません。このメソッドは、後続のリード バイトを内部バッファに残す可能性があることに注意してください。これにより、BytesToRead 値が 0 より大きくなります。

を呼び出した後、さらに読み取るデータがあるかどうかを確認してくださいReadExisting

void sp_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
    if(textbox1.InvokeRequired)
    {
        textbox1.Invoke(new SerialDataReceivedEventHandler(sp_DataReceived), sender, e);
    }
    else
    {
        while(sp1.BytesToRead > 0)
        {
            var valueOfPort = sp1.ReadExisting();
            textBox1.AppendText(valueOfPort);
        }
    }
}
于 2013-07-22T00:31:33.283 に答える
1

デバイスの EOL を定義し、プログラムで正しく設定しましたか? C# シリアル ポートは、必ずしもメッセージの開始時に DataReceive を開始するわけではなく、メッセージの終了位置も認識しません。メッセージのどこでも終了する可能性があります。ポートが受信メッセージをバッファリングし、完了したらそれを返すために、ポートによって一意に識別できる EOL を明示的に設定してみてください。

// e.g. I normally used (carriage return + newline) instead of just either one
sp1.NewLine = "\r\n";
于 2013-07-22T00:31:54.520 に答える