'DSS4 Sag River near Deadhorse Site 042 'Adapted from Ken Irving's das2-12sep2012.cr1 program. 'Written by Joel Bailey 6/28/2015 '7/23/2015 - Joel Bailey - added 15min sample for PT1stage and PT2Stage in QtrHrWtr Table '7/28/2015 - Joel Bailey - added normally open scheme to OBS500, wiper closes ever 4 hours to remove sediment '3/30/2016 - Joel Bailey - changed delay for the AT sensor to 4 seconds '5/13/2016 - Ken Irving - added barometer '6/23/2016 - joel bailey - changed PT1 SD12 address to 0 in constant table, changed MET Table to -1 to auto-allocate size '5/27/2017 - Joel Bailey - per Campbell Sci recommendation, changed OBS500 to start open at the beggining of the program ' added enable variable for Hydro and QtrHrWtr tables, added Precip bucket to PP 2 '9/2/2019 - Joel Bailey - changed ENABLE_HYDRO_TABLE to only effect QtrWtr ' constants for base logger-diagnostics rh-pwr-on air-hc2s3 wind-rmyoung barometer-cs106 rh-pwr-off time-variables relay-control-sub camera modem pt-aquistar turbidity-obs500 call-met-tables call-hydro-tables Const NR_WS_CORR = 0.021286 Const TWOPI = 4 * ATN2(1,0) Const PT_PSI_TO_CM = 70.377285 ConstTable Const PAKBUS_INFO = 140 Const SPANEL_VDIV__SE = 11 Const P_MODL = "TE525M" Const P_SN = "XXX" Const P_TIP = 0.1 Const P_UNITS = "mm" Const P__PP = 2 Const RH_RELAY__CP = 4 Const RH_MODL = "HC2S3" Const RH_SN = "XXX" Const RH_MULT = 0.1 Const RH_OFS = 0 Const AT_MULT = 0.1 Const AT_OFS = -50 Const AT__SE = 1 Const RH__SE = 2 Const WS_MODL = "RMY 05103" Const WS_UNITS = "m/s" Const WS_MULT = 0.098 Const WD_UNITS = "deg" Const WD_OFS = 0 Const WD_MULT = 355 Const WS__PP = 1 Const WD__SE = 8 Const WD__EX = Vx1 Const SDI12__CP = 5 Const CAM_PWR__CP = 6 Const CAM_MODL = "CAM-CC640" Const CAM_SN = "01490" Const CAM_ON_MIN = -1 Const CAM_OFF_MIN = 1 Const CAM_PERIOD = 60 Const CAM_V_LIM = 12.4 Const CAM_HOLD_V_LIM = 12.6 Const LATITUDE = 69 Const LONGITUDE = -149 Const TZ_HOURS = -9 Const SUN_ELEV_MIN_DEG = -10 Const MODM_PWR__CP = 9 Const MODM_MODL = "FGR115" Const MODM_SN = "XXX" Const MODM_ON_MIN = 0 Const MODM_OFF_MIN = 10 Const MODM_PERIOD = 30 Const MODM_V_LIM = 12.4 Const MODM_HOLD_V_LIM = 12.6 Const PT_MODL = "INW AquiStar PT12" Const PT1_SN = "?" Const PT2_SN = "?" Const PT1_SDI_ADDR = 0 Const PT2_SDI_ADDR = 2 Const TURB_MODL = "OBS500" Const TURB_SN = "XXX" Const TURB_SDI_ADDR = 0 Const TURB_SDI__CP = 3 Const TURB_ENABLE = 1 Const PB_MODL = "CS106/PTB110" Const PB_UNITS = "mBar" Const PB_MULT = 0.24 Const PB_OFS = 600 Const PB__SE = 15 EndConstTable ' base: Public progSig As Long ' logger-diagnostics: Public battery, SolarPnlV, PanelT Units PanelT = degC Units battery = Volts ' Precip TE525MM Rain Guage Public P Units P=mm ' air-hc2s3: Public at, rh, dp Units at = degC Units rh = percent Units dp = depC ' wind-rmyoung: Public ws, wd Alias ws = windSpeed Units ws = WS_UNITS Alias wd = windDir Units wd = WD_UNITS ' time-variables: Dim Time(9) Alias Time(4) = thisHour Alias Time(5) = thisMinute Alias Time(9) = thisDOY ' camera: Public camOnMin, camOffMin, camPeriod, camVlim, camHldVlim Public camHold As Boolean, camForce As Boolean Public sun_elev, sun_setpt, sun_ok As Boolean ' modem: Public modemOnMin, modemOffMin, modemPeriod, modemVlim, modemHldVlim Public modemHold As Boolean, modemForce As Boolean ' pt-aquistar: Public pt1(3), pt2(3) Alias pt1 = pt1stage, pt1temp, pt1batt Alias pt2 = pt2stage, pt2temp, pt2batt Units pt1stage = cm Units pt2stage = cm Units pt1temp = degC Units pt2temp = degC Units pt1batt = Volts Units pt2batt = Volts ' turbidity-obs500: ' note: obs stands for optical backscatter Public obs(4), turb_en Public TimeCounter Public obsDatOpen(4),obsDatClose(4) Alias obs = backscatter,sidescatter,obs_temp,obs_is_wet Alias obsDatOpen(1) = Open_counts 'Full movement of slider is about 20,000 counts. If it jams this # will be smaller Alias obsDatOpen(2) = Open_Max_mA_cnts ' Number of times the shutter stops while opening because of max current Alias obsDatOpen(3) = Open_slip 'Open timeout count. If the threads are stripped the slide will not move and this count will increase Alias obsDatOpen(4) = Open_mA ' mA current of the motor Alias obsDatClose(1) = Close_counts 'Full movement of slider is about 20,000 counts. If it jams this # will be smaller Alias obsDatClose(2) = Close_Max_mA_cnts ' Number of times the shutter stops while opening because of max current Alias obsDatClose(3) = Close_slip 'Open timeout count. If the threads are stripped the slide will not move and this count will increase Alias obsDatClose(4) = Close_mA ' mA current of the motor Units backscatter = TU Units sidescatter = TU Units obs_temp = degC Public pb : Units pb = PB_UNITS ' enable/disable variable for PT Tables Public ENABLE_HYDRO_TABLE As Boolean ' Daily: base air-hc2s3 wind-rmyoung DataTable(Daily,1,-1) DataInterval(0,1440,Min,0) Sample(1,progSig,uint2) Average(1,at,fp2,0) WindVector(1,windSpeed,windDir,fp2,0,0,0,0) Totalize(1,P,FP2,False) EndTable ' HrlyAtms: base air-hc2s3 wind-rmyoung DataTable(HrlyAtms,1,-1) DataInterval(0,60,Min,0) Sample(1,progSig,uint2) Sample(1,at,fp2) Average(1,at,fp2,0) Minimum(1,at,fp2,0,0) Maximum(1,at,fp2,0,0) Sample(1,rh,fp2) Minimum(1,rh,fp2,0,0) Maximum(1,rh,fp2,0,0) Sample(1,windSpeed,fp2) Sample(1,windDir,fp2) WindVector(1,windSpeed,windDir,fp2,0,0,0,0) Maximum(1,windSpeed,fp2,0,0) Average(1,pb,fp2,0) Totalize(1,P,FP2,False) EndTable ' HrlyDiag: base logger-diagnostics DataTable(HrlyDiag,1,-1) DataInterval(0,60,Min,0) Sample(1,progSig,uint2) Average(1,battery,fp2,0) Average(1,SolarPnlV,fp2,0) Average(1,PanelT,fp2,0) Sample(1,pb,fp2) EndTable ' Hydro: base pt-aquistar turbidity-obs500 DataTable(Hydro,1,-1) DataInterval(0,15,Min,0) Sample(1,progSig,uint2) Average(1,pt1stage,fp2,0) Average(1,pt1temp,fp2,0) Average(1,pt2stage,fp2,0) Average(1,pt2temp,fp2,0) Average(4,obs,fp2,0) EndTable ' Met: base air-hc2s3 wind-rmyoung DataTable(Met,1,-1) DataInterval(0,60,Min,0) Sample(1,progSig,uint2) Average(1,at,fp2,0) Sample(1,rh,fp2) WindVector(1,windSpeed,windDir,fp2,0,0,0,0) Totalize(1,P,FP2,False) EndTable ' QtrHrWtr: base pt-aquistar turbidity-obs500 DataTable(QtrHrWtr,ENABLE_HYDRO_TABLE,-1) DataInterval(0,15,Min,0) Sample(1,progSig,uint2) Sample(1,pt1stage,fp2) Maximum(1,pt1stage,fp2,0,0) Minimum(1,pt1stage,fp2,0,0) Sample(1,pt1temp,fp2) Sample(1,pt2stage,fp2) Maximum(1,pt2stage,fp2,0,0) Minimum(1,pt2stage,fp2,0,0) Sample(1,pt2temp,fp2) Sample(4,obs,fp2) EndTable ' relay-control-sub:relayControl() Sub relayControl(relayPort,onMin,offMin,period,Vlimit,holdVlimit,hold,force) ' uses globals thisMinute, battery If force Then Call setRelayState(relayPort,1) If thisMinute MOD period = onMin AND battery >= Vlimit Then Call setRelayState(relayPort,1) If thisMinute MOD period = onMin AND battery < holdVlimit Then hold = 0 If thisMinute MOD period = offMin AND NOT hold Then Call setRelayState(relayPort,0) EndSub ' relay-control-sub:relayControl2() Sub relayControl2(relayPort,onMin,offMin,period,Vlimit,holdVlimit,hold,force,condition) ' uses globals thisMinute, battery If force Then Call setRelayState(relayPort,1) If thisMinute MOD period = onMin AND battery >= Vlimit AND condition Then Call setRelayState(relayPort,1) If thisMinute MOD period = onMin AND battery < holdVlimit Then hold = 0 If thisMinute MOD period = offMin AND NOT hold Then Call setRelayState(relayPort,0) EndSub ' relay-control-sub:setPortState() Sub setRelayState(relay,state As Boolean) ' portSet() does not allow variable for port, so brute force it: If relay = 9 Then PortSet(9,state) Else If relay = 6 Then PortSet(6,state) Else If relay = 5 Then PortSet(5,state) Else If relay = 4 Then PortSet(4,state) Else If relay = 3 Then PortSet(3,state) Else If relay = 2 Then PortSet(2,state) Else If relay = 1 Then PortSet(1,state) EndIf EndSub ' camera:calc_sunElev() Sub calc_SunElev() Dim declination, solar_hour RealTime(Time()) solar_hour = thisHour + (thisMinute/60) + (LONGITUDE/15 - TZ_HOURS) declination = -23.45 * COS( TWOPI * (thisDOY + 10) / 365 ) sun_elev = (LATITUDE - 90) * COS(solar_hour * 15 * TWOPI / 360) + declination EndSub BeginProg ' for base: progSig = status.ProgSignature ' for camera: camOnMin = (CAM_ON_MIN + CAM_PERIOD) MOD CAM_PERIOD camOffMin = (CAM_OFF_MIN + CAM_PERIOD) MOD CAM_PERIOD camPeriod = CAM_PERIOD camVlim = CAM_V_LIM camHldVlim = CAM_HOLD_V_LIM sun_setpt = SUN_ELEV_MIN_DEG ' for modem: modemOnMin = (MODM_ON_MIN + MODM_PERIOD) MOD MODM_PERIOD modemOffMin = (MODM_OFF_MIN + MODM_PERIOD) MOD MODM_PERIOD modemPeriod = MODM_PERIOD modemVlim = MODM_V_LIM modemHldVlim = MODM_HOLD_V_LIM ' for turbidity-obs500: turb_en = TURB_ENABLE SerialOpen (Com4,115200,4,0,1000) SDI12Recorder (obsDatOpen(),TURB_SDI__CP,TURB_SDI_ADDR,"M3!",1,0) 'Start with shutter open, Rev_1 ENABLE_HYDRO_TABLE = 1 Scan(60,sec,0,0) ' logger-diagnostics: PanelTemp(PanelT,250) battery(battery) VoltSe(SolarPnlV,1,mV5000,SPANEL_VDIV__SE,True,0,250,0.01,0) 'TE525MM/TE525M Rain Gauge measurement 'P' PulseCount(P,1,P__PP,2,0,P_TIP,0) ' rh-pwr-on: PortSet(RH_RELAY__CP,1) Delay(0,4000,mSec) ' air-hc2s3: VoltSe(at,1,mV2500,AT__SE,1,0,250,AT_MULT,AT_OFS) VoltSe(rh,1,mV2500,RH__SE,1,0,250,RH_MULT,RH_OFS) DewPoint(dp,at,rh) ' wind-rmyoung: PulseCount(ws,1,WS__PP,1,1,WS_MULT,0) BrHalf(wd,1,mV2500,WD__SE,WD__EX,1,2500,1,0,250,WD_MULT,WD_OFS) ' barometer: VoltSe(pb,1,mV2500,PB__SE,1,0,250,PB_MULT,PB_OFS) ' rh-pwr-off: PortSet(RH_RELAY__CP,0) ' time-variables: RealTime(Time()) ' camera: calc_sunElev() sun_ok = sun_elev>=sun_setpt relayControl2(CAM_PWR__CP,camOnMin,camOffMin,camPeriod,camVlim,camHldVlim,camHold,camForce,sun_ok) ' modem: relayControl(MODM_PWR__CP,modemOnMin,modemOffMin,modemPeriod,modemVlim,modemHldVlim,modemHold,modemForce) ' call-met-tables: CallTable Daily CallTable HrlyAtms CallTable HrlyDiag CallTable Met NextScan SlowSequence Scan(180,sec,0,0) ' pt-aquistar: '' outputs: 1:pressure (PSI), 2:water temp (C), 3:battery (V) SDI12Recorder(pt1(),SDI12__CP,PT1_SDI_ADDR,"M!",1.0,0) SDI12Recorder(pt2(),SDI12__CP,PT2_SDI_ADDR,"M!",1.0,0) pt1(1) = pt1(1) * PT_PSI_TO_CM pt2(1) = pt2(1) * PT_PSI_TO_CM ' turbidity-obs500: If turb_en Then TimeCounter = TimeCounter + 1 'Wipe at a slower interval than the scan interval If TimeCounter >= 16 Then 'This value, 16, will wipe once every 16 scan intervals. 4 hours in this case SDI12Recorder (obsDatClose(),TURB_SDI__CP,TURB_SDI_ADDR,"M7!",1,0) SDI12Recorder (obsDatOpen(),TURB_SDI__CP,TURB_SDI_ADDR,"M3!",1,0) TimeCounter = 0 EndIf 'Read OBS500 each scan interval outputs: 1:optical backscatter, 2:sidescatter, 3:temp (C), 4:1=wet, 0=dry SDI12Recorder(obs(),TURB_SDI__CP,TURB_SDI_ADDR,"M4!",1,0)' Measure without moving the wiper EndIf ' call-hydro-tables: CallTable Hydro CallTable QtrHrWtr NextScan EndProg