win10IoT - UWP (vb.net) - handle is invalid

1

I have a little problem with my UWP app, I try to turn on an LED, the INIT function works (the LED comes on when the GPIO is booted), however when I click on the ON or OFF button j have the following error:

System.runtime.interopservices.comexception (0x80070006) The handle is invalid.

MainPage.Xaml

<StackPanel x:Name="pnlOneLed" HorizontalAlignment="Center" VerticalAlignment="Top" Margin="10,160,10,10" Width="340">
        <Button x:Name="btnOneLedInit" Content="Init"  Margin="10" HorizontalAlignment="Center" Click="btnOneLedInit_Click"/>
        <TextBox x:Name="tbxOneLedStatement" Text="Led, Statement!" Margin="10" IsReadOnly="True"/>
        <Button x:Name="btnOneLedPushON" Content="ON"  Margin="10" HorizontalAlignment="Center" Click="btnOneLedPushON_Click"/>
        <Button x:Name="btnOneLedPushOFF" Content="OFF"  Margin="10" HorizontalAlignment="Center" Click="btnOneLedPushOFF_Click"/>
        <Image x:Name="imgOneLedDemo" Height="100" Margin="10" HorizontalAlignment="Stretch" Source="Assets/gpio-numbers-pi2.png" />
    </StackPanel>

MainPage.Xaml.vb

    Private Sub MainPage_Loaded() Handles Me.Loaded
    OneLed_Load()
End Sub

Private Sub MainPage_Unloaded() Handles Me.Unloaded
    UnloadGPIO()
End Sub

Private stateGpioPin5 As Integer = -1 '-1 : no value / 0 : OFF / 1 : ON
Private Const idGpioPin5 As Integer = 5 'GPIO Pin(5) = Physical Pin(29)
Private esGpioPin5 As GpioPin
Private esGpioPinValue5 As GpioPinValue

Private Sub OneLed_Load()
    btnOneLedInit.Content = "Click Me for Init"
End Sub

Private Sub btnOneLedInit_Click(sender As Object, e As RoutedEventArgs) Handles btnOneLedInit.Click
    Try
        If stateGpioPin5 < 0 Then
            If InitGPIO() Then
                btnOneLedInit.Content = "Disable"
                tbxOneLedStatement.Text = "GPIO ENABLE !"
            End If
        ElseIf stateGpioPin5 >= 0 Then
            If UnloadGPIO() Then
                btnOneLedInit.Content = "Enable"
                tbxOneLedStatement.Text = "GPIO DISABLE !"
            End If
        End If
    Catch ex As Exception
        tbxOneLedStatement.Text = "btnOneLedInit_Click FAILED : " & ex.ToString
    End Try
End Sub

Private Sub btnOneLedPushON_Click(sender As Object, e As RoutedEventArgs) Handles btnOneLedPushON.Click
    If PushGPIO(True) Then
        tbxOneLedStatement.Text = "LED ON !"
    Else
        UnloadGPIO()
    End If
End Sub

Private Sub btnOneLedPushOFF_Click(sender As Object, e As RoutedEventArgs) Handles btnOneLedPushOFF.Click
    If PushGPIO(False) Then
        tbxOneLedStatement.Text = "LED OFF !"
    Else
        UnloadGPIO()
    End If
End Sub

Private Function PushGPIO(pStatement As Boolean) As Boolean
    Dim output As Boolean = False
    Try
        If pStatement Then
            esGpioPinValue5 = (GpioPinValue.High)
        Else
            esGpioPinValue5 = (GpioPinValue.Low)
        End If
        esGpioPin5.Write(esGpioPinValue5)

        output = True
    Catch ex As Exception
        tbxOneLedStatement.Text = "PushGPIO FAILED : " & ex.ToString
    End Try

    Return output
End Function

Private Function InitGPIO() As Boolean
    Dim output As Boolean = False
    Try
        Dim gpio = GpioController.GetDefault()
        If Not gpio Is Nothing Then
            esGpioPin5 = gpio.OpenPin(idGpioPin5)
            esGpioPin5.Write(GpioPinValue.Low)
            esGpioPin5.SetDriveMode(GpioPinDriveMode.Output)
            stateGpioPin5 = 0

            output = True
        End If
    Catch ex As Exception
        tbxOneLedStatement.Text = "InitGPIO FAILED : " & ex.ToString
    End Try

    Return output
