Public Class Main
    '*----------------------------------------------------------------------
    '* (c) 2008 Microstrain, Inc.
    '*----------------------------------------------------------------------
    '* THE PRESENT SOFTWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING 
    '* CUSTOMERS WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER 
    '* FOR THEM TO SAVE TIME. AS A RESULT, MICROSTRAIN SHALL NOT BE HELD LIABLE 
    '* FOR ANY DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY 
    '* CLAIMS ARISING FROM THE CONTENT OF SUCH SOFTWARE AND/OR THE USE MADE BY 
    '* CUSTOMERS OF THE CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH 
    '* THEIR PRODUCTS.
    '*----------------------------------------------------------------------
    Private Sub ExitToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ExitToolStripMenuItem.Click
        'quit app
        End
    End Sub

    Private Sub Main_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        'populate comm port combo box
        Dim X As Integer
        For X = 1 To 32
            cmbCommPort.Items.Add(Trim(Str(X)))
        Next

        'Sets a value indicating whether to catch calls on the wrong thread that access a control's Handle property 
        txtHeader.CheckForIllegalCrossThreadCalls = False
        txtM11.CheckForIllegalCrossThreadCalls = False
        txtM12.CheckForIllegalCrossThreadCalls = False
        txtM13.CheckForIllegalCrossThreadCalls = False
        txtM21.CheckForIllegalCrossThreadCalls = False
        txtM22.CheckForIllegalCrossThreadCalls = False
        txtM23.CheckForIllegalCrossThreadCalls = False
        txtM31.CheckForIllegalCrossThreadCalls = False
        txtM32.CheckForIllegalCrossThreadCalls = False
        txtM33.CheckForIllegalCrossThreadCalls = False
        txtTimerTick.CheckForIllegalCrossThreadCalls = False
        txtElapsed.CheckForIllegalCrossThreadCalls = False
        txtMyCheckSum.CheckForIllegalCrossThreadCalls = False
        txtTheirCheckSum.CheckForIllegalCrossThreadCalls = False
    End Sub

    Private Sub SampleToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles SampleToolStripMenuItem.Click
        'set error handler
        On Error GoTo ErrorHandler

        'test for comm port selection
        If cmbCommPort.Text = "" Then
            'event
            Call ReportEvent("Comm Port not selected")
            'exit
            Exit Sub
        End If

        'determine action based on menu check
        If SampleToolStripMenuItem.Checked = False Then
            'event
            Call ReportEvent("Sampling started")
            'set menu check
            SampleToolStripMenuItem.Checked = True
            'disable combo
            cmbCommPort.Enabled = False
            'disable numupdown
            NumUpDown.Enabled = False
            'zero elapsed time counter
            ElapsedTime = 0
            'zero previous time counter
            PreviousTime = 0
            'set flag
            flgFirstPass = 0
            'get limit for determinant
            Limit = NumUpDown.Value / 10000
            'set serial port number
            SerialPort1.PortName() = "COM" + Trim(cmbCommPort.Text)
            'set receive threshold
            SerialPort1.ReceivedBytesThreshold = 43
            'open serial port
            SerialPort1.Open()
            'populate byte array with polling command for 0xC5
            ReDim arrBytes(0 To 0)
            arrBytes(0) = 197
            'send command
            SerialPort1.Write(arrBytes, 0, 1)
        ElseIf SampleToolStripMenuItem.Checked = True Then
            'open serial port
            SerialPort1.Close()
            'event
            Call ReportEvent("Sampling stopped")
            'set menu check
            SampleToolStripMenuItem.Checked = False
            'set checksum indicator
            lblCheckSum.ForeColor = Color.Red
            'enable combo
            cmbCommPort.Enabled = True
            'enable numupdown
            NumUpDown.Enabled = True
        End If

        Exit Sub
