07-15-2014 09:32 AM - edited 07-15-2014 09:33 AM
Hi everyone,
I want to make a change detection on 3 port, it works perfectly for 1 port, the code is a copy & paste for the 2 others.
I have follow the NiDaqMx example.
The C file :
#pragma hdrstop
#pragma argsused
#include <tchar.h>
#include <stdio.h>
#include <string>
#include <time.h>
#include <windows.h>
#include <iostream>
#include "NIDAQmx.h"
#include "GPIO.h"
#define DAQmxErrChk(functionCall) if( DAQmxFailed(error=(functionCall)) ) throw error; else
int32 CVICALLBACK ChangeDetectionCallback(TaskHandle taskHandle, int32 signalID, void *callbackData);
static uInt32 numLines;
static uInt8 cachedData[200];
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
int32 error=0;
int retour=0, exit=0;
uInt8* data_port;
uInt8* data_port_in;
uInt8 data_port_out[48];
int32 nb_echantillons=0;
char choix;
unsigned char buffer_port_task_in1[] = "Dev1/port0/line0:4";
unsigned char buffer_port_task_in2[] = "Dev1/port1/line0:4";
unsigned char buffer_port_task_in3[] = "Dev1/port2/line0:4";
TaskIn tache_in1(buffer_port_task_in1);
TaskIn tache_in2(buffer_port_task_in2);
TaskIn tache_in3(buffer_port_task_in3);
try
{
printf("creation des taches\n");
tache_in1.create();
tache_in2.create();
tache_in3.create();
printf("creation reussie\n\n");
while(exit == 0)
{
printf("%s\n", "1 : Lecture port 0");
printf("%s\n", "4 : activation interruptions / change - detections");
printf("%s\n", "8 : DESactivation interruptions / change - detections");
printf("%s\n", "autre : exit");
fflush(stdin);
choix = getchar();
switch(choix)
{
case '1' : data_port = tache_in1.ReadDigChan();
data_port = tache_in2.ReadDigChan();
data_port = tache_in3.ReadDigChan();
exit = 0;
break;
case '4' : tache_in1.activeInterupt();
tache_in2.activeInterupt();
tache_in3.activeInterupt();
exit = 0;
break;
case '8' : tache_in1.desactiveInterupt();
tache_in2.desactiveInterupt();
tache_in3.desactiveInterupt();
exit = 0;
break;
default : exit = 1;
break;
}
}
//fermetures des taches si elles sont ouvertes et destructions
tache_in1.~TaskIn();
tache_in2.~TaskIn();
tache_in3.~TaskIn();
retour = 1;
}
catch (string s) //mes messages DE DEBUG
{
cout << s << endl;
retour = 0;
}
catch(int32 error) //rattrapage de toutes les erreurs
{
if(error == tache_in1.error){
printf("Erreur sur la lecture des signaux : %d\n", tache_in1.error);
printf("(Premier des 3 test)\n\n");
DAQmxGetExtendedErrorInfo(tache_in1.errBuff,2048);
}
if(error == tache_in2.error){
printf("Erreur sur la lecture des signaux : %d\n", tache_in2.error);
printf("(Premier des 3 test)\n\n");
DAQmxGetExtendedErrorInfo(tache_in2.errBuff,2048);
}
if(error == tache_in3.error){
printf("Erreur sur la lecture des signaux : %d\n", tache_in3.error);
printf("(Premier des 3 test)\n\n");
DAQmxGetExtendedErrorInfo(tache_in3.errBuff,2048);
}
retour = 0;
}
if(retour) //1=succes, 0=fail
printf("Sortie du programme, appuyez sur une touche");
else
printf("ECHEC - Sortie du programme, appuyez sur une touche\n");
fflush(stdin); //vider le buffer d'entree
getchar();
return retour;
}
GPIO::GPIO(unsigned char* buffer_nom) : error(0), buffer_nom(buffer_nom), TaskHandle(0), activite_tache(0)
{
errBuff[0]='\0';
}
GPIO::~GPIO()
{
}
void GPIO::affichage_data_canal(char value)
{ //affichage de 1 ou 0 suivant le bit associé
printf("\nParking_FIN1 = %d\n", (value & PARK_FIN1));
printf("Referencement_FIN2 = %d\n", (value & REF_FIN2) >> (REF_FIN2 -1));
printf("TTL_FB = %d\n", (value & TTL_FB) >> (TTL_FB -1));
printf("Alarme1 = %d\n", (value & ALARME1) >> (ALARME1 -1));
printf("Alarme2 = %d\n", (value & ALARME2) >> (ALARME2 -1));
}
TaskIn::TaskIn(unsigned char* buffer_in) : GPIO(buffer_in), interrupt_validees(0)
{
}
void TaskIn::create()
{
DAQmxErrChk (DAQmxCreateTask("",&TaskHandle)); //ensuite acces par le taskHandle
DAQmxErrChk (DAQmxCreateDIChan(TaskHandle,buffer_nom,"",DAQmx_Val_ChanForAllLines));
}
TaskIn::~TaskIn()
{
if( TaskHandle !=0 )
{
if(activite_tache == 1) //cad tache active
{
DAQmxStopTask(TaskHandle);
activite_tache = 0;
}
DAQmxClearTask(TaskHandle);
}
}
uInt8* TaskIn::ReadDigChan()
{
uInt8 data[100];
int32 read,bytesPerSamp;
int32 i;
string my_string = "\nINTERRUPTION VALIDEES, IMPOSSIBLE DE LIRE\n\n";
try
{
//si les interruptions sont activées on ne peut poas lire en meme temps
if(interrupt_validees == 0)
{
// DAQmx Start Code
if(activite_tache == 0)
{
DAQmxErrChk (DAQmxStartTask(TaskHandle));
activite_tache = 1;
}
// DAQmx Read Code
DAQmxErrChk (DAQmxReadDigitalLines(TaskHandle,1,10.0,DAQmx_Val_GroupByChannel,data,100,&read,&bytesPerSamp,NULL));
for(i=0;i<bytesPerSamp;++i)
{
printf("valeur decimale : %d, canal : %d, source : %s\n", data[i], i, buffer_nom);
}
DAQmxErrChk (DAQmxStopTask(TaskHandle));
activite_tache = 0;
}
else
throw my_string;
}
catch (string s) //mes messages DE DEBUG
{
cout << s << endl;
data[0]=-1;
}
return(data);
}
void TaskIn::activeInterupt()
//permet de notifier le soft d'un changement via les change detectection
{
if(interrupt_validees == 0)
{
interrupt_validees = 1;
DAQmxErrChk (DAQmxCfgChangeDetectionTiming(TaskHandle,buffer_nom,buffer_nom,DAQmx_Val_ContSamps,1));
DAQmxErrChk (DAQmxRegisterSignalEvent(TaskHandle,DAQmx_Val_ChangeDetectionEvent,0,ChangeDetectionCallback,NULL));
DAQmxErrChk (DAQmxGetTaskNumChans(TaskHandle,&numLines));
if(activite_tache == 0)
{
DAQmxErrChk (DAQmxStartTask(TaskHandle));
activite_tache = 1;
}
printf("interruptions lancees (si la tache est active), go au callback\n");
printf("tache active si lecture (1)");
}
else
printf("interruptions deja validees");
}
void TaskIn::desactiveInterupt()
{
if(interrupt_validees == 1)
{
Cleanup();
create(); //recréation de la tache sur le meme objet
interrupt_validees = 0;
}
else printf("les interruptions ne sont pas validees!\n");
}
void TaskIn::Cleanup (void)
{
if( TaskHandle!=0 )
{
/*********************************************/
// DAQmx Stop Code
/*********************************************/
DAQmxStopTask(TaskHandle);
DAQmxClearTask(TaskHandle);
TaskHandle = 0;
}
}
int32 CVICALLBACK ChangeDetectionCallback(TaskHandle taskHandle, int32 signalID, void *callbackData)
{
int32 error = 0;
uInt8 data[200]={0};
int32 numRead;
uInt32 i=0;
char buff[512], *buffPtr;
char *timeStr;
time_t currTime;
if( taskHandle ) {
time (&currTime);
timeStr = ctime(&currTime);
timeStr[strlen(timeStr)-1]='\0'; // Remove trailing newline.
// DAQmx Read Code lecture de ligne (autre utilisation présent dans GPIO.h)
DAQmxErrChk (DAQmxReadDigitalLines(taskHandle,1,10.0,DAQmx_Val_GroupByScanNumber,data,8,&numRead,NULL,NULL));
if( numRead ) {
buffPtr = buff;
strcpy(buff, timeStr);
strcat(buff," ");
buffPtr = buff + strlen(buff);
for(;i<numLines;++i) {
sprintf(buffPtr,"%d",data[i]);
buffPtr++;
}
strcat(buff," ");
buffPtr = buff + strlen(buff);
for(i=0;i<numLines;++i) {
sprintf(buffPtr,"%c",data[i]==cachedData[i]?'-':'X');
buffPtr++;
cachedData[i] = data[i];
}
puts(buff);
fflush(stdout);
}
}
return 0;
}
the header file :
#ifndef GPIO_H
#define GPIO_H
#define PARK_FIN1 0x01
#define REF_FIN2 0x02
#define TTL_FB 0x04
#define ALARME1 0x08
#define ALARME2 0x10
#define OFF_ 0x00
#define ON_ 0x01
class GPIO
{
public:
union int32bitint {
uInt32 integer;
unsigned char byte[4];
};
void affichage_data_canal(char value);
GPIO(unsigned char* buffer_nom);
~GPIO();
public :
int32 error;
int32 activite_tache;
TaskHandle TaskHandle;
char errBuff[2048];
unsigned char* buffer_nom;
};
class TaskIn : public GPIO
{
public:
void activeInterupt();
void desactiveInterupt();
void Cleanup (void);
uInt8* ReadDigChan();
void create();
TaskIn(unsigned char* buffer_in);
~TaskIn();
private:
int interrupt_validees;
};
#endif
It fails on the :
DAQmxErrChk (DAQmxStartTask(TaskHandle));
of
void TaskIn::activeInterupt()
{
}
Thanks you very much for your reply.
Simon Irand.
07-15-2014 10:43 AM
I have something which is running, I have create 1 task including 3 ports
Is it possible to create 3 different tasks?
Thank you
#pragma hdrstop
#pragma argsused
#include <tchar.h>
#include <stdio.h>
#include <string>
#include <time.h>
#include <windows.h>
#include <iostream>
#include "NIDAQmx.h"
#include "GPIO.h"
#define DAQmxErrChk(functionCall) if( DAQmxFailed(error=(functionCall)) ) throw error; else
int32 CVICALLBACK ChangeDetectionCallback(TaskHandle taskHandle, int32 signalID, void *callbackData);
static uInt32 numLines;
static uInt8 cachedData[200];
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
int32 error=0;
int retour=0, exit=0;
uInt8* data_port;
uInt8* data_port_in;
uInt8 data_port_out[48];
char choix;
unsigned char buffer_port_task_in[] = "Dev1/port0/line0:4, Dev1/port1/line0:4, Dev1/port2/line0:4";
TaskIn tache_in(buffer_port_task_in);
try
{
printf("creation des taches\n");
tache_in.create();
printf("creation reussie\n\n");
while(exit == 0)
{
printf("%s\n", "1 : Lecture port 0");
printf("%s\n", "4 : activation interruptions / change - detections");
printf("%s\n", "8 : DESactivation interruptions / change - detections");
printf("%s\n", "autre : exit");
fflush(stdin);
choix = getchar();
switch(choix)
{
case '1' : data_port = tache_in.ReadDigChan();
exit = 0;
break;
case '4' : tache_in.activeInterupt();
if(tache_in.activite_tache == 0)
{
DAQmxErrChk (DAQmxStartTask(tache_in.TaskHandle));
tache_in.activite_tache = 1;
}
exit = 0;
break;
case '8' : tache_in.desactiveInterupt();
exit = 0;
break;
default : exit = 1;
break;
}
}
//fermetures des taches si elles sont ouvertes et destructions
tache_in.~TaskIn();
retour = 1;
}
catch (string s) //mes messages DE DEBUG
{
cout << s << endl;
retour = 0;
}
catch(int32 error) //rattrapage de toutes les erreurs
{
if(error == tache_in.error){
printf("Erreur sur la lecture des signaux : %d\n", tache_in.error);
printf("(Premier des 3 test)\n\n");
DAQmxGetExtendedErrorInfo(tache_in.errBuff,2048);
}
retour = 0;
}
if(retour) //1=succes, 0=fail
printf("Sortie du programme, appuyez sur une touche");
else
printf("ECHEC - Sortie du programme, appuyez sur une touche\n");
fflush(stdin); //vider le buffer d'entree
getchar();
return retour;
}
GPIO::GPIO(unsigned char* buffer_nom) : error(0), buffer_nom(buffer_nom), TaskHandle(0), activite_tache(0)
{
errBuff[0]='\0';
}
GPIO::~GPIO()
{
}
void GPIO::affichage_data_canal(char value)
{ //affichage de 1 ou 0 suivant le bit associé
printf("\nParking_FIN1 = %d\n", (value & PARK_FIN1));
printf("Referencement_FIN2 = %d\n", (value & REF_FIN2) >> (REF_FIN2 -1));
printf("TTL_FB = %d\n", (value & TTL_FB) >> (TTL_FB -1));
printf("Alarme1 = %d\n", (value & ALARME1) >> (ALARME1 -1));
printf("Alarme2 = %d\n", (value & ALARME2) >> (ALARME2 -1));
}
TaskIn::TaskIn(unsigned char* buffer_in) : GPIO(buffer_in), interrupt_validees(0)
{
}
void TaskIn::create()
{
DAQmxErrChk (DAQmxCreateTask("",&TaskHandle)); //ensuite acces par le taskHandle
DAQmxErrChk (DAQmxCreateDIChan(TaskHandle,buffer_nom,"",DAQmx_Val_ChanForAllLines));
}
TaskIn::~TaskIn()
{
if( TaskHandle !=0 )
{
if(activite_tache == 1) //cad tache active
{
DAQmxStopTask(TaskHandle);
activite_tache = 0;
}
DAQmxClearTask(TaskHandle);
}
}
uInt8* TaskIn::ReadDigChan()
{
uInt8 data[100];
int32 read,bytesPerSamp;
int32 i;
string my_string = "\nINTERRUPTION VALIDEES, IMPOSSIBLE DE LIRE\n\n";
try
{
//si les interruptions sont activées on ne peut poas lire en meme temps
if(interrupt_validees == 0)
{
// DAQmx Start Code
if(activite_tache == 0)
{
DAQmxErrChk (DAQmxStartTask(TaskHandle));
activite_tache = 1;
}
// DAQmx Read Code
DAQmxErrChk (DAQmxReadDigitalLines(TaskHandle,1,10.0,DAQmx_Val_GroupByChannel,data,100,&read,&bytesPerSamp,NULL));
for(i=0;i<bytesPerSamp;++i)
{
printf("valeur decimale : %d, canal : %d, source : %s\n", data[i], i, buffer_nom);
}
DAQmxErrChk (DAQmxStopTask(TaskHandle));
activite_tache = 0;
}
else
throw my_string;
}
catch (string s) //mes messages DE DEBUG
{
cout << s << endl;
data[0]=-1;
}
return(data);
}
void TaskIn::activeInterupt()
//permet de notifier le soft d'un changement via les change detectection
{
if(interrupt_validees == 0)
{
interrupt_validees = 1;
DAQmxErrChk (DAQmxCfgChangeDetectionTiming(TaskHandle,buffer_nom,buffer_nom,DAQmx_Val_ContSamps,1));
DAQmxErrChk (DAQmxRegisterSignalEvent(TaskHandle,DAQmx_Val_ChangeDetectionEvent,0,ChangeDetectionCallback,NULL));
DAQmxErrChk (DAQmxGetTaskNumChans(TaskHandle,&numLines));
printf("interruptions lancees (si la tache est active), go au callback\n");
printf("tache active si lecture (1)");
}
else
printf("interruptions deja validees");
}
void TaskIn::desactiveInterupt()
{
if(interrupt_validees == 1)
{
Cleanup();
create(); //recréation de la tache sur le meme objet
interrupt_validees = 0;
}
else printf("les interruptions ne sont pas validees!\n");
}
void TaskIn::Cleanup (void)
{
if( TaskHandle!=0 )
{
DAQmxStopTask(TaskHandle);
DAQmxClearTask(TaskHandle);
TaskHandle = 0;
}
}
int32 CVICALLBACK ChangeDetectionCallback(TaskHandle taskHandle, int32 signalID, void *callbackData)
{
int32 read,bytesPerSamp;
int32 error = 0;
uInt8 data[200]={0};
if( taskHandle )
{
DAQmxErrChk (DAQmxReadDigitalLines(taskHandle,1,10.0,DAQmx_Val_GroupByChannel,data,100,&read,&bytesPerSamp,NULL));
for(int i=0;i<bytesPerSamp;++i)
{
printf("valeur decimale : %d, canal : %d\n", data[i], i);
}
}
return 0;
}
07-22-2014 10:34 AM
Hello,
What kind of card do you have ?
Regards
Samuel G. | GEMESIS
Certified LabVIEW Architect
Certified TestStand Developer