Our full technical support staff does not monitor this forum. If you need assistance from a member of our staff, please submit your question from the Ask a Question page.


Log in or register to post/reply in the forum.

TableFile created files always one iteration behind


Lumox100 Feb 21, 2014 12:34 PM

I am putting together a buoy with various instruments, which I am currently testing.

I am having trouble getting the data to be real-time with the following program which uses FTP. The data sent is always an hour behind. I presume it has to do with the "TableFile" function not completing until the next call to "DataTable/EndTable". But I do not want to "CallTable" multiple times in the Scan as I am not always sure when I will have data available, and I do not want to have duplicate data recorded. "DataInterval" works fine in the "BuoyVoltage" table as this is always being read, but it will not work in the other tables as the data is not always received at the same time.

Could someone give me any advice as to how I may overcome this problem. I could always create the files myself using "FileWrite", but since "TableFile" already contains all the functionality I require, I would rather not do this.

Also, does it matter where "TableFile" is called in the "DataTable"? Is there another way to make the "TableFile" function end so that the file is created?

In the program, the weather station is switched on for the last 10 minutes of each hour, then switched off and data recorded. This is to save battery power.

'CR1000 Series Datalogger
'PB200 weather station (GGA and WIMDA strings) - Com2
'Nortek Aquadopp Z-Cell - Com3

Const PI=3.141592654
Const nBins=10
Const numZCell=nBins * 3 + 17

Const FNlen=40
Const FtpUserDriveSize=1048576 '1 MB
Const FTPHost="*****"
Const FTPUser="*****"
Const FTPPass="*****"

Const TableCnt=4
Const MaxFiles=48
Const FListCnt=MaxFiles*TableCnt 'Number of filenames to keep in buffer in case sending fails
Const FTPSendInt=60 'Table file output interval(minutes)
Const FTPPath="/buoy_data/"
Const IDstr="Test"
Const FTP_fnBV="USR:"+IDstr+"_BuoyVoltage"
Const FTP_fnZCELL="USR:"+IDstr+"_ZCELL"
Const FTP_fnWS="USR:"+IDstr+"_WS"
Const FTP_fnGPS="USR:"+IDstr+"_GPS"

Dim y, si, fi, RTime(9), Min_hr, Flag_pwr, Hrs, gotWSdata, I1,I2

Public BattV, ws_u, ws_v, ws_u_avg, ws_v_avg, ws_bp_avg, ws_at_avg, ws_sp_avg, ws_dr_avg, gga_lat, gga_lon, gga_lat_avg, gga_lon_avg, ws_pitch_avg, ws_roll_avg
Public c2str As String * 500
Public c3str As String * 2000
Public u(nbins), v(nbins), spd(nbins), dir(nbins)
Public wimdastr As String * 100
Public ggastr As String * 100
Public yxxdrstr As String * 100

Public gga_f(6), wimda_f(20), yxxdr_f(2)
Public gga_s(8) As String * 10
Public zc(numZCell)
Public zcDate As String * 10
Public zcTime As String * 10

'FTP State 0:Disconnected 1:Initializing 2:Dialing 3:Sending 4:Sent 5: Disconnecting
Public FTPState
Public FTPSent
Public FTPUnsent
Public PPPResultStr As String * 120
Public PPPFilterStr As String * 15="ppp ip: 0.0.0.0"
Public FTP_FileList(FListCnt) As String * FNlen
Public SendFN As String * FNlen
Public LastFN_BV As String * FNlen
Public LastFN_ZCELL As String * FNlen
Public LastFN_WS As String * FNlen
Public LastFN_GPS As String * FNlen
Public doneBV As Boolean
Public doneZCELL As Boolean
Public doneWS As Boolean
Public doneGPS As Boolean

Alias wimda_f(2)=ws_bp
Alias wimda_f(3)=ws_at
Alias wimda_f(4)=ws_winddir
Alias wimda_f(7)=ws_windspd
Alias yxxdr_f(1)=ws_pitch
Alias yxxdr_f(2)=ws_roll
Alias zc(9)=zc_batt
Alias zc(14)=zc_press
Alias zc(15)=zc_temp
Alias zc(11)=zc_hdg
Alias zc(12)=zc_pitch
Alias zc(13)=zc_roll
Units ws_bp=bar
Units ws_u=m/s
Units ws_v=m/s

DataTable(BuoyVoltage,True,-1)
DataInterval(0,60,Min,10)
TableFile(FTP_fnBV,8,MaxFiles,0,FTPSendInt,Min,doneBV,LastFN_BV)
Minimum(1,BattV,FP2,0,False)
EndTable

