Need a better Trap
Need a better Trap
Need a better Trap
Need a better Trap
Need a better Trap
Need a better Trap Need a better Trap Need a better Trap Need a better Trap Need a better Trap Need a better Trap Need a better Trap Need a better Trap
Need a better Trap Need a better Trap
Need a better Trap
Go Back  Xtreme Visual Basic Talk > > > Need a better Trap


Reply
 
Thread Tools Display Modes
  #1  
Old 12-08-2010, 01:30 PM
Mshkor Mshkor is offline
Newcomer
 
Join Date: Aug 2004
Location: Baltimore, Maryland
Posts: 13
Default Need a better Trap


I'm written a small data logger that reads the output of a CO2 monitor. Every second it throws out something like

$CO2:Cppm:h:d:wf:C123ppm:T20C:-D4%:wf33.3eac

I'm currently parsing the data to be importable to a spreadsheet.. here's a snippet of the code.

Quote:
Private Sub Form_Load()

MSComm1.RThreshold = 1
MSComm1.InputLen = 0
MSComm1.Settings = "9600,N,8,1"
MSComm1.CommPort = 1
MSComm1.PortOpen = True

End Sub
Quote:
'triggers every 1000 milliseconds
Private Sub Timer1_Timer()

Dim inputbuf As String
Dim StartPosition As String
Dim Data As String

'updated 12/6/10 as trap to reset failed serial connection
If MSComm1.PortOpen = False Then MSComm1.PortOpen = True

POLL:
If MSComm1.CommEvent = comEvReceive Then inputbuf = MSComm1.Input

StartPosition = InStr(inputbuf, "$CO2")
If StartPosition = 1 Then GoTo LOC1
If StartPosition <> 1 Then GoTo LOC5

LOC1:
'records data, irrelevant to the post

LOC5:
Label1.Caption = Date$
Label2.Caption = Time$
Text1.Text = "Please"
Text2.Text = "close"
Text3.Text = "and"
Text4.Text = "restart"
Text5.Text = "CO2"
Text6.Text = "monitor"
'updated 12/6/10 as trap to reset failed serial connection
MSComm1.PortOpen = False
My hope was that on a failed reading (failed readings look like they grab the input string halfway through the transmission), it would briefly display the error message, close the port, then reopen the port on the next cycle through and start working again.

Maybe I need more time to let the port close/reopen, maybe I need to handle the incoming data better, maybe my current trap just sucks and needs to be redone.

Any suggestions?
Reply With Quote
  #2  
Old 12-09-2010, 11:20 AM
Mshkor Mshkor is offline
Newcomer
 
Join Date: Aug 2004
Location: Baltimore, Maryland
Posts: 13
Default more info..

Here's the entire code, maybe someone will spot something bad. It randomly crashes, sometimes after 10 minutes, sometimes after 6 hours.
Quote:
'raw input
'"C592ppm:T26.0C:H13.7%:d-3.7C:w11.7C68"
Private Sub Form_Load()


MSComm1.RThreshold = 1
MSComm1.InputLen = 0
MSComm1.Settings = "9600,N,8,1"
MSComm1.CommPort = 1
MSComm1.PortOpen = True

End Sub

Private Sub Timer1_Timer()



Dim inputbuf As String
Dim StartPosition As String
Dim Data As String

'updated 12/6/10 as trap to reset failed serial connection
If MSComm1.PortOpen = False Then MSComm1.PortOpen = True

POLL:
If MSComm1.CommEvent = comEvReceive Then inputbuf = MSComm1.Input


StartPosition = InStr(inputbuf, "$CO2")
If StartPosition = 1 Then GoTo LOC1
If StartPosition <> 1 Then GoTo LOC5

