6

問題の重複を検索しようとしましたが、見つかりませんでした。また、分かりにくいタイトルで申し訳ありません。何を検索しているのか、また用語についても混乱しています。私は、.Net フレームワークに関する知識がほとんどない電子工学エンジニアです。

私の現在のプロジェクトは、測定された心拍数を EEPROM に保存して、後でログを表示するために PC に送信できる心拍数モニターです。

RS-232 (シリアル) プロトコルを使用して 8 ビット マイクロコントローラーと接続しています。lを表すcharlogをマイクロコントローラーに送信するたびに、次の形式でいくつかの情報が返されます。

0x1E 0x21 0x01 0x13 0x14 0x35 0x46 0x1E 0x21 0x01 0x13 0x14 0x43 0x48 0x0A 0x0D

空のスペースは情報提供を目的としており、これらのバイトは互いに分離されていません。

マイクロコントローラーから送信されるこれらの 8 ビット HEX 値には、記録開始情報 ( 0x1EDD MM YY HH MM 形式の日付と時刻、および記録された心拍数) が含まれます。すべてのレコードがエコーされると、0x0A および 0x0D 文字が送信されます。

たとえば、上記のコードは次のことを意味します。

Record start.
21.01.13 14:35
Heart Rate: 70
Record start.
21.01.13 14:43
Heart Rate: 72
End of records.

「S210113143570S210113144372」のような文字列値を取得するにはどうすればSよいですか。その後、正規表現構文をこれに適用し、グループに分割して、これらの値をlistviewコントロールに追加できるようにします。

コメントと回答の後に編集:

私はサンプルを間違って書いていません。残念ながら、エンコーディングは上記とまったく同じです。

4

4 に答える 4

5

したがって、実際には各バイトは数値を表します。どういうわけか、byte[]これらの値を含む配列が既にあると仮定します。

var data = new byte[] { 0x1E, 0x21, 0x01, 0x13, 0x14, 0x35, 0x46,
                        0x1E, 0x21, 0x01, 0x13, 0x14, 0x43, 0x48, 0x0A, 0x0D };

次のような実際のオブジェクトを作成できます。

class LogEntry
{
    public DateTime Timestamp { get; set; }
    public int HeartRate { get; set; }
}

var logEntries = new List<LogEntry>();

for(int i = 0; i < data.Length; i+= 7)
{
    if(data[i] == 0x0a && data[i + 1] == 0x0d)
        break;
    if(data[i] != 0x1e)
        throw new InvalidDataException();

    var logEntry = new LogEntry();
    var year = BcdToDecimal(data[i + 3]) + 2000;
    var month = BcdToDecimal(data[i + 2]);
    var day = BcdToDecimal(data[i + 1]);
    var hour = BcdToDecimal(data[i + 4]);
    var minute = BcdToDecimal(data[i + 5]);
    var heartRate = data[i + 6];
    logEntry.Timestamp = new DateTime(year, month, day, hour, minute, 0);
    logEntry.HeartRate = heartRate;
    logEntries.Add(logEntry);
}

byte BcdToDecimal(byte bcdValue)
{
    return (byte)((bcdValue / 16 * 10) + (bcdValue % 16));
}

このメソッドBcdToDecimalは、BCD を実際の値に変換します。

于 2013-01-21T12:22:01.603 に答える
0

私の非常にばかげた間違いをお詫び申し上げます。マイクロコントローラ側でこれを行うのは非常に簡単で、クロックサイクルをそれほど消費しないことがわかりました。これで、値を解析するのは非常に簡単になりました。

マイクロコントローラー側でこのルーチンを使用しました。

unsigned char BCDtoDecimal(unsigned char bcd_number)
{
  return ((bcd_number>>4)*10 + (bcd_number&0x0F));
}

したがって、C# 側のコードは非常に簡単です。

    private void buttonGetLogs_Click(object sender, EventArgs e)
    {
        string inputBuffer;
        char[] charArray;
        try
        {
            serialPort.Write("l");
            inputBuffer = serialPort.ReadLine();
            charArray = inputBuffer.ToCharArray();
            inputBuffer = string.Empty;
            foreach (char item in charArray)
            {
                inputBuffer += Convert.ToInt32(item).ToString();
            }
        }
        catch (Exception) { }
    }
于 2013-01-21T13:49:25.747 に答える
0

兄弟、文字列の使用を検討する必要があると思います。つまり、

string heartRate=70;
string recordStart=21.01.13 14:35;
string fullValue = heartRate + '|' + recordStart;

正規表現を適用する代わりに、分割メソッドを使用してその文字列を簡単に分割できます。

string splittedValues[]=fullValue.Split('|');

必要に応じてこれらの値を取得します

splittedValues[0] \\it will be heard rate string (at index zero)
similarly
splittedValues[1] \\it will be record start string (at index one)

私はまだあなたの問題を理解していません.私の答えが無関係である場合は、教えてください.

于 2013-01-21T12:22:11.350 に答える
0
public static String ParseData(String data)
{
    MatchCollection matches = Regex.Matches(data, "0[xX]([a-fA-F0-9]{2})");

    Int32 count = 0;
    String result = String.Empty;

    foreach (Match match in matches)
    {
        switch (count)
        {
            case 0:
            {
                if (match.Value.Equals("0x1E", StringComparison.OrdinalIgnoreCase))
                {
                    result += "S";
                    break;
                }

                goto End;
            }

            case 1:
            case 2:
            case 3:
            case 4:
            case 5:
                result += match.Groups[1].Value;
                break;

            case 6:
                result += Int32.Parse(match.Groups[1].Value, NumberStyles.HexNumber).ToString();
                count = -1;
                break;
        }

        ++count;
    }

    End:;

    return result;
}
于 2013-01-21T13:14:26.887 に答える