从电压表通过串口读取数据

时间:2013-08-27 19:27:30

标签: c# .net serial-port

我对此有点新意,我正在编写一个小应用程序来读取电压表的数据。这是一款46S的RadioShack数字万用表。我的程序的目的是在检测到某个电压时自动执行某些操作。我正在使用C#,我已经熟悉了SerialPort类。

我的程序运行并从电压表读取数据。但是,数据都是未格式化/乱码的。该设备带有自己的软件,显示PC上的电压,但这对我没有帮助,因为我需要从我自己的程序中获取电压。我无法弄清楚如何将这些数据翻译成有用的东西。

作为参考,我使用的是SerialPort.Read()方法:

byte[] voltage = new byte[100];
_serialPort.Read(voltage, 0, 99);

它抓取数据并显示如下:

16 0 30 0 6 198 30 6 126 254 30 0 30 16 0 30 0 6 198 30 6 126 254 30 0 30 16 0 3
0 0 6 198 30 6 126 254 30 0 30 16 0 30 0 6 198 30 6 126 254 30 0 30 16 0 30 0 6
198 30 6 126 254 30 0 30 24 0 30 0 6 198 30 6 126 254 30 0 30 16 0 30 0 254 30 6
126 252 30 0 6 0 30 0 254 30 6 126 254 30 0

空格分隔数组的每个元素。如果我使用char []数组而不是byte [],我会得到完全的胡言乱语:

▲   ? ? ▲ ♠ ~ ? ▲   ♠   ▲   ? ? ▲ ♠ ~ ? ▲   ♠   ▲   ? ? ▲ ♠ ~ ? ▲   ♠

使用.ReadExisting()方法给我:

▲ ?~?♠~?▲ ▲? ▲  ?~♠~?▲ ?↑ ▲ ??~♠~?▲ F? ▲ ??~♠~?▲ D? ▲ ??~♠~?▲ f?

.ReadLine()超时,所以不起作用。 ReadByte()和ReadChar()只给我一些类似于Read()到数组函数的数字。

由于我从来没有做过这样的事情,所以我不知道该怎么回事。

4 个答案:

答案 0 :(得分:3)

听起来你很接近,但你需要弄清楚要使用的正确编码。

要从字节数组中获取字符串,您需要知道正在使用的代码页。如果手册中没有介绍它,并且您无法通过google / bing /其他搜索找到它,那么您将需要使用反复试验。

要了解如何使用GetChars()从字节数组中获取字符串,请参阅Decoder.GetChars Method 在代码示例中,请查看以下行:

 Decoder uniDecoder = Encoding.Unicode.GetDecoder();

该行明确指出您将使用Unicode代码页来获取正确的代码页。

从那里,您可以使用Encoding类的覆盖来指定不同的代码页。这在此处记录:Encoding Class

如果正在使用的编码不是标准之一,则可以在Encoding类的构造函数中使用Encoding(Int32)覆盖。可以在Code Pages Supported by Windows

找到有效代码页ID的列表

答案 1 :(得分:0)

解决您的通信问题有两种策略。

  1. 找到并参考相应的文档并设计\修改程序以实现规范。

    以下内容可能适用,但不保证能够描述您拥有的特定型号DVM 。尽管如此,他们 MAY 是一个起点。 请注意,这些文档的作者评论说,各自的模型可能“在视觉上相同”,但也评论“”据报道,使用早期RS-232模型在LINUX上工作的开源软件包不适用于2200039“

  2. http://forums.parallax.com/attachment.php?attachmentid=88160&d=1325568007

    http://sigrok.org/wiki/RadioShack_22-812

    http://code.google.com/p/rs22812/

    1. 尝试对协议进行反向工程。如果您可以在循环中读取数据并收集结果,那么对协议进行逆向工程的一种好方法是将各种代表性信号应用于DVM。您可以使用短路电阻测量,各种稳定电压测量等。
    2. 我建议的技术最有价值的是使用自动变量信号发生器。通过这种方式,通过分析数据模式,您应该更容易识别哪些点代表原始数据哪些点代表稳定的描述性数据,如测量单位,模式操作等。

答案 2 :(得分:0)

某些数字万用表使用7位数据传输。您应该将串行通信端口设置为7个数据位而不是标准的8个数据位。

答案 3 :(得分:0)

我在linux上修改并合并了几个较旧的开源C程序,以便从部件号为2200039的无线电小屋仪表中读取数据值。这已经过了usb。我真的只在一个范围上添加了C或F.我的程序是here,它有链接,我有其他两个程序。

我知道这个例子不在C#中,但它确实提供了您需要的格式信息。可以认为它是用C语言编写的API文档,您只需将其自己翻译成C#即可。

该协议以4800波特率运行,8N1似乎正常工作。