' CR1000 Series Datalogger
' JASTREBARSKO METEO  Profiler STATION WITH SOIL RESPIRATION
' Program Name "METPROF_CRAZIA_A5.CR1"
' version A5
' date: 02/05/2008
' from Program "METPROF_CROAZIA_A2.CR1" & "SR_CR1000_E0_1.CR1" of soil respiration

' program author: Giorgio Alberti & Gemini Delle Vedove, DISAA, University of Udine, Udine
' output data files on the SD card

'************************ PROG CONTROL FLAGS *************************************
' FLAG 1 High: output of the meteo data in mV
' FLAG 2 High: start manually soil respiration measurements
' FLAG 3 High: end soil respiration session
' FLAG 4 High: next chamber
' FLAG 5 High: start profiler
' FLAG 6 High: calibration
' FLAG 7 High: reset operational variables
' FLAG 8 High: standby soil respiration system

' ************************** WIRING DIAGRAM **************************************
' ------------------------------- CR1000  ----------------------------------------
'Analog Channels
'  H1 AM16/32 ODD H1
'  L1 AM16/32 ODD L1
'   AM16/32 EVEN H2
'  L2 AM16/32 EVEN L2
'  H3 Battery pack voltage + (with voltage divider)
'  L3 Battery pack voltage - (with voltage divider)
'  H4 Thermocouple to the Palm box (High)
'  L4 Thermocouple to the Palm box (Low)
'  H5
'  L5
'  H6 CO2 SBA4 (high)
'  L6  CO2 SBA4 (low)
'  H7
'  L7
'  H8
'  L8
'Control Channels
'  C1 LI-7500 SDM Data
'  C2 LI-7500 SDM Clock
'  C3 LI-7500 SDM Enable
'  C4 AM16/32 RES
'  C5 AM16/32 CLK
'  C6 To TDR1, TDR2 control (orange)
'  C7  SBA4 serial Input
'  C8
'  12Vsw to
'  12V
'Excitation channels
'  EX1 Wind sensor excitation
'  EX2
'  EX3
'Pulse channels
'  P1 Raingage
'  P2 Wind speed
'
' Grounds (the order they are connecteder is irrelevant all together)
'  G  GND raingage
'  G  GND wind speed
'  G
'  G
'  G  LI-7500 SDM reference
'
' Shields (the order they are connecteder is irrelevant all together)
'  Shield  LI-7500 SDM shield

' --------------------------------- AM16/32 ----------------------------------------
'1  H1 CMP3 High
'   L1 CMP3 Low
'   H2 NR Lite High
'   L2 NR Lite Low
'2  H1 Li-190 up High  Q37658
'   L1 Li-190 up Low
'   H2 Li-190 down High Q37649
'   L2 Li-190 down Low
'3  H1 Calex IR Temp. High
'   L1 Calex IR Temp. Low
'   H2 Vaisala HMCP Ta High
'   L2 To Ch. 4 L1
'4  H1 Vaisala HMP45C RH High
'   L1 Vaisala HMP45C RH Low and to CR1000 AG
'   H2 Wind direction High
'   L2 Wind direction Low
'5  H1 Soil Tcp 1-4 blue
'   L1 Soil Tcp 1-4 red
'   H2 Soil Tcp 2-5 blue
'   L2 Soil Tcp 2-5 red
'6  H1 Soil Tcp 3-6 blue
'   L1 Soil Tcp 3-6 red
'   H2 Soil Tcp 7-10 blue
'   L2 Soil Tcp 7-10 red
'7  H1 Soil Tcp 8-11 blue
'   L1 Soil Tcp 8-11 red
'   H2 Soil Tcp 9-12 blue
'   L2 Soil Tcp 9-12 red
'8  H1 SHF plates 1 red H073143
'   L1 SHF plates 1 black
'   H2 SHF plates 2 red H073145
'   L2 SHF plates 2 black
'9  H1 SHF plates 3 red H073146
'   L1 SHF plates 3 black
'   H2 SHF plates 4 red H073144
'   L2 SHF plates 4 black
'10 H1 TDR1
'   L1 TDR2
'   H2
'   L2
'11 H1
'   L1
'   H2
'   L2
'12 H1
'   L1
'   H2
'   L2
'13 H1
'   L1
'   H2
'   L2
'14 H1
'   L1
'   H2
'   L2
'15 H1
'   L1
'   H2
'   L2
'16 H1
'   L1
'   H2
'   L2
'
' *********************************** SDM CD16AC relays ****************************
'
' 1 COM - 24V
' 1 NOpen - Valv_prof_1
' 1 NClosed -

' 2 COM - 24V
' 2 NOpen - Valv_prof_2
' 2 NClosed -

' 3 COM - 24V
' 3 NOpen - Valv_prof_3
' 3 NClosed -

' 4 COM - 24V
' 4 NOpen - Valv_prof_4
' 4 NClosed -

' 5 COM - 24V
' 5 NOpen - Valv_prof_5
' 5 NClosed -

' 6 COM - 24V
' 6 NOpen - Valv_prof_6
' 6 NClosed -

' 7 COM - 24V
' 7 NOpen - Valv & Close Chamber 1
' 7 NClosed - Open Chamber 1

' 8 COM - 24V
' 8 NOpen - Valv & Close Chamber 2
' 8 NClosed - Open Chamber 2

' 9 COM - 24V
' 9 NOpen - Valv & Close Chamber 3
' 9 NClosed - Open Chamber 3

' 10 COM - 24V
' 10 NOpen - Valv & Close Chamber 4
' 10 NClosed - Open Chamber 4

' 11 COM - 24V
' 11 NOpen - Valv & Close Chamber 5
' 11 NClosed - Open Chamber 5
'?
' 12 COM - 24V
' 12 NOpen -  Output Profiler valve & flushing SR valve
' 12 NClosed -

' 13 COM - 12V
' 13 NOpen - Pump Profiler A
' 13 NClosed -

' 14 COM - 12V
' 14 NOpen - Main Profiler Pump (Mefar)
' 14 NClosed -

' 15 COM - 12V
' 15 NOpen - SR pump B
' 15 NClosed -

' 16 COM - Zero_irga
' 16 NOpen - Zero_irga
' 16 NClosed -
' SDM variables ************************************************

Public SDMval(16) As Long

