Добрый вечер,
Я занимаюсь устранением неполадок в начале моей системы домашней автоматизации. Я пытаюсь переключить реле с помощью Raspberry PI 3 и Windows IOT на C#. Я играл с кодом и вижу, как реле переключается один или два раза, но затем приложение вылетает. Я нуб IOT, что-то не так с этим кодом? (Имена переменных определены в другом месте, а приведенные ниже странные имена переменных предназначены для моего проекта WIP ... Я предпочитаю устранение неполадок на английском языке) ....
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);
}





Вы не говорите, в чем состоит исключение. Однако я считаю, что вы должны открывать контакт GPIO только один раз для каждого приложения:
var gpio = GpioController.GetDefault();
PinName = gpio.OpenPin(pinnumber);
Это у вас есть в методе, который вызывается один раз при нажатии кнопки. Открывая пин более одного раза, вы обнаруживаете, что пин уже открыт, и я считаю, что именно это вызывает исключение и приводит к сбою приложения.
В моем коде я обрабатываю состояния выводов в классе «драйвера» и имею метод под названием Connect, который я вызываю один раз при запуске приложения. Например:
public async Task Connect()
{
var gpioController = await GpioController.GetDefaultAsync();
try
{
_openPin = gpioController.OpenPin(_doorMotorOpenPin);
_closePin = gpioController.OpenPin(_doorMotorClosePin);
}
}
Это инкапсулирует 2 контакта: _openPin и _closePin в класс, жизненным циклом которого я могу управлять.
Это могло быть ответом. Я создам этот метод 1x для каждого приложения. Это имеет большой смысл, поскольку в настоящее время происходит сбой после того, как контакт переключается один раз, а реле щелкает один раз. Я надеюсь протестировать его в эти выходные и закончить эту термостатическую часть умного дома с защитой от облаков (по крайней мере, я надеюсь, что это так).
Кодекайдзен правильный. Я выделил открытие булавки на метод, который вызывается только один раз и проблема решается.
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);
}
Я вижу две вещи, которые выглядят неправильно, но я не могу сказать наверняка, что это проблема. Вы вызываете
TempFan.Dispose()в кнопке переключения; Это означает, что когда вы отключите кнопку, он попытается использовать TempFan (однако он уже будет удален). Другое дело, что вы вызываетеvar gpio = GpioController.GetDefault();, а затем немедленно пытаетесь назначить вывод от него с помощьюPinName = gpio.OpenPin(pinnumber);.gpioдля нуля. Проверяйте значение null сразу после его назначения, иначе назначение PinName приведет к ошибке.