End Function

Private Function UnloadGPIO() As Boolean
    Dim output As Boolean = False
    Try
        esGpioPin5.Dispose()
        stateGpioPin5 = -1

        output = True
    Catch ex As Exception
        tbxOneLedStatement.Text = "UnloadGPIO FAILED : " & ex.ToString
    End Try

    Return output
End Function
vb.net
windows-10-iot-core
asked on Stack Overflow Nov 23, 2019 by TachikomaWebI

1 Answer

0

The exception is caused since the GPIO is disposed. When you click the Init button, the click event will be invoked twice, the app calls the UnloadGPIO method to dispose the GPIO. The reason is, you assigned the click handler in Xaml and again in code by adding the 'Handles btnOneLedInit.Click' at the end of your handler declaration. Following code will work fine.

Private Sub MainPage_Loaded() Handles Me.Loaded
    OneLed_Load()
End Sub

Private Sub MainPage_Unloaded() Handles Me.Unloaded
    UnloadGPIO()
End Sub

Private stateGpioPin5 As Integer = -1 '-1 : no value / 0 : OFF / 1 : ON
Private Const idGpioPin5 As Integer = 5 'GPIO Pin(5) = Physical Pin(29)
Private esGpioPin5 As GpioPin
Private esGpioPinValue5 As GpioPinValue

Private Sub OneLed_Load()
    btnOneLedInit.Content = "Click Me for Init"
End Sub

Private Sub btnOneLedInit_Click(sender As Object, e As RoutedEventArgs)
    Try
        If stateGpioPin5 < 0 Then
            If InitGPIO() Then
                btnOneLedInit.Content = "Disable"
                tbxOneLedStatement.Text = "GPIO ENABLE !"
            End If
        ElseIf stateGpioPin5 >= 0 Then
            If UnloadGPIO() Then
                btnOneLedInit.Content = "Enable"
                tbxOneLedStatement.Text = "GPIO DISABLE !"
            End If
        End If
    Catch ex As Exception
        tbxOneLedStatement.Text = "btnOneLedInit_Click FAILED : " & ex.ToString
    End Try
End Sub

Private Sub btnOneLedPushON_Click(sender As Object, e As RoutedEventArgs)
    If PushGPIO(True) Then
        tbxOneLedStatement.Text = "LED ON !"
    Else
        UnloadGPIO()
    End If
End Sub

Private Sub btnOneLedPushOFF_Click(sender As Object, e As RoutedEventArgs)
    If PushGPIO(False) Then
        tbxOneLedStatement.Text = "LED OFF !"
    Else
        UnloadGPIO()
    End If
End Sub

Private Function PushGPIO(pStatement As Boolean) As Boolean
    Dim output As Boolean = False
    Try
        If pStatement Then
            esGpioPinValue5 = (GpioPinValue.High)
        Else
            esGpioPinValue5 = (GpioPinValue.Low)
        End If
        esGpioPin5.Write(esGpioPinValue5)

        output = True
    Catch ex As Exception
        tbxOneLedStatement.Text = "PushGPIO FAILED : " & ex.ToString
    End Try

    Return output
End Function

Private Function InitGPIO() As Boolean
    Dim output As Boolean = False
    Try
        Dim gpio = GpioController.GetDefault()
        If Not gpio Is Nothing Then
            esGpioPin5 = gpio.OpenPin(idGpioPin5)
            esGpioPin5.Write(GpioPinValue.Low)
            esGpioPin5.SetDriveMode(GpioPinDriveMode.Output)
            stateGpioPin5 = 0

            output = True
        End If
    Catch ex As Exception
        tbxOneLedStatement.Text = "InitGPIO FAILED : " & ex.ToString
    End Try

    Return output
End Function

Private Function UnloadGPIO() As Boolean
    Dim output As Boolean = False
    Try
        esGpioPin5.Dispose()
        stateGpioPin5 = -1

        output = True
    Catch ex As Exception
        tbxOneLedStatement.Text = "UnloadGPIO FAILED : " & ex.ToString
    End Try

    Return output
End Function
answered on Stack Overflow Nov 25, 2019 by Michael Xu - MSFT

User contributions licensed under CC BY-SA 3.0