2
votes

I'm sort of new at this and I'm writing a small application to read data from a voltmeter. It's a RadioShack Digital Multimeter 46-range. The purpose of my program is to perform something automatically when it detects a certain voltage. I'm using C# and I'm already familiar with the SerialPort class.

My program runs and reads the data in from the voltmeter. However, the data is all unformatted/gibberish. The device does come with its own software that displays the voltage on the PC, however this doesn't help me since I need to grab the voltage from my own program. I just can't figure out how to translate this data into something useful.

For reference, I'm using the SerialPort.Read() method:

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

It grabs the data and displays it as so:

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

The space separates each element of the array. If I use a char[] array instead of byte[], I get complete gibberish:

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

Using the .ReadExisting() method gives me:

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

.ReadLine() times out, so doesn't work. ReadByte() and ReadChar() just give me numbers similar to the Read() into array function.

I'm in way over my head as I've never done something like this, not really sure where else to turn.

4
Don't you have any documentation? Or any support from manufacturer?Oscar
No, it was a cheap RadioShack voltmeter. Their documentation has nothing on this topic, it only pertains to their own software.Robert Joseph Dacunto
You need to get the API documentation from the manufacturer. Without it this is probably a lost cause.user1864610
Sounds like the interface is proprietary then. I would run a bunch of tests and try to reverse engineer it. Look for patterns and then make educated guesses from what you see on the voltmeter and what you see in hex.Lucas B
Take a look at this, although this may not be for your model. See if you can make heads or tails of the data you are getting.Andyz Smith

4 Answers

3
votes

It sounds like you're close, but you need to figure out the correct Encoding to use.

To get a string from an array of bytes, you need to know the Code Page being used. If it's not covered in the manual, and you can't find it via a google/bing/other search, then you will need to use trial and error.

To see how to use GetChars() to get a string from a byte array, see Decoder.GetChars Method In the code sample, look at this line:

 Decoder uniDecoder = Encoding.Unicode.GetDecoder();

That line is specifically stating that you are to use the Unicode code page to get the correct code page.

From there, you can use an override of the Encoding class to specify different Code Pages. This is documented here: Encoding Class

If the Encoding being used isn't one of the standards, you can use the Encoding(Int32) override in the Constructor of the Encoding class. A list of valid Code Page IDs can be found at Code Pages Supported by Windows

0
votes

There are two district strategies for solving your communications problem.

  1. Locate and refer to appropriate documentation and design\modify a program to implement the specification.

    The following may be appropriate, but are not guaranteed to describe the particular model DVM that you have. Nonetheless, they MAY serve as a starting point. note that the authors of these documents comment that the Respective models may be 'visually identical', but also comments that '"Open-source packages that reportedly worked on LINUX with earlier RS-232 models do not work with the 2200039"

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

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

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

  1. Try to reverse engineer the protocol. if you can read the data in a loop and collect the results, a good approach to reverse engineering a protocol, is to apply various representative signals to the DVM. You can use a short-circuit resistance measurements, various stable voltage measurements, etc.

The technique I suggest is most valuable is to use an automated variable signal generator. In this way, by analyzing the patterns of the data, you should be more readily be able to identify which points represent the raw data and which points represent stable descriptive data, like the unit of measurements, mode of operation, etc.

0
votes

Some digital multimeters use 7 bit data transfer. You should set serial communication port to 7 data bits instead of standard 8 data bits.

0
votes

I modified and merged a couple of older open source C programs together on linux in order to read the data values from the radio shack meter whose part number is 2200039. This is over usb. I really only added a C or an F on one range. My program is here, and it has the links where I got the other two programs in it.

I know this example is not in C#, but it does provide the format info you need. Think of it is as the API documentation written in C, you just have to translate it into C# yourself.

The protocol runs at 4800 baud, and 8N1 appears to work.