Public Class Form1
    Dim WithEvents Spatial_Device As Phidgets.Spatial
    Dim GyroHeading(3) As Double
    Dim lastTime As Double


    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Spatial_Device = New Phidgets.Spatial()
        Spatial_Device.open()              'Use this line to open locally
        'Spatial_Device.open("ServerID")   'Use this line to open remotely

        attachedTxt.Text = "Not Attached"

    End Sub

    Private Sub Spatial_Attach(ByVal sender As Object, ByVal e As Phidgets.Events.AttachEventArgs) Handles Spatial_Device.Attach
        'When the Phidget RFID attaches update the form text boxes
        serialTxt.Text = (Str(Spatial_Device.SerialNumber))

        attachedTxt.Text = Spatial_Device.Attached.ToString()
        nameTxt.Text = Spatial_Device.Name.ToString()
        serialTxt.Text = Spatial_Device.SerialNumber.ToString()
        versionTxt.Text = Spatial_Device.Version.ToString()
        compassAxesTxt.Text = Spatial_Device.compassAxes.Count.ToString()
        If (Spatial_Device.compassAxes.Count > 0) Then
            compassBox.Visible = True
        Else
            compassBox.Visible = False
        End If
        gyroAxesTxt.Text = Spatial_Device.gyroAxes.Count.ToString()
        If (Spatial_Device.gyroAxes.Count > 0) Then
            gyroBox.Visible = True

            'Reset some of the variables used for gyro heading integration
            GyroHeading(0) = 0
            GyroHeading(1) = 0
            GyroHeading(2) = 0
            lastTime = 0
        Else
            gyroBox.Visible = False
        End If
        accelAxesTxt.Text = Spatial_Device.accelerometerAxes.Count.ToString()
        If (Spatial_Device.accelerometerAxes.Count > 0) Then
            accelBox.Visible = True

        Else
            accelBox.Visible = False
        End If

        dataRateTrack.Minimum = 1
        dataRateTrack.Maximum = Spatial_Device.DataRateMin / 8
        dataRateTrack.Value = Spatial_Device.DataRate / 8
        dataRateTxt.Text = (dataRateTrack.Value * 8).ToString
    End Sub

    Private Sub Spatial_Detach(ByVal sender As Object, ByVal e As Phidgets.Events.DetachEventArgs) Handles Spatial_Device.Detach
        'When the Phidget RFID detaches, clear text boxes
        serialTxt.Text = ""

        attachedTxt.Text = "Not Attached"
        nameTxt.Text = ""
        serialTxt.Text = ""
        versionTxt.Text = ""
        compassAxesTxt.Text = ""
        gyroAxesTxt.Text = ""
        accelAxesTxt.Text = ""

    End Sub

    Private Sub Spatial_Error(ByVal sender As Object, ByVal e As Phidgets.Events.ErrorEventArgs) Handles Spatial_Device.Error
        'Display any error messages that may be sent
        MessageBox.Show(e.exception.Message, "Error Event")
    End Sub

    Private Sub Spatial_Data(ByVal sender As Object, ByVal e As Phidgets.Events.SpatialDataEventArgs) Handles Spatial_Device.SpatialData
        'A Spatial event can return several data packets at once (if the data rate is set <8ms), we will loop through every packet that is sent
        Dim data_packet As Phidgets.SpatialEventData
        For Each data_packet In e.spatialData

            'If The Spatial contains an accelerometer, read in the values
            If (Spatial_Device.accelerometerAxes.Count > 0) Then
                xTextBox.Text = data_packet.Acceleration(0).ToString("f3")
                yTextBox.Text = data_packet.Acceleration(1).ToString("f3")
                zTextBox.Text = data_packet.Acceleration(2).ToString("f3")
            End If


            'If The Spatial contains a gyroscope, read in the values
            If (Spatial_Device.gyroAxes.Count > 0) Then
                'The gyroscope returns angular acceleration, so we integrate it over time to give us a bearing
                If lastTime = 0 Then lastTime = data_packet.Timestamp.Milliseconds 'Handle the initial case where there was no last time
                GyroHeading(0) += data_packet.AngularRate(0) * ((data_packet.Timestamp.TotalMilliseconds - lastTime) / 1000)
                GyroHeading(1) += data_packet.AngularRate(1) * ((data_packet.Timestamp.TotalMilliseconds - lastTime) / 1000)
                GyroHeading(2) += data_packet.AngularRate(2) * ((data_packet.Timestamp.TotalMilliseconds - lastTime) / 1000)
                lastTime = data_packet.Timestamp.TotalMilliseconds

                headingXText.Text = GyroHeading(0).ToString("f3") + "°"
                headingYText.Text = GyroHeading(1).ToString("f3") + "°"
                headingZText.Text = GyroHeading(2).ToString("f3") + "°"
            End If

            'If the Spatial contains a compass, read in the values
            If (Spatial_Device.compassAxes.Count > 0) Then
                'The compass needs to re-calibrate itself occationally. When this happens, it will not pass back any data. Check to make sure there's data
                If (data_packet.MagneticField.Length > 0) Then
                    compassXTxt.Text = data_packet.MagneticField(0).ToString("f3")
                    compassYTxt.Text = data_packet.MagneticField(1).ToString("f3")
                    compassZTxt.Text = data_packet.MagneticField(2).ToString("f3")
                End If
            End If

        Next
    End Sub

    Private Sub Form1_FormClosing(ByVal sender As System.Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles MyBase.FormClosing
        RemoveHandler Spatial_Device.Attach, AddressOf Spatial_Attach
        RemoveHandler Spatial_Device.Detach, AddressOf Spatial_Detach
        RemoveHandler Spatial_Device.SpatialData, AddressOf Spatial_Data
        RemoveHandler Spatial_Device.Error, AddressOf Spatial_Error
        Application.DoEvents()

        Spatial_Device.close()
        Spatial_Device = Nothing
    End Sub

    Private Sub dataRateTrack_Scroll(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles dataRateTrack.Scroll
        'The Spatial supports data rates in multiple of 8ms, with the following exceptions:
        '1056 will also accept a data rate of 4ms
        '1049 will also accept a data rate of 1, 2, 4ms
        'To simplify the example, we'll just allow 8ms as teh fastest data rate

        Spatial_Device.DataRate = dataRateTrack.Value * 8
        dataRateTxt.Text = (dataRateTrack.Value * 8).ToString()
    End Sub

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Spatial_Device.zeroGyro()
        GyroHeading(0) = 0
        GyroHeading(1) = 0
        GyroHeading(2) = 0
        lastTime = 0
    End Sub
End Class
