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.