user9105725
user9105725

Reputation:

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);
        }

Upvotes: 1

Views: 470

Answers (2)

user9105725
user9105725

Reputation:

Codekaizen is correct. I separated out opening the pin into a method that only gets called once and problem solved.

private void BtnTempFan_Click(object sender, RoutedEventArgs e)
    {
        if (BtnTempFan.IsChecked == false)
        {
            TogglePin(TempFan, TempFan_PIN, BtnTempFan, GpioPinValue.High);
        }
        if (BtnTempFan.IsChecked == true)
        {
            TogglePin(TempFan, TempFan_PIN, BtnTempFan, GpioPinValue.Low);
        }

    }

    private void InitializePins()
    {
        var gpio = GpioController.GetDefault();
        //   Show an error if there is no GPIO controller

        if (gpio == null)
        {
            TempFan = null;
            LblError.Text = "We can't find the controller on the device";
            LblError.Visibility = Visibility.Visible;
            return;
        }

        TempFan = gpio.OpenPin(TempFan_PIN);
        TempFan.SetDriveMode(GpioPinDriveMode.Output);
    }


    private void TogglePin(GpioPin PinName, int PinNumber, ToggleButton Name, GpioPinValue value)
    {
        int pinnumber = PinNumber;
        GpioPinValue pinvalue;
        pinvalue = value;
        PinName.Write(pinvalue);
    }

Upvotes: 0

codekaizen
codekaizen

Reputation: 27419

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.

Upvotes: 1

Related Questions