Multifunction DAQ

cancel
Showing results for 
Search instead for 
Did you mean: 

Haute fréquence avec une carte ENET 9234

Bonjour,

 

Je voudrais faire de l'acquisition haute fréquence avec une carte Enet 9234.

 

Pour cela je développe en C++ et utilise Ni-DAQmx .

 

j'utilise la fonction DAQmxRegisterEveryNSamplesEvent pour enregistrer une fonction callback

 

et dans cette fonction j'utilise la fonction de lecture : DAQmxReadAnalogF64

 

Lorsque je fais une acquisition sur plus de 10 minutes à 51200 Hz (max de la carte)

 

j'obtient le message suivant :

 

Attempted to read samples that are no longer available. The requested sample was previously available, but has since been overwritten.

 

Increasing the buffer size, reading the data more frequently, or specifying a fixed number of samples to read instead of reading all available samples might correct the problem.
Property: DAQmx_Read_RelativeTo
Corresponding Value: DAQmx_Val_CurrReadPos
Property: DAQmx_Read_Offset
Corresponding Value: 0

 

Task Name: Dev1_AI

 

Existe t- il une autre méthode pour effecuter des acquisitions à haute fréquence sur des durées importantes (plusieurs heures)  ?

 

Cordialement.

0 Kudos
Message 1 of 3
(3,035 Views)

Bonjour,

 

Merci d’avoir posté votre question sur les forums de National Instruments.

 

Comme l’indique votre message d’erreur, votre problème vient du fait que vous lisez énormément d’échantillons (51200 par seconde) sur une longue période. De ce fait, vous remplissez rapidement l’espace mémoire alloué pour votre opération de lecture d’échantillons. Dès lors, les derniers échantillons enregistrés sont réecrits sur les plus anciens.

 

Une méthode efficace pour résoudre ce problème serait de faire une acquisition de vos échantillons continue et bufférisée. Les données mesurée par votre module 9234 seraient alors stockées dans le buffer jusqu’à lecture (et déchargement) de celui-ci par votre programme. Il faudra bien sûr configurer la lecture du buffer afin que celle-ci soit suffisamment rapide (et décharge un nombre de points suffisant du buffer) par rapport à votre fréquence d’acquisition.

 

Vous pouvez vous inspirer de l’exemple de LabWindows/CVI appelé « ContAcq-IntClk-EveryNsamplesEvent.c » (situé dans l’Example Finder de LabWindows/CVI >> Hardware Input and Output >> DAQmx >> Analog Measurements >> Voltage) pour réaliser cette opération.

 

J’espère que cette réponse vous aura permis d’avancer dans la résolution de votre problème.

 

Cordialement,

Guillaume H.
National Instruments France

0 Kudos
Message 2 of 3
(3,003 Views)

Bonjour,

Merci pour votre réponse.

 

J'utilise déjà cette méthode, lorsque je lance une acquisition très longue (9heures) à une fréquence de 3000Hz, après environ 7 heures d'acq, j'ai le même message d'erreur qui apparait.

 

Je ne comprends pas comment je peux faire pour augmenter la vitesse, car j'utilise une fonction callback.

 

voici le code ma fonction callback :

 

 

