0

シリアル ポートからデータを受信し、それらのデータを複数行のテキスト ボックスに表示します。データには、開始ヘッダー (>)、識別子 (「T」または「I」または「N」)、および終了ヘッダー (<) があります。したがって、完全なメッセージは >T123< または >N456< または >I086< のようなものです。txtOutput に表示されるデータは、シリアル出力ウィンドウでは次のように表示される場合でも、各行ごとに正しい形状 >T123< で表示されます。

>T22
0<\r\n
>T22
2<\r\n
>T22
2<\r\n
>T223<\r\n
>
T225<\r\n
>
T228<\r\n
....

PID で何らかの計算を行うためにこれらのデータをフィルタリングする必要があり、ヘッダーと識別子を削除するクラスを作成しました。このクラスは、他の計算に使用できるように、さまざまな変数 (a、b、c) で既に並べ替えられたデータを返します。これは、シリアルからデータを受け取り、txtOutput にデータを追加するメソッドです。これで問題ありません。次に、メソッドはデータをクラス " strp.Distri(invia , out a, out b, out c)" に送信します。

 private void SetText(string text)
        {
            if (this.txtOutput.InvokeRequired)
            {
             SetTextCallback d = new SetTextCallback(SetText);
             this.BeginInvoke(d, new object[] { text });
            }
            else
            {
               txtOutput.AppendText(text);
               string a = "", b = "", c = "";
               string invia = text.ToString();
               Stripper strp = new Stripper();
               strp.Distri(invia, out a, out b, out c);

               textBox7.Text = a; //current
               textBox2.Text = b; //temperature
               textBox6.Text = c; //giri

これは、不要な文字をフィルタリングして取り除くために使用しているクラスです。

 class Stripper
{

 public  void  Distri (string inComing, out string param1, out string param2, out string param3)

    {
        string current="";
        string temperature="";
        string numRPM="";
        string f = inComing;
        char firstChar = f[0];
        char lastChar =f [f.Length - 1];
        bool test1 =(firstChar.Equals('>'));
        bool test2 =(lastChar.Equals('<'));
        int messLenght = f.Length;

     if (test1 == true && test2 == true && messLenght <=6)
     {
        f = f.Replace("<", "");
        f = f.Replace(">", "");

             if (f[0] == 'I')
             {
              string _current = f;
             _current = _current.Replace("I", "");
              current = _current;
              }
            else if (f[0] == 'T')
            {
            string _temperature = f;
             _temperature = _temperature.Replace("T", "");
              temperature = _temperature;
            }
            else if (f[0] == 'N')
            {
            string _numRPM = f;
            _numRPM = _numRPM.Replace("N", "");
            numRPM = _numRPM;
            }

            else
            {}
     }

     else
     {}
        param1 = current;
        param2 = temperature;
        param3 = numRPM;

    }
}

これは私のシリアル ポートと関連付けられているデリゲートです。

delegate void SetTextCallback(string text);
private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
        {

            try
            {
                SetText(serialPort1.ReadExisting());

            }

            catch (Exception ex)
            {
                SetText(ex.ToString());
            }

        }

私の問題は、「test1」と「test2」の後のメッセージがフラグメントで受信されるため、明らかに真実ではないため、a、b、および c から何も返されないことです。どうすればこの問題を解決できますか? これらのメッセージをクラス Stripper に送信する前に、これらのメッセージを正しく再構成する方法はありますか?

4

3 に答える 3

1

データを受け取ったら、それを文字列に追加します。CRLF (\r\n) を確認し続け、見つかった場合はその行を処理できます。ただし、シリアルポートからフラグメントを受信したため、最後に文字が表示される場合があることに注意してください。

ずっと前に、同様の機能が必要でした。したがって、コードは以下のようになりました。受信ハンドラーは次のようになります (receivedText はグローバル文字列で、receivedData は現在受信したデータです)

        receivedText = String.Concat(receivedText, receivedData);

        /* do nothing - already copied to buffer */
        if ((receivedText.Contains("\r\n") == false))
        {
            return;
        }

        /* get the lines from the received text */
        string[] lines = receivedText.Split(new string[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries);

        /* process your lines here */

        /* keep the remaining portion of the fragment after the end of new line */
        if(receivedText.EndsWith("\r\n"))
        {
            receivedText = "";
        }
        else
        {
            receivedText = receivedText.Substring(receivedText.LastIndexOf('\n') + 1);
        }
于 2013-05-24T14:07:34.640 に答える
0

たとえば、入力文字列が ">T223<\r\n" の場合、firstchar は '>' になり、lastchar は '<' になります。test1 はパスしますが、test2 は常に失敗します。if 条件

if (test1 == true && test2 == true && messLenght <=6)

満たされることはありません。文字列から不要な文字を置き換えるか削除します。

于 2013-05-24T13:36:51.523 に答える