DataTable(WS,True,-1)
TableFile(FTP_fnWS,8,MaxFiles,0,FTPSendInt,Min,doneWS,LastFN_WS)
Sample(1,ws_sp_avg,FP2)
Sample(1,ws_dr_avg,FP2)
Sample(1,ws_u_avg,FP2)
Sample(1,ws_v_avg,FP2)
Sample(1,ws_bp_avg,FP2)
Sample(1,ws_at_avg,FP2)
Sample(1,ws_pitch_avg,FP2)
Sample(1,ws_roll_avg,FP2)
EndTable

DataTable(GPS,True,-1)
TableFile(FTP_fnGPS,8,MaxFiles,0,FTPSendInt,Min,doneGPS,LastFN_GPS)
Sample(1,gga_lat_avg,IEEE4)
Sample(1,gga_lon_avg,IEEE4)
EndTable

DataTable(ZCELL,True,-1)
TableFile(FTP_fnZCELL,8,MaxFiles,0,FTPSendInt,Min,doneZCELL,LastFN_ZCELL)
Sample(1,zc_batt,FP2)
Sample(1,zc_press,FP2)
Sample(1,zcDate,String)
Sample(1,zcTime,String)
Sample(1,zc_temp,FP2)
Sample(3,zc(11),FP2) 'hdg,pitch,roll
Sample(nbins,u(),IEEE4)
Sample(nbins,v(),IEEE4)
Sample(nbins,spd(),IEEE4)
Sample(nbins,dir(),IEEE4)
EndTable

Sub DoFTP()
If FTPState=1 Then
FTPSent=0
FTPUnsent=0
FTPState=2
PPPOpen
EndIf

If FTPState=2 Then
PPPResultStr=status.ipinfo
If (InStr(1,PPPResultStr,PPPFilterStr,2)=0) Then
FTPState=3
For I1=1 To FListCnt
If (FTP_FileList(I1) <> "") Then
SendFN=FTP_FileList(I1)
If (FTPClient(FTPHost,FTPUser,FTPPass,SendFN,FTPPath+Right(SendFN,Len(SendFN)-4),0)=true) Then
FTPSent=FTPSent+1
For I2=1 To FListCnt
If (SendFN=FTP_FileList(I2)) Then FTP_FileList(I2)=""
Next
Else
FTPUnsent=FTPUnsent+1
EndIf
SendFN=""
EndIf
Next
FTPState=4
EndIf
EndIf

If (FTPState=4) Then
FTPState=5
PPPClose
EndIf

If (FTPState=5) Then
PPPResultStr=status.ipinfo
If InStr(1,PPPResultStr,PPPFilterStr,2) <> 0 Then
FTPState=0
EndIf
EndIf
EndSub

Sub UpdateFileList(LastFN As String * FNlen,done As Boolean)
If (LastFN<>"") Then
For I1=1 To FListCnt-1
FTP_FileList(I1)=FTP_FileList(I1+1)
Next
FTP_FileList(FListCnt)=LastFN
FTPState=1
EndIf
LastFN=""
done=false
EndSub

'Main Program
SequentialMode
BeginProg
SetStatus("USRDriveSize",FtpUserDriveSize)
PPPClose
SerialClose(Com2)
SerialOpen(Com2,4800,0,0,2000)
SerialFlush(Com2)
SerialClose(Com3)
SerialOpen(Com3,9600,0,0,2000)
SerialFlush(Com3)
gotWSdata=false

Scan(15,Sec,0,0)
RealTime(RTime)
Battery(BattV)
CallTable(BuoyVoltage)
If (doneBV=true) Then UpdateFileList(LastFN_BV,doneBV)

'12V power switched on hourly for last 8 min
Hrs=RTime(4)
Min_hr=RTime(5)
If (Min_hr>=50 AND Min_hr<=59) Then Flag_pwr=1 Else Flag_pwr=0
If BattV<9.0 Then Flag_pwr=0
PortSet(9,Flag_pwr)

'** Nortek Aquadopp ZCELL
If (SerialInChk(Com3) > 10) Then
Delay(1,1,Sec)
c3str=""
SerialIn(c3str,Com3,500,-1,2000)
SerialFlush(Com3)
SplitStr(zc,c3str,"",numZCell,0) '0 - numeric values are split out
zcDate=FormatLong(zc(3),"%04d")+"-"+FormatLong(zc(1),"%02d")+"-"+FormatLong(zc(2),"%02d")
zcTime=FormatLong(zc(4),"%02d")+":"+FormatLong(zc(5),"%02d")+":"+FormatLong(zc(6),"%02d")
si=19
For y=1 To nbins
u(y)=0
v(y)=0
spd(y)=zc(si)
dir(y)=zc(si+1)
si=si+3
Next y
CallTable(ZCELL)
If (doneZCELL=true) Then UpdateFileList(LastFN_ZCELL,doneZCELL)
EndIf