LOC1:
'12/6/10 added to improve parsing
Ppmstart = InStr(inputbuf, "BTf9") + 7
Tempstart = InStr(inputbuf, "ppm:T") + 5
Humidstart = InStr(inputbuf, "C:H") + 3
Dstart = InStr(inputbuf, "%:d") + 3
Wstart = InStr(inputbuf, "C:w") + 3
'data line ends with a CR or NL, having problems detecting which
'Wstop = InStr(inputbuf, Chr$(0))

Ppmlen = (Tempstart - 5) - Ppmstart
Templen = (Humidstart - 3) - Tempstart
Humidlen = (Dstart - 3) - Humidstart
Dlen = (Wstart - 3) - Dstart
' 7 is long enough to capture whatever value it may be
wlen = 7

Data = Mid(inputbuf, StartPosition + 22, 37)
CO2 = Mid(inputbuf, Ppmstart, Ppmlen)
AIR = Mid(inputbuf, Tempstart, Templen)
RH = Mid(inputbuf, Humidstart, Humidlen)
DP = Mid(inputbuf, Dstart, Dlen)
WBTF9 = Mid(inputbuf, Wstart, wlen)

'original parser
'Data = Mid(inputbuf, StartPosition + 22, 37)
'CO2 = Mid(inputbuf, StartPosition + 23, 3)
'AIR = Mid(inputbuf, StartPosition + 31, 5)
'RH = Mid(inputbuf, StartPosition + 38, 5)
'DP = Mid(inputbuf, StartPosition + 45, 5)
'WBTF9 = Mid(inputbuf, StartPosition + 52, 7)

Label1.Caption = Date$
Label2.Caption = Time$
Text1.Text = Data
Text2.Text = CO2
Text3.Text = AIR
Text4.Text = RH
Text5.Text = DP
Text6.Text = WBTF9

If Text8.Text < 2 Then GoTo LOC3
If Text8.Text > 1 Then GoTo LOC4

LOC3:
Open "C:\CO2Monitor\CO2.txt" For Append As #1
Write #1, Date$, Time$, CO2, AIR, RH, DP, WBTF9, Data
Close #1

Text8.Text = Text7.Text
GoTo LOC6

LOC4:
Text8.Text = Text8.Text - 1
GoTo LOC6

LOC5:
Label1.Caption = Date$
Label2.Caption = Time$
Text1.Text = "Please"
Text2.Text = "close"
Text3.Text = "and"
Text4.Text = "restart"
Text5.Text = "CO2"
Text6.Text = "monitor"
'updated 12/6/10 as trap to reset failed serial connection
MSComm1.PortOpen = False


LOC6:

End Sub
Reply With Quote
  #3  
Old 12-09-2010, 11:25 AM
Mshkor Mshkor is offline
Newcomer
 
Join Date: Aug 2004
Location: Baltimore, Maryland
Posts: 13
Default

Just moved the bulk of the code from
Quote:
Private Sub Timer1_Timer()
into
Quote:
Private Sub MSComm1_OnComm()
Now to wait a couple hours and see if it crashes
Reply With Quote
  #4  
Old 12-09-2010, 11:51 AM
ZaCkOX's Avatar
ZaCkOX ZaCkOX is offline
Contributor
 
Join Date: May 2006
Location: CA
Posts: 645
Default Run it in debug mode

Run it in debug mode the whole time. Then when you find what line you get the error post it here.

Another thing you can do is copy down the data into a text file and save it, longer process but at least you'll have the data to view after the error happens and hopefully you'll have the last of the data when errored. Since we don't know what kind of error you have yet (and I don't know mscomm, sorry). Hopefully someone will help you out soon.

Assuming this error is with mscomm and not really detectable?
__________________
ZaCkO ... Who is your attitude?

Last edited by ZaCkOX; 12-09-2010 at 12:02 PM.
Reply With Quote
  #5  
Old 12-09-2010, 12:42 PM
Mshkor Mshkor is offline
Newcomer
 
Join Date: Aug 2004
Location: Baltimore, Maryland
Posts: 13
Default

