How to Continuously acquire signal
-
Hello guys I am getting a signal continuously from a USB device. I want to store or display it on screen the whole time untill my program is stopped or someone pushes the stop button how i can do that. I have install the drivers for the device and i can read the signal also but, the problem is when i run my code it read the signal value at that particular time and not for the whole time till the program is stopped. Should i use the while loop and read the signal in this while loop till the program is stopped. Please help. Thanks in advance.
-
@rockon209 said in How to Continuously acquire signal:
Should i use the while loop and read the signal in this while loop till the program is stopped.
No.
Do the reading in a qobject and move that qobject in another thread
Can you show your current code?
-
@VRonin
for example following is the code and i am getting 1000 sample (data) points but i want to all the sample till the program is running#include <QApplication> #include <QWidget> #include <QDebug> #include <NIDAQmx.h> int main(int argc, char **argv) { // Initialize a usual Qt application QApplication app(argc, argv); QWidget w; // Initialize DAQmx and read analog input (Copied and simplified from // http://www.ni.com/tutorial/5409/en/#toc3 ) TaskHandle taskHandle = 0; int32 samplesReceived = 0; float64 data[1000]; DAQmxCreateTask("MyTask", &taskHandle); DAQmxCreateAIVoltageChan(taskHandle, "Dev1/ai0", "", DAQmx_Val_Cfg_Default, -10.0, 10.0, DAQmx_Val_Volts, NULL); DAQmxCfgSampClkTiming(taskHandle, "", 10000.0, DAQmx_Val_Rising, DAQmx_Val_FiniteSamps, 1000); DAQmxStartTask(taskHandle); DAQmxReadAnalogF64(taskHandle, 1000, 10.0, DAQmx_Val_GroupByChannel, data, 1000, &samplesReceived, NULL); DAQmxStopTask(taskHandle); DAQmxClearTask(taskHandle); // Print results qDebug() << "Received" << samplesReceived << "points"; for (int i = 0; i < samplesReceived; ++i) qDebug() << data[i]; // Run Qt event loop w.show(); return app.exec(); }
-
@SGaist @Irshad @VRonin
Actually I am new to Qt. Could you please explain it with an example so that I can understand. I have written DAQmx read/write function in one .cpp file.and will call them when i want to read/write the data. But i dont know how I can read it all the time till the program is running. -
#include <QObject> #include <QThread> #include <QCoreApplication> #include <atomic> #include <array> class DAQmxWorker : public QObject{ Q_OBJECT Q_DISABLE_COPY(DAQmxWorker) public: explicit DAQmxWorker(QObject* parent=Q_NULLPTR) :QObject(parent) { m_continueLoop.store(false); } Q_SIGNAL void sampleReceived(int32 samplesReceived, const std::array<float64,1000>& data); Q_SIGNAL void finished(); Q_SLOT void execute(){ m_continueLoop.store(true); while(m_continueLoop.load()){ TaskHandle taskHandle = 0; int32 samplesReceived = 0; std::array<float64,1000> data; DAQmxCreateTask("MyTask", &taskHandle); DAQmxCreateAIVoltageChan(taskHandle, "Dev1/ai0", "", DAQmx_Val_Cfg_Default, -10.0, 10.0, DAQmx_Val_Volts, NULL); DAQmxCfgSampClkTiming(taskHandle, "", 10000.0, DAQmx_Val_Rising, DAQmx_Val_FiniteSamps, 1000); DAQmxStartTask(taskHandle); DAQmxReadAnalogF64(taskHandle, 1000, 10.0, DAQmx_Val_GroupByChannel, data.data(), 1000, &samplesReceived, NULL); DAQmxStopTask(taskHandle); DAQmxClearTask(taskHandle); sampleReceived(samplesReceived,data); QCoreApplication::processEvents(); } finished(); } Q_SLOT void stop(){ m_continueLoop.store(false); } private: std::atomic_bool m_continueLoop; };
now you can use it as suggested in the post linked above:
QThread* thread = new QThread; DAQmxWorker* worker = new DAQmxWorker(); worker->moveToThread(thread); connect(thread, SIGNAL(started()), worker, SLOT(execute())); connect(worker, SIGNAL(finished()), thread, SLOT(quit())); connect(worker, SIGNAL(finished()), worker, SLOT(deleteLater())); connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater())); thread->start();
when new data gets read the
sampleReceived
signal will be emitted and you can connect to it from whatever thread you like.
to stop it just callworker->stop();
from the main thread -
Hello @VRonin
please have a look at this code i have just entered a while loop and it works fine just to read the data continuously. Is this the right way to do it.?#include <QApplication>
#include <QWidget>
#include <QDebug>#include <NIDAQmx.h>
int main(int argc, char **argv)
{
// Initialize a usual Qt application
QApplication app(argc, argv);
QWidget w;
while(true)
{
// Initialize DAQmx and read analog input (Copied and simplified from
// http://www.ni.com/tutorial/5409/en/#toc3 )
TaskHandle taskHandle = 0;
int32 samplesReceived = 0;
float64 data[1000];DAQmxCreateTask("MyTask", &taskHandle); DAQmxCreateAIVoltageChan(taskHandle, "Dev1/ai0", "", DAQmx_Val_Cfg_Default, -10.0, 10.0, DAQmx_Val_Volts, NULL); DAQmxCfgSampClkTiming(taskHandle, "", 10000.0, DAQmx_Val_Rising, DAQmx_Val_FiniteSamps, 1000); DAQmxStartTask(taskHandle); DAQmxReadAnalogF64(taskHandle, 1000, 10.0, DAQmx_Val_GroupByChannel, data, 1000, &samplesReceived, NULL); DAQmxStopTask(taskHandle); DAQmxClearTask(taskHandle); // Print results qDebug() << "Received" << samplesReceived << "points"; for (int i = 0; i < samplesReceived; ++i) qDebug() << data[i];
}
// Run Qt event loop
w.show();
return app.exec();
} -
if you try it you'll see your widget will not show up at all.
I gave you the solution above...
Otherwise (and probably better) see if DAQmx allows to pass a callback function to execute when data is available (something like QIODevice does with the readyRead() signal)
-
@VRonin ya you are right
But I am not able to understand how your logic of QThread is working. Suppose i have a start button and if i press it ,the code(your code) will store the data in an array. Means let say that i have a analog input (room temperature measuring device connected) to the NI device. And I want to check the the temp every one second. So how I can make the logic so that i can measure and display it in the widget. -
@rockon209 said in How to Continuously acquire signal:
And I want to check the the temp every one second.
This is not continuously acquire data. this is reading every once in a while. You can use a QTimer for that, either in the main thread or the worker object
QTimer updateTimer(1000); connect(&updateTimer,&QTimer::timeout,[]()->void{ // Initialize DAQmx and read analog input (Copied and simplified from // http://www.ni.com/tutorial/5409/en/#toc3 ) TaskHandle taskHandle = 0; int32 samplesReceived = 0; float64 data[1000]; DAQmxCreateTask("MyTask", &taskHandle); DAQmxCreateAIVoltageChan(taskHandle, "Dev1/ai0", "", DAQmx_Val_Cfg_Default, -10.0, 10.0, DAQmx_Val_Volts, NULL); DAQmxCfgSampClkTiming(taskHandle, "", 10000.0, DAQmx_Val_Rising, DAQmx_Val_FiniteSamps, 1000); DAQmxStartTask(taskHandle); DAQmxReadAnalogF64(taskHandle, 1000, 10.0, DAQmx_Val_GroupByChannel, data, 1000, &samplesReceived, NULL); DAQmxStopTask(taskHandle); DAQmxClearTask(taskHandle); // Print results qDebug() << "Received" << samplesReceived << "points"; for (int i = 0; i < samplesReceived; ++i) qDebug() << data[i]; };) updateTimer.start();