'** PB200 weather station
If (Flag_pwr=1) Then
If (SerialInChk(Com2) > 10) Then
Delay(1,10,mSec)
c2str=""
SerialIn(c2str,Com2,100,-1,500)
SerialFlush(Com2)
'GPGGA string
si=InStr(1,c2str,"GPGGA",2) 'index of GPGGA
fi=InStr(si,c2str,"*",2) 'index of *
ggastr=Mid(c2str,si,fi-si)
SplitStr(gga_f,ggastr," ",6,0)
SplitStr(gga_s,ggastr,",",8,5) 'get strings for N/S,E/W
If ((gga_f(2) <> "NAN") AND (gga_f(3) <> "NAN")) Then
gga_lat=INT(gga_f(2)/100) + (gga_f(2) - 100*INT(gga_f(2)/100))/60
gga_lon=INT(gga_f(3)/100) + (gga_f(3) - 100*INT(gga_f(3)/100))/60
If ((gga_s(4)="S") AND (gga_s(4) <> "NAN")) Then gga_lat=-gga_lat
If ((gga_s(6)="W") AND (gga_s(6) <> "NAN")) Then gga_lon=-gga_lon
AvgRun(gga_lat_avg,1,gga_lat,30)
AvgRun(gga_lon_avg,1,gga_lon,30)
EndIf
'WIMDA string
si=InStr(1,c2str,"WIMDA",2)
fi=InStr(si,c2str,"*",2)
wimdastr=Mid(c2str,si,fi-si+1)
fi=InStr(1,wimdastr,"*",2)
wimdastr(1,1,fi)=","
SplitStr(wimda_f,wimdastr,"",20,0)
ws_u=ws_windspd * SIN(ws_winddir * PI / 180)
ws_v=ws_windspd * COS(ws_winddir * PI / 180)
ws_bp=1000*ws_bp
AvgRun(ws_u_avg,1,ws_u,30)
AvgRun(ws_v_avg,1,ws_v,30)
AvgRun(ws_bp_avg,1,ws_bp,30)
AvgRun(ws_at_avg,1,ws_at,30)
ws_dr_avg=ATN2(ws_u_avg,ws_v_avg)*180/PI
If (ws_dr_avg < 0) Then ws_dr_avg=ws_dr_avg+360
ws_sp_avg=SQR(ws_u_avg^2 + ws_v_avg^2)
'YXXDR string
si=InStr(1,c2str,"YXXDR",2) 'index of YXXDR
If (si > 0) Then
fi=InStr(si,c2str,"*",2)
yxxdrstr=Mid(c2str,si,fi-si)
SplitStr(yxxdr_f,yxxdrstr," ",2,0)
AvgRun(ws_pitch_avg,1,ws_pitch,30)
AvgRun(ws_roll_avg,1,ws_roll,30)
EndIf
gotWSdata=true
EndIf
EndIf

If (gotWSdata AND (Flag_pwr=0)) Then
gotWSdata=false
CallTable(WS)
If (doneWS=true) Then UpdateFileList(LastFN_WS,doneWS)
CallTable(GPS)
If (doneGPS=true) Then UpdateFileList(LastFN_GPS,doneGPS)
EndIf

NextScan

SlowSequence
Scan(1,min,0,0)
DoFTP()
NextScan
EndProg


aps Feb 21, 2014 03:42 PM

The Tablefile instruction is spawned off as a separate thread in the logger operating system to allow the program to continue without excessive delays if for instance you had chosen to write a very large file to a card. For this reason the flag saying a file has been stored will not be set for at least one scan after the tablefile was triggered to store data, it could be longer than this for large amounts of data (unlikely with your program).

It is hard to see through the logic of your program as to whether this might be the cause of the issue you have but it is a possibility.

Can I suggest that instead of the two options you mention you also look to using the new FTP "Streaming" options available in the latest operating systems. This effectively embeds the tablefile functions into the ftpclient command, controlled by new optional parameters. This will make your program a lot simpler plus you avoid the complexity of needing to use the USR drive and managing the files on it. The data written should be up to date at the point the ftpclient is triggered to send data.

Log in or register to post/reply in the forum.