'Alias SDMval(1)=ProfValv(1)
'Alias SDMval(2)=ProfValv(2)
'Alias SDMval(3)=ProfValv(3)
'Alias SDMval(4)=ProfValv(4)
'Alias SDMval(5)=ProfValv(5)
'Alias SDMval(6)=ProfValv(6)
Alias SDMval(7)=Ch1
Alias SDMval(8)=Ch2
Alias SDMval(9)=Ch3
Alias SDMval(10)=Ch4
Alias SDMval(11)=Ch5
Alias SDMval(12)=Flush_valve      'Open in profiler mode rat
Alias SDMval(13)=A_Pump                   'Pump A
Alias SDMval(14)=Prof_Pump		'Min profiler pump
Alias SDMval(15)=Ch_pump               'Chamber Pump
Alias SDMval(16)=Irga_zero

' ******************************** VARIABLES *************************************

Public i,j,acount,b
Public Vbat, time, main_PWR, Ta_palm
Units Vbat = mV
Units Ta_palm = Celsius
Units main_PWR = mV

Public Tref
Units Tref = Celsius

Public P, WS, WD, Rn, Rg, PPFD, PPFDd, Tc, Ta, Rh
Public WD_mV, Rg_mV, Rn_mV, PPFD_mV, PPFDd_mV, Tc_mV
Public Ts(6)

Alias Tc = Canopy_temp

Units P = mm
Units WD = m/s
Units WD = degree
Units Rn = W/m^2
Units Rg = W/m^2
Units PPFD = umol/(m^2*s)
Units PPFDd = umol/(m^2*s)
Units Tc = Celsius
Units Ta = Celsius
Units Rh = percentage
Units Ts(6) = Celsius

Public period(2)
Public periodc(2)
Public SWC(2)
Public shf_cal(4), shf_mV(4), shf(4)
Dim irga_raw(4)
Public AGC As Long
Public CO2, H2O, Press

Units period(2) = unitless
Units periodc(2) = unitless
Units shf(4) = W/m^2
Units AGC = unitless

' HFP01SC plates
Alias shf(1) = H073143
Alias shf(2) = H073145
Alias shf(3) = H073146
Alias shf(4) = H073144

' LICOR 7500 IRGA VARIABLES
Alias irga_raw(1) = co2_raw
Alias irga_raw(2) = h2O_raw
Alias irga_raw(3) = press_raw
Alias irga_raw(4) = diag_irga_raw
'LICOR 7500 UNITS
Units co2_raw = umol/m^3
Units h2O_raw = umol/m^3
Units press_raw = kPa
Units diag_irga_raw = unitless

' Flags
Public FLAG(8) As Boolean

' ******************************* CONSTANTS ****************************************
Const AM16clk=15000
Const ON=1
Const OFF=0

' TDR CS616 Water Content Reflectometry
Const C0 = -0.0663
Const C1 = -0.0063
Const C2 = 0.0007
Const C3 = 0.526
Const C4 = -0.052
Const C5 = 0.00136

' CMP3 Global radiation sensor
Const M1 = 10.85/1000

' NR-Lite Net radiation
Const M2 = 0.0148

' Wind speed and direction
Const m_WS = 1
Const m_WD = 1

' HFT Rebs Soil heat flux plates
Const H073143_cal  = 34.5
Const H073145_cal  = 35.1
Const H073146_cal  = 37.4
Const H073144_cal  = 33.5

' ******* Profiler AND Soil Respiration Variables ****************************************
Public Task_Mode As String * 16  ' Profiler or SR task
'SBA 4 Varaibles
Public SBA_string As String * 80
Public SBA_ID As String * 2
Public SBA_vect(12) As Float
Public CO2dry As Float
Public lun_sbastring As Long
Public clockchk As Boolean
Public Trig_IRGAread As Boolean
Public Trig_SEfflux As Boolean

Alias SBA_vect(1)=dig_ZERO
Alias SBA_vect(2)=dig_CO2
Alias SBA_vect(3)=dig_CO2AV
Alias SBA_vect(4)=IRGA_temp
Alias SBA_vect(5)=Ea_mb
Alias SBA_vect(6)=Ea_temp
Alias SBA_vect(7)=Asba
Alias SBA_vect(8)=Bsba
Alias SBA_vect(9)=Csba
Alias SBA_vect(10)=Dsba
Alias SBA_vect(11)=Esba
Alias SBA_vect(12)=sba_Press

'declare as public rTime to 9
Public rTime(9), ClockValues(7)
Alias rTime(1) = Year	'assign the alias Year to rTime(1)
Alias rTime(2) = Month	'assign the alias Month to rTime(2)
'Alias rTime(3) = Day	'assign the alias Day to rTime(3)
Alias rTime(4) = Hour	'assign the alias Hour to rTime(4)
Alias rTime(5) = Minute	'assign the alias Minute to rTime(5)
Alias rTime(6) = Second	'assign the alias Second to rTime(6)
Alias rTime(7) = uSecond	'assign the alias uSecond to rTime(7)
Alias rTime(8) = WeekDay	'assign the alias WeekDay to rTime(8)
Alias rTime(9) = Day_of_Year	'assign the alias Day_of_Year to rTime(9)

'
' Profiler Variable
Const  flush_level_int=22.4			                              ' seconds to flush a level (def 14*1.6=22.4sec)
Const sdm_address=0                                                       '  set SDM address 'Address
Public prof_Timer
Public CO2_Profiler As Boolean 			                       ' logical variable if true it operates Profiler if FALSE it operate Soil Respiration
Public Chk_profilestp As Boolean 			               'logical var. if false the Sub. Chk_profsetup is called
Public Trig_CO2prof  As Boolean 			                       ' Profiler  output Trigger
Public ProfMode As String
Public Prof_Output_Long As Boolean                               ' Long output of profiler
Public Out_Prof_int  As Long				'USER  defined    Output Interval (SEC)  of Profiler  averages
Public Rep_level As Long 					' USER  defined  Num of repl for each level during  an Out_Prof_Int
Public min_lev_count As Long 				' USER  defined  minimum data for each sampling for each level
Public level_list As String *100			         ' USER  defined list of profiler levels (def (1.....,6)
Public Elev_list As String * 100				' USER  defined list of Heights  [m] from LOWEST to HIGHEST (eg 1,2.2,3.4....
'
Public  level_int  As Long						'   seconds to sample a level Computed in sub
Public  Profile_elev(16) As Float   		 	' High of samplers (m) from level floor to top (1 to 6 )
Public level  As Long				 			' profiler level 1 = ProfValv(1) =lowest ; 6 =ProfValv(6) = highest
Public lev_h As Float                                ' sampling height (m)
Public N_level  As Long				 		' profiler's levels
Public Sec_level As Long					' total seconds of each level during   an Out_Prof_Int
Public lev_seq(16) As Long 						'sequential order of levels as entered in level_list
Public lev_count As Long						' measurements counter for each level
Public prof_rawdata(6,10) 					'Matrix of raw data (levels, data)

