Skip to content
English
  • There are no suggestions because the search field is empty.

How can you program Campbell Scientific CR1000 data loggers to allow serial communication?

Programming of Campbell Scientific CR1000 Data Loggers to Allow Serial Communication with 2B Tech Analyzers.

Technical Note No. 39

Programming of Campbell Scientific CR1000 Data Loggers to Allow Serial 
Communication with 2B Tech Analyzers

Date: 08 April 2015

Author: Andrew Turnipseed

Requirements

  •  Campbell Scientific CR1000 Data Logger

  •  2B Tech Analyzer

  •  Serial Cable (“straight through”, not “cross over”)

Background

Although all of the 2B analyzers have internal memory for data storage, it is often 
advantageous to collect data via a central field data logger which is linked to 
several different instruments and/or meteorological sensors. There are numerous 
commercially available data loggers; however, Campbell Scientific has been a 
leader in this field for the past few decades and their data loggers have gained 
wide acceptance in environmental, meteorological and atmospheric monitoring 
studies. As such, there have been numerous situations where 2B customers have 
needed to interface their 2B instrument with data loggers manufactured by 
Campbell Scientific. 

Nearly all 2B Technologies analyzers are capable of outputting a simple analog 
voltage that is proportional to the concentration of the species measured (e.g., O3, 
NO, NO2) and the simplest method of interfacing is to connect the analog output to 
either a differential or single-ended analog input of the data logger. However, this 
only provides information on the analyzer concentration output and does not 
include any other operating parameters such as the flow rate, temperature or 
pressure, which can be useful for verifying the validity of the data. Furthermore, 
this analog output can be confusing in cases where multiple concentrations are 
measured sequentially (such as in the model 405 which can measure both NO and 
NO2). Finally, by simply monitoring the analog output, one cannot interact with the 
analyzer. For example, simple serial commands can be used with the Model 410 
NO monitor to put the analyzer in a “zero” mode for measuring the offset, followed 
by a second command returning it to a normal sampling mode. These serial 
commands can be embedded within the timing of the datalogger programing to 
perform periodic offset measurements. 

Procedure

Current Campbell Scientific data loggers use CRbasic for programming. Below is 
an example of CRbasic program written for a CR1000 Campbell Scientific 
datalogger which: (1) collects data from a 2B Model 410 NO monitor/Model 401 
NO2 converter combination every 10 seconds, (2) outputs an hourly average and 
standard deviation of the concentration data (NO and NO2), (3) outputs a second 
data table consisting of 10-minute averaged data for concentration as well as 
instrumental variables such as flow, temperature and pressure, and (4) switches 
the analyzer into a zeroing mode at midnight for 10 minutes. Simple variations of 
this program can be used for logging data from other 2B Technologies 
instruments. For assistance in modifying this program for other 2B instruments, 
please contact 2B Technologies.

Wiring:

Sample Program:

′CR1000 Series Datalogger
′ **************************************************************************
′ CR-Basic Program to ingest serial data from 2B model 410 NO analyzer coupled 
with the model 401 
′ NO2 converter
′Written for Campbell Scientific CR1000 data logger, Andrew Turnipseed
′12/15/2014
′ ***************************************************
′ Runs an auto-zero every night at midnight for 10 minutes
′ Serial RS-232 communication on COM port: com4 (Control Ports 7 and 8 on 
CR1000)
′ Wiring:
′ CR1000 DB-9 Serial Connector (to 2B)
′ C7 (Tx) -------------------------------- Pin 3
′ C8 (Rx) -------------------------------- Pin 2
′ G (grd) -------------------------------- Pin 5
′ *******************************
′ Flag(1) = Data Flag for 10 min. data
′ Flag(2) = Data Flag for zero mode
′ Flag(3) = Data Flag for hourly data
′ ****************************************************
′ Variables:
Public NO2, NO, NOx, temperature, pressure, 
Public Sflow, Tflow, Oflow, Tscrub, O3
Public status, state As Long
Public tout(13) As String *8
Public raw As String *70
Public date As String *8
Public time As String *8
Public Flag(3) As Boolean
Public TC As Long
Public counts As Long

' OUTPUT SECTION
'********** Hourly averaged data ******************************** ***
DataTable(DataHour,true,5000) ′ 5000 hrs = 416 days of data
 DataInterval(0,60,Min,0)
 Average(1, NO2, IEEE4,Flag(3)) ′Average NO2 concentration
 StdDev(1, NO2, IEEE4,Flag(3))
 Average(1, NO, IEEE4,Flag(3)) ′Average NO concentration
 StdDev(1, NO, IEEE4,Flag(3))
 Average(1, NOx, IEEE4,Flag(3)) ′ NOx = NO + NO2
 Totalize(1, Counts, Long,Flag(3)) ′ number of measurements included in the 
