- several logger sites
- same logger with SAME logger code
- very similar sensor setup
- DIFFERENT sensor calibration values
How would I go about this if my aim was to load the same CRBasic program to the loggers (CR3000's) but also have distinguishable calibration files - file-names then for example:
The logger code should be able to either look for all files and as there will be only one on the CRD/CPU take the one that is available without compilation errors.. unfortunately #If/#EndIf aren't very keen on being fed with anything else than Constants during compile time, for example:
#If FileSize("CPU:Cal_Site1.CR3") Then
TestForFile = FileSize("CPU:Cal_Site1.CR3")
#If TestForFile = False Then
Or alternatively the filename should be able to contain wildcards so that the part that I as a human use to distinguish them from each other isn't acted upon by the compiler when loading the cal file that's on the logger, for example:
I did read up on CalFile() but it doesn't look like to being cut out for my application scenario?
Thanks for any pointer or help.
You should take a look at the "FieldCal" CRBasic Programming instruction. You can run the very same program on all of your dataloggers (containing FieldCal), then after the program starts running on each logger you can do a "sensor-specific" calibration without having to stop the program. The results of the calibration get stored into a *.CAL file on the CPU or CRD drive that has the same name as the Program.
You seem to know what calibration values you want to put into the program for each sensor ahead of time. So in that case, you could manually place those values in after the program starts running.
The CalFile instruction is older and doesn't have as much flexibility/functionality as FieldCal.
Take a look at Chapter 9 of the RTDAQ manual for
an extended treatment of FieldCal:
Re: I did read up on CalFile() but it doesn't look like to being cut out for my application scenario?
Is that because the values are not stored in a human readable ASCII format? Or is it because you need calibration values that are not of type float?
Based on your post, and if the previous statement is true, I doubt FieldCal is going to be of interest either.
Since you are only going to put one on the datalogger, you could solve your issue by renaming the cal_site?.cr3 file to a single/uniform for all installations name like cal.cr3.
If that is still not acceptable, then you can use CRBasic to open your file, parse the input, and use the values. Once you go down that path, there is a lot of flexibility and ways to solve the problem.
Maybe this will spark some ideas
Public ReadCal As Boolean
Dim FNum As Long
Dim FName(20) As String * 32
Dim FHandle As Long
Dim FContent As String * 1024
Erase(FName) 'clear the list of names
FNum = FileList ("CPU",FName) 'get a list of files on the CPU
For i = 1 To FNum 'go through them
'find one that start with cpu:cal_site
If InStr (1,UpperCase(Fname(i)),"CPU:CAL_SITE",2) Then
'open it up, read the contents into a string
'close it, parse it, return the results
FHandle = FileOpen (FName(i),"rb",0)
'SplitStr (Dest,FContent,";, " & CHR(13) & CHR(10),5,7)
If ReadCal Then
ReadCal = false
Hi Sam and GTProdMngr.
I'll go with the constant table in a separate file that is being included at startup.
The solution with my own file manager and all that might come in handy down the road - thanks for that Sam.
I am currently trying to do exactly the same thing as you were - same issue of desiring to use 'wildcards' in the calibration file names so that I - as a human - can distinguish between the calibration files while also being able to use only one main CRBasic program for all my loggers.
If you see this, would you mind clarifying a little more what you ended up doing to solve the problem? How did you approach this: "I'll go with the constant table in a separate file that is being included at startup." Did that require you to have a slightly different main CRBasic program for each logger?
Have any code or pseudo code that you could share for this situation?
Ghosts of times past :-)
Yes, the loggers I'm responsible for are still running with that scheme.
There is one universal main program, let's call it Logger.CRx which contains all the logging logic, variable + table definitions, etc. Then there is the calibration file (which also is loggercode, as far as loggernet is concerned) that contains all the site specific constant definitions, let's call that one Calibration.CRx.
The first entry in that file should be something like:
Const SiteName = "Your Site"
The calibration code is being invoked in the Logger.CRx code via:
(replace x with the correct one for your logger)
When you deal with the logger, you use the file control option, to send the calibration file (in case of CF/SD cards, make sure the Calibration.CRx is on the CPU memory, not on the cards, or you have to adjust above include statement (CPU -> CRD or whatever).
Once you upload the Logger.CRx file it will be compiled and grab the Calibration.CRx file.
You can test it working in CRbasic when you compile the code there, as it will need the calibration file in the folder where you got the Logger.CRx file, otherwise a lot of errors will appear.
The culprit is, that the name of the calibration file (Calibration.CRx) although having different content per site, will always need to be the same when the code is compiled, as the universl loggercode won't find it otherwise. That's why I have the site constant at the top of the file (explanation is following).
Upon creating the calibration file (on your computer, etc.) you keep the filenames for the calibration of all the sites unique, by adding a site ID to the file.. but after uploading that file to the logger, you have to remove that.
The way to be able to track (at least later on) if what you collect in data is actually being calibrated with the correct constants you need to logg another table - the constants. Call it once per day or week or even month in Logger.CRx - dunno how often stuff changes for you.
That table looks like this:
DataTable (CalibrationSnapshot,True,-1) DataInterval (0,1,Day,10) Sample(1,SiteName,String) 'site name for calibration constants file FieldNames("SiteName") Sample(1,Li7500_DelayStepInc,FP2) 'generic factor FieldNames("Li7500_DelayStepInc") Sample(1,Li7500_SDMdelayTime,FP2) 'mSec FieldNames("Li7500_SDMdelayTime") Sample(1,Li7500_Bandwidth,FP2) 'should be 5Hz - will be checked FieldNames("Li7500_Bandwidth") Sample(1,Li7500_SDM_Delay,FP2) 'should be as close to 200 mSec as possible FieldNames("Li7500_SDM_Delay") Sample(1,CSAT_ExecParam,FP2) 'should be 10 Hz FieldNames("CSAT_ExecParam") Sample(1,Az_CSAT,FP2) 'CSAT3 orientation FieldNames("Az_CSAT") Sample(1,Fsu_NR01_mult,FP2) 'Pyranometer DOWN FieldNames("Fsu_NR01_mult") ... FieldNames("Si121_c2_ofst") Sample(1,Si121_c1_ofst,FP2) FieldNames("Si121_c1_ofst") Sample(1,Si121_c0_ofst,FP2) FieldNames("Si121_c0_ofst") EndTable
And yes, that's a lot of work and afaik no other way available to have the correct labels on the constant values being logged - I'm talking about the 'FieldNames' command. If you don't use that, the label will be generic (forgot what it was) and it is way harder to keep track.
On the upside - one only has to do this once for that particular setup and it allows you to track calibration changes over the years (in case data needs to be post-corrected) - as you know exactly what calibration values you had running at which point in time.
Keeping a copy of each deployed version of your loggercode + the calibration tables aong with your data will allow you to always go back and post-correct if needed.