Search code examples
c#raspberry-pi3windows-iot-core-10

Windows IOT UWP - Relay


Good Evening,

I’m doing some troubleshooting on the beginning of my home automation system. I am trying to toggle a relay using a Raspberry PI 3 and Windows IOT in C#. I’ve been playing with the code and I can see the relay toggle once or twice, but then the app crashes. I’m an IOT Noob, so is there something wrong with this code? (Variable names are defined elsewhere and the weird variable names I have below are for my WIP project... I prefer troubleshooting in English)....

private void BtnTempFan_Click(object sender, RoutedEventArgs e)
    {
        if (BtnTempFan.IsChecked == true)
        {
            TogglePin(TempFan, TempFan_PIN, BtnTempFan, GpioPinValue.High);
        }
        else
        {
            TempFan.Dispose();
        }
    }
    private void TogglePin(GpioPin PinName, int PinNumber, ToggleButton Name, GpioPinValue value)
    {
        int pinnumber = PinNumber;
        GpioPinValue pinvalue;
        var gpio = GpioController.GetDefault();
        PinName = gpio.OpenPin(pinnumber);

        if (gpio == null)
        {
            PinName = null;
            LblError.Text = "We can't find the controller on the device" + PinName;
            LblError.Visibility = Visibility.Visible;
            return;
        }
        if (PinName == null)
        {
            LblError.Text = "We can't find the pin on the device. Pin number " + PinNumber + "does not exist";
            LblError.Visibility = Visibility.Visible;
            return;
        }
        if (Name.IsChecked == true)
        {
            pinvalue = value;
            PinName.Write(pinvalue);
            PinName.SetDriveMode(GpioPinDriveMode.Output);
        }

Solution

  • You don't say what the exception is. However, I believe you are supposed open a GPIO pin only once per app:

    var gpio = GpioController.GetDefault();
    PinName = gpio.OpenPin(pinnumber);
    

    You have it in a method which is called once per button click. By opening the pin more than once, you are encountering that the pin is already open, and I believe this is what throws an exception and crashes the app.


    In my code, I handle pin states in a "driver" class, and have a method called Connect which I call once when starting the application. For example:

    public async Task Connect()
    {
        var gpioController = await GpioController.GetDefaultAsync();
    
        try
        {
            _openPin = gpioController.OpenPin(_doorMotorOpenPin);
            _closePin = gpioController.OpenPin(_doorMotorClosePin);
        }
    }
    

    This encapsulates the 2 pins: _openPin and _closePin into a class that I can manage the lifecycle of.