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
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
User contributions licensed under CC BY-SA 3.0