1. Introduction
Measurement automation application is an important part of modern technological world. Flexibility is very important part of this type of application. Multiple vendors produce similar pieces of equipment: power meters, multimeters, switches, scopes, power supplies, TV cameras etc. All these devices use one or multiple communication channels like serial port, GPIB, Ethernet or some custom made busses. Pluggable modules can be combined into custom-build measurement systems using chassis (i.e. Agilent 816XA/B or JDSU Map). Each manufacturer uses original set of binary or text commands. In order to provide flexibility of R&D and manufacturing process, software engineer should provide switching from one type of communication channel to another, sharing of one communication channel between several devices, switching between several brands of same type of equipment and so on without rebuilding measurements procedures itself, using some sort of initialization utility only.
Object Oriented Programming (OOP) approach provides solution for all these challenges. Communication channel, device, device’s user interface, measurement procedure and procedure’s sequence can be implemented as objects. They can be assigned as properties of other objects through abstract interfaces, providing switching from one implementation to another and sharing of the same instance of an object. OOP also provides code reusability shortening time of applications development.
Concept
Let’s define six abstraction layers:
- communication channel
- device
- device’s graphic user interface (GUI)
- measurement procedure
- procedure’s sequence
- application
There are objects, representing each abstraction layer, communicating through abstract interfaces with each other.
All objects are created and referenced to each other by some Initialization Procedure, using several steps:
- create instances of all communication channels (i.e. RS232, GPIB etc); switching from one type of communication channel to another is happening at this step
- create instances of all measurement tools and devices under test (DUT); switching between different brands is happening at this step
- assign communication channel to each measurement tool and DUT; communication channel sharing is happening at this step
- create instances of all device’s GUI
- assign instance of device to device’s GUI; one instance of device can be assign to several instances of device’s GUI
- create instances of measurement procedures, combine them in to sequences if necessary
- assign instances of devices (measurement tools and DUT) to measurement procedures; several different procedures can control same devices
Application is ready to run at this point, executing sequences of measurement procedures. Let’s take a close look to each abstraction layer:
3. Communication Channel
Let’s define the next class hierarchy for communication channels with a pure abstract interface:
ICommChannel
virtual HRESULT Write(int iNumberOfBytesToWrite, BYTE* pArr) = 0;
virtual HRESULT Read(int iMaxNumberOfBytesToRead, BYTE* pArr, int* piNumberOfBytesWasRead) = 0;
and concrete classes, derived from ICommChannel, i.e.:
RS232Port : public ICommChannel
HRESULT Init(char* PortName, …);
HRESULT Write(int iNumberOfBytesToWrite, BYTE* pArr);
HRESULT Read(int iMaxNumberOfBytesToRead, BYTE* pArr, int* piNumberOfBytesWasRead);
GPIBPort : public ICommChannel
HRESULT Init(int iBoardNumber, int iAddress, …);
HRESULT Write(int iNumberOfBytesToWrite, BYTE* pArr);
HRESULT Read(int iMaxNumberOfBytesToRead, BYTE* pArr, int* piNumberOfBytesWasRead);
SocketPort : public ICommChannel
HRESULT Init(char* HostAddr, int iHostPort, …);
HRESULT Write(int iNumberOfBytesToWrite, BYTE* pArr);
HRESULT Read(int iMaxNumberOfBytesToRead, BYTE* pArr, int* piNumberOfBytesWasRead);
etc., see diagram on Fig.1:
Figure 1
4. Device (measurement tool or DUT)
Every class, developed to control some device, is supposed to have private (or public) member of abstract type pointer to ICommChannel, i.e.
ICommChannel* m_ pCmCh;
It can be set from outside using some method or property, i.e.:
HRESULT SetCommChannel(ICommChannel* pCmCh);
or
HRESULT Init(ICommChannel* pCmCh, …);
or
m_ pCmCh = … ; for public member.
In this case, device doesn’t even know what particular communication channel it’s using. This method should be called by Initialization Procedure prior the initial/first-time usage of any device; Initialization Procedure can assign the same instance of communication channel to different devices for communication sharing.
Similar approach can be applied to instances of devices for sharing them between instances of device’s GUI and measurement procedures.
Let’s take an optical power meter (OPM) as an example and define the next class hierarchy with a pure abstract interface:
IOpticalPowerMeter
virtual HRESULT SetOPMWavelength(double WLnm) = 0;
virtual HRESULT MeasureOpticalPower(double* pPWRdBm) = 0;
and concrete classes, derived from IOpticalPwerMeter
, to control optical power meters from different manufactures, i.e.:
NewportOPM: public IOpticalPowerMeter
HRESULT Init(ICommChannel* pCmCh, bool AutoRangeFlag);
HRESULT SetOPMWavelength(double WLnm);
HRESULT MeasureOpticalPower(double* pPWRdBm) ;
AgilentOPM: public IOpticalPowerMeter
HRESULT Init(ICommChannel* pCmCh, int iSlotNumber, int iChannelNumber, bool AutoRangeFlag);
HRESULT SetOPMWavelength(double WLnm);
HRESULT MeasureOpticalPower(double* pPWRdBm) ;
JDSUMapOPM: public IOpticalPowerMeter
HRESULT Init(ICommChannel* pCmCh, int iSlotNumber, int iChannelNumber);
HRESULT SetOPMWavelength(double WLnm);
HRESULT MeasureOpticalPower(double* pPWRdBm) ;
etc., see diagram on Fig.2:
Figure 2
5. Measurement procedure
Every class, implementing some measurement procedure, is supposed to have private (or public) members of abstract type pointers to various devices, such IOpticalPowerMeter
and similar (IPowerSupply
, ITunableLaser
etc.) i.e.:
IOpticalPowerMeter* m_pOPM;
Devices (measurement tools and devices under the test), can be set from outside using some methods or properties i.e.:
HRESULT SetMeasurementTools(IOpticalPowerMeter* pOPM, IPowerSupply* pSply, …);
or
HRESULT SetDUT(…);
or
m_pOPM = … ; for public member.
In case of multiple devices of the same type, similar methods can be implemented, but accepting arrays of pointes of abstract type, i.e.:
HRESULT SetOpticalPowerMeters(IOpticalPowerMeter** ppOPMs, char** OPMNames, int iNumberOfOPMs);
This approach allows application to run measurement procedures without even knowing what particular brand of similar devices is physically connected to computer. These methods should be called by Initialization Procedure before first usage of any measurement procedure; Initialization Procedure can assign the same instance of device (measurement tool or DUT) to different measurement procedures.
Let’s derive all measurement procedures from the same abstract interface, i.e.
ITest
virtual HRESULT Run() = 0;
In this case instances of different measurement procedures can be combined into test sequences, using arrays of pointers type ITest*. Application executes measurement procedures by calling Run() method of each instance.
6. Conclusion
OOP allows software developer to build flexible measurement automaton applications, providing switching between different types of communication channels and different brands of similar Devices (measurement tools and DUT) without any code changing, but editing configuration information only.
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.