08-27-2010 01:43 AM
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.
08-31-2010 02:44 AM - edited 08-31-2010 02:50 AM
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
09-23-2010 08:55 AM
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