Hi, I want to connect Gill Windmaster via Serial (RS232) and collect data every 50 msec. The bound rate at 9600 is limited by the length of the cable, which is 6.5m. Here the working code I used:
'CR6 Series & Gill WindMaster RS232
Const STX=CHR(2) 'ASCII start-of-text
Const ETX=CHR(3) 'ASCII end-of-text
Public row1 As String * 50
Public istart1 As Long
Public tmp As String * 50
'Declare Public Variables
Public u_1
Public v_1
Public w_1
Public Ts_1
'Define Data Tables
DataTable (Sonic,True,-1)
DataInterval(0,50,mSec,0)
TableFile ("CRD:"&Status.SerialNumber(1,1)&"_sonic_data_",64,-1,0,1,Day,0,0)
Sample(1, u_1,FP2)
Sample(1, v_1,FP2)
Sample(1, w_1,FP2)
Sample(1, Ts_1,FP2)
EndTable
'String out:"Q,+000.00,-000.01,+000.02,M,+022.55,00,"
BeginProg
SerialOpen(ComC1,9600,3,0,512,0)
Scan(50,mSec,1,0)
SerialIn(row1,ComC1,0,ETX,50) 'read until ETX > complete string ()
istart1 = InStr(1,row1,"Q",2)
tmp = Mid(row1,istart1,40)
If (istart1 = 0) OR (Len(tmp) <> 40) Then
SerialFlush (ComC1)
Else
u_1 = Mid(row1,istart1+2,7)
v_1 = Mid(row1,istart1+10,7)
w_1 = Mid(row1,istart1+18,7)
Ts_1 = Mid(row1,istart1+28,7)
EndIf
CallTable Sonic
NextScan
EndProg
The code works but I had to introduce the tmp and if statement to exclude cases where the saved string was truncated, with the middle characters missing like
Q,+022.55,00,
These cases appear once every 10 min if I remove the "If (istart1 = 0) OR (Len(tmp) <> 40)" part.
My question:
1) There is a best way to implement a fast serial read communication?
2) If I replace SerialIn() with
SerialInRecord (ComC1,row1,"Q",0,ETX,n1,01)
no rows are stored, why?
Thanks
If using SerialInRecord(), remove SerialFlush() from your program. Use the number of bytes returned by SerialInRecord to indicate if there is new data to process.
Thanks, so both SerialIn() and SerialInRecord() codes are equally efficient or one of the two is preferable?
SerialInRecord() will be more reliable.
I suggest looking at the example program Campbell Scientific provides for the Windsonic1 (RS-232). The data is a very similar format.
FYI, I think at 9600 baud and the ASCII format, you won't be able to achieve 50ms output. It takes a little over 1 ms per character to be transmitted at that baud rate. You can probably do RS-232 at 19200 baud with that cable length. If there is too much electrical noise at site to run that baud rate, change the sensor and CR6 to RS-485 half duplex.
ok thanks, SerialInRecord() works with 2 and 3 in start and stop byte instead of STX and ETX, here working code:
'pinoiut
'N/GN (TX) --> C2 or C4 (RX)
'N/WN (RX) --> C1 or C3 (TX)
'B/BN --> 12V
'R/RN --> 12V
'N/RN --> GND
'Shield --> GND
'Serial COM RS232
Const STX=CHR(2) 'ASCII start-of-text
Const ETX=CHR(3) 'ASCII end-of-text
Public row1 As String * 50
Public n1 As Long
'Declare Public Variables
Public u_1
Public v_1
Public w_1
Public Ts_1
Units u_1=m/s
Units v_1=m/s
Units w_1=m/s
Units Ts_1=C
'Define Data Tables
DataTable (Sonic,True,-1)
DataInterval(0,50,mSec,0)
TableFile ("CRD:"&Status.SerialNumber(1,1)&"_sonic_data_",64,-1,0,1,Day,0,0)
Sample(1, u_1,FP2)
Sample(1, v_1,FP2)
Sample(1, w_1,FP2)
Sample(1, Ts_1,FP2)
Sample(1, row1, String)
EndTable
'Q,+000.00,+000.00,+000.00,M,+023.39,00,3B
BeginProg
SerialOpen(ComC1,9600,3,0,512,0)
Scan(50,mSec,1,0)
'SerialInRecord (ComC1,row1,&H02,0,&H0D0A,n1,01)
SerialInRecord (ComC1,row1,2,0,3,n1,01) '2 and 3 ascii char or &H02 and &H0D0A
If n1 = 39 Then
u_1 = Mid(row1,3,7)
v_1 = Mid(row1,11,7)
w_1 = Mid(row1,19,7)
Ts_1 = Mid(row1,29,7)
EndIf
CallTable Sonic
NextScan
EndProg
If someone needs, here a working code for CR6 and Gill Windmaster RS485 half duplex:
'CR6 Series & Gill WindMaster RS485 half duplex
'Every 50ms Gill send out string:"Q,+000.00,-000.01,+000.02,M,+022.55,00,"
'Gill Windmaster set at 38400 bound, sufficient to send 42+2 (entire string) char every 50ms
'Gill Windmaster Settings: Output Format M3 Polled, ASCII format Fixed Field
'pinoiut
'N/GN (TX-) --> C3 (-)
'N/WN (RX-) --> C3 (-)
'G/GN (TX+) --> C4 (+)
'W/WN (RX+) --> C4 (+)
'B/BN --> 0V
'R/RN --> 12V
'N/RN --> GND
'Shield --> GND
'Serial COM RS232
Const STX=CHR(2) 'ASCII start-of-text
Const ETX=CHR(3) 'ASCII end-of-text
Public row1 As String * 50
Public n1 As Long
'Declare Public Variables
Public u_1
Public v_1
Public w_1
Public Ts_1
Units u_1=m/s
Units v_1=m/s
Units w_1=m/s
Units Ts_1=C
'Define Data Tables
DataTable (Sonic,True,-1)
DataInterval(0,50,mSec,0)
TableFile ("CRD:"&Status.SerialNumber(1,1)&"_sonic_data_",64,-1,0,1,Day,0,0)
Sample(1, u_1,FP2)
Sample(1, v_1,FP2)
Sample(1, w_1,FP2)
Sample(1, Ts_1,FP2)
Sample(1, row1, String)
EndTable
'Q,+000.00,+000.00,+000.00,M,+023.39,00,3B
BeginProg
SerialOpen(ComC3,38400,3,0,512,4)
Scan(50,mSec,1,0)
SerialOutBlock (ComC3,"?Q",2) 'start polled mode
Delay (0,1,mSec)
SerialInRecord (ComC3,row1,2,0,3,n1,01) '2 and 3 ascii char or &H02 and &H0D0A to get entire string
If n1 = 39 Then
u_1 = Mid(row1,3,7)
v_1 = Mid(row1,11,7)
w_1 = Mid(row1,19,7)
Ts_1 = Mid(row1,29,7)
EndIf
SerialOutBlock (ComC3,"!",1) 'stop polled mode
CallTable Sonic
NextScan
EndProg