' Soil Respiration Variables
Public CO2ini,CO2fin, CO2ana
Public Rhoini, t0, Efflux
Public Trig_CO2Out As Boolean ' SR output Trigger
Public Mode As String * 16
Public nread, mixread,interpread,firsttime
Public TimerMode As Float,Timerinterp As Float 'TimerCo as FLOAT
Public WarmInt									'Interval FOR warmup in Manual meas.nts
Public OutputTime							'Sec after closure start Output CO2reads
Public IRGA_ZeroInt							'Interval FOR switch zeroing of IRGA
Public CoInt, CoTime							'Mode Cocalculation
Public MixInt,MixTime						' Mode Mixing
Public InterpInt,InterpTime					'Mode Interpolation
Public FlushInt									'Mode Flushing waiting in valve 13
Public runAvgmodule						' counts in runavg
Public manual, sess_hour
Public val_number

'OPerational variables
Public chksetupvar As Boolean ' check FOR execution of sub setupvar
Public Ch_list As String * 100 , Ch_clTime_List As String * 100,Ch_col_ht_List As String * 100
Public Ch_seq(6) As Long
Public col_ht(6)  ' H collare+camera fuori terra -6.6 cm (altezza camera) (cm)
Public CloseInt(6),CloseTime 	' Mode Closechamber
Public Nchambers,seq_Ch,Chamber ,Cycle
Public Ncycles,LoggerID As String * 16
Public Vbase, Area, Vtot
Public niter, iCx, iCo,ia   ' numero di iterazioni, e val.iniziali parametri
Public status
Const automeas=240			'(min) interval Automatic Measurement
Const autostart=240			'(min) into interval Automatic START

' GaussNewton
Public Cdry(100) As Float, dt As Float
Public iter, iread
Public Cx,Co,a, dCx, dCo, da, Ct
Public SCx2,SCo2,Sa2,SCxCo,SCxa,SCoa,Res, SRCx, SRCo, SRa
Public det
Public n,eat,e2at,eant,e2ant

'Dim Counter
Public I1,I2,I3,I4,I5,I6

' *********************************** SubRoutines ****************************

' *********************************** OUTPUT VARIABLES ****************************

DataTable (Meteo,1,-1)
   OpenInterval
   DataInterval (0,30,Min,10)
   CardOut (0,-1000)
   Average(1,Vbat,FP2,0)
   Average(1,main_PWR,FP2,0)
   Average (1,Ta_palm,FP2,0)
   Average(1,Ta,FP2,0)
   Average(1,Rh,FP2,0)
   Average(1,Tc,FP2,0)
   Totalize(1,P,FP2,0)
   Average(1,WD,FP2,0)
   Totalize(1,WS,FP2,0)
   Average(1,Rn,FP2,0)
   Average(1,Rg,FP2,0)
   Average(1,PPFD,FP2,0)
   Average(1,PPFDd,FP2,0)
   Average(6,Ts(),FP2,0)
   Average(2,SWC(),FP2,0)
   Average (4,shf(),IEEE4,False)
   Average (1,co2_raw,IEEE4,0)
   Average (1,h2O_raw,IEEE4,0)
   Average (1,press_raw,IEEE4,0)
   Average (1,AGC,IEEE4,0)
EndTable

DataTable (Meteo_mV,1,-1)
   OpenInterval			'SEE help (F1)
   DataInterval (0,30,Min,10)
   CardOut (0,-1000)
   Average(1,WD_mV,FP2,0)
   Average(1,Rn_mV,IEEE4,0)
   Average(1,Rg_mV,IEEE4,0)
   Average(1,PPFD_mV,IEEE4,0)
   Average(1,PPFDd_mV,IEEE4,0)
   Average(1,Tc_mV,IEEE4,0)
   Average(2,period(),IEEE4,0)
   Average(2,periodc(),IEEE4,0)
   Average (4,shf_mV(),IEEE4,False)
EndTable

' **** MAIN PROGRAM ******************************
'PipeLineMode

PreserveVariables  '? try it  - uncomment