int32 TCarteNImx::everyN(TaskHandle taskHandle, int32 everyNsamplesEventType, uInt32 nSampless)
{
if (taskHandle != m_TaskHandleAI)
	return 0;
try
	{

	// calcul du temps courant

	// Dans cette fonction on lit la totalité des voies
	//Entier NbVoies = LPEntreesAnalogique.size();
	unsigned long NbVoies = 0;

	DAQmxErrChk (DAQmxGetTaskNumChans(taskHandle,&NbVoies));

	if (NbVoies == 0)
		return 0;

	int32       NbEchLuParVoie = 0;


	/*********************************************/
	// DAQmx Read Code
	/*********************************************/
	uInt32 Availble;
	DAQmxErrChk(DAQmxGetReadAvailSampPerChan(taskHandle,&Availble));
	/*#ifdef _DEBUG
	uInt64 Position;
	int32 Offset;

	DAQmxErrChk(DAQmxGetReadCurrReadPos(taskHandle,&Position));
	DAQmxErrChk(DAQmxGetReadOffset(taskHandle,&Offset));


	LOG("Nombre restant à lire : " + ToStr((int)Availble) + " - nSampless :" + ToStr((int)nSampless) + " - " + ToStr((int)Position) + " Offset :" + ToStr((int)Offset));

	#endif*/

	// Création du tableau pour récupérer les valeurs des voies
	// La taille du tableau doit être égal à nSampless*NbVoies
	// sinon on ne lit pas assez de valeurs sur la carte

	Entier TailleTotalBuffer = Availble*NbVoies;
	float64     *data = new float64[TailleTotalBuffer];


	// lecture du buffer de la carte
	DAQmxErrChk (DAQmxReadAnalogF64(taskHandle,
									Availble, /* DAQmx_Val_Auto, /* On recupère les valeurs disponibles */
									10.0, /* TimeOut de récupération */
									DAQmx_Val_GroupByChannel, //DAQmx_Val_GroupByScanNumber, /* Entrelacement des données */
									data, /* Tableau de récupération */
									TailleTotalBuffer, /* Taille total du tableau */
									&NbEchLuParVoie, /* Nombre d'echantillons récupérés par voie */
									NULL));

	if (NbEchLuParVoie == 0)
		return 0;

	TIteratorListePVoieCartes Iv;
	TEntreeAnalogique *PVoie;

	Entier IndiceVoie = 0;

	// La taille du tableau est définie en fonction du nombre de point
	// Reel que l'on doit mettre dans les voies
//	Entier TailleTab = NbEchLuParVoie;
	cDonnees Donnee;
	for (Iv = LPEntreesAnalogique.begin();Iv != LPEntreesAnalogique.end(); Iv++)
		{
		PVoie = (TEntreeAnalogique*)(*Iv);
		if (PVoie && PVoie->m_ALire)
			{
			PVoie->m_Frequence = m_FrequenceReel;
			if (PVoie->Numero >= 0)
				{
				// Enregistre la valeur dans la voie
				// En lui appliquant les coefficients du capteur associé
				Entier nbEchDsVoie = PVoie->m_NbEch;

				// Indice de correspondance dans le tableau
				Entier Debut = IndiceVoie*NbEchLuParVoie;
				Entier Fin = Debut + NbEchLuParVoie;

				//cDonnees *Tab = new cDonnees[NbEchLuParVoie];

				for (Entier i=0; i < NbEchLuParVoie; i++)
					{
					if ((Debut+i)<TailleTotalBuffer)
						{
					//	Tab[i].m_X = (Reel(nbEchDsVoie+i))/m_FrequenceReel;
					//	Tab[i].m_Y = data[Debut+i];

						// On ajoute la données dans la voie
						Donnee.m_X = (Reel(nbEchDsVoie+i))/m_FrequenceReel;
						Donnee.m_Y = data[Debut+i];
						PVoie->Ajouter(Donnee);
						}
					}
				/*if (TailleTab != 0)
					PVoie->Ajouter(Tab,TailleTab);
				delete[] Tab;*/
				}
			IndiceVoie++;
			}
		}
	delete[] data;

	// Increment le nombre d'echantillon lu depuis le dernier callback
	m_NbEchLus += NbEchLuParVoie;
	// toutes les voies sont lues alors on leve un evenement
	if (m_CallBack != NULL && m_NbEchLus >= m_FrequenceCallBack)
		{
		// Set le drapeau Lecture terminée de la carte
		m_LectureTerminee = true;

		m_CallBack(m_NbEchLus);
		m_NbEchLus = 0;
		}
	}
catch (Exception &e)
	{
	int32       error=0;
	char        errBuff[2048]={'\0'};
	DAQmxGetExtendedErrorInfo(errBuff,2048);
	EffacerTaches();
	LOG(errBuff);
	if (m_CallBackErreur)
		{
		m_CallBackErreur(errBuff);
		}
	}
}

 

 

Merci pour votre aide.

Cordialement

0 Kudos
Message 3 of 3
(2,927 Views)