head 4.4; access ; symbols ; locks oasisa:4.4; strict; comment @ * @; 4.4 date 2001.06.19.12.12.44; author oasisa; state Exp; branches ; next ; desc @New Repository; 6/19/2001 (klh) @ 4.4 log @New Repository; 6/19/2001 (klh) @ text @/****************************************************************************/ /* Copyright 1995 MBARI */ /****************************************************************************/ /* $Header: co2.c,v 1.1 2001/06/19 11:42:44 oasisa Exp $ */ /* Summary : Driver Routines for pCO2 Analyzer on OASIS mooring */ /* Filename : co2.c */ /* Author : Robert Herlien (rah) */ /* Project : OASIS Mooring */ /* $Revision: 1.1 $ */ /* Created : 02/15/95 from sensors.c */ /* */ /* MBARI provides this documentation and code "as is", with no warranty, */ /* express or implied, of its quality or consistency. It is provided without*/ /* support and without obligation on the part of the Monterey Bay Aquarium */ /* Research Institute to assist in its use, correction, modification, or */ /* enhancement. This information should not be published or distributed to */ /* third parties without specific written permission from MBARI. */ /* */ /****************************************************************************/ /* Modification History: */ /* 15feb95 rah - created from sensors.c */ /* $Log: co2.c,v $ * Revision 1.1 2001/06/19 11:42:44 11:42:44 oasisa (Oasis users) * Initial revision * * Incorporated old pump driver into pco2 driver, 4/21/2000 bobh * * Revision 3.9 97/10/28 13:59:48 13:59:48 bobh (Bob Herlien) * EqPac Deployment of Nov 1997 * * Revision 3.7 97/07/23 11:18:10 11:18:10 bobh (Bob Herlien) * July '97 M1 deployment, new shutter code * * Revision 3.5 96/07/19 09:53:37 09:53:37 bobh (Bob Herlien) * July '96 Deployment of M2 with ARGOS code * * Revision 3.4 96/06/18 15:24:23 15:24:23 bobh (Bob Herlien) * June '96 deployment of M1 * * Revision 3.1 95/03/09 19:30:59 19:30:59 hebo (Bob Herlien) * March '95 Deployment of M1A * * Revision 3.0 95/02/21 18:42:45 18:42:45 hebo (Bob Herlien) * February '95 Deployment * */ /****************************************************************************/ #include /* MBARI type definitions */ #include /* MBARI constants */ #include /* OASIS controller definitions */ #include /* OASIS I/O definitions */ #include /* Log record definitions */ #include /* ARGOS definition */ #include <80C196.h> /* 80196 Register mapping */ #include /* OASIS Multitasking definitions */ #include /* Standard I/O functions */ #define PCO2_BUFSIZE 128 /* Buffer size for pCO2 */ #define DATA_RETRIES 5 /* Times to try for data */ /* 11/09/00 (klh) Calibration sample interval scheme was changed to adjust itself according to the sample interval. Previously, the number was a simple modulus of the number of times the driver ran. When done this way, the calibration sample schedule is thrown off if the sample rate is changed but CALIBR_CNT is not changed (e.g. when deploying for EQPAC vs local). To prevent this, the cal sample modulus is now calculated based on the sample INTERVAL and the desired cal sample interval, CAL_INTERVAL ( expressed in HOURS, rather than seconds). As before, it won't be possible to take cal samples more frequently than regular samples, or to change the CAL_INTERVAL in the field. Setting CAL_INTERVAL to 23 should cause the cal sample to 'walk around the clock', sampling one hour earlier each day. If INTERVAL or CAL_INTERVAL is <=0, no calibration samples are taken. DO_AUX is still passed through so that aux pco2 will force a cal sample regardless of INTERVAL or CAL_INTERVAL. 1/17/01 - CAL_MODULUS rolled into a single constant, CAL_INTERVAL. Two Int32s, cal_modulus and cal_interval are by default initialized to CAL_INTERVAL. If CO2_ADJUSTCAL is defined, cal_modulus is calculated based on the value of cal_interval (CAL_INTERVAL is interpreted to be hours). If not, cal_modulus is set to CAL_INTERVAL (interpreted as a modulus). The values of cal_modulus and cal_interval are in RAM and can be altered over packet as necessary. */ /********************************/ /* External Functions */ /********************************/ Extern Void drvLog( Driver *dp, Byte *samplep, Int16 len ); Extern Void drvLogError( Driver *dp, Errno err ); Extern char *drvSerPortAndMalloc( Driver *dp, Nat16 size ); Extern Void drvSerReleaseAndFree( Driver *dp, char *buffer ); Extern Void drv_ser_port( Driver *dp ); Extern Void drv_ser_release( Driver *dp ); Extern Void drv_pwroff( Driver *dp ); Extern Void io_pwron( Word pwrbits ); /* Turn power on */ Extern Void io_pwroff( Word pwrbits ); /* Turn power off */ Extern Void xputs( const char *s ); Extern Int16 xgetn_tmout( char *s, Int16 len, Nat16 tmout ); Extern Void xprintf( const char *format, ... ); Extern MBool getnum( char **s, Int16 *result, Nat16 radix ); Extern char *tmpMalloc( Nat16 size ); Extern Void tmpFree( char *ptr ); #ifdef ARGOS_CO2 Extern Void argosCo2Sample( Int16 sample, MBool calibr ); #endif /********************************/ /* External Data */ /********************************/ Extern char *pco2_cmd; /* Command string for pCO2 */ #ifdef CALCO2 Extern char *co2_cal0; /* Set Cal string for pCO2 */ Extern char *co2_cal1; Extern char *co2_cal2; Extern char *co2_cal3; Extern char *co2_cal4; #endif Extern Nat16 pwr_perm; /* Devices to leave powered on */ /********************************/ /* Module Local Data */ /********************************/ MLocal const char co2_relay1_on[] = "*0642,0,5\r"; MLocal const char co2_relay1_off[] = "*0642,0,1000\r"; MLocal const char co2_relay2_on[] = "*0542,0,5\r"; MLocal const char co2_relay2_off[] = "*0542,0,1000\r"; MLocal Int32 cal_modulus; #ifdef CO2_ADJUSTCAL MLocal Int32 cal_interval; #endif /************************************************************************/ /* Function : pco2_wake */ /* Purpose : pCO2 serial wakeup function */ /* Inputs : Driver ptr, MBool (TRUE for on, FALSE for off) */ /* Outputs : TRUE */ /************************************************************************/ MBool pco2_wake( Driver *dp, MBool on ) { if ( !on ) drv_pwroff( dp ); return( TRUE ); } /* pco2_wake() */ /************************************************************************/ /* Function : getCo2Data */ /* Purpose : Get data from pCO2 sensor */ /* Inputs : Driver Pointer, data buffer, char to mark data with */ /* Outputs : Integer part of first data word */ /************************************************************************/ Int16 getCo2Data( Driver *dp, char *pco2_buf, char dataMark ) { char *bufp; Int16 i, len, result; for ( i = DATA_RETRIES; i; i--) { xputs( "*12\r" ); /* Ask for data */ len = xgetn_tmout(pco2_buf, PCO2_BUFSIZE, dp->drv_parms[TIMEOUT]); bufp = pco2_buf; result = 0; if ( len > 0 ) { pco2_buf[len++] = dataMark; pco2_buf[len] = '\0'; /* Mark end of string */ if ( getnum(&bufp, &result, 10) ) /* Get the 2nd number of result*/ break; } } if ( len > 0 ) drvLog( dp, (Byte *)pco2_buf, len ); /* Log the data */ else drvLogError( dp, TMOUT_ERR ); /* Log an error */ return( result ); } /* getCo2Data() */ /************************************************************************/ /* Function : pco2_drv */ /* Purpose : pCO2 Sensor driver */ /* Inputs : Driver Pointer */ /* Outputs : None */ /************************************************************************/ Void pco2_drv( Driver *dp ) { char *pco2_buf; /* Buffer for pCO2 data */ Reg Int16 sample; Word pump_pwr; /* Power bit for pump */ pump_pwr = dp->drv_parms[PARM2]; io_pwron( pump_pwr ); /* Turn on pump */ delay_secs( dp->drv_parms[PARM0] ); /* Wait for pump */ if ( (pco2_buf = drvSerPortAndMalloc(dp, PCO2_BUFSIZE)) == NULL ) return; /* Get ser port, buffer, turn on*/ task_delay( 5 * TICKS_PER_SECOND ); /* Wait 5 seconds */ xprintf( "%s\r", pco2_cmd ); /* Send setup string */ xputs( co2_relay1_off ); xputs( co2_relay2_off ); delay_secs( dp->drv_parms[PARM1] ); /* Wait to turn off pump */ getCo2Data( dp, pco2_buf, 'I' ); /* Get "pump on" sample */ if ( (pump_pwr & pwr_perm) == 0 ) io_pwroff( pump_pwr ); /* Turn off pump */ delay_secs ( dp->drv_parms[PARM1] >> 1); /* Wait for instrument sample*/ sample = getCo2Data( dp, pco2_buf, '\0' ); /* Get and log actual data sample*/ #ifdef ARGOS_CO2 argosCo2Sample( sample, FALSE ); /* Put it in argos buffer */ #endif cal_modulus = CAL_INTERVAL; #ifdef CO2_ADJUSTCAL cal_interval = CAL_INTERVAL; if((dp->drv_parms[INTERVAL]>0 && cal_interval>0) || (dp->drv_flags & DO_AUX)) cal_modulus=(Int32)(3600*cal_interval/dp->drv_parms[INTERVAL]); #endif if ((++(dp->drv_cnt) >= cal_modulus) || (dp->drv_flags & DO_AUX)) { /* If time for calibration, do it*/ task_delay( TICKS_PER_SECOND ); xputs( co2_relay1_on ); /* Switch relay to ref cell */ task_delay( TICKS_PER_SECOND ); xputs( co2_relay1_off ); /* Turn it off */ dp->drv_cnt = 0; delay_secs( PCO2_CAL_DELAY ); /* Wait for equilibrium */ sample = getCo2Data( dp, pco2_buf, 'C' ); /* Get and log sample */ #ifdef ARGOS_CO2 argosCo2Sample( sample, TRUE ); /* Put it in argos buffer */ #endif xputs( co2_relay2_on ); task_delay( TICKS_PER_SECOND ); xputs( co2_relay2_off ); #ifdef CALCO2 /* Update Cal constants */ xprintf( "%s\r%s\r%s\r%s\r%s\r",co2_cal0,co2_cal1,co2_cal2,co2_cal3,co2_cal4); #endif } task_delay( 2 * TICKS_PER_SECOND ); /* Let solenoids act */ drvSerReleaseAndFree( dp, pco2_buf ); /* Release serial port & buffer*/ drv_pwroff( dp ); /* Turn off pco2 power */ } /* pco2_drv() */ @