2

GSMモデムからの通話を読み取るためのC#アプリケーションを開発しました。タイマーを使って定期的にポートを読み取り、着信があったときに通知しました。

今、私はAT + CSQを書き込む別のタイマーを使用しようとしています-信号品質を知るために、ポートで、品質値のポートを読み取ります。両方のタイマーで、正規表現を使用して、必要なデータを照合および分離しました。ここで問題となるのは、信号品質を読み取っている私のtimer2だけが機能しているだけで、着信コールのタイマー読み取りは機能していないということです。

タイマー読み取り信号強度:

private void tmr_sig_quality_Tick(object sender, EventArgs e)
    {
        if (port.IsOpen)
        {
            port.WriteLine("AT+CSQ");
            string s= port.ReadExisting();
            var match= Regex.Match(s,@"\+CSQ: (\d+),(\d+)");
            if (match.Success)
            {
                progressBar1.Value = int.Parse(match.Groups[1].Value);
            }

        }
    }

着信コールを読み取るタイマー:

      private void timer1_Tick(object sender, EventArgs e)
       {
                s = port.ReadExisting();

                var match = Regex.Match(s, "RING[^\\+]*\\+CLIP:\\s*\"(?<phone>[^\"]*)\",(\\d+),\"([^\"]*)\",(\\w*),\"(\\w*)\",(\\w*)");

                if (match.Success && s.Contains("RING"))
                {
                    incall_status.Text = "Incoming Call...." + match.Groups["phone"].Value;
                    incall_status.Visible = true;
                }
        }

なぜこれが起こっているのですか、解決策をお願いしますか?

4

2 に答える 2

2

2つの大きな問題。最初は ReadExisting() で、常に空の文字列を返します。コードを 1 行ずつデバッグしてステップ実行する場合を除きます。これにより、モデムが応答を送信するのに十分な時間が与えられます。しかし、フルスピードで実行すると、これは機能しません。返されたすべての文字を取得するのに十分な時間、プログラムが待機することを保証するブロッキング呼び出しを行う必要があります。代わりに ReadLine() を使用してください。

2 番目の致命的な問題は、コマンドを混在させていることです。あなたの tmr_sig_quality_Tick() メソッドは、timer1_Tick() が読み取るはずだったものを読み取る可能性があります。このアプローチを再考する必要があります。コマンドへの応答が受信されるまで先に進まないコマンドのキューのようなもの。

于 2012-07-30T12:57:50.183 に答える
1

あなたの質問に対する実際の回答ではありませんが、GSM モデムと通信するための一般的なアドバイス:

シリアル ポートは 1 つしかないため、通信チャネルは 1 つしかないことに注意してください。GSM モデムは、RING、FAX、VOICE イベントなどの自発的なイベントを送信できるため、AT+CSQ を記述したときに、最初の応答が期待どおり、つまり信号品質であるという保証はありません。

Aが自発的なイベントの1つを読み取ったため、Bで予想されたときに最終的にタイマーAで1つのコマンドの応答になるため、意図したように2つのタイマーを使用することはお勧めできません...など.

はるかに優れた堅牢な方法は、受信データを読み取って解釈し、必要に応じてアプリケーションに配布するワーカー スレッドを用意することです。また、送信データを処理することもできます。このスレッドとのデータ交換には、同時キューとシグナル メカニズム (AutoResetEvent など) を使用します。これにより、ハードウェア デバイスへのインターフェイスがよりクリーンになり、アプリケーションでタイミングなどを気にする必要がなくなります。

于 2012-07-30T12:55:30.580 に答える