This page assumes familiarity with concepts covered in the basics. This shows how to run a sequence of experiments and controlling when to stop an experiment and start another based on external conditions. For simplicity, we are assuming having a single device connected and we are running on a single channel. So, we will not have to keep track of devices and channels. We will just focus on running and controlling the workflow of different experiments.
First we will set the environment and create the experiments:
char** test = nullptr;
int args;
QCoreApplication app(args, test);
5,
1,
10
);
0.002,
1,
10
);
auto experimentA = std::make_shared<AisExperiment>();
experimentA->appendElement(cvElement, 1);
auto experimentB = std::make_shared<AisExperiment>();
experimentB->appendElement(ccElement, 1);
auto experimentC = std::make_shared<AisExperiment>();
experimentC->appendElement(cvElement, 2);
an experiment that simulates a constant current flow with more advance options for stopping the exper...
Definition: AisConstantCurrentElement.h:15
an experiment that simulates a constant applied voltage.
Definition: AisConstantPotElement.h:15
Now we have the experiments set up. Next we will create the logic for the sequence of experiments. We will be using timers as external conditions to control the workflow. You may substitute that with your own conditions.
The following lambda function creates a logic and assigns it to the given handler. We will call this function after the AisDeviceTracker::newDeviceConnected signal has been emitted and a handler has been created. The workflow will be as follows:
- Start the first timer
- Once the timer times out, start Experiment A
- Once Experiment A completes, start the second timer
- Once the second timer times out, start Experiment B
- Start a third timer to stop Experiment B early
- Once the third timer times out, stop Experiment B
- Start a fourth timer
- Once the fourth timer times out, start Experiment C
- Once Experiment C completes, start Experiment B
QTimer* timer1 = new QTimer();
timer1->setSingleShot(true);
timer1->start(1000);
QObject::connect(timer1, &QTimer::timeout, [=]() {
qDebug() << "Initial condition met. Starting Experiment A ";
handler->uploadExperimentToChannel(0, experimentA);
handler->startUploadedExperiment(0);
static int experimentStep = 0;
qDebug() << "Experiment Step " << experimentStep << " Completed";
experimentStep++;
if (experimentStep == 1) {
QTimer* timer = new QTimer();
timer->setSingleShot(true);
timer->start(10000);
QTimer* StopEarlyTimer = new QTimer();
StopEarlyTimer->setSingleShot(true);
QObject::connect(StopEarlyTimer, &QTimer::timeout, [&]() {
qDebug() << "External early stop condition met";
handler->StopExperiment(0);
});
QObject::connect(timer, &QTimer::timeout, [&,StopEarlyTimer]() {
qDebug() << "External condition met, starting experiment B";
handler->uploadExperimentToChannel(0, experimentB);
handler->startUploadedExperiment(0);
StopEarlyTimer->start(2000);
});
} else if (experimentStep == 2) {
QTimer* timer = new QTimer();
timer->setSingleShot(true);
timer->start(10000);
QObject::connect(timer, &QTimer::timeout, [&]() {
qDebug() << "External condition met, starting Experiment C ";
handler->uploadExperimentToChannel(0, experimentC);
handler->startUploadedExperiment(0);
});
} else if (experimentStep == 3) {
QTimer* timer = new QTimer();
timer->setSingleShot(true);
timer->start(10000);
QObject::connect(timer, &QTimer::timeout, [&]() {
qDebug() << "External condition met, starting Experiment B ";
handler->uploadExperimentToChannel(0, experimentB);
handler->startUploadedExperiment(0);
});
}
});
});
};
this class provides control of the device including starting, pausing, resuming and stopping an exper...
Definition: AisInstrumentHandler.h:24
void experimentStopped(uint8_t channel)
a signal that is emitted whenever an experiment was stopped manually or has completed.
This logic we have shown demonstrates how to start and stop experiments based on external conditions/variables, and how to do so based on the behavior of other experiments as well.
We then connect the tracker's signals as we have explained in more details before.
auto tracker = AisDeviceTracker::Instance();
auto handler = tracker->getInstrumentHandler(deviceName);
createLogic(handler);
});
qDebug() << deviceName << "is disconnected ";
});
tracker->connectToDeviceOnComPort("COM3");
void deviceDisconnected(const QString &deviceName)
a signal to be emitted whenever a device has been disconnected.
void newDeviceConnected(const QString &deviceName)
a signal to be emitted whenever a new connection has been successfully established with a device.
Finally, you can start the application as follows:
Note however that this will hold your execution thread. That would be fine if this is your main application or if you have previously spawned a thread specifically for this application. Alternatively, you can start the application as follows:
while (handler.isChannelBusy(0)) {
app.processEvents();
}
app.processEvents();
You can learn more about Qt app execution here: https://doc.qt.io/qt-5/qcoreapplication.html#static-public-members