-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathtracer-stationary.cr1
327 lines (289 loc) · 11.9 KB
/
tracer-stationary.cr1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Wheat pile emission scoping study May 2018
'
' Source code for stationary station (background) logger. Responsible for:
' * TSI DustTrak II - aerosol monitor
' * LICOR Biosciences LI-840A - CO2 analyzer
' * Garmin GPS16X-HVS - GPS receiver
'
' Copyright 2018 :: Patrick O'Keeffe
' Laboratory for Atmospheric Research at Washington State University
'
' Contains adapted example code from Campbell Scientific product docs
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
ConstTable
Const UTC_OFFSET = -7 'Pacific Daylight Time
Const DAYS_OF_DATA = 7
EndConstTable
'HINT edit this value using the Public table or keyboard display!
Public csat3b_azimuth 'direction sonic array is pointing wrt True North
Units csat3b_azimuth = degreesEofN
'---------- NO USER SERVICEABLE PARTS BELOW THIS LINE ;) -----------------
Public debug_on As Boolean = True
Const SETTINGS_FILE = "CPU:tracer-stationary.dat"
Dim filehandle As Long
Dim old_azimuth
Const CSAT_SDM_ADDR = 3
Const DperR = 180/3.14159 'unit conversion
Const CSAT_VAZ = 90 'sensor-specific geometry indicator
Const LI840A_COM = Com4
Const LI840A_BAUD = 9600
Const LI840A_FMT = 3 '8/n/1, RS232 logic
Const LI840A_REC = 120
Const LI840A_BUFF = LI840A_REC*2 + 1
Const GPS_COM_ADDR = Com3 'GPS serial input port #
Const DF_TSI_PM = 1
'Const TSI_PM_OFF = 0.0103 'XXXX unit-specific calibration offset (sn 8530152108)
'Const TSI_PM_MLT = (1.0 - TSI_PM_OFF)/5000 '0-1.0 mg/m^3, 0-5V
Const TSI_PM_OFF = 0.008 'XXXX unit-specific calibration offset (sn 8530150710)
Const TSI_PM_MLT = (1.0 - TSI_PM_OFF)/5000 '0-1.0 mg/m^3, 0-5V
Const DF_LI840A_CO2 = 3
Const LI840A_CO2_OFF = 0 'ppm
Const LI840A_CO2_MLT = (2500 - LI840A_CO2_OFF)/5000 '0-5000ppm, 0-5V
Dim CSATvals(5)
Alias CSATvals(1) = csat3b_Ux
Alias CSATvals(2) = csat3b_Uy
Alias CSATvals(3) = csat3b_Uz
Alias CSATvals(4) = csat3b_sonicTemp
Alias CSATvals(5) = csat3b_diag
Units CSATvals = m/s
Units csat3b_sonicTemp = degC
Units csat3b_diag = arb
Dim CSATmeta(4)
Alias CSATmeta(1) = csat3b_boardTemp
Alias CSATmeta(2) = csat3b_boardHumidity
Alias CSATmeta(3) = csat3b_inclinePitch
Alias CSATmeta(4) = csat3b_inclineRoll
Units csat3b_boardTemp = degC
Units csat3b_boardHumidity = %
Units csat3b_inclinePitch = degrees
Units csat3b_inclineRoll = degrees
Dim li840a_config As String * 300
Dim li840a_resp As String * 32
Dim li840a_record As String * LI840A_REC
Dim li840a(6)
Alias li840a(1) = li840a_cell_T
Alias li840a(2) = li840a_cell_P
Alias li840a(3) = li840a_CO2
Alias li840a(4) = li840a_pwr_src
Alias li840a(5) = li840a_H2O
Alias li840a(6) = li840a_dewpoint
Units li840a_cell_T = degC
Units li840a_cell_P = kPa
Units li840a_CO2 = ppm
Units li840a_pwr_src = Vdc
Units li840a_H2O = ppth
Units li840a_dewpoint = degC
Dim li840a_analog_CO2
Units li840a_analog_CO2 = ppm
Dim dusttrak2_analog_pm
Units dusttrak2_analog_pm = mg/m^3
Dim nmea_sentence(2) As String * 90
Dim gps_data(15)
Alias gps_data(1) = latitude_deg 'Degrees latitude (+ = East; - = West)
Alias gps_data(2) = latitude_min 'Minutes latitude
Alias gps_data(3) = longitude_deg 'Degress longitude (+ = East; - = West)
Alias gps_data(4) = longitude_min 'Minutes longitude
Alias gps_data(5) = speed 'Speed
Alias gps_data(6) = course 'Course over ground
Alias gps_data(7) = mag_variation 'Magnetic variation from true north (+ = East; - = West)
Alias gps_data(8) = fix_quality 'GPS fix quality: 0 = invalid, 1 = GPS, 2 = 'differential GPS, 6 = estimated
Alias gps_data(9) = nmbr_satellites 'Number of satellites used for fix
Alias gps_data(10) = altitude 'Antenna altitude
Alias gps_data(11) = pps 'Elapsed ms since last pulse per second (PPS) from GPS
Alias gps_data(12) = dt_since_gprmc 'Time since last GPRMC string, normally less than '1 second
Alias gps_data(13) = gps_ready 'Counts from 0 to 10, 10 = ready
Alias gps_data(14) = max_clock_change 'Maximum value the clock was changed
Alias gps_data(15) = nmbr_clock_change 'Number of times the clock was changed
Units latitude_min = degreesN
Units latitude_deg = minutesN
Units longitude_min = degreesE
Units longitude_deg = minutesE
Units speed = m/s
Units course = degreesEofN
Units mag_variation = degreesEofN
Units fix_quality = unitless
Units nmbr_satellites = unitless
Units altitude = m
Units pps = ms
Units dt_since_gprmc = s
Units gps_ready = unitless
Units max_clock_change = ms
Units nmbr_clock_change = occurrences
Dim instant_WS, instant_WD
Units instant_WS = m/s
Units instant_WD = degreesEofN
Dim work_out(3)
Alias work_out(1) = wnd_spd
Alias work_out(2) = unit_wnd_dir
Alias work_out(3) = std_wnd_dir
Units wnd_spd = m/s
Units unit_wnd_dir = degreesEofN
Units std_wnd_dir = degrees
Dim panel_tmpr
Units panel_tmpr = degC
DataTable(work,True,1)
TableHide
DataInterval(0,1,Min,1)
WindVector(1,-1*csat3b_Uy,csat3b_Ux,FP2,csat3b_diag,0,1,0)
EndTable
DataTable(debug_,debug_on,1)
Sample(1,instant_WS,IEEE4)
Sample(1,instant_WD,IEEE4)
'see the `tsfast` table for real-time 10hz data
Sample(4,CSATmeta(1),IEEE4)
Sample(1,li840a_record,String)
Sample(6,li840a(1),IEEE4)
Sample(1,li840a_analog_CO2,IEEE4)
Sample(1,dusttrak2_analog_pm,IEEE4)
Sample(2,nmea_sentence(1),String)
Sample(15,gps_data(1),IEEE4)
Sample(1,panel_tmpr,FP2)
EndTable
DataTable(tsfast,True,-1)
DataInterval(0,100,mSec,10)
CardOut(0,84600*10*DAYS_OF_DATA)
Sample(5,CSATvals(1),IEEE4)
FieldNames("csat3b_Ux:wind vector streamwise component (into array)," & _
"csat3b_Uy:wind vector horizontal crosswise component," & _
"csat3b_Uz:wind vector vertical component," & _
"csat3b_sonicTemp:ultrasonic (virtual) temperature," & _
"csat3b_diag:sensor diagnostic word")
EndTable
DataTable(tsdata,True,-1)
DataInterval(0,1,Sec,5)
CardOut(0,86400*DAYS_OF_DATA)
Sample(1,dusttrak2_analog_pm,FP2)
FieldNames("dusttrak2_analog_pm:aerosol concentration")
Sample(1,li840a_CO2,IEEE4)
FieldNames("li840a_CO2:CO2 mixing ratio")
Sample(1,li840a_H2O,IEEE4)
FieldNames("li840a_H2O:H2O mixing ratio")
Sample(1,li840a_analog_CO2,IEEE4)
FieldNames("li840a_analog_CO2:CO2 mixing ratio (analog data)"
Sample(1,instant_WS,FP2)
FieldNames("instant_WS:instantaneous horizontal wind speed")
Sample(1,instant_WD,FP2)
FieldNames("instant_WD:instantaneous wind direction")
EndTable
DataTable(minutely,True,-1)
DataInterval(0,1,Min,1)
CardOut(0,1440*DAYS_OF_DATA)
Sample(1,dusttrak2_analog_pm,FP2)
FieldNames("dusttrak2_analog_pm:aerosol concentration")
Average(1,li840a_CO2,IEEE4,li840a_CO2=NAN)
FieldNames("li840a_CO2:CO2 mixing ratio")
Average(1,li840a_H2O,IEEE4,li840a_H2O=NAN)
FieldNames("li840a_H2O:H2O mixing ratio")
Average(1,li840a_cell_T,IEEE4,li840a_cell_T=NAN)
FieldNames("li840a_cell_T:sample cell temperature")
Average(1,li840a_cell_P,IEEE4,li840a_cell_P=NAN)
FieldNames("li840a_cell_P:sample cell pressure")
Average(1,li840a_dewpoint,IEEE4,li840a_dewpoint=NAN)
FieldNames("li840a_dewpoint:H2O dewpoint")
Average(1,li840a_pwr_src,IEEE4,li840a_pwr_src=NAN)
FieldNames("li840a_pwr_src:power input")
Average(1,latitude_deg,FP2,latitude_deg=NAN)
FieldNames("gps_latitude_deg:position latitude degrees component")
Average(1,latitude_min,IEEE4,latitude_min=NAN)
FieldNames("gps_latitude_min:position latitude decimal minutes component")
Average(1,longitude_deg,FP2,longitude_deg=NAN)
FieldNames("gps_longitude_deg:position longitude degrees component")
Average(1,longitude_min,IEEE4,longitude_min=NAN)
FieldNames("gps_longitude_min:position longitude decimal minutes component")
Median(1,mag_variation,60,FP2,mag_variation=NAN)
FieldNames("gps_mag_variation:position magnetic variation")
Minimum(1,gps_ready,FP2,gps_ready=NAN,0)
FieldNames("gps_ready:status indicator (10=ready)")
Average(1,csat3b_boardTemp,FP2,csat3b_boardTemp=NAN)
FieldNames("csat3b_boardTemp:sonic internal temperature")
Average(1,csat3b_boardHumidity,FP2,csat3b_boardHumidity=NAN)
FieldNames("csat3b_boardHumidity:sonic internal humidity")
Average(1,csat3b_inclinePitch,FP2,csat3b_inclinePitch=NAN)
FieldNames("csat3b_inclinePitch:sonic pitch incline angle")
Average(1,csat3b_inclineRoll,FP2,csat3b_inclineRoll=NAN)
FieldNames("csat3b_inclineRoll:sonic roll incline angle")
Sample(1,csat3b_azimuth,FP2)
FieldNames("csat3b_azimuth:sonic orientation wrt north")
Sample(3,work_out(1),IEEE4)
FieldNames("csat3b_wnd_spd:mean horizontal wind speed," & _
"csat3b_unit_wnd_dir:unit vector mean wind direction," & _
"csat3b_std_wnd_dir:wind direction stdev (Yamartino algorithm)")
Sample(5,CSATvals(1),IEEE4)
FieldNames("csat3b_Ux:wind vector streamwise component (into array)," & _
"csat3b_Uy:wind vector horizontal crosswise component," & _
"csat3b_Uz:wind vector vertical component," & _
"csat3b_sonicTemp:ultrasonic (virtual) temperature," & _
"csat3b_diag:sensor diagnostic word")
Average(1,li840a_analog_CO2,IEEE4,li840a_analog_CO2=NAN)
FieldNames("li840a_analog_CO2:CO2 mixing ratio (analog data)")
Average(1,panel_tmpr,FP2,panel_tmpr=NAN)
FieldNames("logger_panel_tmpr:logger wiring panel temperature")
EndTable
DisplayMenu("Release site", -1)
MenuItem("CSAT azimuth", csat3b_azimuth)
SubMenu("View data")
DisplayValue("PM, mg/m^3", dusttrak2_analog_pm)
DisplayValue("CO2, ppm", li840a_CO2)
DisplayValue("WS, m/s", instant_WS)
DisplayValue("WD, deg", instant_WD)
DisplayValue("Lat. minute", latitude_min)
DisplayValue("Long. minute", longitude_min)
DisplayValue("Logger tmpr", panel_tmpr)
EndSubMenu
EndMenu
'===========================================================================
BeginProg
SetStatus("StationName", "tracer-stationary") 'disabled by CardOut()
li840a_config = ("<li840><cfg><outrate>1</outrate></cfg><rs232><co2>true</co2>" & _
"<co2abs>false</co2abs><h2o>true</h2o><h2odewpoint>true</h2odewpoint>" & _
"<h2oabs>false</h2oabs><celltemp>true</celltemp><cellpres>true</cellpres>" & _
"<ivolt>true</ivolt><raw>false</raw><strip>true</strip></rs232></li840>")
li840a_resp = ("<li840><ack>true</ack></li840>")
SerialOpen(LI840A_COM,LI840A_BAUD,LI840A_FMT,0,LI840A_BUFF)
SerialOut(LI840A_COM,li840a_config,li840a_resp,3,1)
filehandle = FileOpen(SETTINGS_FILE,"rb",0) 'check for exists
FileClose(filehandle)
If (filehandle = 0) Then 'not found
csat3b_azimuth = 0
Else
Calfile(csat3b_azimuth,1,SETTINGS_FILE,1) 'read file
EndIf
old_azimuth = csat3b_azimuth
Scan(100,mSec,0,0)
CSAT3B(CSATvals(1),0,CSAT_SDM_ADDR,0)
CallTable(tsfast)
CallTable(work)
If (work.Output(1,1) ) Then
GetRecord(work_out(1),work,1)
unit_wnd_dir = (360 + unit_wnd_dir + csat3b_azimuth) MOD 360
EndIf
NextScan
SlowSequence
Scan(1,Sec,0,0)
VoltDiff(dusttrak2_analog_pm,1,mv5000,DF_TSI_PM,True,0,250,TSI_PM_MLT,TSI_PM_OFF)
VoltDiff(li840a_analog_CO2,1,mv5000,DF_LI840A_CO2,True,0,250,LI840A_CO2_MLT,LI840A_CO2_OFF)
PanelTemp(panel_tmpr, 250)
SerialIn(li840a_record,LI840A_COM,50,&h0A,LI840A_BUFF)
If (Len(li840a_record)) Then
SplitStr(li840a(1),li840a_record,"",6,0)
Else
Move(li840a(1),6,NAN,1)
EndIf
instant_WS = SQR(csat3b_Ux*csat3b_Ux + csat3b_Uy*csat3b_Uy)
instant_WD = INT(ATN2(-1*csat3b_Ux,-1*csat3b_Uy)*DperR + CSAT_VAZ + _
csat3b_azimuth + 360) MOD 360
CallTable(tsdata)
CallTable(minutely)
CallTable(debug_)
If (old_azimuth <> csat3b_azimuth) Then
Calfile(csat3b_azimuth,1,SETTINGS_FILE,0) 'write to file
old_azimuth = csat3b_azimuth
EndIf
NextScan
SlowSequence
Scan(1,Min,0,0)
GPS (latitude_deg,GPS_COM_ADDR,UTC_OFFSET*3600,0,nmea_sentence(1))
CSAT3BMonitor(CSATmeta(1),0,CSAT_SDM_ADDR)
NextScan
EndProg