How to call two functions at the same time
-
Hello Guys,
I am using National Instruments to read sensor values in a time loop
I have two channels on NI device to read one is analog and one is digital. To read the channels i have NI function to call and i am able to call this functions. I am creating two 100 ms timers and these timers are calling these two functions of NI to read but my problem is both are not called at the same time, at first which ever function is called that function is executed and then other function is called. I dont want that i want both the functions to be called simultaneously.
How can i achieve that. Please help. Thanks in advance
Below is my code logic// Call Initialize channel functions
void manualMode::initializeChannels()
{
const char* waterCounter= "Dev1/ctr0";
const char* linecounter= "/Dev1/PFI0";
ni6002.intinalizeCounter(waterCounter, linecounter, samplesPerSecond);
const char* pressurechan="Dev1/ai0:2";
ni6002.intitializeReadAnalogPressure(const char* chan);
}
// Start Time Loop
void manualMode:: startTimeloop()
{
startCounterDataAcquisition =new QTimer();
connect(startCounterDataAcquisition, SIGNAL(timeout()), this, SLOT(getCounterData()));
startCounterDataAcquisition->start(100);
startAnalogDataAcquisition =new QTimer();
connect(startAnalogDataAcquisition, SIGNAL(timeout()), this, SLOT(getAnalogData()));
startAnalogDataAcquisition->start(100);
}//"getCounterData" and "getAnalogData" function(Time Loop Functions) will be called every 100ms in a time loop
void manualMode::getCounterData()
{
readCounterData=ni6002.readCounter();
memmove(counterBuffer, readCounterData, sizeof(double)*(samplesPerSecond/10));
counterBuffer+=(samplesPerSecond/10);
}
void manualMode::getAnalogData()
{readAnalogData=ni6002.readAnalogPressure();
memmove(dataBuffer, readAnalogData, sizeof(double)3(samplesPerSecond/10));
dataBuffer+=3*(samplesPerSecond/10);}
TaskHandle taskHandlePressure = 0;
TaskHandle taskHandle1 = 0;
// Initialize Counter
void NI6002Communication::intinalizeCounter(const char* counter, const char* linecounter,
int samplesPerSecond)
{
DAQmxCreateTask("counter", &taskHandle1);
DAQmxCreateCICountEdgesChan(taskHandle1,counter,"",DAQmx_Val_Rising,0,DAQmx_Val_CountUp);
DAQmxCfgSampClkTiming(taskHandle1,"",0.1samplesPerSecond,DAQmx_Val_Rising,DAQmx_Val_ContSamps,
0.1samplesPerSecond);//sampTerm
DAQmxStartTask(taskHandle1);
}
// Initialize Analog
void NI6002Communication::intitializeReadAnalogPressure(const char* chan)
{
int samplesPerSecond= directoryTab.settings->value("Prefill_Sample_Rate_Hz").toInt();
DAQmxCreateTask("pressure", &taskHandlePressure);
DAQmxCreateAIVoltageChan(taskHandlePressure,chan,"",DAQmx_Val_RSE,-10.0,10.0,DAQmx_Val_Volts,NULL);
DAQmxCfgSampClkTiming(taskHandlePressure,"",0.1samplesPerSecond,DAQmx_Val_Rising,DAQmx_Val_ContSamps,0.1samplesPerSecond);
DAQmxStartTask(taskHandlePressure);
}
// Read Analog
double* NI6002Communication::readAnalogPressure()
{
int samplePerSecond= directoryTab.settings->value("Prefill_Sample_Rate_Hz").toInt();
int32 samplesReceivedPressure = 0;
DAQmxReadAnalogF64(taskHandlePressure, 0.1samplePerSecond, 10.0, DAQmx_Val_GroupByChannel,
dataPressure, 30.1samplePerSecond, &samplesReceivedPressure, NULL);
return dataPressure;
}
// Read Counter
double NI6002Communication::readCounter()
{
int samplePerSecond= directoryTab.settings->value("Prefill_Sample_Rate_Hz").toInt();
int32 samplesReceivedcounterdata = 0;
DAQmxReadCounterF64(taskHandle1, 0.1samplePerSecond,10.0, counterdata,0.1samplePerSecond,
&samplesReceivedcounterdata,NULL);
return counterdata;
} -
@rockon209 said in How to call two functions at the same time:
I dont want that i want both the functions to be called simultaneously.
In computer theory there is no real "simultaneously".
The common approach is to use threads. Those threads are executed, halted, switched just so fast it looks like they are executed simultaneously.But still there are some things which can be done wrong which make the usage of threads even worse than not to use them.
So i would say first get some knowledge about threads (see the link above) and create 2 threads, one for each channel and do your work in there.
-
@raven-worx said in How to call two functions at the same time:
hed j
Thanks for the reply and information. I have already seen that link and in that its mentioned to first try with timer and i tried but doesnt work. So is there any other way except threading coz i am not familiar with threading and its very complex
-
@rockon209
In this case i think QThread is your friends.@rockon209 said in How to call two functions at the same time:
I have already seen that link and in that its mentioned to first try with timer and i tried but doesnt work.
Can you tell us how you did it?
-
// Call Initialize channel functions void manualMode::initializeChannels() { const char* waterCounter= "Dev1/ctr0"; const char* linecounter= "/Dev1/PFI0"; ni6002.intinalizeCounter(waterCounter, linecounter, samplesPerSecond); const char* pressurechan="Dev1/ai0:2"; ni6002.intitializeReadAnalogPressure(const char* chan); } // Start Time Loop void manualMode:: startTimeloop() { startCounterDataAcquisition =new QTimer(); connect(startCounterDataAcquisition, SIGNAL(timeout()), this, SLOT(getCounterData())); startCounterDataAcquisition->start(100); startAnalogDataAcquisition =new QTimer(); connect(startAnalogDataAcquisition, SIGNAL(timeout()), this, SLOT(getAnalogData())); startAnalogDataAcquisition->start(100); } //"getCounterData" and "getAnalogData" function(Time Loop Functions) will be called every 100ms in a time loop void manualMode::getCounterData() { readCounterData=ni6002.readCounter(); memmove(counterBuffer, readCounterData, sizeof(double)*(samplesPerSecond/10)); counterBuffer+=(samplesPerSecond/10); } void manualMode::getAnalogData() { readAnalogData=ni6002.readAnalogPressure(); memmove(dataBuffer, readAnalogData, sizeof(double)3(samplesPerSecond/10)); dataBuffer+=3*(samplesPerSecond/10); } TaskHandle taskHandlePressure = 0; TaskHandle taskHandle1 = 0; // Initialize Counter void NI6002Communication::intinalizeCounter(const char* counter, const char* linecounter, int samplesPerSecond) { DAQmxCreateTask("counter", &taskHandle1); DAQmxCreateCICountEdgesChan(taskHandle1,counter,"",DAQmx_Val_Rising,0,DAQmx_Val_CountUp); DAQmxCfgSampClkTiming(taskHandle1,"",0.1samplesPerSecond,DAQmx_Val_Rising,DAQmx_Val_ContSamps, 0.1samplesPerSecond);//sampTerm DAQmxStartTask(taskHandle1); } // Initialize Analog void NI6002Communication::intitializeReadAnalogPressure(const char* chan) { int samplesPerSecond= directoryTab.settings->value("Prefill_Sample_Rate_Hz").toInt(); DAQmxCreateTask("pressure", &taskHandlePressure); DAQmxCreateAIVoltageChan(taskHandlePressure,chan,"",DAQmx_Val_RSE,-10.0,10.0,DAQmx_Val_Volts,NULL); DAQmxCfgSampClkTiming(taskHandlePressure,"",0.1samplesPerSecond,DAQmx_Val_Rising,DAQmx_Val_ContSamps,0.1samplesPerSecond); DAQmxStartTask(taskHandlePressure); } // Read Analog double* NI6002Communication::readAnalogPressure() { int samplePerSecond= directoryTab.settings->value("Prefill_Sample_Rate_Hz").toInt(); int32 samplesReceivedPressure = 0; DAQmxReadAnalogF64(taskHandlePressure, 0.1samplePerSecond, 10.0, DAQmx_Val_GroupByChannel, dataPressure, 30.1samplePerSecond, &samplesReceivedPressure, NULL); return dataPressure; } // Read Counter double NI6002Communication::readCounter() { int samplePerSecond= directoryTab.settings->value("Prefill_Sample_Rate_Hz").toInt(); int32 samplesReceivedcounterdata = 0; DAQmxReadCounterF64(taskHandle1, 0.1samplePerSecond,10.0, counterdata,0.1samplePerSecond, &samplesReceivedcounterdata,NULL); return counterdata; }
it is better to read.
-
I set two timer of 100 ms (startCounterDataAcquisition and startAnalogDataAcquisition)
and start them when i press a QPushbutton after each 100 ms i am calling getCounterData, getAnalogData functions (refer the code provided) -
@raven-worx
I am using one Qthread now to read one channel but the problem is my GUI is getting slow coz in my thread there is while loop which is continuously calling the NI function to read the values at one channel