'Program name: TTS_5_1.CR8 'Original conversion: 'Date converted by Transformer: 3/1/2007 (from 10X revision of 11/28/2006) 'Modified extensively by Jack Lewis 3/5/2007 'Debugged sampling logic and incorporated Rand Eads changes 3/12/2007 'Debugged & tested measurement subroutines, Rand Eads 3/30/07 'Renamed variables and subroutines, added Flag aliases, Jack Lewis 4/6/07 'Restructured ReadTurbidity and reversed initialization logic, Rand Eads 4/19/07 'Removed initialization flag and renumbered airTempFlag and rainFlag JL 4/24/07 'Transform Version: 0.5 'Transform file: CR10X_800.TRN Version: 1.1 'This program was converted from TTS_5_0.CSI ' using Campbell Scientific's Transformer application. 'Revision History ' Date/individual: 10/01/2010 Rand Eads, RiverMetrics LLC ' Revsion designation: 5.1 ' Program changes: Add code to sub ReadStage that allows optional connection of CS450 ' SDI-12 pressure transducer. ' Fixed error in Main program for fixed time sampling where "device" and "limit" where mixed up ' in 2 statements and 2 locations (rising and falling) ' Added DataInterval instruction to reduce memnory useage 'Original TTS Edlog version by Jack Lewis, Rand Eads, and Noah Campbell-Lund 'Redwood Sciences Laboratory, USDA Forest Service ' ----======= TURBIDITY THRESHOLD SAMPLING PROGRAM (TTS) ======-------- ' CRBasic Version ' Jack Lewis ' Redwood Sciences Laboratory ' USDA Forest Service ' 1700 Bayview Drive ' Arcata, CA 95521 ' Rand Eads ' RiverMetrics LLC ' PO Box 507 ' Lafayette, OR 97127 '=========================>>> NOTICE <<<============================ ' Both U.S. Government & private individuals produced this software ' and, thus, no copyright can be claimed and this program is available ' for use by the public. ' This software is provided "as is" without warranty of any kind. ' The authors, Redwood Sciences Laboratory, and RiverMetrics LLC do not warrant, ' guarantee or make any representations regarding the use or ' correctness, reliability, or otherwise. The user of this program ' assumes the entire risk as to the results and performance of the ' software. In no case will any party involved with creation or use ' of the software be liable for any damage that may result. The user agrees ' to terms above by downloading or installing this software. ' The use of trade names is not an endorsement by the USDA Forest Service. '************** CAMPBELL DATA LOGGER PROGRAM DESCRIPTION ************ ' The program wakes up every 10 or 15 minutes, depending on the site. ' The OBS-3/3+ sensors sample turbidity at 0.5-second intervals for 30 ' seconds for a total of 60 readings. Or, the DTS-12 collects 100 ' samples in about 7 seconds. The Analite NEP395 collects 100 samples ' in about 10 seconds. In all cases, the median turbidity is saved. ' The median turbidity and average stage values are used to ' trigger a pumping sampler if the sampling criteria are satisfied. ' The conditions which govern sampling are as follows: ' BASE FLOW: This condition occurs when the stage is less than the ' specified minimum stage (minimumStage). Minimum stage is the lowest ' stage where both the turbidity probe and pumping sampler intake ' are adequately submerged and functional. No sampling takes place ' in this mode. ' RISING: A start-up sample is collected at the first interval ' above minimum stage, if the turbidity is above the first rising ' threshold, and no rising thresholds have been sampled within the ' past 72 (startWait) intervals. The condition becomes rising at the ' first interval above base flow. For sampling to occur in a rising ' turbidity condition, the turbidity must be equal to, or greater than, ' the next rising threshold for 2 (persistence) intervals. In addition, a ' threshold will not be resampled if it has already been sampled in the ' past 18 (waitCount) intervals. ' REVERSALS: A turbidity reversal occurs when the turbidity has ' changed direction for 2 (persistence) intervals, and has dropped 10% ' (peakChange) from the prior peak or risen 20% (troughChange) from the ' prior trough, and changed least 5 NTUs (reversalMinimum) in both cases. ' A sample is collected if a threshold has been crossed since the ' previous peak or trough, unless that threshold has already been ' sampled in the past 18 (waitCount) intervals. ' FALLING: Sampling occurs in a falling turbidity condition when ' the turbidity is less than, or equal to, the next falling ' threshold for 2 (persistence) intervals. And a threshold will not be ' resampled within 18 (waitCount) intervals. ' OVERFLOW: Turbidity sensor output exceeds the data logger's ' millivolt limit setting (mvLimitOBS: OBS-3/3+) or (turbLimit: DTS-12 ' and NEP395). In this mode, two (fixedTimeWait) intervals will be skipped ' between each sampled interval. ' Recorded information is written to the datalogger memory for all the ' above conditions. ' Between each execution interval the datalogger goes into a ' quiescent state. ' The default execution interval is set in the Main Program in Scan() to 10 min. In the Output section ' under DataInterval() the interval should match the scan interval (e.g. 10 min) '******************** PROGRAM PARAMETERS *********************** ' THRESHOLD CODES: ' 0: Indicates when the average stage < the minimum stage ' 1: Indicates rising threshold (rising turbidity) ' 2: Indicates falling threshold (falling turbidity) ' 3: Indicates the first interval into the program and the status ' of whether the thresholds are rising or falling has not yet been ' established. ' SAMPLING CODES: ' 0: No sample collected ' 1: Threshold sample collected ' 2: Depth Integrated sample collected ' 3: Auxillary sample collected (set to 1 if also a threshold sample) ' 4: Start-up sample collected ' 5: Fixed-time sample collected when turbidity probe is above mV limit ' FLAG USAGE: ' FLAG(1) = dumpFlag: ' -Low: No action, normal program execution ' -High: Increments dump counter and resets bottle counter to 0, user to dump data ' FLAG(2) = diSampleFlag: ' -Low: No action, normal program execution ' -High: For a Depth-Integrated sample to be taken at next interval ' FLAG(3) = auxSampleFlag: ' -Low: No action, normal program execution ' -High: For an Auxillary sample to be taken at next interval ' Flag(4) = airTempFlag: ' -Low: Air temperature sensor not connected ' -High: Air temperature sensor (Campbell 107) connected ' Flag(5) = rainFlag: ' -Low: Tipping bucket rain gage not connected ' -High: Tipping bucket rain gage is connected '*********************** SUBROUTINES ******************************** ' Initialize Initializes variables (user sets values here) ' SortTurbidity Sorts turbidity values into ascending order (OBS-3 only) ' ExtractMedian Determines the median turbidity value (OBS-3 only) ' GetNextThresh Determines rising/falling thresholds ' PumpSample Triggers pumped sample and increments bottle counter ' EmergingFromBaseFlow Processes first interval above minimum stage ' FixedTimeSampling Controls sampling above sensor's max turbidity ' ThresholdSample Threshold samples ' ReadTurbidity Reads turbidity sensors ' ReadStage Reads stage from Druck 1830 pressure transducer ' ReadTemperatures Measures water/air temperatures ' CalcDischarge Calculates discharge '****************** SENSOR/DEVICE CONNECTIONS *********************** ' See the Redwood Sciences Lab's web site for wiring connections at: ' http://www.rsl.psw.fs.fed.us/projects/water/tts_webpage ' under "Implementation" '************************** EQUIPMENT ************************** ' Instruction parameters are set for the following types of equipment: ' Data loggers: Campbell CR800, CR850, & CR1000 (the CR1000 has addition ' sensor connections not utilized in this code) ' Turbidity probe: D & A Instruments, OBS-3 and OBS-3+, with 2.5V clamp installed ' powered through SW12V (both sensors DIFF2, or SE3 OBS-3 single-ended) ' or FTS DTS-12 digital probe with wiper (on port C1), ' or Analite NEP395 digital probe with wiper (on port C1). ' Pressure transducer: Druck PDCR 1830 differential mV output ' Pumping samplers: ISCO 3700, 6712, and Sigma model 900 ' Triggered from C2, optional second sampler (sequential) on C3 ' The use of different devices may require program modifications. '******************* SITE-SPECIFIC INSTRUCTIONS ********************* ' Check the program locations below and change the default values to ' meet the specific site and equipment requirements ' Scan instruction at start of Main Program: ' set execution interval to 10 or 15 minutes for most rivers ' DataTable statement ' Uncomment statements to output water temp, air temp, and rain, as appropriate. ' If adding other sensors write the extra values at the end of the table ' to permit proper functioning of plotting & analysis software ' Initialize, Site & equipment variables that can modified by the user are ' identified with "<===========" ' Enter rising and falling thresholds where indicated '\\\\\\\\\\\\\\\\\\\\\\\\\ DECLARATIONS ///////////////////////// SequentialMode PreserveVariables 'Variables are listed in alphabetic order Public airTemp Public averageStage Public batteryVolt Public both Public bottle Public bottleCount Public CS450(2) Public daily Public delayTime Public didSample as boolean Public doSample as boolean Public dtsArray(7) Public dtsTemp Public dumpCount Public fallingThresh(24) Public fixedTimeWait Public flag(5) as boolean 'Declared as array to show in ports and flags window Alias CS450(1) = stage450 Alias CS450(2) = waterTemp450 Alias flag(1) = dumpFlag Alias flag(2) = diSampleFlag Alias flag(3) = auxSampleFlag Alias flag(4) = airTempFlag Alias flag(5) = rainFlag Public fThresh public i Public inArrayBounds as boolean Public index Public insert as boolean Public interval Public j Public k Public lastFallingIntSampled(24) Public lastIntervalSampled Public lastRisingIntSampled(16) Public medianMv Public medianTurb Public midpoint Public minimumStage Public mv(60) Public mvLimitOBS Public n Public nepArray(3) Public nepTemp Public nepWipeCode Public nextBottle Public nextIndex Public nextThresh Public nFalling Public nRising Public oldTurb Public peakChange Public persistence Public q Public qCalc as boolean Public qExponent Public qMultiplier Public rain Public rawMv Public rawStage Public reversalCount Public reversalMinimum Public reversalThresh Public risingThresh(16) Public rThresh Public sampleCode Public samplers Public season Public stage Public stageDevice Public stageOffset Public startWait Public stgMultiplier Public threshCode Public threshCount Public threshold Public threshPointer Public totalStage Public troughChange Public turbC0 'replaces turb_off Public turbC1 'replaces turb_mult Public turbC2 Public turbDevice Public turbLimit Public turbPeak Public turbTrough Public waitCount Public waterTemp Public waterTempDevice public wipeStage '\\\\\\\\\\\\\\\\\\\\\\\\ OUTPUT SECTION //////////////////////// DataTable(TtsTable,1,-1) DataInterval (0,10,Min,10) Sample(1, dumpCount,FP2) Sample(1, bottle, FP2) Sample(1, threshCode, FP2) Sample(1, sampleCode, FP2) Sample(1, stage, FP2) Sample(1, medianTurb, FP2) ' *** To record any of the 3 following statements uncomment by ' removing single quote "'" in front of Sample or Totalize, ' then Save & Compile program, and send to the data logger ' If recording water temperature then uncomment the following Sample statement: ' Sample(1, waterTemp, FP2) ' If recording air temperature, then uncomment the following Sample statement: ' Sample(1, airTemp, FP2) ' If recording rainfall, then uncomment the following Totalize statement: ' Sample(1, rain, FP2) EndTable '\\\\\\\\\\\\\\\\\\\\\\\\\ SUBROUTINES ////////////////////////// Sub Initialize 'Initialize variables 'Site and equipment variables, user modifies values below preceeded by <======== ' then Save & Compile program before sending program to data logger 'For OBS-3+, turbC0, turbC1, and turbC2 depend on the range selected via the DIFF2 high connection ' i.e. 1X (blue wire) and 4X (white wire) ranges each have their own polynomial turbC0 = 0 '<======== Enter turbidity offset (intercept) turbC1 = 0.8 '<======== Enter coefficient of x (multiplier) for OBS-3 or OBS-3+, ' for linear equation c1 = 0.8, enter value for poly. turbC2 = 0 '<======== Enter coefficient of x^2 for OBS-3 or OBS-3+, ' for linear equation c2 = 0, enter value for poly. stgMultiplier = 0 '<======== Enter multiplier for pressure transducer stageOffset = 0 '<======== Enter stage offset for pressure transducer minimumStage = 0 '<======== Enter minimum stage for sampling wipeStage = 0 '<======== Enter minimum stage for wiping sensor optics airTempFlag = False '<======== True = Air temp active, requires uncommenting Output statement rainFlag = False '<======== True = Rain gage active, requires uncommenting Output statement qCalc = False '<======== True = calculate water discharge, requires uncommenting Output statement ' and entering values in the two following statements qMultiplier = 1 '<======== Enter multiplier (F) for discharge calc. F*stg**exp qExponent = 1 '<======== Enter exponent (exp) for discharge calc. F*stg**exp turbDevice = 1 '<======== Select turbidity sensor & type of connection: ' 1 = DTS-12 (SDI-12 C1) ' 2 = OBS-3 or OBS-3+ (differential connection DIFF2) OBS-3+ 1X or 4X ' 3 = OBS-3 (single-ended connection SE3) ' 4 = Analite NEP 395 (SDI-12 C1) waterTempDevice = 0 '<======== Select water temperature device, requires uncommenting Output statement if selected ' 0 = None ' 1 = Campbell temperature sensor 107 ' 2 = DTS-12's on-board temperature sensor ' 3 = NEP395's on-board temperature sensor stageDevice = 1 '<======== Select stage device (pressure transducer) ' 1 = Druck 1830 analog ' 2 = CS450 SDI-12 samplers = 1 '<======== Number of pumping sampers connected ' 1 = 1 sampler connected ' 2 = 2 samplers connected 'Logic parameters, as needed user modifies values below preceded by <======== delayTime = 100 '<======== Enter delay (0.01s) that selected port is high reversalMinimum = 5 '<======== Enter minimum absolute change in NTU for program to detect turbidity reversal peakChange = 0.1 '<======== Enter value for the reversal % from rising to falling turbidity troughChange = 0.2 '<======== Enter value for the reversal % from falling to rising turbidity persistence = 2 '<======== Enter # of intervals before a reversal or new threshold waitCount = 18 '<======== Enter # of intervals between two untilizations of same threshold startWait = 72 '<======== Enter # of intervals between last sample and a new startup sample mvLimitOBS = 2500 '<======== mV turbidity limit above which samples are collected ' at fixed time intervals (OBS-3 only) turbLimit = 1550 '<======== NTU or FNU turbidity limit (DTS-12 or NEP395 only) ' use 95% of the sensor's maximum output (see calibration sheet) fixedTimeWait = 2 '<======== Number of intervals skipped between samples ' when mvLimitOBS or turbLimit exceeded 'Other initializations dumpCount = 1 ' dump counter waterTemp = 999 ' water temperature airTemp = 999 ' air temperature interval = 0 ' wakeup interval counter bottleCount = 0 ' bottle counter nextBottle = 1 ' next-bottle counter reversalCount = 0 ' reversal counter threshCount = 0 ' threshold counter inArrayBounds = True lastIntervalSampled = -999 'Thresholds nRising = 10 '<======== Enter number of rising thresholds nFalling = 17 '<======== Enter number of falling thresholds 'Enter the Rising threshold values risingThresh(1) = 20 risingThresh(2) = 69 risingThresh(3) = 148 risingThresh(4) = 257 risingThresh(5) = 395 risingThresh(6) = 583 risingThresh(7) = 760 risingThresh(8) = 988 risingThresh(9) = 1244 risingThresh(10)= 1531 'Enter the Falling threshold values fallingThresh(1) = 1531 fallingThresh(2) = 1371 fallingThresh(3) = 1220 fallingThresh(4) = 1077 fallingThresh(5) = 943 fallingThresh(6) = 819 fallingThresh(7) = 703 fallingThresh(8) = 596 fallingThresh(9) = 497 fallingThresh(10)= 408 fallingThresh(11)= 327 fallingThresh(12)= 256 fallingThresh(13)= 193 fallingThresh(14)= 139 fallingThresh(15)= 94 fallingThresh(16)= 57 fallingThresh(17)= 30 'Initialize the last rising sample and last falling sample arrays For i = 1 to nRising lastRisingIntSampled(i) = -999 Next i For i = 1 to nFalling lastFallingIntSampled(i) = -999 Next i EndSub Sub SortTurbidity 'Sorts turbidity mV values into ascending order (OBS-3) k = k + 1 j = k insert = False 'Loop for inserting new values Do While (j<>1 And insert = False) If (rawMv >= mv(j-1)) Then insert = True 'will get us out of loop Else mv(j) = mv(j-1) j = j - 1 EndIf Loop 'Insert (rawMv) intoto array mv(j) = rawMv EndSub Sub ExtractMedian 'Find median turbidity (millivolts) -- OBS-3 'If k is odd If (k MOD 2 <> 0) Then k = k + 1 'Divide k in half to find the location for the median value 'Add .5 and truncate to round correctly in case of floating point error midpoint = INT(0.5*k + 0.5) 'Save middle value as median medianMv = mv(midpoint) 'Else [k is even] Else 'Take the average of the 2 middle values midpoint = INT(0.5*k + 0.5) medianMv = 0.5 * (mv(midpoint) + mv(midpoint+1)) EndIf EndSub Sub GetNextThresh 'Determine next rising or falling threshold inArrayBounds = True If (threshCode = 1) Then 'rising thresholds nextIndex = 1 nextThresh = risingThresh(nextIndex) 'Loop through the threshold locations until conditions are met Do While (nextThresh <= medianTurb And nextIndex < nRising) nextIndex = nextIndex + 1 nextThresh = risingThresh(nextIndex) Loop threshold = nextThresh If (medianTurb >= nextThresh) Then inArrayBounds = False threshPointer = nextIndex Else If (threshCode = 2) Then 'falling thresholds nextIndex = 1 nextThresh = fallingThresh(nextIndex) 'Loop through the threshold locations until conditions are met Do While (nextThresh >= medianTurb and nextIndex < nFalling) nextIndex = nextIndex + 1 nextThresh = fallingThresh(nextIndex) Loop threshold = nextThresh If (nextThresh >= medianTurb) Then inArrayBounds = False threshPointer = nextIndex EndIf threshCount = 0 EndSub Sub PumpSample 'Collect a pumped sample didSample = False 'If water and air temp above freezing '(Default waterTemp and air temp if no sensor is 999) If (waterTemp >= 0.5 And airTemp >=0.5) Then bottleCount = bottleCount + 1 nextBottle = nextBottle + 1 'non-zero bottle numbers are written out only when they are collected bottle = bottleCount 'If sampler 1 not full If (bottle < 25) Then 'Pulse Port 2 to trigger pumped sampler on C2 PortSet(2,1) Delay(0,100,mSec) PortSet(2,0) 'PulsePort (2 ,10) didSample = True Else If (samplers = 2) Then 'Pulse Port 3 to trigger second pumped sampler on C3 PortSet(3,1) Delay(0,100,mSec) PortSet(3,0) 'PulsePort (3 ,10) didSample = True EndIf EndIf If (didSample) Then lastIntervalSampled = interval 'If it was a threshold sample then store interval in lastRisingIntSampled or lastFallingIntSampled array If (sampleCode = 1) Then If (threshCode = 1) Then lastRisingIntSampled(threshPointer) = interval Else lastFallingIntSampled(threshPointer) = interval EndIf EndIf EndIf EndSub Sub EmergingFromBaseFlow 'First interval above minimum stage 'If turbidity exceeds first threshold and wait period is up If (interval - lastIntervalSampled >= startWait And medianTurb >= risingThresh(1)) Then 'If no threshold samples have been taken during this scan If (sampleCode = 0) Then 'Set sample code for threshold sample collected sampleCode = 4 PumpSample EndIf EndIf turbPeak = medianTurb threshCode = 1 reversalCount = 0 GetNextThresh EndSub Sub FixedTimeSampling 'Control sampling above sensor's max turbidity 'If turbidity condition is falling If (threshCode = 2) Then 'Set turbidity condition to rising threshCode = 1 turbPeak = medianTurb reversalCount = 0 'Determine max threshold GetNextThresh EndIf If (lastIntervalSampled + fixedTimeWait < interval) Then 'Assign overflow sample code sampleCode = 5 PumpSample reversalCount = 0 EndIf EndSub Sub ThresholdSample 'Threshold samples doSample = False 'If enough intervals have passed since prior use of the threshold then sample If (threshCode = 1) Then If (interval > lastRisingIntSampled(threshPointer) + waitCount) Then doSample = True Elseif (threshCode = 2) Then If (interval > lastFallingIntSampled(threshPointer) + waitCount) Then doSample = True EndIf If (doSample) Then 'If no pumped samples have been taken If (sampleCode = 0) Then 'Set sample code for threshold sample collected sampleCode = 1 PumpSample EndIf 'If an AUX sample was already selected If (sampleCode = 3) Then 'Override AUX sample code with threshold sample code sampleCode = 1 EndIf EndIf EndSub Sub ReadTurbidity oldTurb = medianTurb If (turbDevice = 1) Then 'DTS-12 is connected 'If measuring DTS-12 water temperature If (waterTempDevice = 2) Then 'Get water temp, mean turbidity and variance from SDI address 0 SDI12Recorder(dtsArray, 1, "0", "M!", 1, 0) dtsTemp = dtsArray(1) 'If invalid temperature, set to error code 991 If (dtsTemp < -100) Then waterTemp = 991 Else waterTemp = dtsTemp EndIf EndIf 'If submerged and above freezing, wipe before measuring 'Store mean, variance, median, BES, min, max, and temperature If (stage >= wipeStage And waterTemp >= 0.5) Then SDI12Recorder(dtsArray, 1, "0", "M2!", 1, 0) Else 'just measure SDI12Recorder(dtsArray, 1, "0", "M1!", 1, 0) EndIf 'Add turbidity offset to 3rd value collected (median) medianTurb = dtsArray(3) + turbC0 ElseIf (turbDevice = 2) Then 'OBS-3 or OBS-3+ differential connection DIFF2 k = 0 'Switch 12V power on PortSet (9 ,1 ) 'Wait 3 seconds for sensor warm-up Delay(0,3,sec) 'Loop to read 60 turbidity values (mV) For i = 1 to 60 'Read differential voltage on DIFF2 VoltDiff (rawMv,1,mV2500,2,True,0,_60Hz,1.0,0) 'Delay each reading so 60 measurements takes 30 sec Delay(1,460,mSec) 'Insert rawMv at proper location in sorted mv array SortTurbidity Next i 'Switch 12V power off PortSet (9 ,0) 'Extract the median mV value from the sorted array ExtractMedian 'Convert millivolts to NTUs (both linear & polynomial) medianTurb = turbC0 + turbC1*medianMv + turbC2*medianMv^2 ElseIf (turbDevice = 3) Then 'OBS-3 single-ended connection k = 0 'Switch 12V power on PortSet (9 ,1 ) 'Wait 3 seconds for sensor warm-up Delay(0,3,sec) 'Loop to read 60 turbidity values (mV) For i = 1 to 60 'Assigns OBS-3 or OBS-3+ (mV) on channel 3 to rawMv VoltSe (rawMv,1,mV2500,3,0,0,_60Hz,1.0,0) 'Delay each reading so loop takes 30 sec Delay(1,460,mSec) 'Insert rawMv at proper location in sorted mv array SortTurbidity Next i 'Switch 12V power off PortSet (9 ,0) 'Extract the median mV value from the sorted array ExtractMedian 'Convert millivolts to NTUs (both linear & polynomial) medianTurb = turbC0 + turbC1*medianMv + turbC2*medianMv^2 Else 'device must be NEP395 by default 'If measuring NEP395 water temperature If (waterTempDevice = 3) Then 'Get water temp from SDI address 0; M7 returns a single value SDI12Recorder(nepTemp, 1, "0", "M7!", 1, 0) 'If invalid temperature, set to error code 991 If (nepTemp < -100) Then waterTemp = 991 Else waterTemp = nepTemp EndIf EndIf 'If submerged and above freezing, wipe NEP395 optics 'Status code is stored in nepWipeCode variable If (stage >= wipeStage And waterTemp >= 0.5) Then SDI12Recorder(nepWipeCode, 1, "0", "M8!", 1, 0) EndIf 'Measure median, min, and max turbidity with NEP395 SDI12Recorder(nepArray, 1, "0", "M2!", 1, 0) 'Add turbidity offset to 1st value collected (median) medianTurb = nepArray(1) + turbC0 EndIf EndSub Sub ReadStage If (stageDevice = 1) Then 'Read stage is Druck 1830 pressure transducer 'Initialize total stage totalStage = 0 'Initialize stage loop counter n = 0 'Loop 150 times to read and sum millivolts from pressure transducer For i = 1 To 150 n = n + 1 BrFull(rawStage, 1,Autorange, 1, VX1, 1, 2500, True, True, 800, 250, 1, 0) totalStage = rawStage + totalStage Next i averageStage = totalStage / n 'Convert millivolts to feet of stage, stage = averageStage * stgMultiplier + stageOffset Else 'stage device is CS450 pressure transducer, SDI-12, Address = 4, on C1 SDI12Recorder (CS450,1,"4","M!",1.0,0.0) 'convert stage psig to depth (ft) and add offset stage = (stage450 * 2.31) + stageOffset EndIf EndSub Sub ReadTemperatures 'Measure water/air temperature 'If water temperaure device is Campbell 107 If (waterTempDevice = 1) Then 'Read water temperature on SE5 Therm107(waterTemp,1,5,VX2,400,250,1,0) 'If temperature invalid, set to error code 992 If (waterTemp < -100) Then waterTemp = 992 EndIf 'If air temperature requested, then measure with Campbell sensor 107 on SE6 If airTempFlag = True then Therm107(airTemp,1,6,VX2,400,250,1,0) 'If temperature invalid, set to error code 993 If (airTemp < -100) Then airTemp = 993 EndIf EndSub Sub CalcDischarge 'Calculate water discharge If (qCalc = True) Then q = qMultiplier * stage ^ qExponent EndSub '\\\\\\\\\\\\\\\\\\\\\\\\\\\ MAIN PROGRAM //////////////////////////// BeginProg 'Initizations for program start-up Initialize 'Set scan rate in seconds Scan(10,Min, 3, 0) 'Read battery voltage Battery(batteryVolt) 'If it is a new dump If dumpFlag = True Then dumpCount = dumpCount + 1 'Increment dump counter bottleCount = 0 'Reset bottle counter to 0 nextBottle = 1 'Reset next pump sample counter to 1 dumpFlag = False EndIf 'Initializations for each wake-up sampleCode = 0 bottle = 0 interval = interval + 1 'Read sensors and, if applicable, calculate discharge ReadTemperatures ReadStage ReadTurbidity CalcDischarge 'If rainFlag set, measure rainfall If rainFlag = True Then 'Read rain gage pulses PulseCount(rain, 1, 1, 2, 0, 0.01, 0) daily = rain + daily 'Acuumulate daily total season = rain + season 'Accumulate seasonal total, user to edit as needed 'If midnight, reset daily total If TimeInToInterval(0,1440,Min) Then daily = 0 EndIf 'If diSampleFlag set, then take a depth integrated sample If diSampleFlag = True then sampleCode = 2 PumpSample diSampleFlag = False EndIf 'If auxSampleFlag set, then take an auxillary sample If auxSampleFlag = True then sampleCode = 3 PumpSample auxSampleFlag = False EndIf 'If stage is below minimum stage If (stage < minimumStage) Then threshCode = 0 'Base flow condition 'Write a record to data logger memory and jump to end of program CallTable TtsTable ContinueScan EndIf 'If first interval, write a record and jump to end of program If (interval = 1) Then 'Set threshold code to signify initial turbidity condition as unknown threshCode = 3 'Write a record to the output table and jump to end of program CallTable TtsTable ContinueScan EndIf 'If previous interval was in base flow If (threshCode = 0) Then EmergingFromBaseFlow 'Write a record to output table and jump to end of program CallTable TtsTable ContinueScan EndIf 'If second interval, then determine turbidity condition If (interval = 2) Then If (oldTurb < medianTurb) Then threshCode = 1 'Signifies rising turbidity turbPeak = medianTurb 'Save maximum for this rise Else threshCode = 2 'Signifies falling turbidity turbTrough = medianTurb 'Save minimum for this recession EndIf GetNextThresh 'Write a record to output table and jump to end of program CallTable TtsTable ContinueScan EndIf 'Processing for rising turbidity condition If (threshCode = 1) Then If (inArrayBounds And medianTurb >= threshold) Then threshCount = threshCount + 1 'If turbidity has exceed threshold long enough If (threshCount >= persistence) Then 'Possible threshold sample ThresholdSample 'Determine next threshold GetNextThresh EndIf Else 'not true that (inArrayBounds And medianTurb >= threshold) 'Check for turbidity exceeding sensor limit If (turbDevice = 1 AND medianTurb >= turbLimit) Then FixedTimeSampling If (turbDevice <> 1 AND medianMv >= mvLimitOBS) Then FixedTimeSampling EndIf If (medianTurb >= turbPeak) Then turbPeak = medianTurb reversalCount = 0 EndIf 'Check for change from rising to falling turbidity condition If (medianTurb < oldTurb) Then If (sampleCode <> 5) Then reversalCount = reversalCount + 1 If (reversalMinimum < turbPeak * peakChange) Then reversalThresh = turbPeak * (1 - peakChange) Else reversalThresh = turbPeak - reversalMinimum EndIf If (medianTurb <= reversalThresh And reversalCount >= persistence) Then threshCode = 2 'Switched to falling turbidity 'Determine next threshold GetNextThresh turbTrough = medianTurb If (nextIndex > 1) Then If (inArrayBounds) Then index = nextIndex - 1 'point above next falling threshold Else 'turbidity is at or below lowest falling threshold index = nextIndex 'point at lowest falling threshold EndIf fThresh = fallingThresh(index) If (fThresh < turbPeak) Then 'Save current offset into threshold array threshPointer = index 'Possible threshold sample ThresholdSample 'Increment threshPointer to point at next threshold If (inArrayBounds) Then threshPointer = threshPointer + 1 EndIf EndIf reversalCount = 0 EndIf 'End If medianTurb <= reversalThresh And reversalCount >= persistence EndIf 'End If medianTurb < oldTurb 'Write a record to output table and jump to end of program CallTable TtsTable 'Continue next scan at time interval ContinueScan EndIf 'End If threshCode = 1, rising turbidity 'Processing for falling turbidity condition If (threshCode = 2) Then If (inArrayBounds And medianTurb <= threshold) Then threshCount = threshCount + 1 If (threshCount >= persistence) Then 'Possible threshold sample ThresholdSample 'Determine next threshold GetNextThresh EndIf Else 'not true that (inArrayBounds = True and median turbidity <= threshold) 'Check for turbidity exceeding sensor limit If (turbDevice = 1 AND medianTurb >= turbLimit) Then FixedTimeSampling If (turbDevice <> 1 AND medianMv >= mvLimitOBS) Then FixedTimeSampling EndIf If (turbTrough >= medianTurb) Then turbTrough = medianTurb reversalCount = 0 EndIf 'Check for change from falling to rising turbidity condition If (medianTurb > oldTurb) Then reversalCount = reversalCount + 1 If (reversalMinimum < turbTrough * troughChange) Then reversalThresh = turbTrough * (1 + troughChange) Else reversalThresh = turbTrough + reversalMinimum EndIf If (medianTurb >= reversalThresh And reversalCount >= persistence) Then threshCode = 1 'Switched to rising turbidity 'Determine next threshold GetNextThresh turbPeak = medianTurb If (nextIndex > 1) Then If (inArrayBounds) Then index = nextIndex - 1 'point below next rising threshold Else 'turbidity is at or above highest rising threshold index = nextIndex 'point at highest rising threshold EndIf rThresh = risingThresh(index) If (turbTrough < rThresh) Then 'Save current offset into threshold array threshPointer = index 'Possible threshold sample ThresholdSample If (inArrayBounds) Then threshPointer = threshPointer + 1 EndIf EndIf 'End If nextIndex > 1 reversalCount = 0 EndIf 'End If medianTurb >= reversalThresh And reversalCount >= persistence 'End If medianTurb > oldTurb EndIf 'Call the table and write a record to data logger memory CallTable TtsTable ContinueScan 'End If threshCode = 2, turbidity falling EndIf NextScan EndProg '\\\\\\\\\\\\\\\\\\\\\\\\\\\ END MAIN PROGRAM ////////////////////////////