From Friday, April 19th (11:00 PM CDT) through Saturday, April 20th (2:00 PM CDT), 2024, ni.com will undergo system upgrades that may result in temporary service interruption.

We appreciate your patience as we improve our online experience.

Digital I/O

cancel
Showing results for 
Search instead for 
Did you mean: 

multiple port change detection NIDAQMx

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.

0 Kudos
Message 1 of 3
(5,082 Views)

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;
}

 

0 Kudos
Message 2 of 3
(5,073 Views)

 

Hello,

 

What kind of card do you have ?

 

Regards

Samuel G. | GEMESIS

Certified LabVIEW Architect

Certified TestStand Developer

GEMESIS.EU

0 Kudos
Message 3 of 3
(5,008 Views)