ErrorHandler:
        'open serial port
        If SerialPort1.IsOpen = True Then SerialPort1.Close()
        'event
        Call ReportEvent("Sampling errored: " + Err.Description)
        'set menu check
        SampleToolStripMenuItem.Checked = False
        'set checksum indicator
        lblCheckSum.ForeColor = Color.Red
        'enable combo
        cmbCommPort.Enabled = True
        'enable numupdown
        NumUpDown.Enabled = True
        'exit
        Exit Sub
    End Sub

    Private Function ReportEvent(ByVal MyEvent As String) As Boolean
        'add event to text
        If txtEvent.Text = "" Then
            txtEvent.Text = MyEvent
        Else
            txtEvent.Text = txtEvent.Text + Chr(13) + Chr(10) + MyEvent
        End If
    End Function

    Private Function CheckSum() As Boolean
        'set error handler
        On Error GoTo ErrorHandler

        '-----calc TheirCheckSum
        'dim
        Dim X As Double
        'zero variable
        TheirCheckSum = 0
        'calc TheirCheckSum
        For X = 0 To 40
            TheirCheckSum = TheirCheckSum + CDbl(arrBytes(X))
        Next X

        'handle CheckSum rollover
        TheirCheckSum = TheirCheckSum Mod 65536

        'calc MyCheckSum
        MyCheckSum = (CDbl(arrBytes(41)) * 256) + arrBytes(42)

        'compare checksums
        If MyCheckSum = TheirCheckSum Then
            ''set checksum return
            CheckSum = True
            'calc datapoints
            MyHeader = arrBytes(0)
            'convert array of 32bit floating point values in IEEE-754 format
            arrTemp(0) = arrBytes(4)
            arrTemp(1) = arrBytes(3)
            arrTemp(2) = arrBytes(2)
            arrTemp(3) = arrBytes(1)
            M11 = BitConverter.ToSingle(arrTemp, 0)
            'round
            M11 = Math.Round(M11, 4)
            'convert array of 32bit floating point values in IEEE-754 format
            arrTemp(0) = arrBytes(8)
            arrTemp(1) = arrBytes(7)
            arrTemp(2) = arrBytes(6)
            arrTemp(3) = arrBytes(5)
            M12 = BitConverter.ToSingle(arrTemp, 0)
            'round
            M12 = Math.Round(M12, 4)
            'convert array of 32bit floating point values in IEEE-754 format
            arrTemp(0) = arrBytes(12)
            arrTemp(1) = arrBytes(11)
            arrTemp(2) = arrBytes(10)
            arrTemp(3) = arrBytes(9)
            M13 = BitConverter.ToSingle(arrTemp, 0)
            'round
            M13 = Math.Round(M13, 4)
            'convert array of 32bit floating point values in IEEE-754 format
            arrTemp(0) = arrBytes(16)
            arrTemp(1) = arrBytes(15)
            arrTemp(2) = arrBytes(14)
            arrTemp(3) = arrBytes(13)
            M21 = BitConverter.ToSingle(arrTemp, 0)
            'round
            M21 = Math.Round(M21, 4)
            'convert array of 32bit floating point values in IEEE-754 format
            arrTemp(0) = arrBytes(20)
            arrTemp(1) = arrBytes(19)
            arrTemp(2) = arrBytes(18)
            arrTemp(3) = arrBytes(17)
            M22 = BitConverter.ToSingle(arrTemp, 0)
            'round
            M22 = Math.Round(M22, 4)
            'convert array of 32bit floating point values in IEEE-754 format
            arrTemp(0) = arrBytes(24)
            arrTemp(1) = arrBytes(23)
            arrTemp(2) = arrBytes(22)
            arrTemp(3) = arrBytes(21)
            M23 = BitConverter.ToSingle(arrTemp, 0)
            'round
            M23 = Math.Round(M23, 4)
            'convert array of 32bit floating point values in IEEE-754 format
            arrTemp(0) = arrBytes(28)
            arrTemp(1) = arrBytes(27)
            arrTemp(2) = arrBytes(26)
            arrTemp(3) = arrBytes(25)
            M31 = BitConverter.ToSingle(arrTemp, 0)
            'round
            M31 = Math.Round(M31, 4)
            'convert array of 32bit floating point values in IEEE-754 format
            arrTemp(0) = arrBytes(32)
            arrTemp(1) = arrBytes(31)
            arrTemp(2) = arrBytes(30)
            arrTemp(3) = arrBytes(29)
            M32 = BitConverter.ToSingle(arrTemp, 0)
            'round
            M32 = Math.Round(M32, 4)
            'convert array of 32bit floating point values in IEEE-754 format
            arrTemp(0) = arrBytes(36)
            arrTemp(1) = arrBytes(35)
            arrTemp(2) = arrBytes(34)
            arrTemp(3) = arrBytes(33)
            M33 = BitConverter.ToSingle(arrTemp, 0)
            'round
            M33 = Math.Round(M33, 4)
            'calc timer tick and elapsed time
            TimerTick = TimerTickCalc(37)
        Else
            'set checksum return
            CheckSum = False
        End If

        'exit
        Exit Function
