Keysight VISA.NET Help
Formatting Enumerations

Formatting Enumerations

VISA.NET Printf methods allow calling programs to convert enumeration members to strings with a bit of extra programming effort.

Mapping Enumeration Members to Strings

Although the .NET Framework allows programs to convert an enumeration value to a string that contains the enumeration member name, this is not typically useful for instrument communication. Instruments that use message-based communication typically use SCPI. SCPI and .NET naming conventions are very different, so it would not be unusual for a SCPI name and a .NET name to differ. We need a mechanism for converting from a .NET enumeration member to a SCPI name for that member.

Consider a simple SCPI command that sets a DMM measurement function:

MEASurement:FUNCtion {ACVolts|DCVolts|ACCurrent|DCCurrent|CONTinuity|RESistance}

Most programs use the abbreviated form of the commands. The abbreviated forms of the commands are the leading uppercase letters:

MEAS:FUNC {ACV|DCV|ACC|DCC|CONT|RES}

This command might be represented in a .NET program by the following enumeration:

MeasurementFunction
Copy Code
public enum MeasurementFunction
{
  ACVolts = 0,
  DCVolts = 1,
  ACCurrent = 2,
  DCCurrent = 2,
  Continuity = 2,
  Resistance = 2,
}

We want the .NET member names to map to the short SCPI string member names when formatting enumeration values:

.NET Name

SCPI String

  ACVolts

  DCVolts

  ACCurrent

  DCCurrent

  Continuity

  Resistance

ACV

DCV

ACC

DCC

CONT

RES

VISA.NET Formatted I/O gives you the ability to define a type formatter class that does exactly this.

How Type Formatting Works

Since enumerations are typically specific to the calling program, we need to provide the actual mapping for the values. Since the IVI Formatted I/O class uses the mapping to format and read enumeration values, the calling program needs to provide the mapping information in a form that the Formatted I/O class can understand. To accomplish this, the IVI VISA.NET components include an interface, ITypeFormatter, that formalizes the communication between the calling program and Formatted I/O.

At a high level, using Formatted I/O with type formatting works like this:

  1. The calling program creates a class (let's call it TypeMapper) that is capable of mapping the members of one or more enumerations to strings. This class exposes the ITypeFormatter interface.

  2. The calling program then registers the TypeMapper class with Formatted I/O using the IMessageBasedFormattedIO.TypeFormatter property.

  3. When Printf needs to format an enumeration value as a string, it calls the ITypeFormatter.ToString method implemented in TypeMapper, which returns the string that corresponds to the specified enumeration value.

  4. When Scanf needs to read a string and convert it to an enumeration member value, it calls the ITypeFormatter.Parse method implemented in TypeMapper, which returns the enumeration value that corresponds to the specified string.

Keep in mind the following caveats:

A Sample Type Formatter Class

Sample Type Formatter
Copy Code

public enum MeasurementFunction

{

  ACVolts = 0,

  DCVolts = 1,

  ACCurrent = 2,

  DCCurrent = 2,

  Continuity = 2,

  Resistance = 2,

}

 

public class TypeMapper : Ivi.Visa.ITypeFormatter

{

  public Boolean IsSupported(Type type);

  {

    switch (type)

    {

      case MeasurementFunction:

        return true; break;

      default:

        return false;

    }

  }

 

  public String ToString(Object obj);

  {

    Type type = obj.GetType();

    switch (type)

    {

      case MeasurementFunction:

        switch ((MeasurementFunction)obj)

        {

          case MeasurementFunction.ACVolts:    return "ACV"; break;

          case MeasurementFunction.ACCurrent:  return "ACC"; break;

          case MeasurementFunction.DCVolts:    return "DCV"; break;

          case MeasurementFunction.DCCurrent:  return "DCC"; break;

          case MeasurementFunction.Continuity: return "CONT"; break;

          case MeasurementFunction.Resistance: return "RES"; break;

        }

        break;

      default:

        throw new System.ArgumentException("Type {0} not supported", type.ToString());

    }

  }

 

  public Object Parse(Type type, String data);

  {

    switch (type)

    {

      case MeasurementFunction:

        switch (data)

        {

          case "ACV" return MeasurementFunction.ACVolts; break;

          case "ACC" return MeasurementFunction.ACCurrent; break;

          case "DCV" return MeasurementFunction.DCVolts; break;

          case "DCC" return MeasurementFunction.DCCurrent; break;

          case "CONT": return MeasurementFunction.Continuity; break;

          case "RES": return MeasurementFunction.Resistance; break;

          default:

            throw new System.ArgumentException("Value {0} not supported for type {1}",

                                               data, type.ToString());

        }

        break;

      default:

        throw new System.ArgumentException("Type {0} not supported", type.ToString());

    }

  }

}

Using the Type Formatter Class

Remember that Printf is adding bytes to the formatted write buffer. In this case, Printf is converting enumeration values to strings and adding the string to the buffer. Assume that the io variable is a valid reference to IMessageBasedFormattedIO.

Using the Type Formatter
Copy Code

TypeMapper mapper = new TypeMapper();

io.TypeFormatter = (ITypeMapper)mapper;

 

// Add |MEAS:FUNC CONT| to the buffer.

io.Printf("MEAS:FUNC %s", MeasurementFunction.Continuity);

 

 


© Keysight Technologies 2015-2025