hourly average.
 Totalize(1, TC, Long,0) ′ total number of measurements cycles 
within the hour. 
EndTable
′ Note: (TC – Counts) = the number of measurement cycles not included in the 
hourly average.
′ This would include cycles when measuring the offset or times when certain data 
flags are violated.
'*************** QC data: *****************************************
'**************** 10 min. avg'd data ********************************
DataTable(Data10min,TRUE,-1) ' will fill remainder of data storage
 DataInterval(0,10,Min,0)
 Average(1, NO2, IEEE4,Flag(1))
 Average(1, NO, IEEE4,Flag(1))
 Average(1, temperature, IEEE4,Flag(1))
 Average(1, pressure, IEEE4,Flag(1))
 Average(1, Sflow, IEEE4,Flag(1)) ′Sample Flow
 Average(1, Tflow, IEEE4,Flag(1)) ′Total Flow
 Average(1, Oflow, IEEE4,Flag(1)) ′Ozone Flow
 Average(1, Tscrub, IEEE4,Flag(1)) ′Scrubber Temperature
 Average(1, O3, IEEE4,Flag(1)) ′Excess ozone concentration
 Average(1, state, IEEE4,Flag(1)) ′Measurement state (see 2B manual for 
Status byte values)
EndTable
′′′′′′′′′′′′′′′′′′′′′′′′′′′′′′′′′′′′'
'Define Subroutines \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
' none needed!
'\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
BeginProg
'Initialize parameters:
Status = 1
Flag(3) = False
Flag(2) = False
SerialOpen(com4, 4800, 0, 0, 300)
'Start sampling loop: 10 sec. sampling cycle
Scan(10,Sec, 3, 0)
′************************ Timing for auto-zero mode *******************************
′ Time to start zero mode on 410:
 If TimeIntoInterval(0,1440,Min) Then ' executed at 0 min. into every 
1440 (1440 min/day)
SerialOut(com4,CHR(90),"",0,500) ' string sent once, waits for echo for 
500x0.01 sec.
                                                                  ' CHR(90) = "Z" == auto Zero mode
                            Status = 0
Serialflush(com4)                                ' flush the serial buffer (get rid of stray text)
Flag(2) = True                                                    ' data excluded from hourly average
 EndIf

′send another command 10 min. later to leave zero mode:
 If TimeIntoInterval(10,1440,Min) Then ' Executed 10 min. into the same 1440 
min.
         SerialOut(com4,CHR(89),"",0,500) ' string sent once, waits for echo for 
500x0.01 sec.
                                                                ' CHR(89) = "Y" == back to previous mode
Status = 1
Serialflush(com4)                               ' flush the serial buffer (get rid of stray text)
Flag(2) = False                                    ' Reset the hourly data flag
 EndIf
′********************* End of zero mode timing *************************************
′ Set Flag(1) to False every time through (assumes data will be valid)
Flag(1) = False

'reading serial output of the model 410:
SerialIn (raw,com4,0,13,75)
'split the string at each comma
SplitStr(tout(1), raw, CHR(44), 13,5)
'converting string to numeric
          NO2 = tout(1) 'ppbv
          NO = tout(2) 'ppbv
          NOx = tout(3) 'ppbv
          temperature = tout(4) 'deg. C
          pressure = tout(5) 'mbar
          Sflow = tout(6) 'cc/min
          Tflow = tout(7) 'cc/min
          Oflow = tout(8) 'cc/min
          Tscrub = tout(9) 'oC
          O3 = tout(10) 'ppbv
         date = tout(11) 'string
         time = tout(12) 'string
         state = tout(13) 'state indicator
′ In cases where there is stray text in the serial buffer or a mistiming - do not want to 
average data.
If (NO2 = NAN) Then
Flag(1) = True                                                ′Excludes data in 10 min. avgs.
Serialflush(com4)                                         ' flush the serial buffer (get rid of stray text)
EndIf
If (state > 85) Then Flag(1) = True           ′Excludes data in Parameter 
Adjust Mode
If (Flag(1) = True) OR (Flag(2) = True) Then Flag(3) = True           ′Excludes 
data in hourly averages
If (Flag(1) = False) AND (Flag(2) = False) Then Flag(3) = False      ′Includes 
data in hourly averages
TC = 1
Counts = 1

'call Datatable for averaging:
 CallTable DataHour

'call Datatable for fast data:
 CallTable Data10min

 NextScan
EndProg