ErrorHandler:
        'set checksum return
        CheckSum = False
        'exit
        Exit Function
    End Function

    Private Sub SerialPort1_DataReceived(ByVal sender As System.Object, ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) Handles SerialPort1.DataReceived
        'set error handler
        On Error GoTo ErrorHandler

        'set variable
        UpperLimitOfArray = SerialPort1.BytesToRead - 1
        'prep array
        ReDim arrBytes(0 To UpperLimitOfArray)
        'get comm buffer
        SerialPort1.Read(arrBytes, 0, SerialPort1.BytesToRead)

        'test for no byte return
        If UBound(arrBytes) = -1 Then
            'set checksum indicator
            lblCheckSum.ForeColor = Color.Red
            'populate byte array with polling command for 0xC5
            ReDim arrBytes(0 To 0)
            arrBytes(0) = 197
            'send command
            SerialPort1.Write(arrBytes, 0, 1)
            'exit
            Exit Sub
        End If

        'test 31 byte return and header
        If Not UBound(arrBytes) = 42 And Not arrBytes(0) = 197 Then
            'set checksum indicator
            lblCheckSum.ForeColor = Color.Red
            'populate byte array with polling command for 0xC5
            ReDim arrBytes(0 To 0)
            arrBytes(0) = 197
            'send command
            SerialPort1.Write(arrBytes, 0, 1)
            'exit
            Exit Sub
        End If

        'test checksum
        If CheckSum() = False Then
            'set checksum indicator
            lblCheckSum.ForeColor = Color.Red
            'populate byte array with polling command for 0xC5
            ReDim arrBytes(0 To 0)
            arrBytes(0) = 197
            'send command
            SerialPort1.Write(arrBytes, 0, 1)
            'exit
            Exit Sub
        End If

        'set checksum indicator
        lblCheckSum.ForeColor = Color.Green

        'display data
        txtHeader.Text = MyHeader
        txtM11.Text = M11
        txtM12.Text = M12
        txtM13.Text = M13
        txtM21.Text = M21
        txtM22.Text = M22
        txtM23.Text = M23
        txtM31.Text = M31
        txtM32.Text = M32
        txtM33.Text = M33
        txtTimerTick.Text = DisplayTimerTickCalc
        txtElapsed.Text = ElapsedTime
        txtMyCheckSum.Text = MyCheckSum
        txtTheirCheckSum.Text = TheirCheckSum

        'calc and display determinant
        Call CalcDeterminant()
        'display determinant
        txtDeterminant.Text = Determinant
        'test determinant
        If Math.Abs(Determinant - 1) > Limit Then
            'event
            Call ReportEvent("Determinate outside limit")
        End If

        'populate byte array with polling command for 0xC5
        ReDim arrBytes(0 To 0)
        arrBytes(0) = 197
        'send command
        SerialPort1.Write(arrBytes, 0, 1)

        Exit Sub
ErrorHandler:

        'close serial port
        If SerialPort1.IsOpen = True Then SerialPort1.Close()
    End Sub

    Private Function CalcDeterminant()
        'dim vars
        Dim aei As Double
        Dim bfg As Double
        Dim cdh As Double
        Dim gec As Double
        Dim hfa As Double
        Dim idb As Double
        'calc products
        aei = M11 * M22 * M33
        bfg = M12 * M23 * M31
        cdh = M13 * M21 * M32
        gec = M31 * M22 * M13
        hfa = M32 * M23 * M11
        idb = M33 * M21 * M12
        'calc determinate
        Determinant = (aei + bfg + cdh) - (gec + hfa + idb)
    End Function

End Class
