CommunicationProtocol

CommunicationProtocol is the thin wrapper that sits between a HardwareObject and the operating system’s I/O facilities. It exposes a uniform writeCmd / writeBinary / queryCmd / readBytes API on top of an underlying QIODevice (or, for buses that have no QIODevice representation, no device at all). Concrete subclasses provide the actual transport: Rs232Instrument wraps a QSerialPort, TcpInstrument wraps a QTcpSocket, GpibInstrument proxies through the GPIB controller, and VirtualInstrument and CustomInstrument keep the device pointer null when no socket-style interface is appropriate.

Read behavior — timeout and termination characters — is shared across transports and is loaded from settings via loadCommReadOptions(). The convenience helpers writeCmd(), writeBinary(), and queryCmd() cover the common ASCII / binary / query patterns and may be extended or overridden by subclasses; the read termination and timeout used by queryCmd() are configured through setReadOptions(). The user-facing controls for selecting and configuring a transport per device live in Hardware and Library Configuration and the connection dialog described in Hardware Dialog.

Reaching the underlying device

_device() returns the raw QIODevice* (or nullptr when no QIODevice representation exists). When a driver needs transport functionality that the wrapper does not expose, the device<T>() template casts to the requested derived type and returns nullptr if the cast is not appropriate, so the wrong-type case is safe to detect at the call site:

CommunicationProtocol *comm = new TcpInstrument("key");
comm->initialize();

auto socket = comm->device<QTcpSocket>();
// socket is a QTcpSocket*

auto serial = comm->device<QSerialPort>();
// serial is nullptr — comm is a TcpInstrument

API Reference

class CommunicationProtocol : public QObject

Communication interface for a HardwareObject.

Interface class. Subclasses provide a transport (e.g. Rs232Instrument wraps QSerialPort, TcpInstrument wraps QTcpSocket; VirtualInstrument and CustomInstrument keep the device pointer null when no QIODevice representation is appropriate) by overriding _device() to return the underlying QIODevice. The device itself is created in initialize(), which subclasses must also implement. Read behavior — query timeout and termination characters — is loaded from settings by loadCommReadOptions().

Subclassed by CustomInstrument, GpibInstrument, Rs232Instrument, TcpInstrument, VirtualInstrument

Public Types

enum CommType

CommunicationProtocol options.

Used by HardwareObject to determine which subclass to create.

Values:

enumerator Virtual
enumerator Tcp
enumerator Rs232
enumerator Gpib
enumerator Custom
enumerator None

Public Functions

explicit CommunicationProtocol(QString key, QObject *parent = nullptr)

Constructor.

Parameters:
  • key – Key assigned to ::d_key

  • parent – QObject parent

virtual ~CommunicationProtocol()

Destructor. Does nothing.

virtual bool writeCmd(const QString &cmd)

Writes cmd to the device as ASCII-encoded data.

This function can be safely called even if the device is nullptr.

Parameters:

cmd – Data to write

Returns:

Whether data was written successfully

virtual bool writeBinary(const QByteArray &dat)

Writes dat to the device as binary data.

This function can be safely called even if the device is nullptr

Parameters:

dat – Data to write

Returns:

Whether data was written successfully

virtual QByteArray queryCmd(const QString &cmd, bool suppressError = false)

Writes cmd to the device and attempts to read a response.

This function can be safely called even if the device is nullptr. The settings used in the read portion of this function should be set using setReadOptions(). By default, a hardwareFailure() signal is emitted if there is a problem reading or writing data. This signal can be blocked by setting suppressError to true. This may be useful if intermittent failures are expected and are handled by the caller.

Parameters:
  • cmd – Command to send to the device

  • suppressError – If true, suppress the hardwareFailure() signal on read/write error

Returns:

Response from device

virtual QByteArray readBytes(qint64 n, bool suppressError = false)

Reads n bytes from device, respecting timeout.

Parameters:
  • n – Number of bytes to read

  • suppressError – If true, no failure signal will be emitted if all bytes are not read

Returns:

Bytes read

virtual QIODevice *_device() = 0

Returns a pointer to the underlying device.

Returns:

QIODevice pointer or nullptr

template<typename T>
inline T *device()

Convenience function for casting QIODevice to type T.

Returns:

Pointer to device of type T* or nullptr

void setErrorString(const QString str)

Sets contents of error string.

Parameters:

str – Error message

QString errorString()

Returns last error and clears the error string.

Returns:

Error message

void loadCommReadOptions()

Loads read options from settings for this communication protocol.

Public Members

const QString d_key

Key used to identify the communication protocol instance.

Public Slots

bool bcTestConnection()

Attempts to open the QIODevice.

This function calls testConnection() and grabs the error string if the call fails.

Returns:

Whether the QIODevice was opened successfully

virtual void initialize() = 0

Creates the QIODevice.

Signals

void hardwareFailure()

Emitted when a failure occurs with the QIODevice.

Private Functions

inline void setReadOptions(int timeout, const QString &termChar)

Sets read options for communication protocol.

Parameters:
  • timeout – Read timeout in ms (<=0 disables timeout)

  • termChar – Termination character(s) (empty disables termChar)

virtual bool testConnection() = 0

Attempts to open the QIODevice.

This function should return true if the device was opened successfully or if there is no QIODevice to open.

Returns:

Whether device was opened successfully.

Private Members

QString d_errorString

Most recent error message

QByteArray d_readTerminator

Termination characters that indicate a message from the device is complete.

bool d_useTermChar = {false}

If true, a read operation is complete when the message ends with d_readTerminator

int d_timeOut = {1000}

Timeout for read operation, in ms