'CR1000 'Created by Short Cut (3.2) ' Modified by Joel Bailey 10-5-2016 ' Changed ATB to SE6 (was SE9) 6/12/2018 eky ' Added PTs to C3 6/12/2018 eky ' **Need to modify constant for HMP45c or H2CS3 AT Offset depending on what we use. ' **Need to modify constant for SR50 height ' 6-22-18 Joel Bailey - removed comments from Camera control, this will enable hourly photos ConstTable Const PAKBUS_INFO = 380 Const SPANEL_VDIV__SE = 11 Const P_MODL = "TE525M" Const P_SN = "50937-412" Const P_TIP = 0.1 Const P_UNITS = "mm" Const P__PP = 2 Const RH_RELAY__CP = 4 Const RH_MODL = "HMP45C" Const RH_SN = "unkn" Const RH_MULT = 0.1 Const RH_OFS = 0 Const AT_MULT = 0.1 Const AT_OFS = -40 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 SST_MODL = "Therm109" Const SST_SN = "266459" Const SST_MULT = 1 Const SST_OFS = 0 Const SST__SE = 5 Const SST__EX = Vx3 Const PB_MODL = "CS100" Const PB_SN = "5319019" Const PB_UNITS = "mBar" Const PB_MULT = 0.2 Const PB_OFS = 600 Const PB__SE = 15 Const PB_EN__CP = 8 Const NR_MODL = "NR-LITE2" Const NR_SN = "114131" Const NR_CALIB = 12.1 Const NR_CALIB_UNITS = "uV/W/m^2" Const NR_UNITS = "W/m^2" Const NR__DIFF = 2 Const SNW_MODL = "SR50A" Const SNW_SN = "2170" Const SNW_HT_CM = 200 Const SNW_SDI_ADDR = 0 Const SDI12__CP = 5 Const MODM_MODL = "iridium" Const MODM_SN = "unk" Const MODM_ON_MIN = 0 Const MODM_OFF_MIN = 10 Const MODM_PERIOD = 60 Const MODM_V_LIM = 12.4 Const MODM_HOLD_V_LIM = 12.6 Const CAM_EN__CP = 6 Const CAM_MODL = "CAM-CC5MPX" Const CAM_SN = "1328" Const CH200_SDI12__CP = 7 Const ATB__SE = 6 'FIXED RESISTOR VALUE FOR GWS THERMISTOR CIRCUITS Const Rf = 1.0 'FIXED RESISTOR 1 (kOHM) HERE ' For YSI thermistors -- conversion of kOHM to deg C Const a = 0.0014654354 Const b = 0.0002386780 Const c = 0.0000001000 ' PTs: Const PT_MODL = "INW AquiStar PT12" Const PT_SDI12__CP = 3 Const CM_PER_PSI = 70.377 Const PT_QTY = 2 EndConstTable 'Declare Variables and Units Public progSig As Long Public Battery Public PTemp_C Public P Public AT Public RH Public DP Public WS Public WD Public PB Public NR Public sr50_raw(2), sr50_down, sd, sr50_height Public SST Public atb_kOhm, ATB ' for GWS Atb Dim atb_x, atb_ln ' for GWS Atb Dim pt_output(3) Public pt_stage(PT_QTY) : Units pt_stage = cm Public pt_temp(PT_QTY) : Units pt_temp = degC Public pt_batt(PT_QTY) : Units pt_batt = V Public pt_addr(PT_QTY) As Long Dim i 'CH200variables Public DlyBatCrtIn_AHr, DlyBatCrtOut_AHr Public LoadPwr_W, ChargePwr_W Public CH200_M0(9) 'Array to hold all data from CH200 Public CH200_MX(4) ' Array to hold extended data from CH200 Alias CH200_MX(1) = BattTargV ' Battery charging target voltage Alias CH200_MX(2) = DgtlPotSet ' Digital potentiometer setting Alias CH200_MX(3) = BattCap ' Present battery capacity Alias CH200_MX(4) = Qloss ' Battery charge deficit ' SDI-12 formatted battery capacity value Public SDI12command As String ' Response from CH200. Retrns the address of the unit and "ok" if all went well Public SDI12result As String Public NEWBATTCAP ' the new battery capacticty if you need to change it. Alias CH200_M0(1)=CH200BattVolts_V 'Battery voltage: VDC Alias CH200_M0(2)=BattCrnt_A 'Current going into, or out of, the battery: Amps Alias CH200_M0(3)=LoadCrnt_A 'Current going to the load: Amps Alias CH200_M0(4)=SolarPanel_V 'Voltage coming into the charger: VDC Alias CH200_M0(5)=SolarPanel_A 'Current coming into the charger: Amps Alias CH200_M0(6)=Chgr_Tmp_C 'Charger temperature: Celsius Alias CH200_M0(7)=Chgr_State 'Charging state: 2=Cycle, 3=Float, 1=Current Limited, or 0=None Alias CH200_M0(8)=Chgr_Source 'Charging source: 0=None, 1=Solar, or 2=AC Alias CH200_M0(9)=Ck_Batt 'Check battery error: 0=normal, 1=check battery Alias sr50_raw(2) = sr50_quality Units Battery=Volts Units PTemp_C=Deg C Units P=mm Units AT=Deg c Units RH=% Units atb=Deg c Units WS=meters/second Units WD=degrees Units PB=mbar Units NR=W/m^2 Units DP=Deg C Units SST=Deg C ' time-variables: Dim Time(9) Alias Time(4) = thisHour Alias Time(5) = thisMinute Alias Time(9) = thisDOY ' modem: Public modemOnMin, modemOffMin, modemPeriod, modemVlim, modemHldVlim Public modemHold As Boolean, modemForce As Boolean Dim Initialized 'Define Data Tables DataTable(HrlyAtms,True,-1) DataInterval(0,60,Min,10) Sample(1,progSig,uint2) Totalize(1,P,FP2,False) Sample(1,AT,FP2) Average(1,AT,FP2,False) Minimum(1,AT,FP2,False,False) Maximum(1,AT,FP2,False,False) Sample(1,RH,FP2) Minimum(1,RH,FP2,False,False) Maximum(1,RH,FP2,False,False) Sample(1,DP,fp2) Average(1,DP,fp2,0) Minimum(1,DP,fp2,0,0) Maximum(1,DP,fp2,0,0) Sample(1,atb,FP2) Average(1,atb,FP2,False) Minimum(1,atb,FP2,False,False) Maximum(1,atb,FP2,False,False) Sample(1,WS,FP2) Sample(1,WD,FP2) WindVector(1,WS,WD,FP2,False,0,0,0) FieldNames("WS_S_WVT,WD_D1_WVT,WD_SD1_WVT") Maximum(1,WS,fp2,0,0) Sample(1,SST,fp2) Average(1,SST,fp2,0) Minimum(1,SST,fp2,0,0) Maximum(1,SST,fp2,0,0) Sample(1,PB,FP2) Average(1,PB,FP2,False) Average(1,NR,FP2,False) Average(1,SD,FP2,False) EndTable 'DataTable(QtrHrWtr,True,-1) 'DataInterval(0,15,Min,10) 'Average (PT_QTY,pt_stage,FP2,False) 'Sample(PT_QTY,pt_stage,fp2) 'Average(PT_QTY,pt_temp,fp2,0) 'Sample(PT_QTY,pt_addr,uint2) 'Sample(1,progSig,uint2) 'EndTable DataTable(Daily,True,-1) DataInterval(0,1440,Min,10) Sample(1,progSig,uint2) Minimum(1,Battery,FP2,False,False) Totalize(1,P,FP2,False) Average(1,AT,FP2,False) Average(1,atb,FP2,False) Average(1,WS,FP2,False) WindVector(1,WS,WD,FP2,False,0,0,0) FieldNames("WS_S_WVT,WD_D1_WVT,WD_SD1_WVT") Average(1,SST,FP2,False) Average(1,NR,FP2,False) Average(1,SD,FP2,False) EndTable DataTable(HrlyDiag,True,-1) DataInterval(0,60,Min,10) Sample(1,progSig,uint2) 'BATTERY VOLTS (V) Sample (1,Battery,FP2) Average (1,Battery,FP2,False) Maximum (1,Battery,FP2,False,False) Minimum (1,Battery,FP2,False,False) 'BATTERY CURRENT (A) Sample (1,CH200_M0(2),FP2) Average (1,CH200_M0(2),FP2,False) Maximum (1,CH200_M0(2),FP2,False,False) Minimum (1,CH200_M0(2),FP2,False,False) 'LOAD CURRENT (A) Sample (1,CH200_M0(3),FP2) Average (1,CH200_M0(3),FP2,False) Maximum (1,CH200_M0(3),FP2,False,False) Minimum (1,CH200_M0(3),FP2,False,False) 'SOLAR PANEL VOLTS (V) Sample (1,CH200_M0(4),FP2) Average (1,CH200_M0(4),FP2,False) Maximum (1,CH200_M0(4),FP2,False,False) Minimum (1,CH200_M0(4),FP2,False,False) 'SOLAR PANEL CURRENT (A) Sample (1,CH200_M0(5),FP2) Average (1,CH200_M0(5),FP2,False) Maximum (1,CH200_M0(5),FP2,False,False) Minimum (1,CH200_M0(5),FP2,False,False) Average (1,CH200_M0(6),FP2,False) 'Charge Regulator Temperature (deg C) Sample (1,NEWBATTCAP,FP2) Sample (1,BattCap,FP2) Sample (1,DlyBatCrtIn_AHr,FP2) Sample (1,DlyBatCrtOut_AHr,FP2) Average (1,ChargePwr_W,FP2,False) Maximum (1,ChargePwr_W,FP2,False,False) Minimum (1,ChargePwr_W,FP2,False,False) Average (1,LoadPwr_W,FP2,False) Maximum (1,LoadPwr_W,FP2,False,False) Minimum (1,LoadPwr_W,FP2,False,False) ' Charger state Sample (1,CH200_M0(7),FP2) Average (1,PTemp_C,FP2,False) 'Logger Temperature (deg C) EndTable DataTable(MET,True,-1) DataInterval(0,60,Min,10) Sample(1,progSig,uint2) Totalize(1,P,FP2,False) Average(1,AT,FP2,False) Sample(1,RH,FP2) Average(1,atb,FP2,False) Average(1,WS,FP2,False) WindVector(1,WS,WD,FP2,False,0,0,0) FieldNames("WS_S_WVT,WD_D1_WVT,WD_SD1_WVT") Average(1,SST,FP2,False) Average(1,PB,FP2,False) Average(1,NR,FP2,False) Average(1,sd,FP2,False) EndTable DataTable(SR50,True,-1) DataInterval(0,60,Min,10) Sample(1,progSig,uint2) Sample(1,AT,FP2) Average(1,SD,FP2,False) Sample(1,sr50_height,FP2) Average(1,sr50_quality,FP2,False) EndTable ' modem control Sub relayControl(onMin,offMin,period,Vlimit,holdVlimit,hold,force) ' uses globals thisMinute, battery If force Then SW12(1) If thisMinute MOD period = onMin AND Battery >= Vlimit Then SW12(1) If thisMinute MOD period = onMin AND Battery < holdVlimit Then hold = 0 If thisMinute MOD period = offMin AND NOT hold Then SW12(0) EndSub 'Main Program BeginProg ' for base: progSig = status.ProgSignature sr50_height = SNW_HT_CM ' 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 modemForce = 1 ' for camera communication SerialOpen(Com1,115200,0,0,1000) ' initialize the default (power up) conditions If Initialized = 0 Then Initialized = 1 NEWBATTCAP = 12 ' 100AHr is max capacity the CH200 will accept EndIf 'Main Scan Scan(60,Sec,1,0) 'Default CR1000 Datalogger Battery Voltage measurement 'BattV' Battery(Battery) 'Default CR1000 Datalogger Wiring Panel Temperature measurement 'PTemp_C' PanelTemp(PTemp_C,250) ' Feature to enter specific battery capacity as a Public value and send to charger(s) 'Get additional values from CH200 SDI12Recorder (CH200_MX(),CH200_SDI12__CP,0,"M6!",1.0,0) 'If the present battery capacity isnot the same as the new battery capacity, send the new one. If BattCap <> NEWBATTCAP Then SDI12command = "XC" & FormatFloat (NEWBATTCAP, "%4.1f") & "!" SDI12Recorder (SDI12result,CH200_SDI12__CP,0,SDI12command,1.0,0) EndIf ''''''''''''''' CH200 CHARGE REGULATOR MEASUREMENTS SDI12Recorder (CH200_M0(),CH200_SDI12__CP,0,"MC!",1.0,0) ' Compute running Power and daily running total AmpHours/Day values for each current measurement. LoadPwr_W = CH200BattVolts_V * LoadCrnt_A ChargePwr_W = SolarPanel_V *SolarPanel_A ' Divide each 1 minute Amp sample by 1440 sample/day so that the total at the end of the day is to get avg current for the day ' then muliply be 24 Hr/day to get AHr/Day. or divide by 60 because 24/1440 = 1/60 ' Separate and sum each the positive and negative currents into and out of the battery to get the total AHr in/out for the day. ' Sample hourly and daily, then zero at end of the day. If BattCrnt_A > 0 Then DlyBatCrtIn_AHr = DlyBatCrtIn_AHr + BattCrnt_A/60 If BattCrnt_A < 0 Then DlyBatCrtOut_AHr = DlyBatCrtOut_AHr + BattCrnt_A/60 'TE525MM/TE525M Rain Gauge measurement 'P' PulseCount(P,1,P__PP,2,0,0.1,0) 'If using HMP45C use offset of -40 'HC2S3 (panel switched power) Temperature & Relative Humidity Sensor measurements 'AT' and 'RH' PortSet(RH_RELAY__CP,1) Delay(0,5,Sec) VoltSe(AT,1,mV2500,AT__SE,0,0,250,AT_MULT,AT_OFS) VoltSe(RH,1,mV2500,RH__SE,0,0,250,RH_MULT,RH_OFS) PortSet(RH_RELAY__CP,0) If RH>100 AND RH<103 Then RH=100 DewPoint(DP,AT,RH) 'ATB using GWS thermistors BrHalf (atb_x,1,mV2500,ATB__SE,Vx2,1,2500,True ,0,_60Hz,1.0,0) atb_kOhm = Rf*atb_x/(1-atb_x) atb_ln = LN (1000*atb_kOhm) 'ln resistance (ohm) atb = (1/(a + b*atb_ln + c*(atb_ln)^3)) - 273.15 'Steinhart & Hart Equation '05103 Wind Speed & Direction Sensor measurements 'WS' and 'WD' PulseCount(WS,1,WS__PP,1,1,WS_MULT,0) BrHalf(WD,1,mV2500,WD__SE,WD__EX,1,2500,True,20000,250,WD_MULT,WD_OFS) If WD>=360 OR WD<0 Then WD=0 'CS100 Barometric Pressure Sensor measurement 'PB' If TimeIntoInterval(59,60,Min) Then PortSet(PB_EN__CP,1) If TimeIntoInterval(0,60,Min) Then VoltSe(PB,1,mV2500,PB__SE,1,0,250,PB_MULT,PB_OFS) PB=PB*1 PortSet(PB_EN__CP,0) EndIf 'NR-LITE2 Net Radiometer (dynamic wind speed correction) measurement 'NR' and 'CNR' VoltDiff(NR,1,mv25,NR__DIFF,True,0,250,1000/NR_CALIB,0) If WS>=5 Then NR=NR*(1+0.021286*(WS-5)) Else NR=NR EndIf ' snow-sr50a: '' read SR50A snow depth sensor: '' read distance in m (positive) and quality number into sr50_raw() '' make distance down negative, convert to cm '' apply correction for speed of sound as f(temperature, 0C) '' calculate snow depth as sum of sensor height and distance down If TimeIntoInterval(0,10,Min) Then SDI12Recorder(sr50_raw, SDI12__CP, SNW_SDI_ADDR, "M1!", 1, 0) sr50_raw = sr50_raw * -100.0 sr50_down = sr50_raw * SQR((AT+273.15) / 273.15) sd = sr50_height + sr50_down EndIf '109 Temperature Probe measurement 'sst' Therm109(SST,1,SST__SE,SST__EX,0,250,SST_MULT,SST_OFS) ' time-variables: RealTime(Time()) 'Camera Control, take a picture at the top of every hour If TimeIsBetween(0,1,60,Min) Then If TimeIsBetween(420,1200,1440,min) Then PortSet(CAM_EN__CP,1) Delay(0,2,Sec) PortSet(CAM_EN__CP,0) EndIf Else PortSet(CAM_EN__CP,0) EndIf ' modem: relayControl(modemOnMin,modemOffMin,modemPeriod,modemVlim,modemHldVlim,modemHold,modemForce) 'Call Data Tables and Store Data CallTable HrlyAtms CallTable Daily CallTable HrlyDiag CallTable MET CallTable SR50 If IfTime (0,1440,Min) Then DlyBatCrtIn_AHr = 0 DlyBatCrtOut_AHr = 0 EndIf NextScan EndProg