Dale,
This is how it's done in my application ATM (I'll try to simplify it later)
Data received by the Comm control is passed to a Scale Control object in the form of a string.
Code:
Private Sub MSComm_OnComm()
Dim s As String
'Dim T As Single
Select Case MSComm.CommEvent
Case comEvReceive
s = MSComm.Input
SC.DataInput s 'pass data to scale control object
Case Is = comEvCTS
'CTS line change
If MSComm.CTSHolding Then
SendIdentify
Else
SC.RemoveAll 'lead unplugged
End If
End Select
End Sub
The Scale Control object splits up the string, works out what to do with the parts and passes that data onto the appropriate handler.
Code:
'* < DataInput Sub Header >
'* Author.......: {UserName}
'* Date.........: 03-Aug-2007 12:32
'* Purpose......: Data from verniers
'* Assumptions..:
'* Effects......:
'* Inputs.......: sting data from scales
'* Returns......:
'* ------------------------------------------------------------------------
Public Sub DataInput(vData As String)
Dim strErrmsg As String
If Not IsInIDE() Then On Error GoTo DataInputError
'------------------------------------------------------------------------ Main Code
'update appropriate vernier class
Dim VS As clsVernier 'Vernier scale object
Static RXS As String
Dim SCid As String
Dim sData As String
Dim vMode As Integer
Dim vType As String
Dim vUnit As String
RXS = RXS & vData
Do While InStr(RXS, ":") 'Len(RXS) >= 9
sData = Sfmt.SplitAtDelim(RXS, ":")
Select Case Left(sData, 1)
Case Is = "C"
'connect e.g CX
SCid = Mid(sData, 2, 1)
'AddScale ScID
RaiseEvent ScaleComms("I0")
Case Is = "D"
'disconnected e.g DX
SCid = Mid(sData, 2, 1)
RemoveScale SCid
Case Is = "I"
'info string ID,Mode,Type,Unit e.g. IX,0,Decimal,Inch:
SCid = Mid(Sfmt.SplitAtDelim(sData, ","), 2, 1)
vMode = Sfmt.SplitAtDelim(sData, ",")
vType = Sfmt.SplitAtDelim(sData, ",")
vUnit = sData
If Not Scales.Exists(SCid) Then AddScale SCid
For Each VS In Scales ' find the correct Vernier Scale object
If VS.Key = SCid Then
VS.Mode = vMode
VS.ScaleType = vType
VS.Unit = vUnit
End If
Next
Case Is = "R"
'scale has been zeRoed (can't use Z)
SCid = Mid(sData, 2, 1)
For Each VS In Scales
If VS.Key = SCid Then
VS.ResetAbsolute
End If
Next
Case Else
'data e.g. X+00.0000
SCid = Left(sData, 1) 'uses the the identifier e.g. W, X,Y or Z to choose the scale ID
If Scales.Exists(SCid) Then 'check if scale ID is in scales collection
Set VS = Scales.Item(SCid) ' set current vernier scale object
VS.Setdata Right(sData, Len(sData) - 1) ' pass data
End If
End Select
Loop
'------------------------------------------------------------------------ End of Main Code
The Vernier Scale object has to work out the data type convert it and save it in a standard form (e.g. inches)
The PIC can output three type depending the make of digital vernier used:
1)A 6 digit Hex number where 20480(d) units = one inch
2)A signed two significant digit + four decimal place string in Inches
3) A signed three significant digit + two dp string in millimetres.
Code:
Public Sub Setdata(sData As String)
'takes sData string e.g. H000000 (hex 1/20480"), +00.0000 (inches) or -000.00 (mm)
'and converts it to ABS value
Dim pos As Long
Dim NV As Single
Select Case True
Case Mid(sData, 5, 1) = "."
'decimal vernier in metric mode
NV = Val(Right(sData, 7)) / 25.4
Case Mid(sData, 4, 1) = "."
'decimal vernier in inch mode
NV = Val(Right(sData, 8)) ' convert decimal string
Case Left$(sData, 1) = "H"
' convert hex string
pos = 1 - Val("&" & sData & "00") 'shift 24bit to 32bit and invert
NV = pos / 5242880 '20480* 256
End Select
'add to glitch filter
If mRev Then
AddToFilter NV * -1
Else
AddToFilter NV
End If
mController.Refresh Me 'update the controller
End Sub
In order to improve the display stability and remove jitter and glitches I added a simple filter to the output.
Code:
Private Sub AddToFilter(NV As Single)
'filter new value add to abs value
Static FI As Integer 'filter index
Dim n As Integer
Dim FT As Integer
FT = UBound(Filter())
Dim Tot As Single
'glitch filter
'average last few readings
Filter(FI) = NV
FI = FI + 1
If FI >= FT Then FI = 0
For n = 0 To FT - 1
Tot = Tot + Filter(n)
Next
mvarAbsValueInch = Tot / FT
End Sub
The display routine reads the Scale object's AbsValueInch or AbsValueMM (the scale object does the conversion to a single precision variable).