I've been running it in debug for longer periods of time today. The input string comes in about every second, but it's of slightly variable length, anywhere from 59 to 62 characters. I think what's happening is the over/under is creating shorts and longs of string data, so when the application reads it, the digits that should be in any given position are shifted left or right in the string, and the digits at the very end sometimes get cut off.

I just changed the threshold and input length from 60 to 120, hoping that will grab two strings worth at a time, and find all the information it needs in between the two. kind of an ugly fix, but timing is the issue I think.

Last time I wrote this type of app, I was creating both sides of the project, and I ran it at 2400 baud so I wouldn't have to worry about precise timing. In this case its 9600 and there's nothing I can do about it.
Reply With Quote
  #6  
Old 12-09-2010, 11:00 PM
loquin's Avatar
loquinNeed a better Trap loquin is offline
Google Hound

Retired Moderator
* Guru *
 
Join Date: Nov 2001
Location: Arizona, USA
Posts: 12,400
Default

Will the incoming data string have a delimiter, or EOL character? If not, does each new line always begin with $CO2: ?

Typically, you would want to run at the receiving end using an event driven approach, instead of the polling method that you are currently employing.

When you receive an event, pull all the data from the mscomm input buffer to a static (or module level) string buffer in your app. Continue to do so until you encounter the EOL character or the beginning of line marker. Once you do, pull all data before the EOL/BOL marker out of the client string buffer, and do whatever you need to do with it.

Take a look at BillSoo's Serial Port Tutorial in the code library. Remember that when in the event-based receiving mode, when you have a receive event, you might have one byte in the mscomm receive buffer, you might have three or four bytes, or you might have a bunch of data. Pull it off, and append it to your app's receive buffer variable. Then, check your app's local buffer to see if you need to process a 'row' of data. If no, you're done for now. If yes, process that chunk, and then you're done for now.
__________________
Lou
"I have my standards. They may be low, but I have them!" ~ Bette Middler
"It's a book about a Spanish guy called Manual. You should read it." ~ Dilbert
"To understand recursion, you must first understand recursion." ~ unknown

Last edited by loquin; 12-09-2010 at 11:20 PM.
Reply With Quote
  #7  
Old 12-10-2010, 03:38 AM
Banjo's Avatar
BanjoNeed a better Trap Banjo is offline
Hell's Angel

Retired Moderator
* Guru *
 
Join Date: Jul 2001
Location: Yorkshire, UK
Posts: 10,394
Default

Just to add to what Loquin said:
Quote:
Originally Posted by loquin View Post
Then, check your app's local buffer to see if you need to process a 'row' of data. If no, you're done for now. If yes, process that chunk, and then you're done for now.
You actually need to use a loop to look for the end of row chars and process rows of data. The reason is that it is quite possible for the comm control to have accumulated 2 or more of your messages before raising the event.
__________________
A wise one man once said "what you talking about dog breath"
Reply With Quote
Reply


Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off

Forum Jump

Advertisement:





Free Publications
The ASP.NET 2.0 Anthology
101 Essential Tips, Tricks & Hacks - Free 156 Page Preview. Learn the most practical features and best approaches for ASP.NET.
subscribe
Programmers Heaven C# School Book -Free 338 Page eBook
The Programmers Heaven C# School book covers the .NET framework and the C# language.
subscribe
Build Your Own ASP.NET 3.5 Web Site Using C# & VB, 3rd Edition - Free 219 Page Preview!
This comprehensive step-by-step guide will help get your database-driven ASP.NET web site up and running in no time..
subscribe
Need a better Trap
Need a better Trap
Need a better Trap Need a better Trap
Need a better Trap
Need a better Trap
Need a better Trap Need a better Trap Need a better Trap Need a better Trap Need a better Trap Need a better Trap Need a better Trap
Need a better Trap
Need a better Trap
 
Need a better Trap
Need a better Trap
 
-->