BeginProg
   ' PROFILER & SR  CONFIGS
   Timer(0,sec,2)
   SerialOpen (Com4,9600,7,0,100)'?
   SerialFlush (Com4)
   PortsConfig (&B10111000,&B01111111)
   RealTime(rTime())
   SerialFlush (Com4)' C7-C8 of CR1000
   Do While  SerialInBlock (Com4,SBA_string,1000)=0
   Loop
   uSecond=0                         ' rTime(7)=0
   Move (ClockValues(),7,rTime(),7)

   ClockSet (ClockValues()):
   clockchk=True
   SerialFlush (Com4)               ' C7-C8 of CR1000

   Out_Prof_int=1800  				'USER  defined    Output Interval (SEC)  of Profiler  averages (def 1800 )
   Rep_level=5							' USER  defined  Num of repl for each level during  an Out_Prof_Int (def. 1-10)
   min_lev_count=10 					' USER  defined  minimum data for each sampling for each level (def 10 ->> 16 sec)
   level_list="1,2,3,4,5,6"			' USER  defined list of profiler levels (def (1.....,6)
   Elev_list="1,2.5,5,10,15,25"		' USER  defined list of elevations [m] from LOWEST to HIGHEST (eg "1,2.2,3.4...."
   level_int=50
   Chk_profilestp=False
   clockchk=False                         ' reset clock to match  sba reads with scan interval
   Task_Mode="Profiler"               ' Tasks priorities are Meteo reads, Profiling & SoilResp in the order
   CO2_Profiler=False
   If Ch_list="" Then	Ch_list="1,2"
   If Ch_clTime_List= "" Then Ch_clTime_List= "140,140,148,144,150,150"   ' Closure time of chambers 1 to 5
   MixInt = 20  			' sec. from closure to start Interpolation fitting of Ct=f(Time) funcion

   ' *************************** METEO READINGS *************************

   Scan (30,Sec,3,0)
      PanelTemp (Tref,250)
      Battery (Vbat)
      RealTime(rTime())

      'Read CR1000
      ' Read main power status

      VoltDiff (main_PWR,1,mV5000,3,True ,0,250,0.0104,0)

      ' Read thermocouple in the palm box
      TCDiff (Ta_palm,1,mV2_5C,4,TypeT,TRef,True ,0,250,1.0,0)

      ' Rain
      PulseCount (P,1,1,2,0,0.1,0)

      ' Wind speed
      PulseCount(WS,1,2,0,0,1,0)
      WS = WS * m_WS

      ' LI-7500 CO2, H2O, air pressure and diagnostic
      CS7500 (co2_raw,1,7,6)

      CO2 = co2_raw
      H2O = h2o_raw
      Press = press_raw

      ' Compute the AGC
      AGC = INT ((diag_irga_raw AND &h000f) * 6.25 + 0.5)

      ' Read multiplexer
      PortSet (4,1)
      PulsePort(5,AM16clk)

      ' Global radiation (CMP3)
      VoltDiff (Rg_mV,1,mV25,1,True ,0,250,1.0,0)
      Rg=Rg_mV / M1

      ' Net radiometer (NR - Lite)
      VoltDiff (Rn_mV,1,mV25,2,True ,0,250,1.0,0)
      Rn = Rn_mV / M2

      ' Incoming and outcoming PPFD (0V = 0 - 5 mV = 1000 umol m-2 s-1)
      PulsePort(5,AM16clk)
      VoltDiff (PPFD_mV,1,mV25,1,True ,0,250,1,0)
      VoltDiff (PPFDd_mV,1,mV25,2,True ,0,250,1,0)
      PPFD=PPFd_mV*200
      PPFDd=PPFDd_mV*200

      ' Outcoming long wave radiation (0V = -20 - 5V = 100 C)
      PulsePort (5,AM16clk)
      VoltDiff (Tc_mV,1,mV5000,1,True ,0,250,1.0,0)
      Tc = Tc_mV * 0.024 - 20

      ' Air temperature and air humidity (Vaisala)
      VoltDiff (Ta,1,mV2500,2,True ,0,250,0.1,0)
      Ta = Ta - 40

      PulsePort (5,AM16clk)
      VoltDiff (Rh,1,mV2500,1,True ,0,250,0.1,0)

      ' Wind direction
      VoltDiff (WD_mV,1,mV5000,2,True ,0,250,1,0)
      WD = WD_mV * m_WD

      ' Soil temperature
      For I=1 To 6 Step 2

         PulsePort (5,AM16clk)
         TCDiff (Ts(I),2,mV2_5C,1,TypeT,TRef,True ,0,250,1.0,0)

      Next I
      ' Read HFP01SC plates

      PulsePort (5,AM16clk)
      VoltDiff (shf_mV(1),1,mV250C,1,True ,200,250,1.0,0)
      VoltDiff (shf_mV(2),1,mV250C,2,True ,200,250,1.0,0)
      PulsePort (5,AM16clk)
      VoltDiff (shf_mV(3),1,mV250C,1,True ,200,250,1.0,0)
      VoltDiff (shf_mV(4),1,mV250C,2,True ,200,250,1.0,0)

      ' Load the HFP01SC factory calibration
      shf_cal(1) = H073143_cal
      shf_cal(2) = H073145_cal
      shf_cal(3) = H073146_cal
      shf_cal(4) = H073144_cal

      ' Apply HFP01SC soil heat flux plate calibration
      For I = 1 To 4
         shf(I) = shf_mV(I) * shf_cal(I)
      Next I
      ' Read CS616 Water Content Reflectometry
      PulsePort (5,AM16clk)
      CS616 (period(),2,1,6,4,1.0,0)

      ' Correct CS616 for soil temperature
      For I=1 To 2

         periodc(I)= period(I) + (20-Ts(1))*(0.526 - 0.052*period(I) + 0.00136 * (period(I))^2)
         SWC(I)=C0 + C1 * periodc(I) + C2 * period(I)^2

      Next I
      ' Turnoff multiplexer
      PortSet (4,0)

      ' ****************************** DO OUTPUT ********************
      CallTable meteo
      ' Ouput also meteo_mV (data in mV) if flag1 is High
      If Flag(1) = True Then
         CallTable meteo_mV
      EndIf
   NextScan

   ' ******** PROFILER & SOIL RESPIRATION ***************************
   SlowSequence
   ' ---------------- Profiler setup variables

   Sub Chk_profsetup		' SETUPS the profiler variables
      SplitStr(lev_seq() ,level_list,"",16,0)
      SplitStr(Profile_elev()  ,Elev_list ,"",16,0)

      N_level=0
      For i=1 To 16
         If lev_seq(i)>0 AND lev_seq(i)<=6	Then
            N_level=N_level+1
            lev_seq(N_level)=lev_seq(i)
         EndIf
      Next i
      For i=N_level+1 To 16
         lev_seq(i)=0
      Next i
      'compute profiler parameters to correct invalid inputs
      Sec_level=(Out_Prof_int)/N_level 			' total seconds available for each level during   an Out_Prof_Int

      level=1
      Chk_profilestp=TRUE

   EndSub

   Sub SBAread
      SerialIn (SBA_string,Com4,10,13,100)
      ' If SerialInBlock (Com4,SBA_string,80)=0 Then  ExitSub ' ?sost 1000 con 80
      SerialFlush (Com4)' C7-C8 of CR1000
      lun_sbastring =Len(SBA_string)
      SBA_ID=Left(SBA_string,1)      '? 'SplitStr(SBA_ID,SBA_string,", ",1,1)'?sost last 7 con 1
      SplitStr(SBA_vect(),SBA_string,"",12,0)
      If SBA_ID="M" Then
         If Mode="Interpolation" Then  TimerInterp=Timer(2,mSec,4)/1000 ' ? if SResp active
         CO2dry=dig_CO2AV/(1-Ea_mb/sba_Press )
      Else
         CO2dry=0
      EndIf
   EndSub ' Sbaread
   ' **********************   SR - set-up variables   ***********************

   Sub SRsetupvar
      ' tempi chiusura stazione camere
      LoggerID=Status.StationName(1,1)
      i=Right (LoggerID,1)
      Ch_clTime_List= "140,140,148,144,144"
      MixInt = 20  			' sec. from closure to Interpolation fitting of Ct=f(Time)
      If Ch_list="" Then	Ch_list="1,2,3,4,5"
      If Ch_clTime_List="" Then Ch_clTime_List="143,150,147,141,144"
      If Ch_col_ht_List="" Then Ch_col_ht_List="-1.5,-1.5,-1.5,-1.5,-1.5"

      SplitStr(Ch_seq(),Ch_list,"",5,0)
      SplitStr(CloseInt(),Ch_clTime_List,"",5,0)
      SplitStr(col_ht(),Ch_col_ht_List,"",5,0)
      j=0
      For i=1 To 5
         If Ch_seq(i)>0 AND Ch_seq(i)<=12 	Then
            j=j+1
            Ch_seq(j)=Ch_seq(i)
         EndIf
      Next i
      For i=j+1 To 5
         If i>5 Then ExitFor
         Ch_seq(i)=0
      Next i
      Nchambers=j
      Ncycles=1

      runAvgmodule=3

      Vbase = 1319.3
      Area = 196.1
      OutputTime=120		' Time (sec) after closure start OUTPUT of CO2Reads
      IRGA_ZeroInt=4		' Interval FOR zeroing SBA4

      CoInt = 1.60*8			' sec. used FOR interpolation of C0=f(Time) during MixInterval
      InterpInt = 120             	' sec. used to fit Ct=f(Time)
      WarmInt = 120  		' sec. used to warmup IRGA in Manual Mode
      FlushInt = 5			' sec between chamber's meas.nts

      niter=10
      iCx = 700
      iCo = 420
      ia  = 0.005

      chksetupvar=TRUE

   EndSub  ' Setupvar

   Sub GaussNewton  ' numero di iterazioni, e val.iniziali parametri
      ' numero di iterazioni, e val.iniziali parametri

      'Procedura di fit non lineare secondo il modello LI8100
      'Ct=Cx-(Cx-Co)*exp(-a*t)

      dCx=0
      dCo=0
      da=0
      Cx=CO2fin		'ERA iCx
      Co=CO2ini 'ERA iCo
      a=ia
      For iter=1 To niter

         Cx=Cx+dCx
         Co=Co+dCo
         a=a+da
         dt=Timerinterp/interpread
         e2at=EXP(2*a*dt)
         eat=EXP(a*dt)
         ' sum from closure to End of Mixing
         '		n=mixread 'mixread Counter from ClosureTime to MixTime
         n=interpread 'mixread Counter from ClosureTime to MixTime
         e2ant=EXP(-2*a*n*dt)
         eant=EXP(-a*n*dt)
         SCx2=2*eant/(eat-1)+e2ant/(1-e2at)+(n*e2at-2*eat-n-1)/((eat+1)*(eat-1))
         SCo2=(e2ant-1)/(1-e2at)
         Sa2=(dt*(Cx-Co))^2*(e2ant*(e2at^2*(n+1)^2-e2at*(2*n^2+2*n-1)+n^2)-e2at*(e2at+1))
         Sa2=Sa2/(1-e2at)^3
         SCxCo=eant/(1-eat)+e2ant/(e2at-1)+eat/(e2at-1)
         SCxa =dt*(Cx-Co)*(eant*(n-eat*(n+1))/((eat-1)^2)+e2ant*(e2at*(n+1)-n)/((e2at-1)*(e2at-1))+eat*(e2at+eat+1)/((eat+1)^2*(eat-1)^2))
         SCoa = dt*(Cx-Co)*(e2ant*(n-e2at*(n+1))+e2at)/(e2at-1)^2
         ' Sum from end of Mixing to End of Interpolation
         '		n=nread 'nread counter from Closure Time to Interpolation Time
         '		e2ant=exp(-2*a*n*dt)
         '		eant=exp(-a*n*dt)
         '		SCx2=-SCx2+2*eant/(eat-1)+e2ant/(1-e2at)+(n*e2at-2*eat-n-1)/((eat+1)*(eat-1))
         '		SCo2=-SCo2+(e2ant-1)/(1-e2at)
         '		Sa2=-Sa2+(dt*(Cx-Co))^2*(e2ant*(e2at^2*(n+1)^2-e2at*(2*n^2+2*n-1)+n^2)-e2at*(e2at+1))/(1-e2at)^3
         '		SCxCo=-SCxCo+eant/(1-eat)+e2ant/(e2at-1)+eat/(e2at-1)
         '		SCxa =-SCxa+dt*(Cx-Co)*(eant*(n-eat*(n+1))/((eat-1)^2)+e2ant*(e2at*(n+1)-n)/((e2at-1)*(e2at-1))+eat*(e2at+eat+1)/((eat+1)^2*(eat-1)^2))
         '		SCoa =-SCoa+ dt*(Cx-Co)*(e2ant*(n-e2at*(n+1))+e2at)/(e2at-1)^2
         '
         SRCx = 0
         SRCo = 0
         SRa = 0
         For iread=1 To interpread ' only interpolation Mode data
            eant=EXP(-a*iread*dt)
            Ct=Cdry(iread)						'vettore delle letture
            Res=Ct-(Cx-(Cx-Co)*eant)
            SRCx=SRCx+(1-eant)* Res
            SRCo=SRCo+eant* Res
            SRa=SRa+(Cx-Co)*iread*dt*eant* Res
         Next iread
         det=SCx2*(SCo2*Sa2-SCoa^2)-SCxCo^2*Sa2+SCxa*(2*SCxCo*SCoa-SCxa*SCo2)
         I1=(SCo2*Sa2-SCoa*SCoa)/det
         I2=(SCxa*SCoa-ScxCo*Sa2)/det
         I3=(SCxCo*SCoa-SCxa*SCo2)/det
         I4=(SCx2*Sa2-SCxa*SCxa)/det
         I5=(SCxCo*SCxa-SCx2*SCoa)/det
         I6=(SCx2*SCo2-SCxCo*SCxCo)/det
         dCx=I1*SRCx+I2*SRCo+I3*SRa
         dCo=I2*SRCx+I4*SRCo+I5*SRa
         da=I3*SRCx+I5*SRCo+I6*SRa

      Next iter
   EndSub	'GaussNewton
   ' ********   SUB 2 - close chamber and set variables: Vtot, Tsoil, SWC   *******

   Sub Closechamber
      For i=1 To 13
         SDMval(i)=0
      Next i
      val_number=Chamber+6
      SDMval(val_number) = ON
      Vtot=col_ht(Chamber)*Area+Vbase
      '			CloseTime=CloseInt(Chamber)
      '			MixTime=CloseTime+MixInt
      '			InterpTime=MixTime+InterpInt

   EndSub 'Closechamber
   ' --------------------------- PROFILER OUTPUT ------------------------------

   DataTable (CO2prof,Trig_CO2prof,-1)
      CardOut (0,-1000)

      Sample(1,level,FP2)
      FieldNames ("Level#:Starting from floor")
      Sample(1,lev_count,FP2)
      FieldNames("Meas#:N of Data")
      Sample(1,lev_h,FP2)
      FieldNames ("lev_h:height (m)")
      Sample(1,CO2dry,IEEE4)
      FieldNames("lev_CO2:CO2dry [ppm]")
      Sample(1,Ea_mb,FP2)
      FieldNames("lev_Ea:vapour pressure[mb]")
      Sample(1,Ea_temp ,FP2)
      FieldNames("lev_temp:SBA temp[C]")
      Sample(1,sba_Press,FP2)
      FieldNames("lev_Press:SBA Press[mb]")

   EndTable 'CO2prof

   ' --------------------------- PROFILER OUTPUT LONG------------------------------

   DataTable (CO2prof_Long,Prof_Output_Long,3600*24/1.6) '
      CardOut (0,-1000)

      Sample(1,level,FP2)
      FieldNames ("Level#:Starting from floor")
      Sample(1,CO2dry,IEEE4)
      FieldNames("lev_CO2:CO2dry [ppm]")

   EndTable 'CO2prof

   DataTable (CO2read,Trig_CO2Out,300*12*6)
      CardOut (0,-1000)

      Sample (1,TimerInterp,Long)
      Sample (1,TimerMode,Long)
      Sample (1,Mode,String)
      Sample (1,Chamber,Long)
      Sample (1,Cycle,Long)
      Sample (1,nread,Long)
      Sample (1,interpread,Long)
      Sample (1,CO2dry,IEEE4)
      Sample (1,Ea_temp,FP2)
      Sample (1,Ea_mb,FP2)
      Sample (1,sba_Press,FP2)
      Sample (1,CO2ana,IEEE4)

   EndTable 'CO2read

   DataTable (Effl_Out,Trig_SEfflux,12*12*6)

      CardOut (0,-1000)

      Sample (6,rTime(),IEEE4)
      '	Sample (1,TimerInterp,IEEE4)
      Sample (1,TimerMode,Long)
      Sample (1,Mode,String)
      Sample (1,Chamber,Long)
      Sample (1,Cycle,Long)
      Sample (1,nread,Long)
      Sample (1,Efflux,IEEE4)
      Sample(1,CO2ini,IEEE4)
      Sample (1,CO2fin,IEEE4)
      Sample (1,Co,IEEE4)
      Sample (1,Cx,IEEE4)
      Sample (1,a,IEEE4)
      Sample(1,t0,IEEE4)
      Sample (1,Rhoini,IEEE4)

   EndTable

   ' ------PROFILER MAIN PROGRAM ----------------------------

   Scan (400,mSec,15,0)
      If FLAG(5)  Then                     'Active/de-activate profiler
         If Task_mode="Meteo_only" Then
            Call Chk_profsetup
            clockchk=False
            Task_Mode="Prof_Wait"
            Firsttime=ON
         EndIf
      EndIf
      If flag(5)=False Then
         For i=1 To 6 :  SDMval(i)=OFF :
         Next i:  CO2_Profiler=False
         If Task_Mode<>"SR" Then
            Task_Mode="Meteo_only"
         EndIf
         CO2_Profiler=False
         A_pump=OFF
         Prof_pump=OFF
         ProfMode=""
      EndIf
      If  Task_Mode="Prof_wait" AND Task_Mode<>"SR" AND Minute MOD 6 =0 Then
         Task_Mode="Profiler"
         ProfMode="Prof_wait"
         Prof_Pump=ON
         A_pump=OFF
         SDMCD16AC (SDMval(),1,sdm_address)
      EndIf
      If  Task_Mode="Profiler" AND Task_Mode<>"SR"    AND IfTime (1,6,Min) Then
         Prof_Pump=OFF
         Task_Mode="Profiler"
         ProfMode="Profstart"
         CO2_Profiler=True
         SDMCD16AC (SDMval(),1,sdm_address)
      EndIf
      If main_PWR<22 Then
         For i=1 To 16 :  SDMval(i)=OFF :
         Next i:  CO2_Profiler=False
         Task_Mode="Meteo_only"
         CO2_Profiler=False
         ProfMode=""
         Mode="Standby"
         Flag(5)=False
      EndIf
      If Task_Mode="Profiler" AND CO2_Profiler=True Then
         prof_Timer=Timer(0,mSec,4)/1000
         If Chk_profilestp=FALSE Then Call Chk_profsetup
         '      If clockchk=False Then                ' match system clock and  sba clock
         '         RealTime(rTime())
         '         SerialFlush (Com4)' C7-C8 of CR1000
         '         Do While  SerialInBlock (Com4,SBA_string,1000)=0
         '         Loop
         '         uSecond=0                         ' rTime(7)=0
         '         Move (ClockValues(),7,rTime(),7)
         '
         '         ClockSet (ClockValues()):
         '        clockchk=True
         '         SerialFlush (Com4)               ' C7-C8 of CR1000
         '      EndIf   'clockchk
         Call SBAread
         If SBA_ID <>"M" OR   CO2dry=0 Then
            SerialFlush (Com4)
         EndIf
         If SBA_ID ="M" OR   CO2dry>300 AND Prof_Output_Long= True Then
            CallTable CO2prof_Long
            SerialFlush (Com4)
         EndIf
         ' ***** PROFILER Modes **********************
         If ProfMode="Profstart" Then
            If Firsttime=ON Then
               For i=1 To 6
                  SDMval(i)=OFF
                  For j=1 To 10
                     prof_rawdata(i,j)=0
                  Next j
               Next  i
               Firsttime=OFF
            EndIf
            ' ****** continuous operations *********

            level=1
            SDMval(level)=ON                      'Open valve 1
            A_Pump=ON                              'Turn on pump A
            Flush_valve=ON                         'Open output valve
            Ch_pump=OFF
            SDMCD16AC (SDMval(),1,sdm_address)
            clockchk=False ' to reset clock
            ProfMode="Lev_Zero"
            firsttime=ON
         EndIf 'End ProfMode Profstart
         If  ProfMode="Lev_Zero"  Then
            If firsttime=ON Then
               Irga_zero=ON
               firsttime=OFF
               Timer(0,mSec,2)
               SDMCD16AC (SDMval(),1,sdm_address)
               ContinueScan
            EndIf
            ' ****** continuous operations *********
            If prof_Timer>4 Then
               Irga_zero=OFF
               ProfMode="Lev_Flush"                                  ' non usare firsttime=ON
            EndIf
         EndIf   ' If  ProfMode="Lev_Zero"
         If  ProfMode="Lev_Flush"  Then
            If firsttime=ON Then
               Timer(0,mSec,2)
               firsttime=OFF
            EndIf
            ' ****** continuous operations *********
            If Timer(0,msec,4)/1000>flush_level_int Then
               ProfMode="Lev_Meas"
               lev_count=prof_rawdata(level,5)
            EndIf
         EndIf 'ENDS ProfMode=Lev_Flush
         If ProfMode="Lev_Meas" Then
            ' ****** continuous operations *********
            If SBA_ID ="M"   AND CO2dry>300 Then
               lev_count=lev_count+1
               prof_rawdata(level,1)=(prof_rawdata(level,1)*(lev_count-1)+CO2dry)/lev_count
               prof_rawdata(level,2)=(prof_rawdata(level,2)*(lev_count-1)+Ea_mb )/lev_count
               prof_rawdata(level,3)=(prof_rawdata(level,3)*(lev_count-1)+Ea_temp )/lev_count
               prof_rawdata(level,4)=(prof_rawdata(level,4)*(lev_count-1)+sba_Press )/lev_count
               prof_rawdata(level,5)=lev_count
               SBA_ID ="" ' FORCE Continue Scan after call sbaread (see above)
            EndIf '            If SBA_ID ="M" OR   CO2dry>300
            If Timer(0,mSec,4)/1000>=level_int Then
               SDMval(level)=OFF:
               If level>=N_level Then
                  For i=1 To 6
                     SDMval(i)=OFF
                  Next i
                  Task_Mode="Prof_Wait"
                  ProfMode="Prof_Wait"
                  CO2_Profiler=false
                  A_pump=OFF
                  firsttime=OFF
               Else
                  level=level+1
                  SDMval(level)=ON
                  ProfMode="Lev_Flush"
                  firsttime=ON
               EndIf
            EndIf
         EndIf 'ENDS ProfMode=Lev_Meas
         ' Read sensors
      EndIf' taskmode=PROFILER
      '*********************Output Profiler****************************************
      If  TimeIntoInterval (0,30,Min) Then
         Trig_CO2prof=True                                  'IfTime (0,30,Min)
         j=level
         For i=1 To N_level
            level=i
            lev_h=Profile_elev(i)
            CO2dry=prof_rawdata(i,1)
            Ea_mb= prof_rawdata(i,2)
            Ea_temp =prof_rawdata(i,3)
            sba_Press=prof_rawdata(i,4)
            lev_count=prof_rawdata(i,5)
            CallTable CO2prof
         Next i
         Trig_CO2prof=False
         level=j
         Task_Mode="Prof_Wait"
         firsttime=ON
      EndIf 'Output Profiler****************************************
      '      '****** SOIL RESPIRATION SYSTEM ******************************
      ' --------------- FLAGS -----------------------------------------------------------

      ' -------------- Manual or automated start -------------------------
      If Flag(2) Then		' Manual start
         status=1000
         Task_Mode="SR"
         If manual = OFF Then
            Flag(5)=False
            Mode ="Warm"
            Manual = ON
            firsttime = ON
            sess_hour = Hour
            seq_Ch=0:Cycle=1
         EndIf
      Else

         ' power up 5 min before in automatic
         '			IF PW_IRGA=0 THEN
         If TimeIntoInterval(0,automeas,Min) AND flag(8)=false Then
            Flag(5)=False
            Mode = "Warm"
            Task_Mode="SR"
            firsttime = ON
         EndIf
         ' start sutomatic measurements
         If IfTime(1,automeas,Min) AND flag(8)=false Then
            status = 0
            sess_hour = Hour
            manual = OFF
            Mode = "Zero_IRGA"
            Task_Mode="SR"
            firsttime = ON
         EndIf
         If manual = ON Then
            Mode = "Standby"
            manual = OFF

         EndIf
      EndIf 'end FLAG2 HIGH
      If Flag(3) Then' end session
         Flag(3)=FALSE
         Flag(2)=FALSE
         Mode="Standby"
      EndIf
      If Flag(4) Then' NEXT CHAMBER
         Flag(4)=FALSE
         Mode="Flushing"
         firsttime=ON
      EndIf
      If flag(6) Then			'calibration
         mode="Calibration"
         If firsttime=OFF Then firsttime=ON
      EndIf
      If Flag(7) Then'reset operational variables
         Call (SRsetupvar)
         flag(7)=False
      EndIf
      If Flag(8) Then
         Mode="Standby"
         Flag(2)=false
      EndIf
      ' ------------------------------------ SOIL RESPIRATION TASK MODE ---------------------------------------
      If Task_Mode="SR" Then
         VoltDiff (CO2ana,1,mV5000,6,True ,0,250,0.2,0)'CO2 analogic on Ch4
         TimerMode=Timer(0,mSec,4)/1000
         If Trig_IRGAread=TRUE Then
            Call SBAread
            If SBA_ID <>"M" OR   CO2dry<300 Then
               SerialFlush (Com4)
               ' ContinueScan
            ElseIf   SBA_ID ="M" AND   CO2dry>300 Then
               nread=nread+1
               If Mode="Interpolation" Then interpread=interpread+1
               CallTable CO2read
            EndIf
         EndIf
         If chksetupvar=FALSE Then Call SRsetupvar

         '##################### MODE CONTROL  ######################
         If Mode="" Then
            Mode="Standby"
            Chamber=1
         EndIf
         If Mode= "Calibration" Then
            If firsttime=ON Then
               firsttime=OFF
               Trig_IRGAread= True
               Ch_pump=ON
               Flush_valve=ON
            EndIf
            ' ****** continuous operations *********
            If flag(6)=FALSE Then Mode="Standby"

         EndIf	'Calibration mode
         ' Standby MODE
         If Mode="Standby" Then
            ' ****** continuous operations *********
            If Chamber<>0 OR Ch_pump=1 Then
               For i=1 To 16
                  SDMval(i)=0
               Next i
               Chamber=0
               seq_Ch=0:Cycle=1
               Flag(2)=FALSE
               Trig_CO2Out=FALSE
               Trig_SEfflux=FALSE
               Trig_IRGAread=FALSE
               Task_mode="Prof_Wait"
               Flag(5)=True
            EndIf
         EndIf	'Standby Mode
         ' ======================
         ' Warm MODE
         If Mode="Warm" Then
            ' ****** continuous operations *********
            If firsttime=ON Then
               Flush_valve=1
               Timer(0,mSec,2)
               firsttime=OFF
               Trig_IRGAread=FALSE
            EndIf
            If Timer(0,msec,4)/1000>4 AND Timer(0,msec,4)/1000<=10 Then
               Ch_pump=1
            EndIf
            If Flag(2)=True AND Timer(0,msec,4)/1000>=WarmInt Then
               seq_Ch=0:Cycle=1
               Mode="Zero_IRGA"
               firsttime=ON
            EndIf
         EndIf 'warm Mode
         ' ======================
         ' Zero_IRGA MODE
         If Mode="Zero_IRGA" Then
            If firsttime=ON Then
               firsttime=OFF
               Timer(0,mSec,2)
               Irga_zero=ON
               'Trig_IRGAread=FALSE
            EndIf
            ' ****** continuous operations *********
            If Timer(0,msec,4)/1000>=IRGA_ZeroInt Then
               Irga_zero=OFF
               Mode="Closechamber"
               firsttime=ON
               'moved from closechamber mode
               seq_Ch=seq_Ch+1
               If seq_Ch>Nchambers Then
                  seq_Ch=1
                  Cycle=Cycle+1
                  If Cycle>Ncycles Then
                     Mode="Standby"
                  EndIf
               EndIf
               Chamber=Ch_seq(seq_Ch)
               CloseTime=CloseInt(Chamber)
               OutputTime=CloseTime-CoInt
            EndIf
         EndIf ' Zero_IRGA Mode
         ' ======================
         ' Closechamber MODE
         If Mode="Closechamber" Then
            If firsttime = ON Then
               Ch_pump=ON
               Call Closechamber
               Timer(0,mSec,2) 'azzera Timer
               nread=0
               firsttime=OFF

            EndIf 'firsttime=ON
            ' ****** continuous operations *********
            If Timer(0,msec,4)/1000>=OutputTime Then
               Trig_IRGAread=True
               Trig_CO2Out=TRUE
            EndIf
            If Timer(0,msec,4)/1000>=CloseTime-CoInt Then
               Mode="CoCalculation"
               firsttime=ON
            EndIf
         EndIf' close chamber mode
         ' ======================
         ' CoCalculation MODE
         If Mode="CoCalculation" Then
            ' ****** continuous operations *********
            AvgRun (CO2ini,1,CO2dry,5)
            Rhoini=0.12028*sba_Press/(Ea_temp+273)
            If Timer(0,msec,4)/1000>=CloseTime Then
               Mode="Mixing"
               firsttime=ON
            EndIf
         EndIf 		'CoCalculation & closureTime
         ' ======================
         ' Mixing MODE
         If Mode="Mixing" Then
            If firsttime=ON Then
               nread=0
               MixTime=CloseTime+MixInt
               firsttime=OFF
            EndIf
            ' ****** continuous operations *********
            If Timer(0,msec,4)/1000>=MixTime Then
               mixread=nread
               Mode="Interpolation"
               firsttime=ON
            EndIf
         EndIf ' Mixing Mode
         ' ======================
         ' Interpolation MODE
         If Mode="Interpolation" Then
            If firsttime=ON Then
               firsttime=OFF
               interpread=0
               Timer(2,mSec,2)
               InterpTime=MixTime+InterpInt
            EndIf
            ' ****** continuous operations *********
            If interpread>0 Then Cdry(interpread)=CO2dry
            If Timer(0,msec,4)/1000>=InterpTime Then
               Mode="Flushing"
               firsttime=ON
            EndIf
         EndIf ' Interpolation Mode
         ' ======================
         ' Flushing MODE
         If Mode="Flushing" Then
            ' ****** continuous operations *********
            For i=1 To 12
               SDMval(i)=0
            Next i
            Flush_valve=ON
            Ch_pump=ON
            SDMCD16AC (SDMval(),1,0)
            If firsttime=ON Then
               firsttime=OFF
               Timer(0,msec,2)
               Trig_CO2Out=FALSE:
               Trig_IRGAread=FALSE ' STOP CO2 Readings
               CO2fin=CO2dry
               Call GaussNewton
               t0=-LN(-(CO2ini-Cx)/(Cx-Co))/a
               'CO2ini 'computed at the end of closure chamber

               Efflux=a*(Cx-Co)*Vtot/Area*Rhoini
               Trig_SEfflux=TRUE
               CallTable Effl_Out
               Trig_SEfflux=FALSE
               Timer(2,msec,3)  ' STOP   TimerInterp
               If Nchambers=1 AND Cycle<Ncycles Then FlushInt=CloseTime+20
            EndIf
            If Timer(0,msec,4)/1000>=FlushInt  Then
               Mode="Zero_IRGA"
               firsttime=ON
            EndIf
            If  seq_Ch>=Nchambers AND Cycle>=Ncycles Then	Mode="Standby"
         EndIf	' Flushing mode
      EndIf ' END TASKMODE=SR
      ' ======================

      SDMCD16AC (SDMval(),1,sdm_address)

   NextScan

EndProg

