我试图搜索我的问题的副本,但找不到。此外,抱歉不那么容易理解的标题。我对我正在搜索的内容以及术语非常困惑。我是一名电子工程师,对.Net框架知之甚少,所以请好好对待我:)。
我目前的项目是一个心率监测器,可以将测得的心率存储到EEPROM中,然后发送到PC进行日志查看。
我使用RS-232(串行)协议与8位微控制器连接。每当我向微控制器发送一个代表l
的字符log
时,它会以下列格式向我发送一些信息:
0x1E 0x21 0x01 0x13 0x14 0x35 0x46 0x1E 0x21 0x01 0x13 0x14 0x43 0x48 0x0A 0x0D
空白空间仅供参考,这些字节不会相互分离。
从微控制器发送的这些8位HEX值包括记录信息的开始,0x1E
,DD 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
控件。
在评论和回答后编辑:
我没有写错误的样本。不幸的是,编码与上面完全相同。
答案 0 :(得分: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转换为实际值。
答案 1 :(得分:0)
string heartRate=70;
string recordStart=21.01.13 14:35;
string fullValue = heartRate + '|' + recordStart;
现在,您可以使用split方法轻松拆分该字符串,而不是应用正则表达式 如,
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)
我仍然不明白你的问题,如果我的答案无关紧要,请告诉我,我会澄清
答案 2 :(得分: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;
}
答案 3 :(得分: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) { }
}