Changeset 4892


Ignore:
Timestamp:
07/10/12 17:01:12 (6 years ago)
Author:
kohler
Message:

Incorporated the error macro code as shown in NI sample programs.
Improved loggin.
Named this version "1.1".

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/data_sources/adsendxs/adsendxs.c

    r4828 r4892  
    4545      the Earthworm ew2file program.  The snwclient program can pick 
    4646      up these files and send them to a SeisnetWatch server. 
     47 
     48   Version Numbers: 
     49   1.1  Uses defined function DAQmxErrChk() 
    4750************************************************************************/ 
    4851 
     
    6164#include "adsendxs.h" 
    6265 
     66/* Macro definition to handle error returns from NI function calls. 
     67   If the function fails, the program goes to the Error lablel and then exits. 
     68   **************************************************************************/ 
     69#define DAQmxErrChk(functionCall) if( DAQmxFailed(error=(functionCall)) ) goto Error; else 
     70 
    6371/* Function declarations 
    6472   *********************/ 
    65 void  DAQmxErrorDetected( TaskHandle taskHandle ); 
    66 void  ExitAdsendxs( TaskHandle taskHandle ); 
    6773int   GetGpsTime( time_t *tgps, int *antennaOpen ); 
    6874int   OpenPort( int ComPort, int BaudRate, int ReadFileTimeout ); 
     
    107113static int      traceBufSize;       // In bytes, including tracebuf header 
    108114static MSG_LOGO tbufLogo;           // Logo of tracebuf message to put out 
    109 static int      callbackExitFlag=0; // If 1, a callback function wants the program to exit 
    110115static FILE     *gpsLockFile;       // Contains time of last GPS lock 
    111116static int      antennaOpenPrev = UNKNOWN; 
     117static int      EveryNCallbackRequestedExit = FALSE; 
     118static int      DoneCallbackRequestedExit = FALSE; 
    112119 
    113120/* Share these with other files 
    114121   ****************************/ 
    115122SHM_INFO        Region;              // Structure for shared-memory region 
    116 pid_t           MyPid;               // Process id, sent with heartbeat 
     123pid_t           MyPid;               // Process id, sent to statmgr with heartbeat 
    117124MSG_LOGO        snwLogo;             // Logo of SeisnetWatch message to be sent 
     125 
     126/* The version number and date of this program 
     127   *******************************************/ 
     128const char      version[] = "1.1"; 
     129const char      releaseDate[] = "July 9, 2012"; 
    118130 
    119131 
     
    122134int main( int argc, char *argv[] ) 
    123135{ 
    124    int32         rc; 
    125    TaskHandle    taskHandle=0;      // For NI callback task 
    126    unsigned char InstId;            // Installation id placed in trace header 
    127    int           chan;              // Channel number 
     136   int32         error = 0; 
     137   char          errBuff[2048]={'\0'}; 
     138   TaskHandle    taskHandle=0;       // For NI callback task 
     139   unsigned char InstId;             // Installation id placed in trace header 
     140   int           chan;               // Channel number 
    128141 
    129142/* Get command line arguments 
     
    139152   logit_init( argv[1], 0, 1024, 1 ); 
    140153 
     154/* Log the version number and date 
     155   *******************************/ 
     156   logit( "e", "adsendxs version %s\n", version ); 
     157   logit( "e", "Release date: %s\n\n", releaseDate ); 
     158 
    141159/* Read and log configuration parameters 
    142160   *************************************/ 
     
    147165   } 
    148166   LogConfig(); 
    149    printf( "BaudRate        = %d bps\n",            BaudRate ); 
    150    printf( "GetGpsDelay     = %d milliseconds\n",   GetGpsDelay ); 
    151    printf( "ReadFileTimeout = %d milliseconds\n\n", ReadFileTimeout ); 
    152167 
    153168/* Get our process id for restart purposes 
     
    244259   { 
    245260      logit( "et", "DisableAutoPackets error.\n" ); 
    246       ExitAdsendxs( taskHandle ); 
     261      ClosePort(); 
     262      return -1; 
    247263   } 
    248264 
     
    253269   { 
    254270      logit( "et", "GetPpsOutputStatus error.\n" ); 
    255       ExitAdsendxs( taskHandle ); 
     271      ClosePort(); 
     272      return -1; 
    256273   } 
    257274 
     
    265282   { 
    266283      logit( "et", "SetUtcMode error.\n" ); 
    267       ExitAdsendxs( taskHandle ); 
     284      ClosePort(); 
     285      return -1; 
    268286   } 
    269287 
    270288/* Start setting up the X-series DAQ board. 
    271    First, we create an analog input task. 
     289   First, create an analog input task. 
    272290   ***************************************/ 
    273291   logit( "et", "Creating the NI analog input task.\n" ); 
    274    rc = DAQmxCreateTask( "AnalogInputTask", &taskHandle ); 
    275    if ( DAQmxFailed(rc) ) DAQmxErrorDetected( taskHandle ); 
     292   DAQmxErrChk( DAQmxCreateTask("AnalogInputTask", &taskHandle) ); 
    276293 
    277294/* Use non-referenced, single-ended (NRSE) inputs. 
     
    281298   for ( chan = 0; chan < Nchan; chan++ ) 
    282299   { 
    283       rc = DAQmxCreateAIVoltageChan( taskHandle, 
    284            ChanList[chan].daqChan,  // Physical channel name 
    285            "",                      // Virtual name to assign to channel 
    286            DAQmx_Val_NRSE,          // Input terminal config for channel 
    287            -2.5,                    // Min voltage you expect to measure 
    288            +2.5,                    // Max voltage you expect to measure 
    289            DAQmx_Val_Volts,         // Values are returned in volts 
    290            NULL );                  // Custom scale name (not used) 
    291  
    292       if ( DAQmxFailed(rc) ) DAQmxErrorDetected( taskHandle ); 
     300      DAQmxErrChk( DAQmxCreateAIVoltageChan( taskHandle, 
     301           ChanList[chan].daqChan,    // Physical channel name 
     302           "",                        // Virtual name to assign to channel 
     303           DAQmx_Val_NRSE,            // Input terminal config for channel 
     304           -2.5,                      // Min voltage you expect to measure 
     305           +2.5,                      // Max voltage you expect to measure 
     306           DAQmx_Val_Volts,           // Values are returned in volts 
     307           NULL) );                   // Custom scale name (not used) 
    293308   } 
    294309 
     
    296311   ***************************/ 
    297312   logit( "et", "Configuring NI sample clock timing.\n" ); 
    298    { 
    299       rc = DAQmxCfgSampClkTiming( taskHandle, 
    300            NULL,                     // Use on-board clock 
    301            (float64)SampRate,        // Sampling rate 
    302            DAQmx_Val_Rising,         // Acquire on rising edge of sample clock 
    303            DAQmx_Val_FiniteSamps,    // Specify finite data collection 
    304            (uInt64)SampRate );       // Samples per channel to acquire 
    305       if ( DAQmxFailed(rc) ) DAQmxErrorDetected( taskHandle ); 
    306    } 
     313   DAQmxErrChk( DAQmxCfgSampClkTiming( taskHandle, 
     314           NULL,                       // Use on-board clock 
     315           (float64)SampRate,          // Sampling rate 
     316           DAQmx_Val_Rising,           // Acquire on rising edge of sample clock 
     317           DAQmx_Val_FiniteSamps,      // Specify finite data collection 
     318           (uInt64)SampRate) );        // Samples per channel to acquire 
    307319 
    308320/* Specify the physical channel of the start trigger for the AI task. 
     
    312324   *******************************************************************/ 
    313325   logit( "et", "Configuring the NI digital edge start trigger.\n" ); 
    314    rc = DAQmxCfgDigEdgeStartTrig( taskHandle, 
    315         TriggerChan,           // Physical channel, eg PFI1 
    316         DAQmx_Val_Rising );    // Trigger on rising edge 
    317    if ( DAQmxFailed(rc) ) DAQmxErrorDetected( taskHandle ); 
     326   DAQmxErrChk( DAQmxCfgDigEdgeStartTrig( taskHandle, 
     327        TriggerChan,                    // Physical channel, eg PFI1 
     328        DAQmx_Val_Rising) );            // Trigger on rising edge 
    318329 
    319330   logit( "et", "Making the NI start trigger retriggerable.\n" ); 
    320    rc = DAQmxSetStartTrigRetriggerable( taskHandle, TRUE ); 
    321    if ( DAQmxFailed(rc) ) DAQmxErrorDetected( taskHandle ); 
     331   DAQmxErrChk( DAQmxSetStartTrigRetriggerable(taskHandle, TRUE) ); 
    322332 
    323333/* The EveryNCallback function is invoked after SampRate samples are acquired. 
    324334   **************************************************************************/ 
    325335   logit( "et", "Registering the NI acquisition callback function.\n" ); 
    326    rc = DAQmxRegisterEveryNSamplesEvent( taskHandle, 
     336   DAQmxErrChk( DAQmxRegisterEveryNSamplesEvent( taskHandle, 
    327337        DAQmx_Val_Acquired_Into_Buffer,  // Data are being acquired 
    328338        (uInt32)SampRate,                // After SampRate samples are collected, 
     
    330340        0,                               // Function called in a DAQmx thread 
    331341        EveryNCallback,                  // Name of callback function 
    332         NULL );                          // Value passed to the EveryNCallback function 
    333  
    334    if ( DAQmxFailed(rc) ) DAQmxErrorDetected( taskHandle ); 
     342        NULL) );                         // Value passed to the EveryNCallback function 
    335343 
    336344/* The DoneCallback function is invoked if the analog 
    337    task stops due to an error. 
     345   input task stops due to an error. 
    338346   **************************************************/ 
    339347   logit( "et", "Registering the NI done-event callback function.\n" ); 
    340    rc = DAQmxRegisterDoneEvent( taskHandle, 
     348   DAQmxErrChk( DAQmxRegisterDoneEvent( taskHandle, 
    341349        0,                      // Function called in a DAQmx thread 
    342350        DoneCallback,           // Name of callback function 
    343         NULL );                 // Value passed to the callback function 
    344  
    345    if ( DAQmxFailed(rc) ) DAQmxErrorDetected( taskHandle ); 
     351        NULL) );                // Value passed to the callback function 
    346352 
    347353/* Start the analog input task 
    348354   ***************************/ 
    349355   logit( "et", "Starting the analog input task.\n" ); 
    350    rc = DAQmxStartTask( taskHandle ); 
    351    if ( DAQmxFailed(rc) ) DAQmxErrorDetected( taskHandle ); 
     356   DAQmxErrChk( DAQmxStartTask(taskHandle) ); 
    352357   logit( "et", "The analog input task is started.\n" ); 
    353358 
    354 /* The main program loop begins here. 
    355    Wait for a program termination request. 
    356    **************************************/ 
     359/* Sleep until one of the callback functions fails 
     360   or startstop/statmgr requests program termination 
     361   *************************************************/ 
    357362   while ( 1 ) 
    358363   { 
    359  
    360 /* If the callback function detects a serious error, 
    361    exit the program. 
    362    ************************************************/ 
    363       if ( callbackExitFlag == 1 ) 
     364      if ( EveryNCallbackRequestedExit ) 
    364365      { 
    365          logit( "et", "The callback function detected a serious error. Exiting.\n" ); 
    366          ExitAdsendxs( taskHandle ); 
     366         logit( "et", "EveryNCallback function requested program exit.\n" ); 
     367         break; 
    367368      } 
    368  
    369 /* Startstop asked this program to exit 
    370    ************************************/ 
     369      if ( DoneCallbackRequestedExit ) 
     370      { 
     371         logit( "et", "DoneCallback function requested program exit.\n" ); 
     372         break; 
     373      } 
    371374      if ( tport_getflag( &Region ) == TERMINATE  || 
    372375           tport_getflag( &Region ) == MyPid ) 
    373          ExitAdsendxs( taskHandle ); 
    374  
    375       sleep_ew( 500 ); 
    376    } 
    377 } 
    378  
    379  
    380 /********************************************************** 
    381   DAQmxErrorDetected 
    382  
    383   This gets called if the DAQ board cannot be initialized. 
    384  **********************************************************/ 
    385  
    386 void DAQmxErrorDetected( TaskHandle taskHandle ) 
    387 { 
    388    char errBuff[2048] = {'\0'}; 
    389  
    390    DAQmxGetExtendedErrorInfo( errBuff, 2048 ); 
    391    logit( "et", "DAQmx Error: %s\n", errBuff ); 
    392    ExitAdsendxs( taskHandle ); 
    393 } 
    394  
    395  
    396 /********************************************************** 
    397   ExitAdsendxs 
    398  
    399   Clean up and exit this program. 
    400  **********************************************************/ 
    401  
    402 void ExitAdsendxs( TaskHandle taskHandle ) 
    403 { 
    404    if ( taskHandle != 0 ) 
     376      { 
     377         logit( "et", "Startstop/statmgr requested program exit.\n" ); 
     378         break; 
     379      } 
     380      sleep_ew( 100 ); 
     381   } 
     382 
     383/* Exit program 
     384   ************/ 
     385Error: 
     386   if ( DAQmxFailed(error) ) 
     387           DAQmxGetExtendedErrorInfo( errBuff,2048 ); 
     388   if ( taskHandle!=0 ) 
    405389   { 
    406390      DAQmxStopTask( taskHandle ); 
    407391      DAQmxClearTask( taskHandle ); 
    408392   } 
    409    ClosePort(); 
    410    logit( "et", "adsendxs exiting.\n" ); 
    411    exit( 0 ); 
     393   if ( DAQmxFailed(error) ) 
     394      logit( "et", "DAQmx Error: %s\n", errBuff ); 
     395   logit( "et", "Exiting adsendxs.\n" ); 
     396   return 0; 
    412397} 
    413398 
     
    425410                                  void *callbackData ) 
    426411{ 
     412   int32  error = 0; 
    427413   int    i; 
    428    int32  rc; 
    429    char   errBuff[2048] = {'\0'};   // Message returned by NIDAQmx 
    430    char   errMsg[80];               // Message sent to statmgr 
     414   char   errBuff[2048] = {'\0'};       // Message returned by NIDAQmx 
     415   char   errMsg[80];                   // Message sent to statmgr 
    431416   int32  nScansRead; 
    432417   short  *idata = (short *)fldata; 
    433418   time_t tgps; 
    434    int    gpsTimeStatus;        // Possible values are CRITICAL ERROR, 
    435                                 // GPS TIME_UNAVAILABLE, 
    436                                 // UNLOCKED_GPS_TIME_AVAILABLE, 
    437                                 // or LOCKED_GPS_TIME_AVAILABLE 
    438    int    antennaOpen;          // Possible values are TRUE, FALSE, or UNKNOWN 
     419   int    gpsTimeStatus;                // Possible values are CRITICAL ERROR, 
     420                                        // GPS TIME_UNAVAILABLE, 
     421                                        // UNLOCKED_GPS_TIME_AVAILABLE, 
     422                                        // or LOCKED_GPS_TIME_AVAILABLE 
     423   int    antennaOpen;                  // Possible values are TRUE, FALSE, or UNKNOWN 
    439424   static int sendingTracebuf = FALSE;  // Sending tracebuf messages 
    440425 
     
    443428   the collection rate, causing the program to exit. 
    444429   *******************************************************/ 
    445    rc = DAQmxReadAnalogF64( taskHandle, 
     430   DAQmxErrChk( DAQmxReadAnalogF64( taskHandle, 
    446431        -1,                           // Read all samples that were requested 
    447432        0.0,                          // Timeout in seconds.  If 0, read all 
     
    451436        Nchan*nScansRequested,        // Size of fldata array, in samples 
    452437        &nScansRead,                  // Samples per channel read 
    453         NULL );                       // Reserved by NI 
    454  
    455    if ( DAQmxFailed(rc) ) 
    456    { 
    457       DAQmxGetExtendedErrorInfo( errBuff, 2048 );        // Log the error 
    458       logit( "t", "DAQmxReadAnalogF64 error.\n" ); 
    459       logit( "", "%s\n", errBuff ); 
    460  
    461       sprintf( errMsg, "DAQmxReadAnalogF64 error.\n" );  // Report error to statmgr 
    462       ReportErrorToStatmgr( NI_ERROR, errMsg ); 
    463       callbackExitFlag = 1;                              // Tell main program to exit 
    464       return 0; 
    465    } 
     438        NULL) );                      // Reserved by NI 
    466439 
    467440/* Did we get all data requested from the DAQ module? 
     
    470443   { 
    471444      logit( "et", "Error.  We requested %u scans, but\n", nScansRequested ); 
    472       logit( "et", "   DAQmxReadAnalogF64 returned only %d scans.\n", nScansRead ); 
    473       logit( "et", "   Discarding this one-second packet.\n" ); 
     445      logit( "et", "DAQmxReadAnalogF64 returned only %d scans.\n", nScansRead ); 
     446      DAQmxStopTask( taskHandle ); 
     447      DAQmxClearTask( taskHandle ); 
     448      EveryNCallbackRequestedExit = TRUE; 
    474449      return 0; 
    475450   } 
     
    492467   if ( gpsTimeStatus == CRITICAL_ERROR ) 
    493468   { 
    494       callbackExitFlag = 1;     // Tell main program to exit 
     469      logit( "et", "Critical error detected by GetGpsTime.\n" ); 
     470      DAQmxStopTask( taskHandle ); 
     471      DAQmxClearTask( taskHandle ); 
     472      EveryNCallbackRequestedExit = TRUE; 
    495473      return 0; 
    496474   } 
    497475 
    498 /* Log and send email if changes occur in the antenna-open 
     476/* Notify someone if changes occur in the antenna-open 
    499477   status.  Send antenna status to SNW periodically. 
    500    *******************************************************/ 
     478   ***************************************************/ 
    501479   if ( (antennaOpen == TRUE) && (antennaOpenPrev != TRUE) ) 
    502480   { 
     
    512490   } 
    513491   antennaOpenPrev = antennaOpen; 
    514  
    515492   ReportAntennaStatusToSNW( antennaOpen ); 
    516493 
     
    519496   if ( gpsTimeStatus == GPS_TIME_UNAVAILABLE ) 
    520497   { 
    521        if ( sendingTracebuf == TRUE ) 
    522           logit( "et", "Stopped sending tracebuf messages to transport ring.\n" ); 
    523        sendingTracebuf = FALSE; 
    524        return 0;                // Wait for next callback to occur 
     498      if ( sendingTracebuf == TRUE ) 
     499         logit( "et", "Stopped sending tracebuf messages to transport ring.\n" ); 
     500      sendingTracebuf = FALSE; 
     501      return 0;                // Wait for next callback to occur 
    525502   } 
    526503   else 
    527504   { 
    528        if ( sendingTracebuf == FALSE) 
    529           logit( "et", "Sending tracebuf messages to transport ring.\n" ); 
    530        sendingTracebuf = TRUE; 
     505      if ( sendingTracebuf == FALSE) 
     506         logit( "et", "Sending tracebuf messages to transport ring.\n" ); 
     507      sendingTracebuf = TRUE; 
    531508   } 
    532509 
     
    601578         SendHeartbeat(); 
    602579   } 
     580 
     581Error: 
     582   if ( DAQmxFailed(error) ) 
     583   { 
     584      DAQmxGetExtendedErrorInfo( errBuff, 2048 ); 
     585      logit( "et", "DAQmx error detected by EveryNCallback: %s\n", errBuff); 
     586      ReportErrorToStatmgr( NI_ERROR, "EveryNCallback error.\n" ); 
     587      DAQmxStopTask( taskHandle ); 
     588      DAQmxClearTask( taskHandle ); 
     589      EveryNCallbackRequestedExit = TRUE; 
     590   } 
    603591   return 0; 
    604592} 
     
    616604                                void       *callbackData ) 
    617605{ 
    618    char errBuff[2048] = {'\0'}; 
    619  
    620    if ( DAQmxFailed( status ) ) 
     606   int32 error = 0; 
     607   char  errBuff[2048] = {'\0'}; 
     608 
     609// See if an error stopped the task. 
     610   DAQmxErrChk( status ); 
     611 
     612Error: 
     613   if ( DAQmxFailed( error ) ) 
    621614   { 
    622615      DAQmxGetExtendedErrorInfo( errBuff, 2048 ); 
     616      logit( "et", "DAQmx error detected by DoneCallback: %s\n", errBuff); 
    623617      DAQmxClearTask( taskHandle ); 
    624       logit( "", "Analog input task stopped due to error: %s\n", errBuff ); 
    625    } 
    626    callbackExitFlag = 1;       // Tell the main program to exit 
     618      DoneCallbackRequestedExit = TRUE; 
     619   } 
    627620   return 0; 
    628621} 
Note: See TracChangeset for help on using the changeset viewer.