This example reviews the basic signals emitted by the AisDeviceTracker and AisInstrumentHandler, which notify users of instrument events, errors, experiment data, and progress. For simplicity, all signals in this example are connected to lambda functions. However, they can be connected to any slot function compatible with the signal's signature.
Tracker Signals
The AisDeviceTracker emits signals regarding device connection, disconnection, and firmware update status. The following example demonstrates how these signals are connected. For details on firmware update signals, refer to the Firmware Update Example.
- C++
qDebug() << "New Device Connected: " << deviceName;
});
qDebug() << "New Device Connected: " << deviceName;
- Python
tracker.newDeviceConnected.connect(startExperiment)
tracker.deviceDisconnected.connect(lambda deviceName: print(f"Device Disconnected: {deviceName}"))
Experiment Data Signals
The AisInstrumentHandler emits signals containing experiment data and progress information during active experiments. The signals AisInstrumentHandler::activeDCDataReady and AisInstrumentHandler::activeACDataReady provide relevant DC and AC, respectively, and should be handled for each experiment.
- C++
qDebug() << "Timestamp: " << data.timestamp << " Current: " << data.current << " Voltage: " << data.workingElectrodeVoltage << " CE Voltage : " << data.counterElectrodeVoltage;
});
qDebug() << "Timestamp: " << data.timestamp << " Frequency: " << data.frequency << "" << data.absoluteImpedance;
});
- Python
handler.activeDCDataReady.connect(lambda channel, data: print(f"Timestamp: {data.timestamp} Current: {data.current} Voltage: {data.workingElectrodeVoltage} CE Voltage : {data.counterElectrodeVoltage}"))
handler.activeACDataReady.connect(lambda channel, data: print(f"Timestamp: {data.timestamp} Frequency: {data.frequency} Absolute Impedance: {data.absoluteImpedance}"))
Other Signals
The AisInstrumentHandler also emits other signals, such as notifications for the start of new elements, the end of an experiment, instrument errors, and more. Below are some examples:
- C++
qDebug() <<
"New element starting: " << info.
stepName;
});
qDebug() << "Experiment Stopped Signal " << channel << "Reason : " << reason;
});
qDebug() << "Device Error: " << error;
});
- Python
handler.experimentNewElementStarting.connect(lambda channel, info: print(f"New element starting: {info.stepName}"))
handler.experimentStopped.connect(lambda channel, reason: (print(f"Experiment Stopped Signal {channel}, {reason}"), app.quit()))
handler.deviceError.connect(lambda channel, error: print(f"Device Error: {error}"))
For othere signals emitted: AisInstrumentHandler signals
Connecting Signals
To connect data and handler signals to a valid AisInstrumentHandler object, ensure the connection to the instrument is fully established. This can be done by connecting signals when the AisDeviceTracker::newDeviceConnected signal is emitted.
Here, a lambda function is created to connect relevant signals to the handler when the device is connected:
- C++
qDebug() << "Timestamp: " << data.timestamp << " Current: " << data.current << " Voltage: " << data.workingElectrodeVoltage << " CE Voltage : " << data.counterElectrodeVoltage;
});
qDebug() << "Timestamp: " << data.timestamp << " Frequency: " << data.frequency << "" << data.absoluteImpedance;
});
qDebug() <<
"New element starting: " << info.
stepName;
});
qDebug() << "Experiment Stopped Signal " << channel << "Reason : " << reason;
});
qDebug() << "Device Error: " << error;
});
};
- Python
def connectSignals(handler):
handler.activeDCDataReady.connect(lambda channel, data: print(f"Timestamp: {data.timestamp} Current: {data.current} Voltage: {data.workingElectrodeVoltage} CE Voltage : {data.counterElectrodeVoltage}"))
handler.activeACDataReady.connect(lambda channel, data: print(f"Timestamp: {data.timestamp} Frequency: {data.frequency} Absolute Impedance: {data.absoluteImpedance}"))
handler.experimentNewElementStarting.connect(lambda channel, info: print(f"New element starting: {info.stepName}"))
handler.experimentStopped.connect(lambda channel, reason: (print(f"Experiment Stopped Signal {channel}, {reason}"), app.quit()))
handler.deviceError.connect(lambda channel, error: print(f"Device Error: {error}"))
Then, call this function after connecting to the device but before starting the experiment:
- C++
auto& handler = tracker->getInstrumentHandler(deviceName);
connectSignals(handler);
AisErrorCode error = handler.uploadExperimentToChannel(CHANNEL, customExperiment);
if (error) {
qDebug() << error.message();
return;
}
error = handler.startUploadedExperiment(CHANNEL);
if (error) {
qDebug() << error.message();
return;
}
- Python
handler = tracker.getInstrumentHandler(deviceName)
connectSignals(handler)
error = handler.uploadExperimentToChannel(CHANNEL, experiment)
if error.value() != AisErrorCode.Success:
print(error.message())
app.quit()
error = handler.startUploadedExperiment(CHANNEL)
if error.value() != AisErrorCode.Success:
print(error.message())
app.quit()
See the full example here
References
For information on syntax and related concepts used in this example, refer to the following documentation links:
With all the relevant code to run an experiment in place, we can now explore how the API supports building more complex experiment logic.